Главная » Статьи » Flash Grid: Изучите CSS Grid, построив систему сетки

Flash Grid: Изучите CSS Grid, построив систему сетки

Flash Grid: Изучите CSS Grid, построив систему сетки

От автора: в последнее время я экспериментировал с идеей создания облегченной системы сетки на основе CSS Grid. У нас в CodyFrame есть система сетки, и она основана на Flexbox. Однако CSS Grid имеет так много мощных функций, которых нет во Flexbox, что я в итоге создал Flash Grid.

Я собираюсь рассказать обо всем процессе создания Flash Grid. Если вы хотите больше узнать о CSS Grid, это отличное место для начала, так как мы коснемся основных свойств CSS Grid и рассмотрим некоторые практические приемы, чтобы максимально эффективно использовать эту мощную систему макетов.

В случае, если вы хотите пропустить руководство и просто взять код:

Давайте начнем! Первый шаг — создание класса .grid:

$grid-columns: 12 !default; .grid { --grid-cols: #{$grid-columns}; display: grid; grid-gap: var(--grid-gap, 0); // default grid-gap = 0 grid-template-columns: repeat(var(--grid-cols), 1fr); // grid of 12 flexible columns > * { grid-column-end: span var(--grid-cols); // each grid item takes full-width by default }
}

При определении количества колонок сетки мы используем флаг SCSS !default в случае, если система сетки импортируется как модуль, и мы хотим, чтобы это значение было настраиваемым.

В свойстве grid-template-columns, где мы определяем макет сетки: нам нужны 12 адаптивных колонок. Ширина каждой колонки составляет 1 fr. Fr (дробная единица) — это умная единица, равная 1 части доступного пространства. Поскольку наша сетка состоит из 12 колонок x 1fr, каждая гибкая гибкий колонка занимает 1/12 доступной ширины.

Функция repeat() позволяет передавать одно значение ширины (1fr). Другой способ определить ту же сетку:

.grid { grid-template-columns: 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr;
}

… но, вы видите … это не так элегантно! Вот краткий обзор только что созданной нами сетки:

Flash Grid: Изучите CSS Grid, построив систему сетки

На приведенном выше снимке экрана обратите внимание на числа между столбцами (пока фокусируйтесь только на положительных числах сверху). Эти номера строк можно использовать для размещения элементов сетки.

Во фрагменте .grid мы также указываем все дочерние элементы сетки и устанавливаем их значение grid-column-end равным span 12.

По умолчанию мы хотим, чтобы каждый дочерний элемент занимал всю доступную ширину. grid-column-end используется для указания конечной позиции элемента сетки. Вы можете использовать это свойство для установки конечной строки (например, grid-column-end: 3;). Но если вы используете волшебное слово «span», вы определяете, сколько столбцов должно занимать элемент сетки. Например, grid-column-end: span 12; означает «растянуть этот элемент на 12 колонок».

Зачем устанавливать диапазон по умолчанию в 12 столбцов для элементов сетки? Мы работаем с мобильными устройствами. Мы можем предположить, что в большинстве случаев наши элементы сетки будут сначала занимать всю ширину (12 столбцов), а затем меньшее количество столбцов на больших экранах. Наше значение по умолчанию не позволяет указывать каждый элемент сетки .col-12 (span 12) вручную.

Количество столбцов задается как пользовательское свойство CSS, если вы хотите изменить его на уровне компонента (или путем создания других служебных классов). Например:

.grid--2 { --grid-cols: 2;
}

Далее мы можем определить служебные классы для свойства grid-gap:

.grid-gap-xxxxs { --grid-gap: var(--space-xxxxs, 0.125rem); }
.grid-gap-xxxs { --grid-gap: var(--space-xxxs, 0.25rem); }
.grid-gap-xxs { --grid-gap: var(--space-xxs, 0.375rem); }
.grid-gap-xs { --grid-gap: var(--space-xs, 0.5rem); }
.grid-gap-sm { --grid-gap: var(--space-sm, 0.75rem); }
.grid-gap-md { --grid-gap: var(--space-md, 1.25rem); }
.grid-gap-lg { --grid-gap: var(--space-lg, 2rem); }
.grid-gap-xl { --grid-gap: var(--space-xl, 3.25rem); }
.grid-gap-xxl { --grid-gap: var(--space-xxl, 5.25rem); }
.grid-gap-xxxl { --grid-gap: var(--space-xxxl, 8.5rem); }
.grid-gap-xxxxl { --grid-gap: var(--space-xxxxl, 13.75rem); }

Переменные интервалов являются частью CodyFrame. Вы можете заменить их собственной шкалой интервалов или использовать резервные значения, указанные в каждой переменной (значение после запятой применяется, если переменная не определена).

Свойство grid-gap используется для определения пространства между элементами сетки. Чтобы завершить базовую систему сетки, мы должны определить классы .col:

@for $i from 1 through $grid-columns { .col-#{$i} { grid-column-end: span #{$i}; }
}

Мы используем цикл SASS @for для генерации классов .col в соответствии с количеством столбцов, указанных в переменной $grid-columns. Скомпилированный CSS:

.col-1 { grid-column-end: span 1; }
.col-2 { grid-column-end: span 2; }
.col-3 { grid-column-end: span 3; }
.col-4 { grid-column-end: span 4; }
.col-5 { grid-column-end: span 5; }
.col-6 { grid-column-end: span 6; }
.col-7 { grid-column-end: span 7; }
.col-8 { grid-column-end: span 8; }
.col-9 { grid-column-end: span 9; }
.col-10 { grid-column-end: span 10; }
.col-11 { grid-column-end: span 11; }
.col-12 { grid-column-end: span 12; }

Классы col определяют количество колонок, занимаемых элементом сетки. Помните, что слово «span» означает «растянуть элемент на x колонок», где x — это число, указанное после span.

Добавляем немного специфики CSS Grid

Напомним, что базовая версия Flash Grid включает в себя определение сетки, зазоров сетки и служебных классов col. Теперь пришло время добавить немного специфики! Вот полезный класс .grid-auto-cols:

.grid-auto-cols { // cols = same size display: grid; grid-gap: var(--grid-gap, 0); grid-template-columns: repeat(auto-fit, minmax(0, 1fr));
}

Этот класс похож на .grid, за исключением того, что мы не устанавливаем количество колонок. auto-fit заменяет 12 в классе .grid. Это означает, что CSS Grid может определять количество столбцов на основе значения ширины столбцов (второе значение функции repeat ()).

Но подождите! Значение ширины (1fr в классе .grid) теперь заменяется функцией minmax(). Это буквально означает, что минимальная ширина столбца равна 0, а максимальное значение равно 1fr. Мы устанавливаем диапазон значений для ширины столбца.

Результат: вы получаете сетку, в которой все столбцы имеют одинаковую ширину, независимо от их содержимого или количества элементов сетки.

Flash Grid: Изучите CSS Grid, построив систему сетки

Используя аналогичный подход, мы создаем служебные классы .grid-auto-{size}:

.grid-auto-xs, .grid-auto-sm, .grid-auto-md, .grid-auto-lg, .grid-auto-xl { // auto-sized grid display: grid; grid-gap: var(--grid-gap, 0); grid-template-columns: repeat(auto-fit, minmax(var(--col-min-width), 1fr));
} .grid-auto-xs { --col-min-width: 8rem; }
.grid-auto-sm { --col-min-width: 10rem; }
.grid-auto-md { --col-min-width: 15rem; }
.grid-auto-lg { --col-min-width: 20rem; }
.grid-auto-xl { --col-min-width: 25rem; }

В отличие от .grid-auto-cols минимальное значение ширины этих новых классов равно —col-min-width. В результате получается адаптивная сетка, в которой добавляется новая колонка, когда для нее достаточно места (минимальная ширина, указанная в функции minmax()).

Flash Grid: Изучите CSS Grid, построив систему сетки

С помощью служебных классов .grid-auto ( .grid-auto-colsи .grid-auto-{size}) вы можете создавать адаптивные макеты без использования классов .col в элементах сетки. На самом деле, вы не должны использовать классы .col вообще, если хотите, чтобы классы .grid-auto работали правильно.

Наконец, чтобы воспользоваться преимуществами номеров строк сетки, мы можем создать новый набор служебных классов: col-start-{line-number} и .col-end-{line-number}.

@for $i from 1 through $grid-columns { .col-start-#{$i} { grid-column-start: #{$i}; } .col-end-#{$i+1} { grid-column-end: #{$i+1}; }
}

Классы .col-start переходят из .col-start-1 в col-start-12, а классы .col-end из .col-end-2 в .col-end-13. Используйте их, если хотите, чтобы элемент сетки находился между определенной начальной и конечной линиями. Помните, что это номера строк:

Flash Grid: Изучите CSS Grid, построив систему сетки

Отрицательные числа внизу являются альтернативным способом указания на те же строки. Чем они полезны: если вы хотите настроить указание на последнюю строку, независимо от количества столбцов, вы можете сделать следующее:

.col-end { grid-column-end: -1; }

Классы .col-start / end позволяют создавать сложные сетки:

Модификаторы классов контрольных точек

Чтобы сделать нашу сетку редактируемой в разных контрольных точках, мы можем добавить модификаторы класса. В CodyFrame соглашение заключается в добавлении суффикса @{breakpoint} к классам (например, col-4@sm) для целевых контрольных точек.

Вот пример модификаторов класса в контрольной точке x-small:

$breakpoints: ( xs: 32rem, sm: 48rem, md: 64rem, lg: 80rem, xl: 90rem
) !default; @mixin breakpoint($breakpoint) { @media (min-width: map-get($map: $breakpoints, $key: $breakpoint)) { @content; }
} @include breakpoint(xs) { .grid-auto-xs\@xs { --col-min-width: 8rem; } .grid-auto-sm\@xs { --col-min-width: 10rem; } .grid-auto-md\@xs { --col-min-width: 15rem; } .grid-auto-lg\@xs { --col-min-width: 20rem; } .grid-auto-xl\@xs { --col-min-width: 25rem; } .grid-auto-cols\@xs { grid-template-columns: repeat(auto-fit, minmax(0, 1fr)); } @for $i from 1 through $grid-columns { .col-#{$i}\@xs { grid-column-end: span #{$i}; } .col-start-#{$i}\@xs { grid-column-start: #{$i}; } .col-end-#{$i+1}\@xs { grid-column-end: #{$i+1}; } } .col-start-auto\@xs { grid-column-start: auto; } .col-end-auto\@xs { grid-column-end: auto; }
}

Окончательный код SCSS:

// Flash Grid
$grid-columns: 12 !default; .grid, [class*="grid-auto-"] { display: grid; grid-gap: var(--grid-gap, 0);
} .grid { --grid-cols: #{$grid-columns}; grid-template-columns: repeat(var(--grid-cols), 1fr); > * { grid-column-end: span var(--grid-cols); }
} .grid-auto-xs, .grid-auto-sm, .grid-auto-md, .grid-auto-lg, .grid-auto-xl { // auto-sized grid grid-template-columns: repeat(auto-fit, minmax(var(--col-min-width), 1fr));
} .grid-auto-xs { --col-min-width: 8rem; }
.grid-auto-sm { --col-min-width: 10rem; }
.grid-auto-md { --col-min-width: 15rem; }
.grid-auto-lg { --col-min-width: 20rem; }
.grid-auto-xl { --col-min-width: 25rem; } .grid-auto-cols { // cols = same size grid-template-columns: repeat(auto-fit, minmax(0, 1fr));
} .grid-gap-xxxxs { --grid-gap: var(--space-xxxxs, 0.125rem); }
.grid-gap-xxxs { --grid-gap: var(--space-xxxs, 0.25rem); }
.grid-gap-xxs { --grid-gap: var(--space-xxs, 0.375rem); }
.grid-gap-xs { --grid-gap: var(--space-xs, 0.5rem); }
.grid-gap-sm { --grid-gap: var(--space-sm, 0.75rem); }
.grid-gap-md { --grid-gap: var(--space-md, 1.25rem); }
.grid-gap-lg { --grid-gap: var(--space-lg, 2rem); }
.grid-gap-xl { --grid-gap: var(--space-xl, 3.25rem); }
.grid-gap-xxl { --grid-gap: var(--space-xxl, 5.25rem); }
.grid-gap-xxxl { --grid-gap: var(--space-xxxl, 8.5rem); }
.grid-gap-xxxxl { --grid-gap: var(--space-xxxxl, 13.75rem); } @for $i from 1 through $grid-columns { .col-#{$i} { grid-column-end: span #{$i}; } .col-start-#{$i} { grid-column-start: #{$i}; } .col-end-#{$i+1} { grid-column-end: #{$i+1}; }
} .col-start { grid-column-start: 1; }
.col-end { grid-column-end: -1; } // breakpoints
$breakpoints: ( xs: 32rem, sm: 48rem, md: 64rem, lg: 80rem, xl: 90rem
) !default; @mixin breakpoint($breakpoint) { @media (min-width: map-get($map: $breakpoints, $key: $breakpoint)) { @content; }
} @include breakpoint(xs) { .grid-auto-xs\@xs { --col-min-width: 8rem; } .grid-auto-sm\@xs { --col-min-width: 10rem; } .grid-auto-md\@xs { --col-min-width: 15rem; } .grid-auto-lg\@xs { --col-min-width: 20rem; } .grid-auto-xl\@xs { --col-min-width: 25rem; } .grid-auto-cols\@xs { grid-template-columns: repeat(auto-fit, minmax(0, 1fr)); } @for $i from 1 through $grid-columns { .col-#{$i}\@xs { grid-column-end: span #{$i}; } .col-start-#{$i}\@xs { grid-column-start: #{$i}; } .col-end-#{$i+1}\@xs { grid-column-end: #{$i+1}; } } .col-start-auto\@xs { grid-column-start: auto; } .col-end-auto\@xs { grid-column-end: auto; }
} @include breakpoint(sm) { .grid-auto-xs\@sm { --col-min-width: 8rem; } .grid-auto-sm\@sm { --col-min-width: 10rem; } .grid-auto-md\@sm { --col-min-width: 15rem; } .grid-auto-lg\@sm { --col-min-width: 20rem; } .grid-auto-xl\@sm { --col-min-width: 25rem; } .grid-auto-cols\@sm { grid-template-columns: repeat(auto-fit, minmax(0, 1fr)); } @for $i from 1 through $grid-columns { .col-#{$i}\@sm { grid-column-end: span #{$i}; } .col-start-#{$i}\@sm { grid-column-start: #{$i}; } .col-end-#{$i+1}\@sm { grid-column-end: #{$i+1}; } } .col-start-auto\@sm { grid-column-start: auto; } .col-end-auto\@sm { grid-column-end: auto; }
} @include breakpoint(md) { .grid-auto-xs\@md { --col-min-width: 8rem; } .grid-auto-sm\@md { --col-min-width: 10rem; } .grid-auto-md\@md { --col-min-width: 15rem; } .grid-auto-lg\@md { --col-min-width: 20rem; } .grid-auto-xl\@md { --col-min-width: 25rem; } .grid-auto-cols\@md { grid-template-columns: repeat(auto-fit, minmax(0, 1fr)); } @for $i from 1 through $grid-columns { .col-#{$i}\@md { grid-column-end: span #{$i}; } .col-start-#{$i}\@md { grid-column-start: #{$i}; } .col-end-#{$i+1}\@md { grid-column-end: #{$i+1}; } } .col-start-auto\@md { grid-column-start: auto; } .col-end-auto\@md { grid-column-end: auto; }
} @include breakpoint(lg) { .grid-auto-xs\@lg { --col-min-width: 8rem; } .grid-auto-sm\@lg { --col-min-width: 10rem; } .grid-auto-md\@lg { --col-min-width: 15rem; } .grid-auto-lg\@lg { --col-min-width: 20rem; } .grid-auto-xl\@lg { --col-min-width: 25rem; } .grid-auto-cols\@lg { grid-template-columns: repeat(auto-fit, minmax(0, 1fr)); } @for $i from 1 through $grid-columns { .col-#{$i}\@lg { grid-column-end: span #{$i}; } .col-start-#{$i}\@lg { grid-column-start: #{$i}; } .col-end-#{$i+1}\@lg { grid-column-end: #{$i+1}; } } .col-start-auto\@lg { grid-column-start: auto; } .col-end-auto\@lg { grid-column-end: auto; }
} @include breakpoint(xl) { .grid-auto-xs\@xl { --col-min-width: 8rem; } .grid-auto-sm\@xl { --col-min-width: 10rem; } .grid-auto-md\@xl { --col-min-width: 15rem; } .grid-auto-lg\@xl { --col-min-width: 20rem; } .grid-auto-xl\@xl { --col-min-width: 25rem; } .grid-auto-cols\@xl { grid-template-columns: repeat(auto-fit, minmax(0, 1fr)); } @for $i from 1 through $grid-columns { .col-#{$i}\@xl { grid-column-end: span #{$i}; } .col-start-#{$i}\@xl { grid-column-start: #{$i}; } .col-end-#{$i+1}\@xl { grid-column-end: #{$i+1}; } } .col-start-auto\@xl { grid-column-start: auto; } .col-end-auto\@xl { grid-column-end: auto; }
}

Автор: Sebastiano Guerriero

Источник: https://dev.to

Редакция: Команда webformyself.