Як вирішувати margin і padding у відсотках до grid і flex елементах CSS?

338

Від автора: CSS Working Group буде рада почути вашу думку. У специфікаціях CSS Grid Layout і Flexbox є давня проблема. Мова йде про те, як правильно поставити в CSS відсотки margin і padding.

Специфікації CSS Grid:

«Процентні margin і padding в grid елементах можна вирішувати наступним чином:

За їх власним осях (відсотки left/right резолвятся по ширині, top/bottom дозволяє по висоті) або

За інлайн осі (відсотки left/right/top/bottom резолвятся по ширині)

Браузер повинен сам вибрати одне з двох поводжень.

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

Авторам взагалі не слід використовувати відсотки в padding та margin у grid елементах, так як вони по-різному ведуть себе в браузерах.»

У специфікації flexbox написано те ж саме.

В чому проблема?

Відсотки повинні спиратися на щось. Якщо grid елементу задати margin-right 10%, то ви очікуєте, що 10% будуть обчислені від ширини grid області. Але як обчислити 50% для margin-bottom? Значення має обчислюватися від загальної висоти сітки або від ширини? Специфікація дозволяє обидва варіанти, реалізації розділені.

Проблема наочно видно в CodePen нижче. У нас є три колонки шириною по 120 пікселів. До всіх колонках застосовано властивість margin-right зі значенням 12 пікселів, 10% від 120. У Chrome і Safari margin-bottom дорівнює 60 пікселів. 50% від ширини 120px = 60px.

У Firefox і Edge margin-bottom використовує висоту сітки, і значення одно 150px, так як я поставив висоту сітки, і елементи розтягуються. Якщо видалити висоту з grid контейнера в Firefox, то контейнер схлопнется, так як більше немає чіткої висоти. Chrome збереже контейнер в 60px – margin.

Таку ж поведінку спостерігається з Flexbox. Тільки в Flexbox обчислення ведуться щодо флекс контейнера. Проте в демо нижче видно, як Chrome використовує 10% від 500px для margin-right і 50% від 500px для margin-bottom. Firefox використовує 10% від 500px для margin-right і 50% від 300px для margin-bottom.

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

Хак з співвідношенням сторін

Одна з причин слідувати поведінки Chrome – хак з співвідношенням сторін для процентного padding працює у flex і grid елементах. На Bram.us є чудова стаття з проблеми сумісності – вертикальні margin/padding і flexbox, незвичайна комбінація. Проблема також описана на Flexbugs і Gridbugs.

Тим не менше, краще правильно вирішувати проблему з співвідношенням сторін і вибрати одне рішення для margin і padding.

Нам потрібні ваші відгуки!

CSS Working Group з радістю вислухає ваші думки з цієї проблеми. З написаного вище видно, що з процентними margin і padding по горизонталі проблем немає, вони ведуть себе, як завжди. Проблема виникає з вертикальними margin і padding. Яка поведінка вам подобається більше, Firefox або Chrome? Чи використовуєте ви вертикальні margin і padding для інших речей, крім хака з співвідношенням сторін.

Можете залишати коментарі в ба на GitHub. Було б круто вирішити цю проблему сумісності.