Шаблоны грид-областей

Перевод не завершен. Пожалуйста, помогите перевести эту статью с английского.

В предыдущем обзоре мы рассмотрели грид-линии и то, как с их помощью размещать элементы в гридах. Когда Вы работаете с CSS Grid Layout, у Вас всегда есть грид-линии, поэтому они - быстрый, прямой и надежный способ расположить элементы. Как бы то ни было, существует альтернативный метод, и этот метод можно использовать как в одиночку, так и в сочетании с расположением элементов по грид-линиям. В этом методе элементы располагаются с помощью именнованных, заранее определенных грид-областей. Давайте рассмотрим, как он работает, и Вы скоро поймете, почему его называют методом ascii-искусства в концепции макетов на гридах!

Имя для грид-области

Вы уже знакомы со свойством grid-area. Это то свойство, которое принимает в качестве значения номера четырех грид-линий, определяющих расположение грид-области.

.box1 {
   grid-area: 1 / 1 / 4 / 2;
}

Что мы делаем, когда задаем все четыре значения? Мы определяем область, ограниченную данными грид-линиями. 

The Grid Area defined by lines

Другой способ определить грид-область, - задать ей имя и определить местоположение как значения свойства grid-template-areas. Вы можете выбрать для грид-области любое имя. Например, если нам нужно создать макет согласно картинке ниже, мы можем назвать четыре основных области следующим образом:

  • header
  • footer
  • sidebar
  • основное содержимое content

An image showing a simple two column layout with header and footer

С помощью свойства grid-area мы можем назначить каждой из этих областей свое собственное имя. Именование областей еще не создает никакого макета, однако теперь у нас есть именнованные области, которые мы можем в нем использовать.

.header {
    grid-area: hd;
}
.footer {
    grid-area: ft;
}
.content {
    grid-area: main;
}
.sidebar {
    grid-area: sd;
}

Определив имена, мы можем приступить к созданию макета. На этот раз вместо того, чтобы расположить элементы с помощью номеров линий, заданных для самих элементов, мы создаем весь макет в грид-контейнере.

.wrapper {
    display: grid;
    grid-template-columns: repeat(9, 1fr);
    grid-auto-rows: minmax(100px, auto);
    grid-template-areas: 
      "hd hd hd hd   hd   hd   hd   hd   hd"
      "sd sd sd main main main main main main"
      "ft ft ft ft   ft   ft   ft   ft   ft";
}

 

<div class="wrapper">
    <div class="header">Header</div>
    <div class="sidebar">Sidebar</div>
    <div class="content">Content</div>
    <div class="footer">Footer</div>
</div>

Если мы используем этот метод, то нам не нужно задавать что-то отдельно для грид-элементов, все задается для грид-контейнера. Весь макет описывается значением свойства grid-template-areas.

Оставляем ячейку пустой

В данном примере мы полностью заполнили грид областями и не оставили пустого пространства. Однако, наш метод также позволяет оставлять грид-ячейки пустыми. Чтобы сделать это воспользуйтесь символом точки, '.'. Если нам нужно отображать футер только под основным содержимым страницы, значит, мы должны оставить три ячейки под сайдбаром пустыми.

.header {
    grid-area: hd;
}
.footer {
    grid-area: ft;
}
.content {
    grid-area: main;
}
.sidebar {
    grid-area: sd;
}
.wrapper {
    display: grid;
    grid-template-columns: repeat(9, 1fr);
    grid-auto-rows: minmax(100px, auto);
    grid-template-areas: 
      "hd hd hd hd   hd   hd   hd   hd   hd"
      "sd sd sd main main main main main main"
      ".  .  .  ft   ft   ft   ft   ft   ft";
}
<div class="wrapper">
    <div class="header">Header</div>
    <div class="sidebar">Sidebar</div>
    <div class="content">Content</div>
    <div class="footer">Footer</div>
</div>

Чтобы сделать наш макет чище, мы можем использовать множество символов .. Если между точками нет пробелов, то они считаются одной ячейкой. В комплексных макетах подобная возможность помогает аккуратно выравнивать строки и колонки. То есть, Вы прямо в CSS можете видеть, как выглядит Ваш макет.

Охватываем несколько ячеек

В нашем примере каждая из областей охватывает несколько грид-ячеек, и получаем мы подобный эффект за счет того, что через пробел повторяем имя этой грид-области несколько раз. Вы можете добавить дополнительные пробелы, чтобы аккуратно выравнять значения в grid-template-areas. В нашем примере мы пробелами подравняли hd и ft , чтобы они коррелировали с  main.

Область, которую мы создаем подобнами цепочками имен, должна быть прямоугольной. На данном этапе нельзя создать L-образную область. В спецификации говорится, что, возможно, в будущем подобная функциональность добавится. А сейчас мы можем охватывать строки так же легко, как и колонки. Например, давайте сделаем так, чтобы наш сайдбар простирался до конца футера. Для этого поменяем . на sd.

.header {
    grid-area: hd;
}
.footer {
    grid-area: ft;
}
.content {
    grid-area: main;
}
.sidebar {
    grid-area: sd;
}
.wrapper {
    display: grid;
    grid-template-columns: repeat(9, 1fr);
    grid-auto-rows: minmax(100px, auto);
    grid-template-areas: 
      "hd hd hd hd   hd   hd   hd   hd   hd"
      "sd sd sd main main main main main main"
      "sd sd sd  ft  ft   ft   ft   ft   ft";
}

Значение grid-template-areas должно отображать законченный грид, а иначе оно невалидно (и игнорируется!). Это значит, что у Вас должно быть одинаковое количество ячеек в каждой строке, а если какая-то ячейка должна быть пустой, то вместо имени в ней должна быть точка. Грид будет также невалидным, если области в нем не прямоугольные.

Переопределение грида с медиа-запросами

Поскольку наш макет теперь содержится в одной части CSS, вносить изменения для различных контрольных точек (breakpoints) становится крайне легко. Сделать это можно либо переопределив сам грид, либо положение элементов на гриде, либо и то, и другое одновеременно.

When doing this, define the names for your areas outside of any media queries. That way the content area would always be called main no matter where on the grid it is placed.

For our layout above, we might like to have a very simple layout at narrow widths, defining a single column grid and stacking up our items.

.header {
    grid-area: hd;
}
.footer {
    grid-area: ft;
}
.content {
    grid-area: main;
}
.sidebar {
    grid-area: sd;
}

.wrapper {
    display: grid;
    grid-auto-rows: minmax(100px, auto);
    grid-template-columns: 1fr;
    grid-template-areas: 
      "hd"
      "main"
      "sd"
      "ft";
}

We can then redefine that layout inside media queries to go to our two columns layout, and perhaps take it to a three column layout if the available space is even wider. Note that for the wide layout I keep my nine column track grid, I redefine where items are placed using grid-template-areas.

@media (min-width: 500px) {
    .wrapper {
        grid-template-columns: repeat(9, 1fr);
        grid-template-areas: 
          "hd hd hd hd   hd   hd   hd   hd   hd"
          "sd sd sd main main main main main main"
          "sd sd sd  ft  ft   ft   ft   ft   ft";
    }
}
@media (min-width: 700px) {
    .wrapper {
        grid-template-areas: 
          "hd hd hd   hd   hd   hd   hd   hd hd"
          "sd sd main main main main main ft ft";
    }
}

Using grid-template-areas for UI elements

Many of the grid examples you will find online make the assumption that you will use grid for main page layout, however grid can be just as useful for small elements as those larger ones. Using grid-template-areas can be especially nice as it is easy to see in the code what your element looks like.

As a very simple example we can create a “media object”. This is a component with space for an image or other media on one side and content on the other. The image might be displayed on the right or left of the box.

Images showing an example media object design

Our grid is a two-column track grid, with the column for the image sized at 1fr and the text 3fr. If you wanted a fixed width image area, then you could set the image column as a pixel width, and assign the text area 1fr. A single column track of 1fr would then take up the rest of the space.

We give the image area a grid area name of img and the text area content, then we can lay those out using the grid-template-areas property.

* {box-sizing: border-box;}

.media {
    border: 2px solid #f76707;
    border-radius: 5px;
    background-color: #fff4e6;
    max-width: 400px;
}
.media {
    display: grid;
    grid-template-columns: 1fr 3fr;
    grid-template-areas: "img content";
    margin-bottom: 1em;
}

.media .image {
    grid-area: img;
    background-color: #ffd8a8;
}

.media .text {
    grid-area: content;
    padding: 10px;
    
}
<div class="media">
    <div class="image"></div>
    <div class="text">This is a media object example. 
      We can use grid-template-areas to switch around the image and text part of the media object.
    </div>
</div>

Displaying the image on the other side of the box

We might want to be able to display our box with the image the other way around. To do this we redefine the grid to put the 1fr track last, and simply flip the values go grid-template-areas.

* {box-sizing: border-box;}

.media {
    border: 2px solid #f76707;
    border-radius: 5px;
    background-color: #fff4e6;
    max-width: 400px;
}
.media {
    display: grid;
    grid-template-columns: 1fr 3fr;
    grid-template-areas: "img content";
    margin-bottom: 1em;
}

.media.flipped {
    grid-template-columns: 3fr 1fr;
    grid-template-areas: "content img";
}

.media .image {
    grid-area: img;
    background-color: #ffd8a8;
}

.media .text {
    grid-area: content;
    padding: 10px;
    
}
<div class="media flipped"> 
    <div class="image"></div> 
    <div class="text">This is a media object example.
      We can use grid-template-areas to switch around the image and text part of the media object.
    </div>
</div>

Grid definition shorthands

Having looked at various ways of placing items on our grids and many of the properties used to define grid, this is a good time to take a look at a couple of shorthands that are available for defining the grid and many things about it all in one line of CSS.

These can quickly become difficult to read for other developers, or even your future self. However they are part of the specification and it is likely you will come across them in examples or in use by other developers, even if you choose not to use them.

Before using any shorthand it is worth remembering that shorthands not only enable the setting of many properties in one go, they also act to reset things to their initial values that you do not, or cannot set in the shorthand. Therefore if you use a shorthand, be aware that it may reset things you have applied elsewhere.

The two shorthands for the grid container are the Explicit Grid Shorthand grid-template and the Grid Definition Shorthand grid.

grid-template

The grid-template property sets the following properties:

The property is referred to as the Explicit Grid Shorthand because it is setting those things that you control when you define an explicit grid, and not those which impact any implicit row or column tracks that might be created.

The following code creates a layout, using grid-template that is the same as the layout create earlier in this guide.

.wrapper {
    display: grid;
    grid-template: 
      "hd hd hd hd   hd   hd   hd   hd   hd" minmax(100px, auto)
      "sd sd sd main main main main main main" minmax(100px, auto)
      "ft ft ft ft   ft   ft   ft   ft   ft" minmax(100px, auto)
             / 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr ;           
}

The first value is our grid-template-areas value but we also declare the size of the row at the end of each row. This is what the minmax(100px, auto) is doing.

Then after grid-template-areas we have a forward slash, after that is an explicit track listing of column tracks.

grid

The grid shorthand goes a step further and also sets properties used by the implicit grid. So you will be setting:

The property also resets the grid-gap property to 0, however you cannot specify the gaps in this shorthand.

You can use this syntax in the exact same way as the grid-template shorthand, just be aware than when doing so you will reset the other values set by the property.

.wrapper {
    display: grid;
    grid: "hd hd hd hd   hd   hd   hd   hd   hd" minmax(100px, auto)
    "sd sd sd main main main main main main" minmax(100px, auto)
    "ft ft ft ft   ft   ft   ft   ft   ft" minmax(100px, auto)
    / 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr ;           
}

We will revisit the other functionality offered by this shorthand later in these guides when we take a look at auto placement and the grid-auto-flow property.

If you have worked through these initial guides you now should be in a position to create grid layouts using line-based placement or named areas. Take some time to build some common layout patterns using grid, while there are lots of new terms to learn, the syntax is relatively straightforward. As you develop examples, you are likely to come up with some questions and use cases for things we haven't covered yet. In the rest of these guides we will be looking at some more of the detail included in the specification – in order that you can begin to create advanced layouts with it.

Метки документа и участники

Метки: 
 Внесли вклад в эту страницу: coshturnina
 Обновлялась последний раз: coshturnina,