Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How is this HTML5 brick falling down?

Tags:

html

css

layout

I've prepared a sample jsfiddle to show the problem I'm currently facing with my layout: when I insert a content dynamically into a particular element (the brick), the element sinks down together with its parent in a way that's beyond my understanding of HTML/CSS. When I remove the content, the original layout is restored, unless I'm using Chrome... then it would retain its position and fall down again when a new content is inserted.

Proof of concept: http://jsfiddle.net/GADk9/

The checkbox in the example simply toggles a text inside the brick, nothing more. I wonder where the above margin (is it?) comes from.

Here is a complete HTML5 document:

<!DOCTYPE html>
<html lang='en'>
<head>
<meta charset='UTF-8'>
<title>HTML5 Falling Brick - What is this?</title>
<style>
#brick {
    background-color: lightgray;
    border: solid black medium;
    border-radius: 1em;
    color: red;
    font-size: 2em;
    height: 100%;
    text-align: center;
}
#contrail { background-color: lightblue; width: 20em; }
#pit { display: table; }
#pit>* { display: table-cell; }
#pit>*>* { height: 4em; }
</style>
</head>
<body>
    <div>
        <label>Click me twice
            <input onchange="document.getElementById('brick').innerHTML = this.checked ? 'FALL!!!' : ''" type='checkbox'></input>
        </label>
    </div>
    <div id='pit'>
        <div>
            <div>
            </div>
        </div>
        <div id='contrail'>
            <div>
                <div id='brick'></div>
            </div>
        </div>
    </div>
</body>
</html>

Update

After reading again my question I realize it may suggest the incorrect impression that what I'm actually trying to accomplish is fixing some HTML. To emphasize the point explicitly, I don't need to change anything here. The example with the brick is just a funny demo of the issue I'm observing. I'm really interested in understanding what is causing the elements to change their position when a content is inserted in an arrangement like this.

like image 382
GOTO 0 Avatar asked Apr 24 '13 00:04

GOTO 0


People also ask

How do you insert a table in HTML?

An HTML table is created with an opening <table> tag and a closing </table> tag. Inside these tags, data is organized into rows and columns by using opening and closing table row <tr> tags and opening and closing table data <td> tags. Table row <tr> tags are used to create a row of data.

How do you add a row in the middle of a table in HTML?

The insertRow() method creates an empty <tr> element and adds it to a table. The insertRow() method inserts the new row(s) at the specified index in the table. Note: A <tr> element must contain one or more <th> or <td> elements.


2 Answers

You have

<div id='pit'>
    <div>
        <div>
        </div>
    </div>
    <div id='contrail'>
        <div>
            <div id='brick'></div>
        </div>
    </div>
</div>

And you are using

#pit { display: table; }
#pit>* { display: table-cell; }
#pit>*>* { height: 4em; }

Now here is our problem as it says #pit is table and #pit>* is a table-cell it is adding up height: 4em; every time.

Now here is my solution.

#pit { display: block; }
#pit>* { display: table; }
#pit>*>* { height: 4em; display: table-cell;}

http://jsfiddle.net/AAbhishekk/GADk9/28/

like image 118
Abhishek Avatar answered Sep 18 '22 13:09

Abhishek


I've seen behavioral differences between browsers when using table, table-row and table-cell display many times. To begin with, I never use them as there is always a better solution. However, to your question:

When dealing with CSS that is intended to behave like tables, it helps to think a little old school.

It turns out the magic CSS property to make your POC in the Fiddle behave properly is vertical-align. In fact, this fixes the odd insertion of additional vertical space in all the browsers, not just Chrome, while also fixing the problem of Chrome retaining the additional space.

Check out this tiny revision to the fiddle: http://jsfiddle.net/rtzeK/

#brick {
    background-color: lightgray;
    border: solid black medium;
    border-radius: 1em;
    color: red;
    font-size: 2em;
    height: 100%;
    text-align: center;
}
#contrail { background-color: lightblue; width: 20em; }
#pit { display: table; }
#pit>* { display: table-cell; vertical-align: top; }
#pit>*>* { height: 4em; }

In the fiddle I linked, I simply set the children that are display: table-cell to have the additional property, vertical-align: top. As it turns out, you can set it to middle or bottom, all with the same effect. It stops the misbehavior - apparently Chrome needs to be told how to behave in this scenario.

I do find it a little odd how Chrome is misbehaving, and it appears to be a bug. That said, I go back to my previous statement about avoiding these display property values like the plague. Combinations of display: inline, inline-block, block, combined with relative and absolute positioning used appropriately across parents and children renders other troublesome css properties, e.g. float, unnecessary.

Cheers

like image 35
Jim Speaker Avatar answered Sep 18 '22 13:09

Jim Speaker