Релиз Berry CSS 4.0

Обновил Berry CSS до 4-й версии. Это итог примерно месячной работы, где целью была — новая структура sass-файлов. Поэтому с точки зрения CSS-классов версия практически ничем не отличается от предыдущей. Было добавлено несколько новых классов, но это я и так делаю постоянно.

Отмечу, что в Berry 4 больше не будет компонентов, которые используют JavaScript. Вместо них можно использовать Alpine.js, которая предлагает намного больший функционал. Связка Berry + Alpine прекрасно себя зарекомендовала, поэтому у меня в планах всё-таки сделать отдельный проект, где будут разные примеры её использования. Это планы на будущее, а пока можно посмотреть примеры, которые я публикую здесь же.

Изменения касаются только sass-структуры фреймворка. И здесь изменения очень серьёзные. Если вы работаете с Sass, то скорее всего вам будет интересно узнать как теперь нужно строить фреймворки с точки зрения Sass.

Модульность

Теперь Berry CSS 100% модульный фреймворк. Это скорее следствие всех переделок, чем изначальная цель, но зато это позволит работать с фреймворком, как с набором отдельных модулей. Модуль — это набор файлов, которые подключаются в одном месте, имеют некие настройки по умолчанию и могут конфигурироваться через отдельные файлы.

То есть теперь можно рассматривать модуль Berry CSS как «черный ящик», который работает сам по себе, а все его настройки вынесены в отдельную конфигурацию. Например, чтобы подключить модуль используется всего одна команда:

@use 'modules/typography';

Так будет подключен модуль typography. Если нужно его настроить, то используем файл config/_typography.scss. Не нужно нигде ничего дополнительно подключать.

Но это ещё не всё. Главное, ради чего вообще я задумывал переделки — это возможность раздельного подключения scss-файлов через файл конфигурации.

В Sass есть большие ограничения: он не позволяет использовать условия в директивах @import/use/forward, поэтому, когда нужно исключить из компиляции ненужный файл, приходилось вручную редактировать основной style.scss — удалять саму строчку подключения.

@import 'utilities/border';
// @import 'utilities/column';
@import 'utilities/cursor';
// @import 'utilities/filters';

Теперь в Berry 4 можно управлять загрузкой с помощью опции модуля:

$modules: (
        'border': true,
        'column': false,
        'cursor': true,
        'filters': fasle,
    ),

Это сильно приближает Berry к фреймворку Tailwind. Только там используется js-компиляция Node, а у меня работает через самый обычный Sass!

Отказ от @import

Изначально я планировал просто реализовать старые задумки, но потом решил, что лучше будет сразу следовать рекомендациям команды Sass, которая объявила директиву @importустаревшей. С октября 2021 год она будет работать с ограничениями, а потом и вовсе перестанет работать как обычно.

Интересно то, что подавляющее большинство sass-проектов работает именно через @import, что в итоге приведёт к большим проблемам в будущем. Разработчики Sass решил, что @importбудет лишь стандартной командой CSS, через которую нельзя будет подключать sass-файлы, как это происходит сейчас.

Мне бы не хотелось ждать час Икс, поэтому я потратил время на то, чтобы разобраться что теперь нужно использовать вместо @import.

Проблемы @use

Вместо @importпредлагается использовать @use, которая также подключает sass-файлы. Но проблема в том, что @useсоздаёт локальную область видимости для переменных. То есть можно создавать одноимённые переменные в sass-файлах и не бояться, что какой-то модуль её переопределит.

Это идёт в разрез с поведением @import, которая формирует глобальную область видимости, а в сочетании с опцией !defaultпозволяет без особых сложностей переписывать переменные фреймворка по умолчанию.

$a: red; // своя переменная
 
$a: black !default; // переменная по умолчанию
 
p {color: $a} // использование переменной во фреймворке

Если теперь разнести этот код по отдельным файлам, как это обычно и делается, то будет так:

@import 'my-var';
 
@import 'module/default';
@import 'module/template';

И всё прекрасно работает. Но если заменить @importна @useкод перестанет работать, поскольку переменная $aбудет в каждом файле своя и итоговый файл module/templateпросто её не увидит.

Решения

Для решения этой проблемы, разработчики Sass предложили использовать синтаксис @use width, где указывается какой файл будет использоваться.

@use 'modules/template' with (
    ... переменные из modules/template
);

Для простых проектов этого может оказаться достаточным, но там где требуется задавать default-переменные, которые могут быть переписаны конфигурацией пользователя, может просто не сработать. С @useнеобходимо переносить логику подключения конфигурации в файл, где она используется. С @importвсё просто — она только подключает файлы, а переменные общедоступны. Но с @useподключением должен заниматься конечный файл, при том, что ему нужно точно знать используемую область видимости. И при этом (вишенка на торте), файл конфигурации тоже должен знать в чью область видимости ему необходимо внедриться. Если используется 3 и более связанных между собой sass-файлов, понять их логику становится очень сложно.

Лично я потратил на самостоятельные поиски больше недели, но так и не смог разобраться, поэтому написал прямо разработчикам Sass, которые показали примеры, на основе которых я смог реализовать задумки.

Я оставлю эти решения здесь, поскольку, когда авторы sass-фреймворков столкнутся с подобными проблемами, эта статья им очень поможет. Это примитивы, которые демонстрируют новую логику работы Sass.

Первый пример по сути повторяет функционал @import, когда нужно переписать (my1.scss, style.scss) дефолтные значения переменных (config.scss) в файле генерации итоговых классов (gen.scss).

// config.scss
$a: black !default;
 
// my1.scss
@use 'config';
config.$a: red;
 
// my2.scss
@use 'config';
config.$a: green;
 
// gen.scss
@use "config";
p { color: config.$a; }
 
// style.scss 
@use 'config' with ($a: blue); // config.scss -> $a: black !default;
@use 'my1';
@use 'my2';
@use 'gen';
 
// output 
// p {color: red;} — green

Использование:

// style.scss 
@use 'config' with ($a: blue); 
@use 'gen'; // p {color: blue;}
 
// style.scss 
@use 'my1'; // red 
@use 'gen'; // p {color: red;}
 
// style.scss 
@use 'my2'; // green 
@use 'gen'; // p {color: green;}
 
// style.scss 
@use 'my1'; // red 
@use 'my2'; // green 
@use 'gen'; // p {color: green;}
 
// style.scss 
@use 'gen'; // p {color: black;}

Здесь файл генерации (gen.scss) явно использует файл default-значений (config.scss). При этом мы компилируем style.scss, в котором можно переопределить переменные через дополнительные файлы конфигурации (my1.scss, my2.scss).

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

// core.scss — not edit
$a: black !default;
$b: black !default;
.d1 { color: $a } // red
.d2 { color: $b } // maroon
 
// def1.scss
@forward 'core' with (
  $a: orange !default,
  $b: maroon !default,
);
 
// design1.scss
@use 'def1' with (
  $a: red,
);

Обратите внимание как здесь меняется логика работы: файл, который генерирует итоговый css-код уже не использует подключение конфигурации. По сути мы работаем только с design1.scss, где меняем дефолтные переменные из def1.scss, а он в свою очередь уже подключает core.scss.

В этом примере уже используется @forwardдля «предподключения» файла (при этом нужно указывать !default).

К чему эти сложности?

Я не знаю. Цель разработчиков Sass перевести всю его работу на модульную систему так, чтобы каждый модуль был изолирован друг от друга. Другое дело, что sass — это не язык программирования, а его основное назначение — быть препроцессором CSS, а значит ему просто не требуется все эти сложности. В крайнем случае можно было бы как-то добавить к функционалу подключения файлов какой-то флаг указывающий на глобальную область видимости, чтобы не ломать работу существующих фреймворков.

Интеграция с Berry CSS

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

Не нужно больше ничего придумывать: просто создаётся свой модуль в рамках Berry с любыми стилями и подключается одной строчкой в компилируемом файле. В demoя разместил несколько рабочих примеров, показывающих как получить доступ к своему файлу конфигурации, а также к модулям colorsи utilities. То есть пользователи Berry CSS получают существенное преимущество в том, что могут использовать уже готовые решения для своих проектов.

Комментариев: 4 RSS

1Денис18-03-2021 17:18

А как им пользоваться? Скачал архив, в нем куча scss файлов и всего 2 css. А дальше что делать с ними? С обычным html и css понятно, а тут как работать? Объясните новичкам.

2MAX18-03-2021 17:52

Скажем так: если вы знаете что такое Sass и можете с ним работать, то используете как написано здесь https://maxsite.org/berry (разделы про sass). Если не знаете, то используете готовый css. Обучение sass достаточно сложно сделать, если нет соответствующей подготовки.

3Денис18-03-2021 18:39

Ясно. Подскажите, можно ли как-то автоматически вытянуть из файла berry.css только те скрипты, которые я использую в проекте. Чтобы все 148 Кб не подгружать и чтобы по нему не рыскать и не копировать нужное в свой маленький файл стилей?

4MAX18-03-2021 23:46

CSS — это не скрипты, а стили. Полный контроль возможен только с помощью sass-компиляции. Для одностраничника можно воспользоваться сервисами по удалению лишних css-классов. Я об этом писал в своём телеграмм-канале.

Оставьте комментарий!

Комментарий будет опубликован после проверки. Вы соглашаетесь с правилами сайта.

(обязательно)