Centering HTML elements larger than their parents
It's not a common problem, but I ' ve run into it a few times. How does you center a element when it is larger than it's parent? I mean really center it, where content overflows both the left and right borders of the parent element equally.
The default behaviour in HTML and CSS (using) are to line up the left edges of the child and the margin:0px auto; parent elements while Al L The overflowing happens on the right side. That ' s not centered at all; It's the most definitely offset to the right, which are painfully obvious if what are really wanted were to have the center of T He child element line up with the center of the parent element, regardless of size.
Page centering Contextthis is the parent element
The child element
which should be centered
IMHO, the ideal behaviour would look something like this image:
So I is working on a project this required the behaviour I was expecting, rather than what HTML and CSS normally provides With a simple margin:0px auto; declaration. It also had to fit a few other strict criteria which ruled out several other "solutions" you can find out there.
- Have to work for children of varying widths, not just those of specified pixel dimensions.
- No absolute positioning or floating
- No javascript-the effect needed to work whether or not JavaScript is enabled or disabled.
Item #1 rules out of the simplest solution which merely applies a negative left margin to the child element. If we know how wide the parent are, and how wide the child is, then we just need to apply a negative left margin that's EQ UAL to the difference of the child element and the parent element widths, divided by. If we don ' t know the width of the child element, setting a specific left margin was just going to make it look weird for Al L widths except one.
Item #2 rules out positioning solutions, combinations of percentage positioning to achieve a centered child elemen T. But because this removes the element from the flow of the document, the bottom of the parent element would cinch up and The content below it would collide with the content of the "child" element. I needed the parent element to remain tall enough to contain the height of the entire child element; It ' s only the width I am concerned about here.
Finally, Item #3 rules out JavaScript solutions that test the parent and child elements after the page has loaded and dete Rmines what negative margins or positioning the values to set. This works every time, except if JavaScript is disabled. Granted that isn ' t often these days for visual browsers, but I still do not want to depend on script for something that W As clearly just a styling issue.
Eventually I happened upon a solution that fit all three criteria above, and although it came with a few issues of its own , I decided I could live with them. You may know of a different or even better-to-accomplish this, but here's what I came up with.
First, instead of setting a width or margins for the parent element WRT The page context, let it expand to the FU ll width. Then relatively position it with a value of right:50%; .
Page centering Contextthis is the parent element
The child element
which should be centered
This puts the center of the parent element directly on the left border of the page centering context. Since the parent element is now the same width as the page centering context, which means its right border is Exac tly in the center of the page centering context! We exploit this fact as we move on.
What we want to does now are to move the center of the child element so it aligns with the right border of the Paren t element. The child element needs to is centered within the parent element so the center of the child element I S also sitting on the left border of the page centering context.
Okay, Leap-of-faith Here:even if it doesn ' t look like it ' s centered, as long as you apply the correct centering Styles, the child element would behave as if it were centered when you apply the negative margins we ' ll need in th E Next step.
But we have a problem. How does center a block if you need to specify both for margin:0px auto; centering and also a negative margin-right ? Doing this would override one of the values of the the margin and the child auto element would no longer be centered. Is there another-to center a block?
yes! We can use our old friend to text-align:center; Center inline elements within the parent block. The style applicable to the block child element we are using, we'll turn it into a hybrid using display:inline-block; . This change introduces a restriction though, which prevents us from have other inline content abutting either side of th e child element. Otherwise the won't text-align center our block properly. The child element needs to is the only inline element on the ' line '. So we'll have a to remove our little "this was the parent element" note to move forward.
Page Centering Context
The child element
which should be centered
Like I mentioned before, it doesn ' t look centered, but its calculated position would behave as if it is when we AP Ply the final step, the negative margin-right . With the parent block's left border resting in the center of the page centering context, we now know the distance between Where the center of the child element was now, and where we need it to be:exactly half the width of the parent element.
This being said, you ' d think a negative of 50% on the "child" margin-right element would move the center point nicely, and in fact It doesn ' t. Actually it only appears to move the block 25% of the width of the the parent element.
Page Centering Context
The child element
which should be centered
This is indeed odd, and if someone knows what it behaves this, I would being grateful to hear it explained. In any case, this oddity is the no big deal to overcome; Just specify a negative of margin-right 100% instead:
Page Centering Context
The child element
which should be centered
centered! Now, the only problem we ' re left with is the parent block; We don ' t want to see it. Hiding the parent block is simple, we'll just remove the border and make sure it background is transparent. We can ' t use display:none; or here visibility:hidden; because, would also affect the visibility of the child element.
Page Centering Context
The child element
which should be centered
And the code: (Important styles are highlighted)
Div#context{Border1pxSolidBlueWidth400px;Margin0pxAuto}div#context div { position:relative; Right :50%; text-align:Center;} Div#context Div p { border:1px solid Green; width:450px; height:50px; display:inline-block; margin-right:-100%;}
ID="context"> page Centering Context <p> This was the child element</div> </div>
We ' re done! The great benefit of this system, despite the restrictions, was that it is uniquely dynamic. You can change the width of the "child" element to whatever and it'll remain centered wrt the page cen tering context, either smaller or larger.
Page Centering Context
The child element
which should be centered
The child element
which should be centered
Things to remember about the This system:
- The parent element can ' t contain any inline content, the abuts the child
inline-block .
- In fact, since the parent element was offset so, you probably can ' t use it for anything other than an empty non-visible con Tainer block for the child element.
- You can use
left margin-left and to accomplish the same thing, although you run the risk of generating a horizontal scrollbar F or the page.
- If the child element is a image, you don ' t need
display:inline-block; the style, as images is already inline-blocks.
- IE7 and earlier can ' t Inderstand
display:inline-block; the style unless you apply it to a element that's inline by default (span, strong , em ...). If you require compatibility for these browsers, use a <span> element for your child block.
http://www.greywyvern.com/?post=323
Centering HTML elements larger than their parents