Як відключити згортання поля?


202

Чи є спосіб взагалі відключити руйнування маржі? Єдині знайдені нами рішення (за назвою "uncollaps") тягнуть за собою використання 1px рамки або 1px прокладки. Я вважаю це неприйнятним: сторонній піксель ускладнює обчислення без поважних причин. Чи є більш розумний спосіб відключити цю згортання поля?


4
Використовуйте макет Flex або Grid, де руйнування поля не існує: stackoverflow.com/a/46496701/3597276
Майкл Бенджамін

Просто дайте елементам значення для, margin-bottomале залиште margin-topяк 0.
Dan Bray

Я зробив пакет, щоб полегшити розрахунок: npmjs.com/package/collapsed-margin
Оуен М

Відповіді:


254

Існує два основних типи краху маржі:

  • Скупчення поля між сусідніми елементами
  • Збірні поля між елементами батьків і дітей

Використання прокладки або бордюру запобіжить згортання лише в останньому випадку. Крім того, будь-яке значення, overflowвідмінне від його за замовчуванням ( visible), застосоване до батьківського, запобігає краху. Таким чином, і те, overflow: autoі те overflow: hiddenматимуть однаковий ефект. Мабуть, єдина відмінність при використанні hidden- це ненавмисний наслідок приховування вмісту, якщо батько має фіксовану висоту.

Інші властивості, які, застосовані до батьків, можуть допомогти виправити цю поведінку:

  • float: left / right
  • position: absolute
  • display: inline-block / flex

Ви можете протестувати їх тут: http://jsfiddle.net/XB9wX/1/ .

Варто додати, що, як зазвичай, Internet Explorer - виняток. Більш конкретно, в IE 7 поля не руйнуються, коли визначений якийсь макет для батьківського елемента, наприклад width.

Джерела: Стаття Sitepoint Розбиваються на полях


1
зауважте, що прокладка також може вплинути на це, якщо це не нульове значення
Младен Яньєтович

3
Зверніть увагу, що overflow: autoможе спричинити появу смуг прокрутки в батьківському елементі, а не дозволяти переповненню вмісту переповнення відповідно до overflow: visible.
Лев

"overflow: auto", здається, не працює в Chrome v44.
tkane2000

3
Дякую за показ: inline-block, це врятувало мене :)
alexcasalboni

3
Будь-яке значення, flexвідміннене від замовчування, також відключить крах маржі
Олі

60

Ви також можете використовувати старий добрий мікро-виправлення для цього.

#container:before, #container:after{
    content: ' ';
    display: table;
}

Дивіться оновлену скрипку: http://jsfiddle.net/XB9wX/97/


Мою відповідь перетворили на вікі спільноти. Будь ласка, не соромтесь продовжити це своєю відповіддю. Дякую.
hqcasanova

3
Я не розумію, коли я бачу, що приклад поля руйнуються (лише 10px вертикальний простір між дівами замість 20px)
Енді,

1
Це допомагає лише у усуненні колапсу між братами та сестрами, які застосовують цей чіткий виправлення. Я показав приклад, щоб продемонструвати це: jsfiddle.net/dpyuyg07 --- і навіть це не вся історія. Це лише прибирає краху поля, що випливає з дітей елементів, де ви застосували це виправлення. Якщо ви додасте поле для самого контейнера, поля все одно будуть руйнуватися, що можна побачити у цій вилці: jsfiddle.net/oew7qsjx
NicBright

4
Я можу сказати це ще точніше: метод clearfix лише запобігає краху поля між батьками та дітьми. Це не впливає на колапс між сусідніми побратимами.
NicBright

Я думаю, що зараз я розумію тенденцію Bootstrap до заповнення DOM :beforeта :afterелементів. Тепер я додав це правило до моєї таблиці стилів: div:before, div:after{content: ' '; display: table;}. Фантастичний. Раптом матеріал починає вести себе так, як очікувалося.
Штійн де Вітт

59

Один акуратний трюк, щоб відключити згортання поля, який не має візуального впливу, наскільки я знаю, - це встановлення батьківського набивання на 0.05px:

.parentClass {
    padding: 0.05px;
}

Прокладка вже не дорівнює 0, тому згортання більше не відбуватиметься, але в той же час прокладка буде досить маленькою, що візуально вона буде округляти до 0.

Якщо потрібна якась інша прокладка, то застосуйте накладку лише на той "напрямок", у якому, наприклад, не потрібне руйнування поля padding-top: 0.05px;.

Робочий приклад:

.noCollapse {
  padding: 0.05px;
}

.parent {
  background-color: red;
  width: 150px;
}

.children {
  margin-top: 50px;

  background-color: lime;      
  width: 100px;
  height: 100px;
}
<h3>Border collapsing</h3>
<div class="parent">
  <div class="children">
  </div>
</div>

<h3>No border collapsing</h3>
<div class="parent noCollapse">
  <div class="children">
  </div>
</div>

Редагувати: змінив значення з 0.1на 0.05. Як Кріс Морган згадував у коментарі нижче, і з цього невеликого тесту , схоже, що дійсно Firefox бере до уваги 0.1pxнабивання. Хоча, 0.05pxсхоже, це і робиться.


2
Це моє улюблене рішення. Ви навіть можете включити це як стиль за замовчуванням. Чому ні? *{padding-top:0.1px}. Ми впевнені, що він працює у всіх браузерах?
Нік Меннінг

Поки працював досить добре для мене, але я не стверджую, що ретельно перевірив це в більшості браузерів.
Ніку Сурду

2
Дуже приємне рішення, здається, працює, як очікувалося, у більшості браузерів. Дякуємо, що поділилися ним!
wiredolphin

1
Це хитромудре рішення , як це робить додати додаткові пікселі в різних умовах, з - за високий DPI дисплеїв і розрахунки субпикселей. (Firefox зробив макет субпікселів для віків; я вважаю, що інші браузери порівняно нещодавно переслідували цей приклад.)
Кріс Морган,

0.05pxЗдається, як і раніше конкретний вибір, а не випадковий номер хитрості браузера, я вважаю за краще 0.01px.
Волкер Е.

22

overflow:hidden запобігає руйнуванню меж, але це не позбавлено від побічних ефектів - а саме ... приховує переповнення.

Крім цього і того, що ви згадали, ви просто повинні навчитися жити разом з цим і дізнаватися в цей день, коли вони дійсно корисні (приходить кожні 3 - 5 років).


Мою відповідь перетворили на вікі спільноти. Я думаю, я висвітлював побічний ефект, про який ви згадали в двох останніх рядках другого абзацу: Можливо, єдиною різницею при використанні прихованого є ненавмисне наслідок приховування вмісту, якщо батьків має фіксовану висоту . Але якщо вам здається, що це потребує додаткового роз'яснення, будь ласка, не соромтесь зробити свій внесок. Дякую.
hqcasanova

7
overflow: autoдобре використовувати, щоб запобігти прихованому переповненню і все-таки запобігти руйнуванню поля.
Гевін

@Gavin, overflow:auto;змусив мою область вмісту отримати смугу прокрутки на деяких сторінках.
Рід

13

Насправді є одна, яка працює бездоганно:

дисплей: флекс; флекс-напрямок: стовпчик;

поки ви можете жити, підтримуючи лише IE10 і вище

.container {
  display: flex;
  flex-direction: column;
    background: #ddd;
    width: 15em;
}

.square {
    margin: 15px;
    height: 3em;
    background: yellow;
}
<div class="container">
    <div class="square"></div>
    <div class="square"></div>
    <div class="square"></div>
</div>
<div class="container">
    <div class="square"></div>
    <div class="square"></div>
    <div class="square"></div>
</div>


Щоб це працювало як загальне рішення, потрібно додати додатковий <div>в межах .container, інакше .containerволя контролюватиме коробку-модель своїх дітей. Наприклад, вбудовані елементи стануть блоковими елементами повної ширини; якщо вони мають маржу, вони також будуть згортатись.
zupa

9

Кожен браузер, що базується на веб-програмах, повинен підтримувати властивості -webkit-margin-collapse. Існують також підвластивості, щоб встановити їх лише для верхнього або нижнього поля. Ви можете надати йому значення колапс (за замовчуванням), відкинути (встановлює маржу в 0, якщо є сусідня межа), і розділити (запобігає краху поля).

Я перевірив, що це працює на версіях Chrome і Safari 2014 року. На жаль, я не думаю, що це було б підтримано в IE, оскільки воно не базується на веб-програмі.

Прочитайте посилання на Safari CSS від Apple для повного пояснення.

Якщо ви перевірте сторінку розширень веб-розширень CSS Mozilla , вони перераховують ці властивості як власні і рекомендують не використовувати їх. Це тому, що вони, швидше за все, не збираються входити в стандартний CSS найближчим часом, і лише веб-браузери, що базуються на них, підтримуватимуть їх.


Це приємно, адже це допомагає нам виправити невідповідність у тому, як Safari та Chrome мають справу з маржами.
Б'юдсон

8

Я знаю, що це дуже стара публікація, але я просто хотів сказати, що використання флексокса на батьківському елементі відключить руйнування поля для його дочірніх елементів.


Не тільки для його дочірніх елементів - це також запобігає руйнуванню поля між батьком та першою та останньою дитиною.
Свен Марнах

2

У мене були подібні проблеми з крахом маржі через те, що батько positionвстановив відносну. Ось список команд, за допомогою яких можна відключити згортання поля.

ТУТ ІГРУЄТЬСЯ ДО ТЕСТУВАННЯ

Просто спробуйте привласнити будь- parent-fix*клас до div.containerелементу, або будь-який клас children-fix*до div.margin. Виберіть ту, яка найкраще відповідає вашим потребам.

Коли

  • Маржа колапсу є відключена , div.absoluteз червоним тлом буде розташований в самому верху сторінки.
  • руйнується межа div.absolute буде розташовуватися на тій же координаті Y, що іdiv.margin

html, body { margin: 0; padding: 0; }

.container {
  width: 100%;
  position: relative;
}

.absolute {
  position: absolute;
  top: 0;
  left: 50px;
  right: 50px;
  height: 100px;
  border: 5px solid #F00;
  background-color: rgba(255, 0, 0, 0.5);
}

.margin {
  width: 100%;
  height: 20px;
  background-color: #444;
  margin-top: 50px;
  color: #FFF;
}

/* Here are some examples on how to disable margin 
   collapsing from within parent (.container) */
.parent-fix1 { padding-top: 1px; }
.parent-fix2 { border: 1px solid rgba(0,0,0, 0);}
.parent-fix3 { overflow: auto;}
.parent-fix4 { float: left;}
.parent-fix5 { display: inline-block; }
.parent-fix6 { position: absolute; }
.parent-fix7 { display: flex; }
.parent-fix8 { -webkit-margin-collapse: separate; }
.parent-fix9:before {  content: ' '; display: table; }

/* Here are some examples on how to disable margin 
   collapsing from within children (.margin) */
.children-fix1 { float: left; }
.children-fix2 { display: inline-block; }
<div class="container parent-fix1">
  <div class="margin children-fix">margin</div>
  <div class="absolute"></div>
</div>

Ось jsFiddle з прикладом, який ви можете редагувати


1

У новішому веб-переглядачі (крім IE11) слід використовувати просте рішення для запобігання згортання поля батьків-дітей display: flow-root. Однак вам все одно знадобляться інші методи, щоб запобігти руйнуванню сусідніх елементів.

DEMO (раніше)

.parent {
  background-color: grey;
}

.child {
  height: 16px;
  margin-top: 16px;
  margin-bottom: 16px;
  background-color: blue;
}
<div class="parent">
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
</div>

DEMO (після)

.parent {
  display: flow-root;
  background-color: grey;
}

.child {
  height: 16px;
  margin-top: 16px;
  margin-bottom: 16px;
  background-color: blue;
}
<div class="parent">
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
</div>


0

Для вашої інформації ви можете використовувати сітку, але з побічними ефектами :)

.parent {
  display: grid
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.