Forums

The forums ran from 2008-2020 and are now closed and viewable here as an archive.

Home Forums CSS Horizontally centering an absolute element

Viewing 12 posts - 1 through 12 (of 12 total)
  • Author
    Posts
  • #197427
    Shikkediel
    Participant

    Been looking around to find the cleanest way to do this…
    There are a few options, like for example when the width is known :

    #somelement {
    width: 200px;
    position: absolute;
    left: 50%;
    margin-left: -100px
    }
    

    Not too shabby – using translate :

    #somelement {
    position: absolute;
    left: 50%;
    -webkit-transform: translateX(-50%);
    transform: translateX(-50%)
    }
    

    But apparently this is also an alternative :

    #somelement {
    position: absolute;
    left: 0;
    right: 0;
    margin: auto
    }
    

    I find this the nicest solution but don’t really get why this actually works. Could someone maybe explain a bit more?

    http://www.w3.org/TR/CSS2/visuren.html#position-props

    #197428
    Paulie_D
    Member

    The first option works when you know the width of the absolutely positioned element. As such it’s not very flexible or responsive.


    The second option works when you don’t know the width of the absolutely positioned element. Excellent for responsiveness but is CSS3…older browsers may have an issue.


    The third option works when you don’t know the width of the absolutely positioned element but makes it 100% wide of it’s parent which might not fit the design.


    If you do know the width, you can use the third option as well and it will center. Again requires defined width so less than flexible.


    I prefer option 2 but they all have their places

    #197429
    Paulie_D
    Member

    Interestingly (or not)…if you don’t know the width (using the third option) but define a max-width the width will default to the that maximum and center.

    Options, options….

    #197445
    Shikkediel
    Participant

    Cheers, Paulie. Nothing has more endless little surprises than CSS.
    I’m using the third option – an animation that needs some exact pixels defined but I’m making it responsive anyway by using scale transform :

    http://ataredo.com/

    The Codepen link of course (resizing starts at screens less tall than 500px)… I could probably do it with view height units as well but that’s used on the image above already so I threw a bit of jQuery at this one.

    Anyway, what I still don’t quite understand is the mechanism of what is set here exactly – making the margin: auto work :

    #somelement {
    left: 0;
    right: 0
    }
    

    Can’t follow what the W3 doc states, it is not about positioning but referring to some bigger scope? Thanks in advance for any insight.

    #197446
    Paulie_D
    Member

    As for a concept overview my reading is this

    This property (TOP) specifies how far an absolutely positioned box’s top margin edge is offset below the top edge of the box’s containing block. For relatively positioned boxes, the offset is with respect to the top edges of the box itself (i.e., the box is given a position in the normal flow, then offset from that position according to these properties).

    The same concept applies to the other properties but let’s just stick with top

    So top:0 means the top edge of the positioned item will be positioned 0 pixels (I think the default is px or just insert your chosen units) away from the top edge of the containing block.

    If we set top:10px it will be 10px below the top edge.

    Now, when we set…

    #somelement {
    left: 0;
    right: 0;
    }
    

    …we are actually saying that (absent any other instructions) the left and right edges of the absolutely positioned element must be 0 pixels away from the containing block’s respective sides.

    When we set the element to position:absolute it makes the element (I think I’m right) automatically display:block which then defaults to 100% wide.

    If we set a width…it will respect that, ditto max-width…and the margin:auto will center just like any other block level element.

    If you don’t use the margin: auto..say like this

    .child {
        position: absolute;
        right: 0;
        left: 0;
        width: 100px;
    }
    

    The natural text flow of the document (usually left aligned) takes over and the right:property is effectively ignored.

    #197449
    Shikkediel
    Participant

    Thanks for the elaborate answer. I’m think I’m gonna have to read it a few times but things are getting clearer…

    #197454
    Paulie_D
    Member

    No problem…this is just my interpretation of what’s going on…I think I’m close but I’m happy to be corrected.

    Basically (I think) margin:auto works to center any block level element with a defined width even if that width is unstated because it’s inherently set by the default to 100%, in which case the centering is irrelevant.

    #197481
    Shikkediel
    Participant

    I’ll mess around with Codepen, hoping my brain finds the connection.

    There was another horizontal alignment issue on that page, be it not one that had to do with absolute positioning – when the page would get so small that the text inside the <a> navigation links becomes larger then the assigned space (extra tricky with a transform involved). The ‘overflow’ of text is then creating an offset, making it not centered.

    Sometimes with CSS you get something to work but you’re not sure how you got there. Wrapped the text in a span and gave it this style :

    .option span {
    display: inline-block; /* needed for scaling */
    position: relative;
    left: 50%;
    margin-left: -100%;
    -webkit-transform: scale(0.7, 1); /* three lines above most relevant */
    transform: scale(0.7, 1)
    }
    

    Works like a charm now but took a lot of trial (and mostly error).

    B-)

    Anyone interested to see the difference, a very small screen (with relatively large height to fit the dev tools) will show the difference when these lines are not applied. Not really another question but maybe interesting for posterity.

    Edit – forgot to mention it’s only the ‘Graphics’ text that is too long…

    #197505
    Shikkediel
    Participant

    Not really another question

    For that matter, I get this one even less than the case I started this topic about. But it’s a stretch to ask anyone to check it out like described above, so here’s a reduced version :

    Centering a text larger than it’s link space

    Apart from the absolute position, still quite on topic. But what I don’t understand is the very last line of CSS. Until that it sort of makes sense but giving it a margin of -100% only seems to move it 50% to the left?

    Removing the positioning on the span (possibly inserting a shorter word) will show how it looks without this extra centering, even with text-align: center applied. I think CSS might sometimes stand for Complicated Strange Secrets, lol.

    #197511
    Shikkediel
    Participant

    Thanks for the reply. I find your description a bit enigmatic but it does lead to some interesting new insight. However, display: inline-block doesn’t seem to be needed and setting margin to -50% only appears to work until a much larger text is inside the span :

    Pen with a whole bunch of text

    Strangely enough the conclusion can be drawn that merely this also works for centering (provided text-align: center is applied) :

    span {
    margin: -100%
    }
    

    Still kinda left with a big question mark… And link to a doc describing this is very welcome. But I’m possibly missing something very basic.

    Edit – I guess not resetting margin and padding on Codepen here isn’t the greatest idea. Gonna have to rethink…

    #197513
    Shikkediel
    Participant

    Got a step closer. No value in percentage would be of use to set margin because it is referring to the size of the containing parent and not to the element itself. So the longer the text, the higher the percentage would have to be to center the text. And no way to reliably do that even if it looks close enough. That’ll be one for jQuery I guess (but prefer CSS).

    Hey, nice…

    span {
    display: inline-block;
    position: relative;
    left: 50%;
    -webkit-transform: translateX(-50%);
    transform: translateX(-50%)
    }
    

    Pen that actually works!

    #197601
    Shikkediel
    Participant

    In retrospect that last question’s quite obvious.. but it’s teaching me that mysterious CSS is usually caused by looking at it crooked.

    Still, transform is a nice solution for it.

    Now, when we set…

    #somelement {
    left: 0;
    right: 0;
    }

    …we are actually saying that (absent any other instructions) the left and right edges of the absolutely positioned element must be 0 pixels away from the containing block’s respective sides.

    When we set the element to position:absolute it makes the element (I think I’m right) automatically display:block which then defaults to 100% wide.

    This is very interesting. Never realised you can influence width like that.

    Minor demonstration

Viewing 12 posts - 1 through 12 (of 12 total)
  • The forum ‘CSS’ is closed to new topics and replies.