27 lip 2019

Tworzymy layout strony głównej za pomocą Grid

Nasz layout zostanie oparty o GRID. Bardzo dobrze sprawdza się do zarządzania wyglądem. Niestety jak zwykle wszystko rozbija się o to czy nasza storna ma być wspierana przez starsze przeglądarki jak opera mini czy ie 11, tzn. ie 10 i 11 wspiera grid ale w okrojonym zakresie.
Jeżeli tak to niestety grid nie jest dla nas, ale olejmy stare przeglądarki więcej na caniuse🙂

Założenia

Strona ma składać się z nagłówka w którym z prawej strony znajdzie się reklama, poniżej z lewej strony nawigacja a z prawej główny element strony z artykułem. Na dole strony stopka na całą szerokość.

| - Header ---------------- | - Ads - |
| - Nav - | --------- Article --------- |
| - Footer --------------------------- |


Do rozdzielczości 575px wygląd elementów ma być następujący. Wszystkie elementy w jednej kolumnie.

| - Header ----- |
| - Article ------ |
| - Nav --------- |
| - Ads --------- |
| - Footer ------ |

Najpierw podstawowe style

* {
  box-sizing: border-box;
}

html {
  height: 100%;
}

body {
  min-height: 100%;
  margin: 0;
}

body {
  font-family: Proxima Nova Regular, Segoe UI, Roboto, Droid Sans, Helvetica Neue, Arial, sans-serif;
  font-size: 20px;
}

Teraz prosty html

<div class="container">
  <header class="pageHeader">Header</header>
  <div class="pageArticle">Article</div>
  <nav class="pageNav">Nav</nav>
  <div class="pageAds">Ads</div>
  <footer class="pageFooter">Footer</footer>
</div>

Każdy z głównych elementów powinien mieć padding.

header,
footer,
nav,
.pageArticle,
.pageAds {
  padding: 1rem; /* kazdy element padding */
  background: yellowgreen; /* dla lepszego wygladu dodajmy kolor tla */
}

.container {
  max-width: 1140px;
  display: grid;
  grid-template-areas: /* tutaj zaczyna sie magia */
    "header header ads"
    "nav article article"
    "footer footer footer";
  grid-template-rows: 80px 1fr 70px;
  grid-template-columns: 20% 1fr 15%;
  grid-gap: 10px; /* odstęp między elementami */
  height: 100vh; /* ustawiamy vh (view port) na 100% */
  margin: auto;
  padding: 0;
}

Teraz trochę o tym czym jest 1fr. Są to jednostki części - ang. fraction units; szerokość lub wysokość ustalana jest na podstawie dostępnego miejsca, np. ustawienie "1fr 2fr" oznacza, że pierwsza kolumna/wiersz zabiera 1/3 dostępnego miejsca a druga 2/3.

W naszym przykładzie jest to grid-template-rows: 80px 1fr 70px; Oznacza to że pierwszy wiesze ma 80px wysokości, drugi będzie 100% wysokości strony pomniejszony o header oraz footer. 70px to wysokość naszej stopki.

grid-template-areas za pomocą tego parametru możemy sterować położeniem poszczególnych elementów. Dosłownie budować nasz layout prawie jak z klocków. Nasz leyout skład się z trzech 3 w poziomie i 3 elementów w pionie.

grid-template-columns: 20% 1fr 15%; dokładnie nam opisuje szerokości kolumn. Mamy head gdzie jego ostatni element to jest Ads o szerokości 15%. Później mamy nav + article - nav będzie miał 20% całego wiersza. Stopka (footer) nie jest uwzględniana bo jest ustawiona na 100% a dokładnie składa się z 3x footer.

Aby element grid-template-areas mógł zadziałać należy do każdego elementu odpowiednio się odwołać przez dodanie np. grid-area: footer; Do każdego z elementów dodamy również kolor aby było widać różnice między nimi.

.pageHeader {
  grid-area: header;
  background-color: red;
}

.pageFooter {
  grid-area: footer;
  background-color: blue;
}

.pageArticle {
  grid-area: article;
  background-color: salmon;
}

.pageNav {
  grid-area: nav;
  background-color: slateblue;
}

.pageAds {
  grid-area: ads;
  background-color: wheat;
}

To by było praktycznie wszystko. Dodamy jeszcze trochę RWD.
Tak jak wcześniej wspomniałem do rozdzielczości 575px każdy z elementów powinien znajdować się w nowym rekordzie, ale trochę skomplikujmy element który w desktopie jest na górze po prawej czyli ads chcę aby znalazł się między nav a footer. Tutaj znowu posłużymy się grid-template-areas

@media (max-width: 575px) {
.container {
  grid-template-areas:
  "header"
  "article"
  "nav"
  "ads"
  "footer";
  grid-template-rows: 80px 1fr 70px 70px 70px;
  grid-template-columns: 1fr;
 }
}

grid-template-rows: 80px 1fr 70px 70px 70px;
80px - wysokość header, 1fr wysokość article, 70px to odpowiedno nav, ads i footer.
grid-template-columns: 1fr; - w tym wypadku daje nam 100% szerokości na stronie.

Podsumowanie

Grid jest bardzo pomocny przy budowaniu skomplikowanych layoutów, tak jak w naszym przypadku div ads został przeniesiony na przedostanie miejsce. Do wykonania css bez grida było by bardzo trudne a czasami nawet niewykonalne.
Dobrym pomysłem jest połączenie grid + flex ale flexem zajmiemy się innym razem.

Niestety jest z 100 jak nie więcej różnych parametrów i opcji:
min-content, max-contnet, minmax(a,b), auto-fill, repet, ...
Więcej możemy poczytać tutaj oraz kilka moich przykładów.

UWAGA

Zapomniałem dodać że tak jak praktycznie we wszystkim potrzebujemy prefiksów 🙂 Ja od dość dawana używam biblioteki autoprefixer która wyręcza mnie z dopisywania ich.
Oczywiście tak jak w przepisach drogowych stosujemy "ograniczone zaufanie" tak samo i w tym wypadku powinniśmy również je zastosować.
Więcej możemy przeczytać w tym artykule CSS Grid in IE: CSS Grid and the New Autoprefixer

UPDATE:

Od pewnego czasu autoprefixer dostał super moce do pluginu ;), do konfiguracji dodajemy grid: "autoplace"

autoprefixer({ grid: "autoplace" })

Dodanie tego wpisu powoduje że większość własności grid jest "kompatybilna" z IE 10/11 CSS Grid in IE

/* zwykła właściwość */
grid-template-columns:repeat(3, 1fr);
/* zamieniana jest na odpowiednią dla IE */
-ms-grid-columns:(1fr)[3];

Oczywiście autoprefixer nie jest nieomylny i każdy kod trzeba dokładnie przetestować.