Подтвердить что ты не робот

Требуется: сетка CSS и коллапсирующие поля

Я думаю, что это тяжело.

Я использую сетку с использованием float:left. Я мог бы переписать его с помощью display:inline-block, но это ничего не изменит.

Скажем, у нас есть два столбца:

<div class="row"> 
    <div class="column">
        <!-- some content here -->
    </div>
    <div class="column">
        <!-- some content here -->
    </div>
</div>

Если я помещаю в него элемент блока с краем-вершиной (например, <h1>), я получаю не сворачивающиеся поля в контент раньше. Это нормально, поскольку оно всегда как таковое с плавающими элементами (или отображает: встроенный блок).

Но я хочу иметь сворачивающиеся поля. Я много старался заставить его работать, но кажется, что каждый CSS, который будет помещать два элемента рядом друг с другом, уничтожит сворачивающиеся поля для содержимого выше.

Я знаю, я мог бы использовать CSS, чтобы получить первый-элемент элемента, чтобы избавиться от margin-top. Но в этом случае это не будет применяться, потому что контент построен с помощью CMS, и до тех пор, пока я не доберусь до элемента, может существовать произвольный уровень глубины элемента.

Есть ли способ сделать это без JavaScript?

Fiddle: http://jsfiddle.net/HerrSerker/ZSV3D/

Вы можете видеть, что маржа-вершина h1 и margin-bottom .header не разрушаются. Это с помощью float:left of .column.

.header {
  font-size: 24px;
  background: rgba(0,255,0,0.1);
}
h1 {
  background: silver;
  margin-bottom: 50px;
  font-size: 28px;
}
.column {
  float: left;
  width: 50%;
  background: rgba(255,0,0,0.1);
}
h2 {
  background: gold;
  margin-top: 50px;
  font-size: 24px;
}
<div class="header"><h1>&lt;h1>Headerh1&lt;/h1></h1></div>
<div class="row">
    <div class="column"><h2>&lt;h2>Col 1, float: left&lt;/h2></h2></div>
    <div class="column"><h2>&lt;h2>Col 2, float: left&lt;/h2></h2></div>
</div>
<p>I want a 50 pixel margin between Header and the Cols, but the two margins don't collapse and I end up with 50 + = 100 pixel gap. If it would work, you wouldn't see the light red above col1 and col2</p>
4b9b3361

Ответ 1

Это невозможно: O

Согласно спецификации (https://www.w3.org/TR/CSS2/box.html#collapsing-margins)

Условие свертывания:

  • оба относятся к блочным блокам в потоке, которые участвовать в том же блоке форматирование контекста   
  • нет строк, без зазоров, без прокладки и без границ отделите их (обратите внимание, что определенная линия нулевой высоты (см. 9.4.2) для этой цели игнорируются.)   
  • оба относятся к вертикально смежным краям ящиков, т.е. образуют один из следующих пар:
    • верхний край поля и верхний край его первого в потоке ребенка
    • нижний край поля и верхний край его следующего потока     следующий брат
    • нижний край последнего дочернего потока и нижнего края его     parent, если родитель имеет "авто" вычисленную высоту
    • верхнее и нижнее поля коробки, которая не устанавливает новый     блок форматирования контекста и который имеет нулевую вычисленную "минимальную высоту", ноль или "авто" ,     вычисленная "высота" и нет     in-flow children

блокировать контейнеры (например, встроенные блоки, таблицы-ячейки и таблицы-титры), которые не являются блочными блоками

Свертывание полей в этой ситуации нарушит правило:

  • Поля между плавающей точкой коробка и любая другая коробка не рушится (даже не между поплавком и его дети в потоке).   
  • Поля элементов, которые устанавливают форматирование нового блока контексты (такие как float и элементы с "переполнением", кроме "видимых" ) не рушатся со своими детьми в потоке.   
  • Поля абсолютно позиционированного коробки не разрушаются (даже с их детьми в потоке).   
  • Поля полей встроенных блоков не сворачиваются (даже не с их детьми в потоке).   
  • Нижний край элемента блока на потоке всегда обрушивается с верхним краем его следующего блочного уровня в потоке брата, если у этого брата нет разрешения.   
  • Верхний край элемента блока в потоке сворачивается с его первый начальный уровень верхнего уровня на уровне блока, если элемент имеет нет верхней границы, нет верхнего заполнения, а у ребенка нет разрешения.   
  • Нижний край блока в потоке блока с "высотой" "авто" и "минимальной высотой" нуля сворачивается с его последним полем нижнего края дочернего блока на уровне блока, если поле не имеет нижней прокладки, а нижняя граница и нижнее дно маржа не сворачивается с верхней границей, которая имеет разрешение.   
  • Собственные поля коробки сворачиваются, если свойство "min-height" равно нулю, и он не имеет ни верхних, ни нижних границ, ни верхней, ни нижней прокладки, и он имеет "высоту" либо 0, либо "auto", и он не содержит строки строки, и все его кратковременная кража детей (если таковая имеется).

flex box также... (https://www.w3.org/TR/css-flexbox-1/#item-margins)

Поля соседних элементов гибкости не разрушаются.

сетка также... (https://www.w3.org/TR/css-grid-1/#item-margins)

поля соседних элементов сетки не сжимаются.

Невозможно свернуть margin-top: 50px; с помощью одного из этих решений: inline-block, position: absolute, float, flex, grid.


Если вы не можете установить маржу на ноль, возможно, вы можете использовать многие другие методы для разрыва функции поля

например: пусть h1 be inline и пусть div имеет золотой фон, чтобы сломать margin-top: 50px;:

В соответствии с спецификацией margin (https://www.w3.org/TR/CSS2/box.html#margin-properties):

Свойства поля определяют ширину области поля поля. Условное свойство "margin" устанавливает маржу для всех четырех сторон, в то время как другие свойства поля только устанавливают свою соответствующую сторону. Эти свойства применяются ко всем элементам, но вертикальные поля не будут иметь любое влияние на незаменяемые встроенные элементы.

Ответ 2

Единственная опция, при которой вы на самом деле сворачиваете поля, без какого-либо трюка селектора или JavaScript, выглядит следующим образом:

Не устанавливайте margin-top: 50px на h1, но на .row

Смотрите эту скрипту

HTML

<div class="header">Header is normal div</div>
<div class="row">
    <div class="column"><h1>Col 1 is float: left</h1></div>
    <div class="column"><h1>Col 2 is float: left</h1></div>
</div>
<p>I want a 50 pixel margin between Header and the Cols, but the two margins don't collapse and I end up with 50 + = 100 pixel gap.</p>

CSS

.header {
  background: silver;
  height: 50px;
  margin-bottom: 50px;
  font-size: 24px;
}
.row {
  margin-top: 50px;
}
.column {
  float: left;
  width: 50%;
}
h1 {
  background: gold;
  font-size: 24px;
}

Ответ 3

Сделайте элемент .row a flex, проблема решена...

Почему вы хотите его плавать?

.header {
  background: silver;
  height: 50px;
  margin-bottom: 50px;
  font-size: 24px;
}

.row {
	display: flex;
}

.column {
  width: 50%;
}
h1 {
  background: gold;
  font-size: 24px;
}

.firstcol {
   margin-top: 0;
}
<div class="header">Header is normal div</div>
<div class="row">
    <div class="column"><h1 class="firstcol">Col 1 is float: left</h1></div>
    <div class="column"><h1 class="firstcol">Col 2 is float: left</h1></div>
</div>
<p>I want a 50 pixel margin between Header and the Cols, but the two margins don't collapse and I end up with 50 + = 100 pixel gap.</p>

Ответ 4

Я не думаю, что вы можете это сделать. Вероятно, лучшим методом было бы нацелить маржу на несколько условий и удалить ее.

Если эта проблема происходит только тогда, когда элементы .column с h1 сразу следуют за .header, вы можете построить немного больше определенного правила CSS. Это будет отменять маржу и отменять ее.

.header + .row h1 {
    margin-top: 0;
}

Там довольно много, если в этом ответе, хотя и без немного больше информации, это довольно сложно решить.

Ответ 5

Согласно Mozzilla Developer Network:

Поля элементов плавающего и абсолютно позиционированного никогда не сбрасываются.

Если гарантируется, что первый элемент нуждается в коллапсе внутри произвольного количества элементов, лучшим выбором будет следующий CSS:

.header + * :first-child {
  margin-top: 0;
}

Если я правильно понял вопрос, это будет так близко, как вы получите только с помощью CSS.

Демо:

.header {
    background: silver;
    height: 50px;
    margin-bottom: 50px;
}
.column {
    float: left;
    width: 50%;
}
h1 {
    background: gold;
    margin-top: 50px;
}
.header + * :first-child {
  margin-top: 0;
}
<div class="header">Header</div>
<div class="row">
    <div class="column"><h1>Col 1</h1></div>
    <div class="column"><h1>Col 2</h1></div>
</div>

Ответ 6

Дайте стиль *{margin:0;} в вашем css. Это позволит избежать всех полей по умолчанию во всех браузерах.

Ответ 7

Будет ли опция display: table/table-row/table-cell?

.header {
  background: silver;
  height: 50px;
  margin-bottom: 50px;
  font-size: 24px;
  display: table-row;
}
.row {
  display: table-row;
}
.column {
  display: table-cell;
  width: 50%;
}
h1 {
  background: gold;
  margin-top: 50px;
  font-size: 24px;
}
<div class="header">Header is normal div</div>
<div class="row">
    <div class="column"><h1>Col 1 is float: left</h1></div>
    <div class="column"><h1>Col 2 is float: left</h1></div>
</div>
<p>I want a 50 pixel margin between Header and the Cols, but the two margins don't collapse and I end up with 50 + = 100 pixel gap.</p>

Ответ 8

.header + *:last-child {
      h1{
         margin-bottom:0px;
       }
}
 .row + * :first-child{
       h2{
         margin-top:0px;
      }
}

Ответ 9

Документация о развале краев довольно ясна...

Поля плавающих и абсолютно позиционированных элементов никогда не рушатся.

https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Box_Model/Mastering_margin_collapsing

Даже использование flexbox не поможет, поведение останется прежним...

Если вы знаете, какие элементы имеют крайний край, возможно, вы можете получить что-то из селектора first-of-type... См. фрагменты:

.header {
  background: silver;
  height: 50px;
  margin-bottom: 50px;
  font-size: 24px;
}
.column {
  float: left;
  width: 50%;
}
h1 {
  background: gold;
  margin-top: 50px;
  font-size: 24px;
}
.column h1:first-of-type {
  margin-top: 0;
}
<div class="header">Header is normal div</div>
<div class="row">
    <div class="column"><h1>Col 1 is float: left</h1></div>
    <div class="column"><h1>Col 2 is float: left</h1></div>
</div>
<p>I want a 50 pixel margin between Header and the Cols, but the two margins don't collapse and I end up with 50 + = 100 pixel gap.</p>

Ответ 10

См. свойство отображения по умолчанию для h1, как показано ниже,

h1{
margin-top: 0.67em;/* which is around 11px*/
margin-bottom: 0.67em;/* which is around 11px*/
margin-left: 0;
margin-right: 0;
}

Таким образом, вместо того, чтобы устанавливать край верхнего или нижнего уровня для h1 или h2, вы можете установить margin-top для строки, которые получают тот же результат, что и h1 и h2, заданное значение поля. Теперь, когда вы изменяете размер своего браузера с помощью этого, как указано в нижеприведенных кодах. Вы могли заметить, что при изменении размера пространство уменьшается и увеличивается. Но в какой-то момент он будет остановлен, поскольку мы назначили margin top +, у нас уже есть маржи h1 и h2 по умолчанию.

.header {
font-size: 24px;
  background: rgba(0,255,0,0.1);
}
h1 {
  background: silver;
  margin-bottom: 50px;
  font-size: 28px;
}
.column {
  float: left;
  width: 50%;
  background: rgba(255,0,0,0.1);
}
h2 {
 background: gold;
  margin-top: 50px;
  font-size: 24px;
}
.row{
  margin-top:7.5%;
}

Но если мы удалим значения h1 и h2 по умолчанию, то пространство между .header и .column будет пространством, назначенным .row (в%), и это уменьшится при изменении размера нашего браузера. Теперь, чтобы назначить ширину от 100% до .column, можно выполнить с помощью медиа-запроса, настроив таргетинг на определенные мобильные устройства. Так, чтобы col 2 располагался ниже col 1 с шириной 100%

body{
margin:0;
}
.header {
  font-size: 24px;
  background: rgba(0,255,0,0.1);
}
h1 {
  background: silver;
  font-size: 28px;
  margin:0;
}
.column {
  float: left;
  width: 50%;
  background: rgba(255,0,0,0.1);
}
h2 {
  background: gold;
  font-size: 24px;
  margin:0;
  }
.row{
  margin-top:7.5%;
}

Ответ 11

Как вы уже слышали несколько раз... Это кажется невозможным...

Я подозреваю, что вы не хотите использовать селектор, чтобы не влиять на все h1 и решать другие элементы (например, h2 или даже p), которые могут быть не h1 и могут не быть смежными siblings элемента .header (возможно, просто h1 без оболочки .header или p с нижним краем 70px)...

Предполагая, что я прав... Вы можете использовать этот селектор для решения всех таких случаев...

.row .column > *:first-child {
  margin-top: 0;
}

Это установит top-margin первого элемента в каждом столбце каждой строки на 0.

Подумайте, что это ближе всего к желаемому поведению...

Лемм знает, помогает ли это.