tags:

views:

123

answers:

6

Damn, I always feel frustated with CSS. I keep reading books and articles/tuturials but CSS is a PITA!

I've the following code:

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Testing CSS</title>
<style type="text/css">
<!--
body {
    background: #dddddd;
    font: 12px "Trebuchet MS", Helvetica, sans-serif;
    color: #000;
}
.box {
    background: #FFF;
    width: 500px;
    border: 1px solid #999999;
    -moz-border-radius: 5px;
}
.box .content {
    background: #FFF;
    padding: 15px;
    -moz-border-radius: 5px;
}
.message {
    border: 1px solid #bbbbbb;
    padding: 10px;
    margin: 0px 0px 15px;
    background-color: #DDDDDD;
    color: #333333;
    -moz-border-radius: 5px;
}
.message.info {
    border-color: #9FD1F5;
    background-color: #C3E6FF;
    color: #005898;
}
._50\% {
    display: inline;
    float: left;
    margin: 0 2%;
    overflow: hidden;
    position: relative;
    width: 46%;
}
-->
</style>
</head>

<body>
    <div class="box">
        <div class="content">
            <div class="message info">Info message.</div>
            <div class="message _50%">Simple message.</div>
            <div class="message _50%">Simple message.</div>
        </div>
    </div>
</body>
</html>

But no matter what I do I can't seem to get the two "Simple Messages" to display side by side, bellow the "Info Message", I already tried playing with display, overflow, etc... Nothing seems to work.

CSS Overflow

What am I missing?

+1  A: 

First thing, try putting overflow: hidden on your .content element. Setting overflow on the child elements won't do much good to prevent them from overflowing. By setting overflow: hidden on the containing element, you will (in most browsers) force it to expand to contain its children.

jrista
Thanks, the simple messages now appear inside the box, one problem down! They still don't appear side by side however and I believe my math is right (2 + 46 + 2) * 2 = 100.
Alix Axel
A: 

try to simple lower the width of the _50% it seems like the total with of the two _50% is bigger than the with of content and instead of using % width, try to use px

this css works for me

._50\% {
    display: inline;
    float: left;
    margin: 0 2%;
    overflow: hidden;
    position: relative;
    width: 90px;
}

if you want to make a div display side by side by display: inline or by float you need to calculate the width of the container and the width of the div's inside the container. Specially if you have a margin and padding since these will take up spaces.

rob waminal
You want to use % widths in fluid websites. There is alot of reason to use % over px.
Thqr
But shouldn't relative units solve that problem? (2% + 46% + 2%) * 2 = 100%, no?
Alix Axel
+1  A: 

I'm not sure how valid (or widely supported) CSS classes using the % character are.

You might also find that your width doesn't take into account the border (differing box models across browsers).

Graphain
Thanks, but shouldn't the relative width solve the problem of the different box models? My interpretation is that they should occupy 100% of the space there is available, but if not, is there a workaround?
Alix Axel
Try removing the border on the internal messages and see what happens. Then try without the padding on `content` as the width might not take this into account. Combining `px` and `%` is always a recipe for disaster (although obviously necessary sometimes).
Graphain
A: 

Because of the margins in ._50 class, I would change width to lower value, eg. 41%. I would also remove position relative and inlne directives.

._50\% {
    float: left;
    margin: 0 2%;
    width: 41%;
}

Add new class .clear, and add new div with this clear class below messages so outer div can expand.

.clear
{
   clear: both;
}

,v

<body>
        <div class="box">
            <div class="content">
                <div class="message info">Info message.</div>
                <div class="message _50%">Simple message.</div>
                <div class="message _50%">Simple message.</div>
              <div class="clear"></div>
            </div>
        </div>
    </body>
    </html>

That is all. Floats are great tool, but you must understand how they wokrk.

zidane
+11  A: 

Your math isn't quite right.

Let's sort of eyeball things to begin with....

The Simple Message boxes have a width of:

2% + 46% + 2% + (1 px BORDER on each side) + (10px PADDING on each side)

That's more than 50% !

The CSS box model says that the width of the padding, border, and margin are added to the outside of the CSS defined width of an element (in theory, in practice older versions of IE don't follow this rule, newer versions do).

So the border and padding definitions for .message are fattening your Simple Message boxes.

If you drop the widths of your Simple Message boxes to 41%, they end up on the same row.

Let's look at the specifics to understand why....


The breakdown

OK, here are your boxes:

class box
    500px wide with a 1px border all around
        Pixels left to play with ==> 500

class content
    15px padding on the OUTSIDE of .content on all side. 
    content is INSIDE .box, the maximum width of .content is 500px
    but the padding is taking up some of this space (15*2 = 30px)
        Pixels left to play with ==> 470

class message info
    The maximum width of anything inside .content is 470px
    There are two _50% boxes, so each can have a max total width
      (including all the padding, border, margin) of 470/2 = 235px
    Width of 
        + 46% of 470px = 216.2          = 216px 
        + 2*10px padding                =  20px
        + 2*1px border                  =   2px
        + 2*(2% of 470px) = 2*9.4 = 2*9 =  18px
        ---------------------------------------
                                          256px! ==> 2*256 > 470

Now why does width 41% work?

class box
        Pixels left to play with ==> 500

class content
        Pixels left to play with ==> 470

class message info
    Width of
        + 41% of 470px = 192.7          = 193px
        + 2*10px padding                =  20px
        + 2*1px border                  =   2px
        + 2*(2% of 470px) = 2*9.4 = 2*9 =  18px
        ---------------------------------------
                                          233px ==> 2*233 < 470

Finally 42% doesn't work because

42% of 470 = 197.4 = 197.
197 + 20 + 2 + 18 = 237
237 * 2 = 474........ and 474 > 470

In General

I suggest a look at things using Firebug. Make sure you alternate between the Layout tab, which shows you the box model, and the Style tab, where you can temporarily test alter your CSS!

For the collapsing box problem, I suggest:

.box .content {
      /* This lets .content expand in height with the floating divs inside it */
    overflow: auto;
}
Peter Ajtai
… and that's before rounding errors which could bump the total of the percentages able 100% before accounting for the borders.
David Dorward
Great explanation, that clears things up. Thanks a lot!
Alix Axel
good math in there.. :)
rob waminal
A: 
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Testing CSS</title>
<style type="text/css">
<!--
body {
    background: #dddddd;
    font: 12px "Trebuchet MS", Helvetica, sans-serif;
    color: #000;
}
.box {
    background: #FFF;
    width: 500px;
    border: 1px solid #999999;
    -moz-border-radius: 5px;
}
.box .content {
    background: #FFF;
    padding: 15px;
    -moz-border-radius: 5px;
}
.message {
    border: 1px solid #bbbbbb;
    padding: 10px;
    margin: 0px 0px 15px;
    background-color: #DDDDDD;
    color: #333333;
    -moz-border-radius: 5px;
}
.message.info {
    border-color: #9FD1F5;
    background-color: #C3E6FF;
    color: #005898;
}
._50\% {
    display: inline;
    float: left;
    margin: 0 5px;
    position: relative;
    width: 42%;
}
-->
</style>
</head>

<body>
    <div class="box">
        <div class="content">
            <div class="message info">Info message.</div>
            <div class="message _50%">Simple message.</div>
            <div class="message _50%">Simple message.</div>
        </div>
    </div>
</body>
</html>
tomvon