Към съдържанието
wannacode

Grid: редове и колони

Накратко: CSS Grid подрежда елементите в редове и колони наведнъж: колони с fr и gap, каталог с repeat(auto-fill, minmax()) и подредба на страницата с grid-template-areas.

Проблем

Последният продукт е огромен

Каталогът е с flex-wrap от миналия урок. Четири продукта: на първия ред се събират три, а четвъртият е сам на втория ред и е широк колкото целия ред.

HTML, CSS, JS

Това не е грешка във flexbox. Всеки ред на flex контейнер дели своето свободно място сам и не знае нищо за реда над него. На втория ред има един продукт, затова той взима всичко: 768px. Нужно е нещо, което чертае колоните веднъж за целия каталог.

Идеята

Редове и колони

Grid е подредба в две измерения: контейнерът чертае колони и редове, а елементите влизат в клетките една по една, ред по ред.

.catalog {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
gap: 24px;
}
  • display: grid прави елемента grid контейнер, а децата му са grid елементи.
  • grid-template-columns казва колко колони има и колко е широка всяка: 200px 1fr е колона от 200px и колона, която взима останалото.
  • fr е дял от свободното място, след като се извадят колоните с размер и gap-овете. 1fr 2fr 1fr е 1 : 2 : 1.
  • repeat(3, 1fr) е същото като 1fr 1fr 1fr.
  • gap е разстоянието между колоните и между редовете.

Разликата с flexbox: при flex елементите решават колко са широки и всеки ред е отделен. При grid контейнерът решава колоните, а елементите само ги заемат. Затова последният продукт остава в своята колона.

Пробвай

Три колони

Направи каталога grid с три еднакви колони и gap 24px. Каталогът е до 720px, затова всяка карта, и последната, трябва да е (720 − 2 × 24) : 3 = 224px.

HTML, CSS, JS

Идеята

Колкото се съберат

Три колони са добре на компютър. На телефон са по 100px и продуктът не се чете. Не искаме да казваме броя, а правило: „колони от поне 200px, колкото се съберат“.

grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  • minmax(200px, 1fr): колоната е най-малко 200px и най-много един дял.
  • auto-fill вместо число: браузърът слага колкото колони от най-малката ширина се събират, заедно с gap-овете.
  • После остатъкът се дели поравно (1fr) и колоните растат до края на реда.

Виж го

Виж как се брои

Едно и също правило в каталог от 960, 680 и 328px.

.catalog {
display: grid;
grid-template-columns:
repeat(auto-fill, minmax(200px, 1fr));
gap: 16px;
}
Стъпка по стъпка, с думи
  1. Каталогът е grid. Колоните не са дадени с брой, а с правило: колкото се съберат, всяка поне 200px.
  2. Каталог от 960px. Браузърът слага колони по 200px с gap 16px, докато се събират: 4 × 200 + 3 × 16 = 848px. Петата би стигнала 1064px: не се събира.
  3. Остават 960 − 848 = 112px. 1fr ги дели поравно: всяка колона е (960 − 3 × 16) : 4 = 228px.
  4. На 680px се събират три колони (3 × 200 + 2 × 16 = 632). Четвъртата би искала 848. Всяка става (680 − 32) : 3 = 216px.
  5. На 328px, телефон, се събира една: две биха искали 416px. Тя взима цялата ширина: 328px.
  6. Едно правило, три подредби. Броят на колоните следва ширината на каталога, без медийни заявки. Продуктите пълнят колоните ред по ред.

Същият каталог като страница, първо на телефон (360px), после на компютър (1000px). Кодът е един и същ.

HTML, CSS, JS
HTML, CSS, JS

Колоните зависят от ширината на каталога, а не на екрана. Каталог в тясна колона на страницата има по-малко колони и на голям екран.

Пробвай

Едно правило за двете места

Страницата има каталог и тясна колона „Купиха също“ (220px). И двете са .catalog с flex-wrap и последният продукт в каталога е твърде широк. Смени правилото за .catalog: grid, колони от поне 200px, колкото се съберат, разтегнати до края. Проверката очаква 3 колони в каталога, всяка по 208px, и 1 колона от 220px вдясно.

HTML, CSS, JS

Идеята

Области на страницата

Grid нарежда и самата страница: шапка, филтри вляво, каталог, долна част. Областите могат да се нарисуват с имена:

.page {
display: grid;
grid-template-columns: 220px 1fr;
grid-template-areas:
"header header"
"filters main"
"footer footer";
gap: 16px;
}
header { grid-area: header; }
.filters { grid-area: filters; }
  • Всеки ред в кавички е ред на грида, а всяка дума е клетка. Една дума в две клетки една до друга прави област, която ги заема: шапката е на две колони.
  • grid-area: header слага елемента в областта с това име.
  • Всеки ред трябва да има толкова клетки, колкото са колоните, а областта трябва да е правоъгълник.

Без имена елемент се поставя с номерата на линиите между колоните: grid-column: 1 / 3 е от първата до третата линия (две колони), а grid-column: 1 / -1 е до последната линия. grid-column: span 2 заема две колони там, където браузърът го сложи.

Пробвай

Страницата

Подреди страницата (900px) с grid-template-areas: горе шапката на цялата ширина, под нея филтрите вляво (220px) и каталогът вдясно, долу долната част на цялата ширина. Разстоянието е 16px.

HTML, CSS, JS

Пробвай

Намери грешката

Страницата се разпадна: шапката, филтрите, каталогът и долната част са една върху друга. В конзолата няма грешка. Кой ред е причината?

Избери реда с грешката.

По-точно, за любопитните

Неявни редове. grid-template-columns и grid-template-rows описват явния грид. Ако елементите са повече, браузърът добавя редове сам. Те са неявни и са auto, колкото съдържанието. Височината им се дава с grid-auto-rows.

auto-fill и auto-fit. Разликата се вижда, когато елементите са по-малко от колоните. В каталог от 960px с два продукта auto-fill пази четирите колони и продуктите са по 228px. auto-fit маха празните колони и двата продукта стават по 472px.

fr и съдържанието. 1fr е minmax(auto, 1fr): колоната не става по-тясна от най-дългата дума в нея. Ако една дълга дума разтяга колоната, minmax(0, 1fr) го спира.

Grid или flex. Flexbox е за една ос: шапка, ред бутони, ред в кошницата. Grid е за две: каталог, страница, табло. Често са заедно: страницата е grid, а шапката в нея е flex.

Още. grid-auto-flow: dense попълва празните клетки с по-късни елементи, но разбърква реда на екрана спрямо дървото. subgrid пуска вложен грид да ползва колоните на родителя.

Упражнение

Продуктът на седмицата

Направи каталога (900px) grid: колони от поне 200px, колкото се съберат, gap 16px. Продуктът на седмицата е първи и заема две колони. Всички редове са високи 160px, и тези, които браузърът добавя сам. Проверката очаква 4 колони по 213px, продукта на седмицата 442px широк и последния продукт 160px висок.

HTML, CSS, JS

Тест

Провери се

1. Каталог от 700px е с grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)) и gap: 20px. Колко колони има?
2. Кога grid е по-добрият избор от flexbox?
3. Какво прави grid-column: span 2?
4. Гридът има grid-template-rows: 160px, а продуктите са на три реда. Колко високи са вторият и третият ред?

Създаден от Иво Гергов като част от кампанията на Evo Tech за достъпно обучение по програмиране ·