Search code examples
htmlcssinlinevertical-alignment

Vertical-align works strangely (on cell-tabs)


I have a problem using the vertical-align:top; property on a cell-tab css content.

Here the picture : http://img4.hostingpics.net/pics/157625Capture.png

My HTML code :

    <!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8" />
        <link rel="stylesheet" href="style_test.css" />
        <title>Test</title>
    </head>
    <body>
            <div class='tableau'>
            AAAA<img class='img1' src='images/drapeau_anglais.gif' />
            <img class='img2' src='images/drapeau_anglais.gif' />
            <span>BBBB</span> 
            <!-- This text lose the vertical-align:top; propertie because it is in the <span> => WHY ??? -->
            <p>CCCC<img src='images/drapeau_anglais.gif' />DDDD</p>
            <!-- As in the span, everything in my <p> loose it s vertical align propertie -->
            </div>
    </body>
</html>

My CSS code :

    .tableau
{
    display:table-cell;
    border:1px solid black;
    vertical-align:top;
}
.tableau p
{
    display:inline-block;
}
.img1
{
    /* I dont say anything here. img1 SHOULD be on top because of the ".tableau" class but it doesnt... why???*/
}
.img2
{
    /* I force the vertical align on my image (but I shouldnt have to do that normally ?) But with this "trick" it works */
    vertical-align:top;
}

Thanks a lot for your help !


Solution

  • I commend you for wanting to understand. The problem with vertical-align is that it doesn't take much HTML and CSS for there to be quite a lot going on. What we can do it to build the layout up piece by piece.

    AAAA

    This text is placed in a anonymous inline box. This goes in a line box, preceded by a zero-width inline box that's the height of the container element's font, called the strut. The strut and the AAAA text are vertically aligned with each other with respect to each others baseline. So already, we have

    Figure with AAAA text, strut, baseline and line box

    <img class='img1' src='...' />

    The vertical-align of the .img1 element is the default which is baseline, and images are replaced inline elements, so the baseline of the image is its bottom margin edge. .img1 has no margins, border or padding, so that makes it the bottom edge of the image itself, so now, if we assume that the image is taller than the font, we have

    addition of img element to the first figure

    Note that the line box is now taller than previously to accommodate the image. In fact the line box is taller than any of its component parts.

    <img class='img2' src='...' /> part one

    We'll skip the second image for the moment and come back to it later. We'll just leave a placeholder for now.

    <span>BBBB</span>

    Exactly as AAAA, except that here the inline box is formed from a real element rather than being anonymous. This gives us

    addition of placeholder and BBBB text to figure 2

    CCCC<img src='...' />DDDD

    This is exactly like AAAA<img src='...' />BBBB`. Nothing new to add here.

    <p>CC...DD</p>

    The p element is set to inline-block, which means that its line-height contribution to the line it is in is its margin box. It has default margins from the user agent stylesheet of (typically) 1em top and bottom. It too is aligned to the other elements on the line using its baseline. So now we have

    addition of p element to figure 3

    Again the line box grows in height, this time to accommodate the p element's margin box.

    <img class='img2' src='...' /> part two

    Now we can fill in the placeholder we left earlier for .img2. This image is vertical align:top, so it doesn't align with the other elements, but with the top of the line box. So that gives us

    addition of top aligned image to figure 4

    .tableau { display:table-cell; vertical-align:top; }

    Then the whole thing is wrapped up as one and positioned at the top of the table-cell.

    Wrap up

    Finally, we need to account for why "AAAA" appears at the top in your picture and not aligned to the other text as depicted in my answer above. This seems to be because you captured the picture from Chrome, and was therefore subjected to Chrome's screwy vertical-align implementation. Firefox and IE display the layout correctly.