Властивості для вирівнювання всього і їх нові таємниці

Якщо ви освоїли флексбокси (а хто не освоїв їх за останні два-три роки?), Для вас давно не проблема відцентрувати що завгодно, та й взагалі вирівняти як завгодно. Вам давно знайомі «чарівні» властивості justify-content, align-content, align-items і align-self. і що робить кожне з них значень (не обов'язково пам'ятати їх все напам'ять, адже завжди можна підглянути в шпаргалку або наочному довіднику :). Але чи все ви знаєте про ці властивості? Що якщо я скажу вам, що їх могутність необмежена флексбоксамі? І що ви бачили лише частину їх значень? І що самих цих властивостей не 4, а в два з гаком рази більше? Якщо хочете оволодіти всією їх міццю, дізнатися, до чого тут новомодна грід-розкладка (CSS Grid Layout), і вас не лякають нетрі специфікацій - ласкаво просимо в цю статтю, де я покажу вам, наскільки глибока кроляча нора W3C.

CSS-гріди згадані не випадково: краще відразу озбройтеся одним з браузерів, де вони вже працюють (Firefox 52+, Chrome 57+, Opera 44+ або Safari 10.1 + / iOS 10.3+ Safari), щоб побачити приклади в усьому їх блиску.

Не тільки флексбокси

В недавній статті про нові можливості флексбоксов і CSS-Грід, коли вони працюють в зв'язці, був короткий приклад з властивістю align-self (і ще одним, але про нього трохи пізніше) для осередків гріда. А нижче - інтерактивний приклад, де ви можете самі порівняти дію всіх чотирьох знайомих властивостей в двох контейнерах з різними контекстами форматування - флексбоксовом і грідовом:

Бачите загальний принцип?

Властивість justify-content визначає, що робити з вільним місцем, які залишилися після розміщення всього контенту по горизонталі (точніше, по головній осі, що залежить від якості flex-direction. Для флексбоксов, і по рядкової осі, що залежить від напрямку тексту, для грід - але поки обмежимося простим випадком, як у прикладі). Чи залишити це місце в кінці рядка (за замовчуванням), перемістити в початок (притиснувши контент до кінця), розкидати порівну справа і зліва від контенту (тим самим відцентрувати його), розкидати порівну між елементами і т.д. Єдина різниця, що в гріді елементи згруповані ще і по вертикалі (по стовпцях), тому і місце мимоволі розподіляється саме між стовпцями, а не самими елементами, як у флексбоксов.

A align-content робить по суті те ж саме, але по вертикалі (точніше, по перпендикулярній осі для флексбоксов і за блочною осі для грід, якщо зовсім занудствовать). Тут в обох випадках контент у нас вже згрупований - в рядки (у флексбоксах) або ряди (в гріді). І вільне місце по вертикалі може бути після всіх цих рядків / рядів, перед ним, порівну до і після них (і тоді вони будуть по центру), порівну між ними ... У флексбоксах (де, на відміну від грід, немає осередків з явними розмірами ) можна ще і рівномірно розтягнути висоту цих рядків / рядів так, що вільного місця не залишиться взагалі.

Іншими словами: властивості * -content керують усім контентом відразу, пересуваючи і розсуваючи (якщо треба) то, будь-що цей контент згрупований: рядки, ряди або колонки.

Ну а align-items вирівнює саме «items», тобто елементи - всередині рядків флексбокса і рядів гріда. А align-self - те ж саме, але для кожного елемента окремо, і вказується для нього самого. Перший задає поведінку елементів за замовчуванням, другий дозволяє його перевизначити.

Але як вирівнювати елементи - все (за замовчуванням) або деякі окремо - по горизонталі, усередині колонок гріда?

Цілих дев'ять властивостей

Виявляється, для кожного об'єкта вирівнювання - всього контенту. всіх елементів за замовчуванням і окремого елемента, його самого - є пара властивостей, одне з яких вирівнює по головній / рядкової осі (в нашому прикладі - по горизонталі), а друге - по поперечної / блокової (в нашому прикладі - по вертикалі). Виходить 6 властивостей - все комбінації з двох варіантів, по якій осі вирівнювати, і трьох - що саме вирівнювати (контент, елементи або сам конкретний елемент). Ось вони:

  • align-content
  • justify-content
  • align-items
  • justify-items
  • align-self
  • justify-self

В наведеному вище прикладі ви можете побачити все 6 властивостей в дії в грідах. У флексбоксах працюють тільки 4 наших старих знайомих: вирівнювати окремі елементи по головній осі там безглуздо, оскільки всім простором між ними вже завідує justify-content. і розподіляти після нього вже нічого.

Так що на додачу до тих шести властивостям тепер є ще три:

Значення кожного з них - комбінація значень align- * і justify- * через пробіл. Наприклад, place-content: center space-between або place-self: stretch center. Порядок (спочатку вертикальне вирівнювання, потім горизонтальне) відповідає порядку, в якому зазначаються, наприклад, відступи (в записах типу margin: 20px auto). Якщо вказано тільки одне значення (наприклад, place-items: start), воно копіюється для обох складових, по обох осях.

Купа нових значень

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

start і end

У флексбоксах ми звикли до значень flex-start і flex-end. залежать від напрямку головної та поперечної осей - які, в свою чергу, залежать від напрямку тексту. Просто start і end - майже те ж саме: початок / кінець рядка або блоку (ряду або колонки) відповідно, в залежності від напрямку тексту. Для рядка / ряду при листі зліва направо start - це лівий край, end - правий. При листі справа наліво - навпаки. При вертикальному листі зверху вниз, відповідно, start - це верх, end - низ. І так далі.

На практиці різниця між start / end і flex-start / flex-end лише в тому, що перші, на відміну від других, не враховують «перевороту» осей в ситуаціях типу flex-flow: row-reversed wrap-reversed. А в грідах вони взагалі по суті синоніми.

У Firefox ці значення вже працюють і для флексбоксов, і для грід, в Chrome - поки тільки для грід.

self-start і self-end (для * -items і * -self)

Ці два значення хочеться назвати «ще більш відносними», ніж просто start і end. вони вирівнюють флекс- і грід-елементи з урахуванням їх власного напрямку тексту. Наприклад, якщо в одних осередках гріда текст йде зліва направо, а в інших - справа наліво (скажімо, це російсько-арабський словник), то при justify-items: self-start вміст перших притулиться до лівого краю, а друге - до правого. Ви могли бачити це в прикладах вище - для передостаннього елемента в кожному контейнері, виділеного зеленим кольором.

left і right

Іноді, хоч і рідко, виникає необхідність вирівняти щось і абсолютно, по правому / лівому краю, незалежно від напрямку тексту. Тепер і для цього є засіб. Але не зловживайте!

space-evenly (для * -content)

У перекладі шпаргалки Джоні Трайтел нам свого часу довелося виправити одну неточність (в оригіналі вона залишилася до сих пір, була вона спочатку і в статті Кріса Койєр, від якої Джоні відштовхувалася). Для space-around було намальовано, наче проміжки між елементами і від країв контейнера до крайніх елементів дорівнюють один одному:

Властивості для вирівнювання всього і їх нові таємниці

Саме такого результату інтуїтивно очікували багато (включно зі мною), і фактичний результат space-around (проміжки між елементами вдвічі ширше, ніж від країв) неприємно здивував. А рівних проміжків досі доводилося домагатися нетривіальними Хакамі - або за допомогою space-between і :: before c :: after. або нетиповим застосуванням margin: auto. І то лише для однорядкових флексбоксов.

first baseline і last baseline

Вирівнювання по базовій лінії здавна було складною темою в CSS, навіть найбільшим майстрам деколи доводилося вести з ним цілі битви. Особливо дивувало, що одні елементи - напр. інлайн-блоки - вирівнювалися по базовій лінії останнього рядка, а інші - напр. інлайн-таблиці - по першій. Тепер цим можна управляти явно. Для цього перед ключовим словом baseline можна вказувати інше слово-модифікатор - first або last.

Зверніть увагу: модифікатор вказується саме через пробіл, не через дефіс, так що значення властивості виходить складовим, з двох слів. Через цієї прогалини ледь не виникла плутанина з скороченими значеннями (як розуміти, наприклад, place-self: first baseline. Як незрозуміле вирівнювання first по одній осі і вираніваніе по базовій лінії по інший або як вирівнювання по базовій лінії по обох осях?) , було навіть пропозиція замінити в скорочених значеннях пробіл слешем, але в підсумку залишили прогалину. Так що будьте уважні!

Їх я поки не зміг побачити в дії ні в одному браузері, тому спочатку навіть не хотів додавати до статті. Але доведеться :)

Можливо, при центруванні елементів в гумовому флекс-контейнері ви стикалися з такою неприємною особливістю: якщо контейнер стає менше елемента, то обидва краї елемента починають виступати за краї контейнера. І якщо контейнер - це сторінка, то частина контенту може піти за її лівий / верхній край і стати недоступною. З цим і бореться ключове слово safe. якщо додати його перед center (наприклад, align-items: safe center;), то елемент буде центрироваться в контейнері лише тоді, коли він там уміщається. Якщо ж він переповнює контейнер, то «зайві» частини виступатимуть лише вправо і вниз (для звичного нам направлення листа), де до них хоча б можна буде дістатися скроллингом. Приблизно так, як поводяться елементи при центруванні через margin: auto. Яке, до речі, і імітує цю поведінку в прикладі нижче:

Є й протилежне ключове слово unsafe - завжди вирівнювати / центрировать елемент так, як зазначено, неважливо, куди і наскільки при цьому виступають «надлишки». А за замовчуванням, за поточним чернетки, має відбуватися щось середнє - елемент повинен вирівнюватися як зазначено, але при появі скролінгу він весь повинен бути доступний для нього (але там залишена застереження: якщо браузери не осилять таке «розумне» поведінку - нехай роблять unsafe :).

normal. auto і ключове слово legacy

Як часто буває в CSS, значення з назвами типу normal і auto виявляються найзаплутанішими :). «Нормальне» поведінку наших властивостей для вирівнювання залежить від конкретного способу форматування, від успадкованих значень (модифікатор legacy якраз впливає на те, чи будуть ці успадковані значення враховуватися), і я навіть не став додавати їх в приклади (де було можна), щоб зовсім вже вас не запитати. Якщо захочете, розібратися докладніше з кожним з них ви зможете безпосередньо в специфікації (див. Нижче). На щастя, і в флексбоксах, і в грідах загальний принцип поведінки за замовчуванням досить простий: що можна - спробувати розтягнути (stretch), решта - притиснути до початку відповідної осі (start).

Цілий модуль специфікації (CSS Box Alignment)

Але найголовніший сюрприз, який приховує в собі цей модуль - те, що властивості для вирівнювання за все не обмежуються одними лише флексбоксамі і Грід: в теорії, вони повинні будуть працювати для багатоколоночних розкладок (до речі, зовсім недавно браузери - Chrome з 55-ї версії , Firefox c 52-й - нарешті прибрали префікси для колоночного властивостей!) і ... барабанний дріб ... для звичайних блоків. Так що, якщо я нічого не переплутав, align-content: center має стати стандартним рішенням легендарної проблеми вертикального центрування довільного контенту. На жаль, для justify-content для блоків явно прописано, що застосовуватися воно не буде (ех, доведеться і далі неінтуітівнимі центрировать margin ами ...), але для align-content. в теорії, надія залишається! У теорії - тому що в браузерах (ні в FIrefox, ні в Chrome Canary) це поки, судячи з усього, не працює.

P.S. Це теж може бути цікаво:

Не минуло й півроку з останньої зміни робочого процесу W3C, як керівництву Консорціуму надійшла пропозиція застосувати нарешті цей новий процес на ділі. І списати вже неактуальні специфікації HTML в музей, щоб вони не заплутували розробників, «прикидаючись» актуальними.

Ще один модуль CSS, про який ми розповідали, непомітно дозрів до статусу, з якого W3C радить починати повсякденне використання новинок. Властивість contain дозволяє обмежувати зміни дерева відтворення, перерисовку CSS-боксів і зміни їх розмірів в межах елемента. Тому воно так важливо ...
ДАЛІ

З Парижа (на фото), де недавно проходила зустріч робочої групи CSS, прилетіла цікава новина: властивості grid-row-gap і grid-column-gap, а також їх скорочення grid-gap ...