Comments 31
1) БЭМ не используется как минимум с 2015 года, когда во всю уже использовались SCSS + CSS Modules.
2) А использовать Tailwind это вообще самая фатальная ошибка.
@apply bg-transparent border-2 border-white text-white py-3 px-6 rounded-lg bg-transparent border-2 border-white text-white py-3 px-6 rounded-lg bg-transparent border-2 border-white text-white py-3 px-6 rounded-lg bg-transparent border-2 border-white text-white py-3 px-6 rounded-lg;
"Замечательный" вырви глаз.
Ну как раз таки есть места и проекты где юзается, но почему tailwind является ошибкой? В любой проект можно запихнуть из за его конфига, мне кажется заново писать свою css систему немного через чур особенно если требуется быстрый старт проекта и к примеру нет дизайнера.
если требуется быстрый старт проекта и к примеру нет дизайнера.
Для этого существуют много много лет Ant Design, Bootstrap, MaterialUI и т.д. и т.п. Никакой tailwind с этим конкурировать не может, потому что это не только стили, а это полноценные компоненты с реализованным функционалом. Вот это по настоящему быстрый старт.
но почему tailwind является ошибкой?
Вот по этому:
@apply bg-transparent border-2 border-white text-white py-3 px-6 rounded-lg bg-transparent border-2 border-white text-white py-3 px-6 rounded-lg bg-transparent border-2 border-white text-white py-3 px-6 rounded-lg bg-transparent border-2 border-white text-white py-3 px-6 rounded-lg;
Ну как раз таки есть места и проекты где юзается
Ну это динозавры. Которых 1% от силы.
Яндекс - динозавры, записал.
А так по поводу пункта выше частично согласен. Тут видимо я уже динозавр если не выкупаю рофла с дубликатами классов, которые еще не никто не запрещает переносить на новую строчку.
Яндекс - динозавры, записал.
Простите, а что вы имели в виду? Что Яндекс - это эталон code style или что?
Яндекс - динозавры, записал.
Как бы да. Более того, там полно говнокода, полно легаси, полно бюрократии, а ещё ЗП самые низкие по рынку. Яндекс это вообще даже близко не dream company.
Тут видимо я уже динозавр
Судя по вашему профилю, вам всего лишь 25 лет (2000 год рождения), т.е. вы только что начали путь программиста. Это я динозавр, я уже почти 15 лет в разработке. И то, для меня БЭМ это уже что-то из эпохи динозавров. Поидее когда вы только начали писать первые строки коммерческого кода БЭМ уже был похоронен) Ну в 99% проектов)
CSS-modules решило проблему именования уже давным-давно.
Согласен, CSS-модули действительно решают проблему именования, но давайте не будем притворяться, что они идеальны:
Попробуй-ка динамически создать класс в CSS-модулях без костылей! Удачи с styles[blockelement--${modifier}] 😅
Глобальные стили? Добро пожаловать в мир :global(.something) или отдельных файлов, которые не модульные. + Как делать туже самую темную тему, тоже не очень понятно.
А что насчёт стилизации на основе родительских компонентов?
И давайте не забудем о доступности кода для новичков. БЭМ понятен с первого взгляда, а styles.button что означает? Нужно идти в файл, чтобы понять стили.
А что на счет оптимизации? Вместо одного класса .button с одинаковыми стилями мы получаем два идентичных класса с разными именами. И так для КАЖДОГО компонента, где ты используешь похожие стили! Конечно, есть инструменты для оптимизации (CSS Nano, PurgeCSS), но проблема фундаментальна — CSS модули поощряют изоляцию вместо переиспользования. Удобно? Да. Эффективно для размера бандла? Не всегда.
CSS-модули крутые для изоляции, БЭМ - для структуры, Tailwind - для скорости разработки.
Не буду убеждать не использовать БЭМ и TW - это определяется количеством легаси, уровнем разработчиков и другими факторами в конкретной компании. Но по проблемам CSS Modules поговорил бы.
Создание класса в CSS Modules "без костылей" - это не использовать block element modificator, а делать `type Props { variant: 'big', 'small' } <div class={styles[props.variant]} />`. Если нужна строгая проверка по типам - есть плагины для генерации .d.ts файлов стилей, то есть на этапе компиляции подсветит, что в классе не хватает чего-то для нового варианта.
Глобальные стили нужны в основном для неподдерживающих стилизацию библиотек. Не такой уж частый случай в наше время, и :global в паре мест не увеличит сложность, зато явно видно - это блок для стилизации некоего легаси.
Как делать темы:
// themes.scss
.light { --border: #e8e8e8; }
.dark { --border: #ccc; }
// автогенератор делает themes.ts
export const themes = {
light: { "--border": "#e8e8e8" },
dark: { "--border": "#ccc" }
}
// при смене темы ставим в рут
Object.entries(themes.light).forEach(([key, value]) => {
root.style.setProperty(key, value);
});
// используем в стилях через CSS variables
.button { border-color: var(--border) }
Смена без перезагрузки страницы, доп. стилей, работают быстрые переходы в IDE, копеечные трудозатраты на реализацию. Можно и переписывать CSS variables при необходимости в конкретных элементах.
"БЭМ понятен с первого взгляда, а styles.button что означает?" - значит кнопка. Семантическое английское имя вместо нагруженных блоков-элементов-модификаторов
Для универсализации стилей есть прекрасный подход из SCSS - mixins. Делаешь `@mixin button {}` и применяешь там, где нужно. CSS Modules - хоть и инструмент, фокусирующийся на модульности и изолированности, никак не запрещает переиспользование при необходимости за счет других механизмов. Но для оптимизации и правда нужно использовать доп. инструменты, но эта проблема только для легаси проектов. В современных есть разделение кода на чанки, и загружаются только те части, которые нужны текущей странице - и вкупе с минификацией + brotli размер файла со стилями не будет проблемой фактически никогда.
Причем в БЭМ с его длинными названиями и обилием классов и оберток проблема оптимизации может встать раньше, ведь нельзя в бандлере 1 строчкой сократить названия стилей - они всегда будут длинными и раздувать html и css.
Также не забывайте про возможность быстрых переходов в IDE на CSS Modules и куда более простой рефакторинг неиспользуемых стилей. Также CSS Modules позволяют генерировать имена классов по месту использования, становясь около-уникальным идентификатором, и сразу видно в Sentry например при клике на какой компонент произошла ошибка. Ни TW, ни БЭМ такого не умеют.
Вот как вы умудряетесь обмазавшись всеми этими "новыми технологиями", продолжать изобретать велосипед? Что это? Зачем?
Вот пример из реального проекта, pure CSS:
/******************************************************************************
Colors
******************************************************************************/
html.light{
--bg: #ffffff;
--bg-side: #f3f3f3;
--fg: #800000;
--fg-script: #000000;
--fg-brackets: #800000;
--fg-script-brackets: #000000;
--fg-cursor: #000000;
--sel: #add6ff;
--counter: #3f7793;
--counter-sel: #14216e;
--nav-border: #d3d3d3;
--nav-border-sel: #d3d3d3;
}
html.dark{
--bg: #272822;
--bg-side: #1e1f1c;
--fg: #f92672;
--fg-script: #a6e22e;
--fg-brackets: #f8f8f2;
--fg-script-brackets: #f8f8f2;
--fg-cursor: #f8f8f2;
--sel: #878b9180;
--counter: #90908a;
--counter-sel: #c2c2bf;
--nav-border: #464741;
--nav-border-sel: #464741;
}
Рассказывать дальше, как поменять цветовую тему? ;)
А зачем копировать то же самое, что я и написал, и говорить что у меня "велосипед"?) Потому что у меня эти переменные есть еще и в ts и могу их типобезопасно использовать для передачи в сторонние библиотеки для стилизации? Если у вас таких кейсов не было - не значит, что ни у кого нет, очень даже полезно.
Или в том, что в html style их проставляю вместо того, чтобы назначать класс dark или light этому же html элементу? Логично же - для SSR. На странице могут быть определенные прелоадеры или скелетоны до того, как загрузится основной CSS файл. И если переменные уже проставлены в изначальный html, то их сразу можно использовать, а light-dark классы придут только после загрузки css файла и будет перерисовка цветов. Можно, конечно, ключевые стили инджектить напрямую в html, но это сложнее в реализации.
Да и CSS Modules и SCSS куда старее тех же CSS Variables, которые вы используете. Это не новые модные технологии, а наиболее удобные и проверенные временем, и решающие проблемы pure css до сих пор.
Потому что у меня эти переменные есть еще и в ts и могу их типобезопасно использовать для передачи в сторонние библиотеки для стилизации?
А зачем css-переменные нужны в ts? Да ещё и "типобезопасные"? Это мода такая? Ну вы html-тэги ещё в ts "типобезопасно" загоните.
И если переменные уже проставлены в изначальный html, то их сразу можно использовать, а light-dark классы придут только после загрузки css файла и будет перерисовка цветов.
Не будет.
Даже если вдруг и будет - тогда точно так же у вас перерисуются все стили.
Да и CSS Modules и SCSS куда старее тех же CSS Variables, которые вы используете. Это не новые модные технологии, а наиболее удобные и проверенные временем, и решающие проблемы pure css до сих пор.
Вопрос не в "старее". А в "на кой ляд городить сторонние решения, которые не решают никаких проблем, а только порождают новые".
Для простых сайтов, конечно, избыточно, можно как я писал обойтись
.light { --border: #e8e8e8; }
.dark { --border: #ccc; }
и менять класс у рутового элемента. А если будет потребность в дополнительном функционале - я привел пример, как его можно просто реализовать. Спор о том, что вам не пригождался дополнительный функционал, и всегда хватает базовой реализации? Ну и отлично. Если будет нужен - будете знать, где найти
А если будет потребность в дополнительном функционале - я привел пример, как его можно просто реализовать.
Какой "функционал"? Вы о чём? Я не увидел в ваших примерах ничего, что не реализуется через ванильный CSS.
Спор о том, что вам не пригождался дополнительный функционал, и всегда хватает базовой реализации?
Нет, спор о том, что вы, видимо, всегда писали код "с нуля". И вам не приходилось редизайнить чей-то чужой - вот тогда приходите, поговорим о миксинах, локальной области видимости и прочей чертовщине...
P.S. Да почему обязательно чужой - можно и со своим собственным затупить... Отвалится какой-нибудь npm-пакет (привет node-sass!) - и приплыли... Или ещё чего наапдейтят...
Вместо одного класса .button с одинаковыми стилями мы получаем два идентичных класса с разными именами. И так для КАЖДОГО компонента, где ты используешь похожие стили!
Так ведь создаётся компонент <Button />. И этот компонент можно переиспользовать 100500 раз. А класс, который внутри (типа .button_jh$#j645hash) будет определён один раз.
Я топлю за tailwind + ui-radix/primitives => свой kit. Но по скорости это скорее неторопливо, потому что в kit влезаю, когда тошнит от бэкенда.
Начинал со стилей в ms word и css в dreamweaver. На современном react юзал bootstrap, но без компонентов - всырую шпаклевал классами из bootstrap. В принципе работало. Потом последовательно узнал shadcn, radix-ui и tailwind. На этом этапе уже понял, что tailwind мне по душе. И нравились radix-ui/themes, но они плюсут свой контекст css-классов, и у меня продукт включает два набора css, что заметно полнит. Сейчас выпиливаю themes, оставляю tailwind+redix-ui/primitives по примеру shadcn.
Длиннющие перечни классов tailwind лечатся переносом строк "x "+"y" или cn(...), которая join'ит строки. Пример посмотрите в shadcn.
И еще там же есть cva(), которая позволяет пропсами настраивать компоненты - а логика из primitives.
Сдаётся мне, проблема тут вовсе не в именовании классов ;)

Это все, чтобы легитимизировать для себя использование margin
для блоков? 😉
Проблема с отступами — в чистом БЭМе блок не должен иметь margin, поэтому приходится создавать дополнительные обертки
Сложность переиспользования для позиционирования — приходится создавать множество модификаторов (block_position-top_margin-left_slightly-to-the-right-no-not-that-right-a-bit-more... идеально!)
То есть в п.4 вы решились нарушить п.2 и поплатились 😁
Разве схлопывание марджинов - это не та сложность переиспользования, с которой предназначены бороться обертки с паддингами?
По-моему, большая часть пользы tailwind идет из того, что утилитарные классики можно навешивать на сам элемент (структура html прямо перед глазами, легко понять к какому блоку что применить). Заменяем утилитарные классы на семантические, выносим использование tailwind через apply в блок css деклараций и теряем преимущество тэйлвинда, что классики вешаем прямо на html. Насчет размера бандла, кстати, не уверен. Бандл ведь не сжимается, как сжался бы при навешивании утилитных классиков прямо на html? В блоке css деклараций появляется лишняя абстракция, не надежней ли использовать стандартный css, если уж мы пишем свои классы.
Хотя, забыл еще одно преимущество тэилвинда - готовая тема. Т.е. можно делать более менее гармоничные сайты без привлечения дизайнера.
Мне нравится sx в MaterialUI, но несколько я знаю, это сильно бьет по перфомансу.
А вот и наследники идеи появляются) Сам конструировал подобное как только появился tw)
В то время все тащились от css-in-js, и понимания я не нашел, не стал развивать наработки, да и tw тогда был сыроват для этого
Просто забудьте про БЭМ
Нет смысла в названии. Можно писать сокращённо x1, x2 и и.д. Смысл в названиях есть если писать на русском. Странно что это никто не делает.
БЭМ + Tailwind: прагматичный гибрид для современного фронтенда