Создайте свою систему проектирования, Интервал Создайте свою систему проектирования, Интервал



В этой статье мы рассмотрим, как установить систему интервалов в CSS и как использовать относительные единицы для реагирования.

 

Установка системы интервалов с использованием переменных CSS

Шаг 1 установки системы интервалов создает масштаб значений (интервалов). Чтобы создать шкалу нелинейных значений, вам нужно первое единица или базовое значение и второе множитель. Мы уже говорили о создании модульной шкалы в нашей статье о веб-типографии.

Основной подход к интервалу будет выглядеть так:

:root {
    --space-xxs:  4px;
    --space-xs:   8px;
    --space-sm:   12px;
    --space-md:   20px;
    --space-lg:   32px;
    --space-xl:   52px;
    --space-xxl:  84px;
}

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

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

Давайте попробуем немного контролировать систему. Мы можем ввести переменную для определения номера единицы и использовать функцию calc () для получения значений интервала.

:root {
    --space-unit: 16px;
    --space-xxs:  calc(0.25 * var(--space-unit)); // 4px
    --space-xs:   calc(0.5 * var(--space-unit));  // 8px
    --space-sm:   calc(0.75 * var(--space-unit)); // 12px
    --space-md:   calc(1.25 * var(--space-unit)); // 20px
    --space-lg:   calc(2 * var(--space-unit));    // 32px
    --space-xl:   calc(3.25 * var(--space-unit)); // 52px
    --space-xxl:  calc(5.25 * var(--space-unit)); // 84px
}

Мы приближаемся! В приведенном выше примере мы определили каждое значение расстояния, умножив число единиц на множитель. Обратите внимание, что последовательность Фибоначчи по-прежнему применяется к мультипликаторам. Теперь, если мы хотим обновить всю систему, мы можем отредактировать значение единицы.

Затем давайте избавимся от абсолютной единицы и заменим её на em. Для этого мы можем заменить 16px на 1em:

:root {
    --space-unit: 1em;
    --space-xxs:  calc(0.25 * var(--space-unit));
    --space-xs:   calc(0.5 * var(--space-unit));
    --space-sm:   calc(0.75 * var(--space-unit));
    --space-md:   calc(1.25 * var(--space-unit));
    --space-lg:   calc(2 * var(--space-unit));
    --space-xl:   calc(3.25 * var(--space-unit));
    --space-xxl:  calc(5.25 * var(--space-unit));
}

То, что выглядит как небольшая настройка, на самом деле сильно меняется! Единица em - относительная единица, равная текущему размеру шрифта. В большинстве браузеров размер шрифта по умолчанию (до применения стилей CSS) составляет 16 пикселей. Поэтому мы можем считать 1em = 16px. Однако, если вы редактируете размер шрифта элемента, 1em больше не является 16px (для этого элемента), но он равен новому размеру шрифта. То, что выглядит как недостаток контроля, является мощным быстродействием. Позвольте мне показать вам, почему.

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

@include breakpoint(md) {
    :root {
        --text-base-size: 1.25em;
    }
}

Обновляя только одну переменную, вы получаете следующее:

Создайте свою систему проектирования, Интервал

Не только это! Поскольку единица измерения расстояния равна 1em, а все другие значения расстояния являются множителями единицы измерения, когда мы обновляем переменную размера текстового размера, мы также влияем на интервал.

Посмотрите, как этот метод влияет на типографику и интервалы одновременно:

Создайте свою систему проектирования, Интервал

Мы по-прежнему обновляем одну переменную (текстовый размер). До сих пор нет дополнительных медиа-запросов! Все, что вам нужно сделать, чтобы воспользоваться этим мощным подходом к отзывчивости, - это использовать промежуточные переменные для установки paddings и полей на уровне компонента:

.header__top {
    background: var(--black);
    padding: var(--space-sm);
    text-align: center;

    a {
        color: var(--white);
        @include fontSmooth;
    }
}

.header__main {
    border-bottom: 1px solid var(--color-border);
    padding-top: var(--space-sm);
    padding-bottom: var(--space-sm);
    background: var(--white);
}

.header__nav {
    ul {
        display: flex;
    }

    li {
        margin-right: var(--space-md);

        &:last-child {
            margin-right: 0;
        }
    }
}

Что делать, если вы хотите обновить все значения интервалов сразу, не изменяя переменную размера текстовой базы? Просто обновите переменную пространства-единицы:

:root {
    --space-unit: 1em;
    --space-xxs:  calc(0.25 * var(--space-unit));
    --space-xs:   calc(0.5 * var(--space-unit));
    --space-sm:   calc(0.75 * var(--space-unit));
    --space-md:   calc(1.25 * var(--space-unit));
    --space-lg:   calc(2 * var(--space-unit));
    --space-xl:   calc(3.25 * var(--space-unit));
    --space-xxl:  calc(5.25 * var(--space-unit));
}

@include breakpoint(md) {
    :root {
        --space-unit: 1.25em;
    }
}

Это правда, что, обняв метод, подобный этому, вы потеряете часть своего «визуального» контроля, но это в пользу простоты и ремонтопригодности. Это правда, что вы не сможете установить идеальные значения пикселей, но вы будете реагировать на реагирование на совершенно новый уровень: большая часть работы будет устанавливать надежный масштаб значений для интервала и типографики. Затем вы можете отредактировать 2-3 переменные в определенных мультимедийных запросах, чтобы создать каскадный эффект, в отличие от настройки всех компонентов и подэлементов.

 

Как установить заполнение по умолчанию для всех компонентов

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

Чтобы быть ясным, я имею в виду те блочные, «контейнерные» компоненты.

Вот пример:

Создайте свою систему проектирования, Интервал

Возвращаясь к нашему файлу _spacing.scss, давайте добавим переменную заполнения компонента:

:root {
    --space-unit: 1em;
    --space-xxs:  calc(0.25 * var(--space-unit));
    --space-xs:   calc(0.5 * var(--space-unit));
    --space-sm:   calc(0.75 * var(--space-unit));
    --space-md:   calc(1.25 * var(--space-unit));
    --space-lg:   calc(2 * var(--space-unit));
    --space-xl:   calc(3.25 * var(--space-unit));
    --space-xxl:  calc(5.25 * var(--space-unit));
  
  /* components padding */
    --component-padding: var(--space-sm);
}

.component {
  padding-top: var(--component-padding);
}

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

 

Полезные классы Margin

Хотя безопасно включать дополнение непосредственно в свой компонентный CSS, в том числе поля могут вызывать проблемы с макетом. Еще раз, мы имеем в виду основные компоненты, те блоки, которые определяют ваш основной макет (не компонент <button>, а элемент <section class = "myComponent">).

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

По этим причинам может быть полезно иметь классы полезности для полей:

.margin-top, .margin-top--md {
    margin-top: var(--space-md);
}

.margin-top--sm {
    margin-top: var(--space-sm);
}

.margin-top--lg {
    margin-top: var(--space-lg);
}

.margin-top--xl {
    margin-top: var(--space-xl);
}

.margin-top--xxl {
    margin-top: var(--space-xxl);
}

.margin-bottom, .margin-bottom--md {
    margin-bottom: var(--space-md);
}

.margin-bottom--sm {
    margin-bottom: var(--space-sm);
}

.margin-bottom--lg {
    margin-bottom: var(--space-lg);
}

.margin-bottom--xl {
    margin-bottom: var(--space-xl);
}

.margin-bottom--xxl {
    margin-bottom: var(--space-xxl);
}

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

@include breakpoint(md) {
    .margin-top, .margin-top--md {
        margin-top: var(--space-lg);
    }
    
    .margin-top--sm {
        margin-top: var(--space-md);
    }
    
    .margin-top--lg {
        margin-top: var(--space-xl);
    }
    
    .margin-top--xl {
        margin-top: var(--space-xxl);
    }
    
    .margin-top--xxl {
        margin-top: var(--space-xxxl);
    }

    .margin-bottom, .margin-bottom--md {
        margin-bottom: var(--space-lg);
    }
    
    .margin-bottom--sm {
        margin-bottom: var(--space-md);
    }
    
    .margin-bottom--lg {
        margin-bottom: var(--space-xl);
    }
    
    .margin-bottom--xl {
        margin-bottom: var(--space-xxl);
    }
    
    .margin-bottom--xxl {
        margin-bottom: var(--space-xxxl);
    }
}

 

Пользовательские значения интервала

Что делать, если вы устанавливаете маржу на элемент, а space-sm выглядит слишком маленьким, а space-md слишком велик? Работа с набором предопределенных переменных означает, что иногда вам приходится идти на компромисс (ради удобства обслуживания системы).

НО! Если вам нужно использовать значение расстояния, которое не включено в шкалу расстояний, и вы не хотите редактировать или прерывать систему, вы можете воспользоваться функцией CSS calc:

.nav__item {
  margin-right: calc(var(--space-sm) * 1.1);
}

Поступая таким образом, вы вводите новое значение расстояния, но вы все еще проверяете, что это новое значение «контролируется» одной и той же системой.

 

Исправлены значения расстояния

Система интервалов, которую мы ввели, подразумевает, что все поля, paddings (и элементы типографии) обновляются одновременно с использованием нескольких переменных. Насколько это возможно, бывают случаи, когда вы не хотите изменять значение расстояния независимо от размера области просмотра.

Для этого вам необходимо определить интервал, используя другой блок: rem. В отличие от em, rem относится к размеру html (root). Поэтому это не влияет на редактирование размера шрифта тела (обновление переменной размера текстового размера).

Чтобы быть ясным, я не предлагаю заменить em на rem, но объединить их.

Самый простой способ установить «фиксированное» значение расстояния:

.nav__item {
  margin-right: 0.5rem;
}

Тем не менее, это означало бы введение множества пользовательских, внесистемных значений интервала. Если мы подумаем о реальном сценарии: новый разработчик присоединяется к вашей команде, они открывают файл CSS и замечают, что вы установили маркер 0.5rem на элемент. В идеальном мире разработчиков вы сообщили своему новому коллеге о системе интервалов или о том, что у проекта есть (современные) рекомендации CSS, или коллега просит больше узнать, как обрабатывается интервал в проекте. В реальном мире разработчиков шансы нового товарища по команде предполагают, что интервал устанавливается с использованием пользовательских значений rem.

Чтобы избежать путаницы, было бы идеально использовать переменные. Если мы это сделаем, коллега вынужден проверить файл _spacing.scss, где они найдут (100%!) ваши полезные комментарии.

Вот пример того, как вы можете (необязательно) установить масштаб «фиксированных» значений расстояния в дополнение к отзывчивым:

:root {
    /* spacing values */
    --space-unit: 1em;
    --space-xxs:  calc(0.25 * var(--space-unit));
    --space-xs:   calc(0.5 * var(--space-unit));
    --space-sm:   calc(0.75 * var(--space-unit));
    --space-md:   calc(1.25 * var(--space-unit));
    --space-lg:   calc(2 * var(--space-unit));
    --space-xl:   calc(3.25 * var(--space-unit));
    --space-xxl:  calc(5.25 * var(--space-unit));

    /* fixed values - not affected by --space-unit or --text-base-size */
    --space-unit-fixed: 1rem;
    --space-xxs-fixed:  calc(0.25 * var(--space-unit-fixed));
    --space-xs-fixed:   calc(0.5 * var(--space-unit-fixed));
    --space-sm-fixed:   calc(0.75 * var(--space-unit-fixed));
    --space-md-fixed:   calc(1.25 * var(--space-unit-fixed));
    --space-lg-fixed:   calc(2 * var(--space-unit-fixed));
    --space-xl-fixed:   calc(3.25 * var(--space-unit-fixed));
    --space-xxl-fixed:  calc(5.25 * var(--space-unit-fixed));
}

 

_spacing.scss

Соединяя все это, вот наш файл _spacing.scss:

/* -------------------------------- 
Spacing
-------------------------------- */

:root {
    /* spacing values */
    --space-unit: 1em;
    --space-xxxs: calc(0.25 * var(--space-unit));
    --space-xxs:  calc(0.375 * var(--space-unit));
    --space-xs:   calc(0.5 * var(--space-unit));
    --space-sm:   calc(0.75 * var(--space-unit));
    --space-md:   calc(1.25 * var(--space-unit));
    --space-lg:   calc(2 * var(--space-unit));
    --space-xl:   calc(3.25 * var(--space-unit));
    --space-xxl:  calc(5.25 * var(--space-unit));
    --space-xxxl: calc(8.5 * var(--space-unit));

    /* components padding */
    --component-padding: var(--space-sm);
}

// optional - edit space unit and padding of all components at a specific breakpoint
@include breakpoint(md) {
    :root {
        --space-unit: 1.25em;
        --component-padding: var(--space-md);
    }
}

/* vertical margins */
.margin-top, .margin-top--md {
    margin-top: var(--space-md);
}

.margin-top--sm {
    margin-top: var(--space-sm);
}

.margin-top--lg {
    margin-top: var(--space-lg);
}

.margin-top--xl {
    margin-top: var(--space-xl);
}

.margin-top--xxl {
    margin-top: var(--space-xxl);
}

.margin-bottom, .margin-bottom--md {
    margin-bottom: var(--space-md);
}

.margin-bottom--sm {
    margin-bottom: var(--space-sm);
}

.margin-bottom--lg {
    margin-bottom: var(--space-lg);
}

.margin-bottom--xl {
    margin-bottom: var(--space-xl);
}

.margin-bottom--xxl {
    margin-bottom: var(--space-xxl);
}

@include breakpoint(md) {
    .margin-top, .margin-top--md {
        margin-top: var(--space-lg);
    }
    
    .margin-top--sm {
        margin-top: var(--space-md);
    }
    
    .margin-top--lg {
        margin-top: var(--space-xl);
    }
    
    .margin-top--xl {
        margin-top: var(--space-xxl);
    }
    
    .margin-top--xxl {
        margin-top: var(--space-xxxl);
    }

    .margin-bottom, .margin-bottom--md {
        margin-bottom: var(--space-lg);
    }
    
    .margin-bottom--sm {
        margin-bottom: var(--space-md);
    }
    
    .margin-bottom--lg {
        margin-bottom: var(--space-xl);
    }
    
    .margin-bottom--xl {
        margin-bottom: var(--space-xxl);
    }
    
    .margin-bottom--xxl {
        margin-bottom: var(--space-xxxl);
    }
}

Надеюсь, вам понравилась статья!


Top

🔖 Выбор по тегам ×

💌 Написать сообщение ×

Все поля обязательны для заполнения!