Is it possible to tell the code to position by the center point of an element, rather than by the top-left point? If my parent element has
width
I got it working by using transform: translateX
with calc
for horizonally positioning by element center instead of top-left. Same trick can be used for vertical using transform: transformY
. This will work with width of any type (try resizing)
Snippet: transform: translateX(calc(-50% + 223px));
Browser support: https://caniuse.com/#feat=transforms2d, https://caniuse.com/#feat=calc
Codepen for more examples: https://codepen.io/manikantag/pen/KJpxmN
Note on offsetLeft/offsetTop etc: el.offsetLeft
will not given proper value for CSS transformed elements. You would require something like el.getBoundingClientRect().left - el.offsetLeft - el.parentNode.offsetLeft
(as mentioned here)
Note about flow effect: as detailed in CSS Things That Don’t Occupy Space, transform doesn't effect the following element without considering the offset caused by transform. Sometimes this may not be the intended behavior. This can be fixed using negative margins if width/height are fixed (doesn't work if width/height are using %
)
.left-positioned {
margin-left: 223px;
background-color: lightcoral;
}
.center-positioned {
transform: translateX(calc(-50% + 223px)); /*=====> actual solution */
background-color: cyan;
}
.with-width {
width: 343px;
background-color: lightgreen;
}
/* styles not related to actual solution */
div {
resize: both;
overflow: auto;
}
.container {
background-color: lightgray;
}
.ele {
display: inline-block;
height: 70px;
text-align: center;
}
Reference element (left at 223px)
^
Center positioned element (center at 223px)
^
Center positioned element with width (center at 223px)