Как этот кирпич HTML5 падает?
Я подготовил образец jsfiddle, чтобы показать проблему, с которой я сейчас сталкиваюсь с моим макетом: когда я динамически вставляю содержимое в конкретный элемент (кирпич), элемент опускается вместе со своим родителем таким образом, что вне моего понимания HTML/CSS. Когда я удаляю содержимое, исходный макет восстанавливается, если я не использую Chrome... тогда он сохранит свою позицию и снова упадет при добавлении нового содержимого.
Доказательство концепции: http://jsfiddle.net/GADk9/
Флажок в примере просто переключает текст внутри кирпича, не более того. Интересно, откуда взялся этот край (это?).
Вот полный документ HTML5:
<!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
После того, как я снова прочитал свой вопрос, я понимаю, что может показаться неправильным впечатление, что то, что я на самом деле пытаюсь выполнить, - это исправление некоторого HTML.
Чтобы особо подчеркнуть этот факт, мне здесь ничего не нужно менять. Пример с кирпичом - просто забавная демонстрация проблемы, которую я наблюдаю.
Мне действительно интересно понять , что заставляет элементы изменять свою позицию при вставке содержимого в такой схеме.
Ответы
Ответ 1
Это проще понять, если вы упростите разметку только на пару ячеек, каждая из которых содержит div.
<div class="cell left">
<div class="inner"></div>
</div>
<div class="cell middle">
<div class="inner"></div>
</div>
<div class="cell right">
<div class="inner"></div>
</div>
Затем присвойте каждому div разную высоту некоторым CSS следующим образом.
.cell {
display:table-cell;
background-color:black;
width:200px;
}
.inner {
background-color:silver;
}
.left .inner {
height:80px;
}
.middle .inner {
height:140px;
}
.right .inner {
height:100px;
}
По умолчанию эти внутренние divs выравниваются по вертикали к их базовой линии. Таким образом, без какого-либо текста все divs выравниваются вдоль нижней части ячеек:
+------+
| |
| +------+
+------+ | |
| | | |
| | | |
+------+------+------+
Однако, если вы добавите текст в любой из них, этот div будет нажат вниз, так что базовая линия первой строки текста выровняется с нижними краями других div.
+------+
| |
| |
+------+ |
| | +------+
| | |Text |
+------+------+ |
| |
+------+
Как было указано другими, вы можете изменить то, что происходит, установив другое свойство vertical-align
. Например, добавление vertical-align:top
в селектор .cell даст вам что-то вроде этого:
+------+------+------+
| | |Text |
| | | |
+------+ | |
| +------+
| |
+------+
Я считаю, что проще всего поиграть с такими вещами в кодефене, где вы можете видеть изменения, как вы их делаете. Здесь пример для экспериментов.
Ответ 2
У вас есть
<div id='pit'>
<div>
<div>
</div>
</div>
<div id='contrail'>
<div>
<div id='brick'></div>
</div>
</div>
</div>
И вы используете
#pit { display: table; }
#pit>* { display: table-cell; }
#pit>*>* { height: 4em; }
Теперь вот наша проблема, поскольку она говорит, что #pit
- это таблица, а #pit>*
- это таблица-ячейка, которая каждый раз сбрасывает height: 4em;
.
Теперь вот мое решение.
#pit { display: block; }
#pit>* { display: table; }
#pit>*>* { height: 4em; display: table-cell;}
http://jsfiddle.net/AAbhishekk/GADk9/28/
Ответ 3
Я видел поведенческие различия между браузерами при многократном использовании таблицы, таблицы и таблицы. Начнем с того, что я никогда не использую их, поскольку всегда есть лучшее решение. Однако на ваш вопрос:
Когда вы работаете с CSS, который должен вести себя как таблицы, это помогает думать о маленькой старой школе.
Оказывается, волшебное свойство CSS, чтобы ваш POC в скрипке вел себя правильно, выравнивается по вертикали. Фактически, это фиксирует нечетную вставку дополнительного вертикального пространства во всех браузерах, а не только в Chrome, а также устраняет проблему Chrome, сохраняя дополнительное пространство.
Посмотрите на эту крошечную версию скрипта:
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; }
В скрипте, с которой я связан, я просто устанавливаю отображаемые дочерние элементы: table-cell имеет дополнительное свойство, vertical-align: top. Как оказалось, вы можете установить его в середине или снизу, все с тем же эффектом. Это останавливает неправильное поведение - очевидно, Chrome нужно сказать, как вести себя в этом сценарии.
Я немного странно понимаю, как Chrome плохо себя ведет, и это кажется ошибкой. Тем не менее, я возвращаюсь к своему предыдущему заявлению об исключении этих значений свойств отображения, таких как чума. Комбинации дисплея: встроенный, встроенный блок, блок, в сочетании с относительным и абсолютным позиционированием, используемым надлежащим образом между родителями и детьми, оказывают другие неприятные свойства css, например. float, не нужно.
Приветствия
Ответ 4
Это лучшая идея, которую я могу придумать. Надеюсь, я пригвошу ее или что она как минимум близка к ней.
В ваших правилах CSS вы:
#pit { display: table; }
#pit>* { display: table-cell; }
#pit>*>* { height: 4em; }
который сообщает браузеру, что #pit
является таблицей, и что все ее дочерние элементы являются ячейками (в то время как внуки - это то, что они есть, поскольку показ не выполняется CSS)
Здесь я вижу 2 проблемы:
Проблема 1
Внутри #pit
у вас есть:
<div>
<div>
</div>
</div>
<div id='contrail'>
<div>
<div id='brick'></div>
</div>
</div>
Обратите внимание на детей, потому что у вас есть 2, а селектор #pit>*
говорит КАЖДЫЙ #pit
РЕБЕНОК
Я бы изменил для этого правила CSS:
#pit { display: table; }
#pit>#contrail { display: table-cell; }
#pit>#contrail>* { height: 4em; }
Но будьте осторожны с тем, что вы хотите, потому что это делает детей от #pit>#contrail
4em high, а не внутреннего ребенка #brick
, возможно, это то, что вы хотите, но обратите внимание на него.
Проблема 2 @Chrome (нет, если вы "решаете" первую проблему)
Я не уверен, что я здесь говорю, но... может ли это быть ошибкой webkit? это происходит и с Opera?
EDIT: Opera не ведет себя как Chrome, она возвращается к нормальному макету, поэтому, возможно, это не ошибка веб-кита:/
Итак, у вас есть таблица и ячейки таблицы, но браузер затем думает "Подождите... если это таблица, и это ячейка... Где строка!?", поэтому она создает "призрак", поэтому он может быть счастлив. Однако я не уверен, что "это" думает, когда вы удаляете текст, потому что он "работает" нормально. Если вы посмотрите на инструменты разработчика, вы увидите, что нет элемента строки или чего-либо подобного.
Когда вы "повторно добавляете" текст, браузер - ум = удар, потому что макеты таблиц. Таким образом, он снова создает строку снова (растягивание #pit
), возможно, потому, что "строки-призраки" не очищаются или потому, что высота #pit
никогда не пересчитывается снова и она увеличивается только тогда, когда появляется строка-призрак.
Если вы хотите оставить одни и те же правила CSS, вам нужно будет сделать что-то вроде:
#pit { display: table; }
#pit>* { display: table-row; }
#pit>*>* { height: 4em; display: table-cell; }
Ответ 5
Иногда самые легкие ответы игнорируются. Вместо того, чтобы сбросить содержимое до нуля (например, ""), просто запустите пустое содержимое как неразрывное пространство, а reset верните его в неразрывное пространство. Ячейки таблицы не отображаются, когда у них нет содержимого. Неразрывное пространство считается содержимым ячейки, и поэтому оно корректно отображается.
JSFiddle здесь
Здесь rub:
Вам нужно добавить это правило в блок #brick:
vertical-align: top;
и вам нужно предоставить некоторый контент вашей пустой ячейке таблицы, которая должна отображать контент, выполненный таким образом:
<div id='contrail'>
<div>
<div id='brick'> </div>
</div>
</div>
Voila, она исправлена в Chrome и отображается одинаково везде. Это проблема старой школы со столами. Кажется, Хром решил быть верным тому, как они изначально вели себя в плохие старые дни.
В качестве альтернативы, для чисто CSS-решения вы можете добавить правило контента в блок #brick:
vertical-align: top;
content: ' ';
Это работает точно так же. Наслаждайтесь!
Ответ 6
Похоже, хром недоволен отображением: table-cell внутри дисплея: таблица без отображения: таблица-строка где-то посередине.
Если вы добавите его (и придадите кирпичу ширину), он перестанет падать:
#brick {
background-color: lightgray;
border: solid black medium;
border-radius: 1em;
color: red;
font-size: 2em;
height: 100%;
width: 200px;
text-align: center;
}
#contrail { background-color: lightblue; width: 20em; }
#pit { display: table; }
#pit>* { display: table-row; }
#pit>*>* { display: table-cell; }
#pit>*>* { height: 4em; }
Ответ 7
#pit { display: table; }
#pit>* { display: table-cell; }
Вышеприведенное приводит к тому, что оно расширяется (& not contract). Это ожидаемое поведение? Нет, поскольку это не происходит в IE или Firefox, я считаю, что это ошибка Chrome, которая неправильно интерпретирует поведение display: table
и display: table-cell
. Кажется, он не пересчитывает высоту таблицы-ячейки, в вашем случае <div id="contrail">
, когда текст удаляется.
Посмотрите на эту скрипту - Я заменил divs фактическими таблицами. Каждый раз, когда текст заполняется, высота ячейки таблицы расширяется, но при удалении текста он сжимается до исходного размера. Я бы сделал вывод, что это ошибка Chrome, поскольку цель этого режима отображения CSS заключается в том, чтобы имитировать использование <table><td>
.
Ответ 8
Я считаю, что было странное правило:
#brick {
background-color: lightgray;
border: solid black medium;
border-radius: 1em;
color: red;
font-size: 2em;
line-height:2em;
height: 100%;
text-align: center;
margin:0;
padding:0;
height:2em;
}
#contrail { background-color: lightblue; width: 20em; }
#pit { display: table; }
#pit>* { display: table-cell; }
http://jsfiddle.net/GADk9/77/
Ответ 9
Я заметил просто добавление
<p> around your text </p>
решил проблему
здесь работает jsfiddle
Ответ 10
Ответ. Браузер не понимает вашу комбинацию макета html/css, потому что она не отформатирована в официальных спецификациях. Неправильно отформатированный HTML сделает элементы браузера ненадлежащим образом.
Ячейка таблицы ДОЛЖНА иметь строку родительской таблицы:
http://www.whatwg.org/specs/web-apps/current-work/multipage/tabular-data.html#the-td-element
Ячейка таблицы НЕ допускается как прямой дочерний элемент элемента таблицы:
http://www.whatwg.org/specs/web-apps/current-work/multipage/tabular-data.html#the-table-element