От автора: в предыдущей статье я рассказал о том, как с помощью CSS Grid создать календарь. Сегодня я хочу поделиться тем, как создать для CSS Grid резервный Flexbox вариант для того же календаря.
Как обеспечить поддержку
В целом, есть три способа обеспечить поддержку, когда дело доходит до CSS. Первый способ: написать резервный код. Переопределить резервный код.
.selector { property: fallback-value; property: actual-value; }
Второй метод: написать резервный код. Переопределить резервный код в запросе функций CSS Feature Queries (@supports). Сбросить свойства внутри @supports, если нужно.
.selector { property: fallback-value; } @supports (display: grid) { property: actual-value; }
Третий метод: написать все в @supports.
@supports not (display: grid) { .selector { property: fallback-value; } } @supports (display: grid) { .selector { property: actual-value; } }
Эти три метода перечислены в порядке убывания сложности. (Если вам нужно переопределить код, это сложнее). Это означает, что написать все в @supports является самым простым из трех способов. Как вы решите поддерживать свой проект, зависит от поддержки браузера для:
Функций
Резервных функций
Запросов функций
Проверка поддержки
Лучшее место, чтобы проверить поддержку — caniuse. Здесь я могу видеть, что поддержка для CSS Grid вполне достойная. Браузеры, о которых я должен беспокоиться:
Opera Mini: глобальное использование 1,42%
Браузеры Android с 2.1 по 4.4.4: 0,67% мирового использования
Браузер Blackberry: глобальное использование 0,02% (не стоит беспокоиться об этом).
Поддержка для резервного варианта (Flexbox) тоже хороша.
Но у нас есть проблема: запасной вариант Flexbox не будет работать в Android с 2.1 по 4.3 (они не поддерживают переносы). Глобальное использование для Android 2.1 — 4.3 составляет 0.37%. Здесь я должен решить:
Стоит ли предоставлять запасной вариант Flexbox для Opera Mini (1,42%), Android 4.4.4 (0,3%) и Blackberry (0,02%)?
Стоит ли менять запасной вариант с Flexbox на более старую функцию для поддержки Android 2.1 — 4.3 (еще 0.37%)?
Давайте предположим, что для этого проекта я решил, что запасной вариант Flexbox достаточен. Я не собираюсь беспокоиться об Android 2.1 — 4.3. Далее я хочу проверить, поддерживают ли браузеры CSS Feature Queries. Здесь я вижу:
Opera Mini поддерживает запросы функций
Android 4.4.4 поддерживает запросы функций
Браузер Blackberry не поддерживает запросы функций
IE 11 не поддерживает запросы функций
Решите, как написать резервный код
Ранее я упоминал, что есть три способа написания резервного кода для CSS:
Написать резервный код. Переопределить резервный код.
Написать резервный код. Переопределить резервный код в @supports.
Написать все в @supports.
Если я напишу все внутри @supports, я могу предоставить поддержку для:
Opera Mini (1,43%)
Android 4.4.4 (0,3%)
Но я теряю поддержку для:
IE 11 (2,3%)
Blackberry (0,02%)
Я не хочу отказываться от 2,3% пользователей IE, что означает, что метод 3 (написать все в @supports) не подходит.
Если я использую метод 2 (написать резервный код, переопределить резервный код в @supports), я могу обеспечить поддержку для:
IE 11 (2,3%)
Opera Mini (1,43%)
Android 4.4.4 (0,3%)
Blackberry браузер (0,02%)
Это все, что мне нужно. Вот почему я собираюсь выбрать метод 2.
Примечание. Если вы хотите переопределить код, вы можете использовать в качестве отправной точки демо из моей предыдущей статьи.
Отключение кода Grid
Во-первых, мы размещаем код CSS Grid в @supports (как мы уже было сказано выше).
@supports (display: grid) { .day-of-week, .date-grid { display: grid; grid-template-columns: repeat(7, 1fr); } .date-grid button:first-child { grid-column: 6; } }
Мы можем отключить код CSS Grid, установив для display недопустимое значение (не grid). Это отключит весь блок кода. (Спасибо Рэйчел Эндрю за этот изящный трюк. Думаю, я научился у нее).
@supports (display: gridx) { /*...*/ }
Написание кода Flexbox
Нам нужно построить ту же сетку из семи столбцов с помощью Flexbox. Первое, что нам нужно сделать, это признать, что Flexbox и Grid работают по-разному. Мы не сможем получить идеальную копию, но мы можем создать что-то близкое. Первое, мы установим для display — flex.
.day-of-week, .date-grid { display: flex; }
Нам нужно, чтобы кнопки в .date-grid переносились, поэтому мы установили для flex-wrap — wrap.
.date-grid { flex-wrap: wrap; }
Нам нужно скопировать сетку из семи столбцов. Простой способ сделать это — рассчитать ширину сетки в соответствии с шириной каждой кнопки. Здесь я уже установил для каждой кнопки 4.5ch. Это означает, что ширина сетки должна быть 7 x 4.5ch.
(Мы можем использовать CSS Calc, чтобы выполнить расчеты.)
.day-of-week, .date-grid { max-width: calc(4.5ch * 7); }
Нам нужно, чтобы элементы .day-of-week распределились на всю доступную ширину. Простой способ сделать это — установить для justify-content — space-between.
.day-of-week { justify-content: space-between; }
Здесь мы видим, что элементы .day-of-week выходят за пределы сетки. Это происходит потому, что мы позволяем Flexbox рассчитывать flex-basis. Если мы хотим, чтобы каждый элемент .day-of-week имел одинаковую ширину, нам нужно установить flex-basis самим.
В этом случае самый простой способ — установить ширину одного элемента сетки flex-basis (или 4.5ch). Примечание: я задал font-size для каждого элемента .day-of-week — 0.7em (для визуальной эстетики). Мы должны учитывать это изменение.
.day-of-week > * { flex-basis: calc(4.5ch / 0.7); }
Наконец, нам нужно сместить 1 февраля на пятницу. (Пять столбцов). Поскольку столбец имеет 4.5ch, мы просто смещаем его на 4.5ch x 5. (Опять же, мы можем использовать CSS Calc).
.date-grid button:first-child { margin-left: calc(4.5ch * 5) }
Исправление версии CSS Grid
Мы можем повторно активировать код CSS Grid и внести любые необходимые изменения.
@supports(display: grid) { /* ... */ }
Здесь мы видим, что некоторые значения уходят далеко вправо. Это происходит потому, что мы добавили margin-left для первого элемента сетки. Нам нужно сбросить добавленное поле.
@supports(display: grid) { /* ... */ .date-grid button:first-child { grid-column: 6; margin-left: 0; } }
Еще одна вещь: мы можем удалить max-width, потому что нам это не нужно в коде CSS. (Даже если это не влияет на код CSS, все же лучше это удалить. Всегда лучше иметь меньше свойств).
@supports(display: grid) { .day-of-week, .date-grid { display: grid; grid-template-columns: repeat(7, 1fr); max-width: initial; } /* ... */ }
Вот визуальная разница между версиями Flexbox и CSS Grid. Не так уж плохо!
Одна забавная вещь
CSS Grid — это круто, потому что элементы размещаются в порядке указания. Мы можем легко изменить поток слева направо и справа налево.
Примечание: я не знаю, читаются ли календари справа налево в языках RTL. Я просто подумал, что будет забавно упомянуть об этом).
Наш код для CSS Grid поддерживает это поведение естественным образом. Если вы хотите поддерживать такое же поведение с Flexbox, вам нужно использовать логические свойства CSS.
Поскольку поддержка логических свойств CSS не так уж и велика, мы должны предоставить запасной вариант. (Лучший способ — использовать метод 1: написать резервный код; переопределить резервный код).
.date-grid button:first-child { margin-left: calc(4.5ch * 5); margin-inline-start: calc(4.5ch * 5); } @supports(display: grid) { /* ... */ .date-grid button:first-child { grid-column: 6; margin-left: 0; margin-inline-start: 0; } }
Вот и все! Вот Codepen окончательного кода:
Источник: https://zellwk.com
Редакция: Команда webformyself.