16 July 2011

Overflow hidden (CSS) - Totally mad as a fish

Anyone who thinks cascading style sheets are what you get when the doors of a laundry delivery van fly open en route to a posh hotel may want to skip this blog.

One of the reasons that so many people stick width fixed-width layouts is that some things, even simple things, can be so damn difficult with fluid layouts. When you don't define everything in pixels, you need to know some tricks to get things to behave themselves.

The reason I'm writing this blog is that I've just discovered one of those tricks, and it turns out to be the same trick that is used for a completely different problem. It is the multi-talented property "overflow : hidden".

Hidden Content


Now the obvious reason to set "overflow : hidden" is when you have a fixed height div and don't want any surplus content to leak out the bottom. I'm sure many people think that's all it does.

Visible Content


But have you ever created a div with no fixed height and stuck an image in the bottom which is shifted down by a relative offset? (come on, you must have done). The height of the div is calculated on the unshifted layout, so as the image shifts it gets cut off at the bottom - how stupid is that?

The trick here is to use "overflow : hidden". Strangely, rather than hiding anything it actually makes the div bigger so nothing is hidden. I spent a lot of time chewing my thinking-pencil when I discovered that. (that's not a euphemism, btw, I chew things when I'm thinking).


Side-by-side

More recently I was trying to make two div sit side by side. The left hand div would have a fixed width, and the other would fill the remaining width of the page. How hard could it be?



<div class='leftpanel'></div>
<div class='rightpanel'></div>


 This is what I was after...


The red div is fixed width and set to "float : left", the blue div is fluid, it has no dimensions defined. Sadly, this is what I got (I've made the blue div slightly transparent to show what is happening).


Interestingly, the text understood what was required, to some extent - it stopped when it got to the red div, but the div itself followed its natural instincts and made itself as wide as possible (if I hadn't made the blue div partly transparent, you would not see the red div at all).

No combination of position, display, or margin settings would make the divs behave. I couldn't make the blue div "display : block", or it would drop below the red div and remain full width. If I made it an inline-block, it shrunk to it's minimum width. (chew, chew...)

So what was the answer? Strangely,  "overflow : hidden".

It seems that by hiding the overflow, the div suddenly sees the floating div and decides not to tred on it. So again, it doesn't hide overflowing content, it changes the size of the div to fit the content, in this case making it behave like a block that respects the floating div. Exactly what I was after.

So, in summary...


When a div has a fixed height, "overflow : hidden" will hide any overflowing content.

When a div has no fixed height and shifted content wants to hide below the bottom of a div, "overflow : hidden" will expand the div downwards.

When a div is next to a floated object and wants to occupy the full width of the parent object, "overflow : hidden" will stop it expanding over the floated object.


I'm almost tempted to say that whenever you don't define the height of a div, set "overflow : hidden". It doesn't actually hide content, it just makes the div behave itself. Wonder why it doesn't do that without being told?

Note to self - need a new box of pencils.