Недавно мне довелось поработать с Bootstrap 5, и в сравнении с Tailwind это был сущий кошмар
В последнее время я занялся созданием небольших учебных пособий для разработчиков. Цель состоит в том, чтобы показать младшим разработчикам, как размышляют их старшие коллеги в процессе работы с кодом. Например, как старшие разработчики изучают документацию или новые фреймворки, с которыми они еще не знакомы, и как можно обнаружить, что что-то идет не так.
Примеры проектов я искал на Frontend Mentors, а код писал с использованием различных технологий. Например, один из первых проектов представлял собой интеграцию компонента карточки товара. Я решил написать решение с помощью чистого CSS, с использованием Tailwind и Bootstrap.
Это оказалось интересно не только аудитории, но и мне самому. Я хотел проследить, как менялись Tailwind и Bootstrap в последние годы. Справедливости ради, я понимал, что работа с Tailwind окажется весьма приятной, но не подозревал, что общение с Bootstrap 5 будет настолько мучительным. Мой опыт оказался настолько ужасен, что я решил написать эту статью.
Здесь вы найдете исторические факты (в основном о Bootstrap), мысли (о моем опыте разработчика) и фрагменты кода. Для начала поговорим об истории.
Время, когда все использовали Bootstrap
Еще несколько лет назад Bootstrap был повсюду. В 2016 году нельзя было встретить сайт, который не работал бы на Bootstrap. CSS Flexbox уже существовал, но CSS Grid еще не был широко известен и мало где поддерживался. Я помню, как в середине 2016 года я беседовал с одним разработчиком о CSS Grid и рассказал ему о возможностях Grid. Его ответ потряс меня до глубины души: сперва он решил, что я говорю об HTML-таблицах, ведь о CSS Grid он и вовсе ничего не слышал. В то время все работали на Bootstrap 3 и активно пользовались jQuery.
Кроме Bootstrap, были и другие CSS-фреймворки. Вторым по известности был Foundations. Кроме как для создания шаблонов электронной почты, я им особо не пользовался. Возможно, он был лучше или хуже Bootstrap, отличался от него или, напротив, копировал. Я и правда знаком с ним слишком мало для того, чтобы делать выводы.
Foundations заявляли (и, судя по их страницам на GitHub, до сих пор заявляют), что они «Самый продвинутый респонсивный фронтенд-фреймворк в мире». Однако при взгляде на официальную документацию и репозиторий проекта на GitHub, складывается впечатление, что он скорее мертв, чем жив. Не хотелось бы тратить слишком много времени на исторические справки, поэтому я пройдусь только по верхам.
Прежде всего, Bootstrap был разработан инженерами Twitter, и они проделали отличную работу. Twitter до сих пор работает на Bootstrap, как и многие другие сайты. В большинстве случаев можно запросто определить, работает ли сайт на Bootstrap или нет, даже не будучи опытным разработчиком. На мой взгляд, это не всегда хорошо. Дело в том, что Bootstrap-сайты, как правило, выглядят однотипно.
Для некоторых сайтов это может быть преимуществом, потому что пользователям не придется переучивать паттерны и способы навигации. К примеру, они уже знают, как выглядят ссылка или кнопка submit. Но на каком-то этапе сайт из-за этого теряет свою идентичность. Вторая сильная сторона Bootstrap заключается в том, что в Bootstrap 5 было принято решение избавиться от jQuery. Не уверен, хорошее это было решение или плохое. В настоящее время jQuery пользуется меньшей популярностью, чем другие фронтенд-фреймворки, и все реже используется разработчиками, так что, в некотором смысле, это решение имело смысл.
Однако удаление jQuery увеличило объем работы, с которым пришлось столкнуться разработчикам, к тому же пришлось попрощаться с рядом инструментов совместимости со старыми браузерами. Если вы хотите узнать подробности, то вот отличная статья на эту тему.
Наконец, я просто благодарен Bootstrap за хорошую работу. Команда Bootstrap 4 крайне много сделала для доступности веб-сайтов и приложений. Она внедрила множество концепций, связанных с атрибутами aria, и привела конкретные примеры и образцы кода, которыми можно пользоваться. На мой вкус, Bootstrap 4 был великолепен! К сожалению, Bootstrap 5 таковым больше не является.
Tailwind: Как он переосмыслил способ работы с CSS
Как и многие другие, я открыл для себя термин «Utility-first CSS» благодаря Tailwind. До этого я пытался ориентироваться на BEM. Не знаю, как вы, но я всегда чувствовал себя с BEM неловко. Я понимаю концепцию модификаторов, но иногда испытываю трудности, когда приходится использовать либо блок, либо элемент. Если Вы не знакомы с BEM, я советую ознакомиться с этим ресурсом. Резюмируя всё вышесказанное, BEM можно расценивать как способ структурирования CSS-кода.
На бумаге такое структурирование CSS кажется разумной идеей. Тем не менее, на практике это приводит к ухудшению читабельности HTML и нарушению принципов разделения ответственности. Вот отличный материал об этих концепциях.
Вернемся к Tailwind. Почему создание «Utility-first» CSS фреймворка оказалось такой удачной идеей? Если вы уже прочитали статью, которой я поделился в последней ссылке, вы уже должны знать ответ. Вместо того, чтобы полагаться на компоненты которые применяют множество стилей одновременно, как в Bootstrap, вы добавляете классы, которые отвечают только за что-то одно. Другими словами, вы оперируете классами, которые можно комбинировать как угодно для построения любого дизайна: один класс отвечает за padding, другой — за размер шрифта и т.д.
Давайте рассмотрим пример.
Вот как можно написать компонент карточки с помощью Bootstrap:
<div class="card" style="width: 18rem;">
<img src="..." class="card-img-top" alt="...">
<div class="card-body">
<h5 class="card-title">Card title</h5>
<p class="card-text">Some quick example text to build on the card title and make up the bulk of the card's content.</p>
<a href="#" class="btn btn-primary">Go somewhere</a>
</div>
</div>
И вот результат:
Источник: Официальная документация Bootstrap
Вот как можно написать компонент карточки с помощью Tailwind:
<figure class="md:flex bg-slate-100 rounded-xl p-8 md:p-0 dark:bg-slate-800">
<img class="w-24 h-24 md:w-48 md:h-auto md:rounded-none rounded-full mx-auto" src="/sarah-dayan.jpg" alt="" width="384" height="512">
<div class="pt-6 md:p-8 text-center md:text-left space-y-4">
<blockquote>
<p class="text-lg font-medium">
“Tailwind CSS is the only framework that I've seen scale
on large teams. It’s easy to customize, adapts to any design,
and the build size is tiny.”
</p>
</blockquote>
<figcaption class="font-medium">
<div class="text-sky-500 dark:text-sky-400">
Sarah Dayan
</div>
<div class="text-slate-700 dark:text-slate-500">
Staff Engineer, Algolia
</div>
</figcaption>
</div>
</figure>
И вот результат:
Источник: Официальная документация Tailwind
Эти две карточки выглядят по-разному, но я хочу, чтобы вы посмотрели на код. В Bootstrap компоненты карточек могут отличаться по размерам и цветам, но в итоге они выглядят более или менее одинаково. Помните, что я говорил вам в начале этой статьи? Легко можно определить, что на сайте используется Bootstrap.
Однако с помощью Tailwind можно добавить собственные стили практически ко всем элементам. Почему это так важно, спросите вы? Во-первых, потому что это позволяет оформить сайт так, как вам хочется, это отличная возможность, особенно для дизайнеров! Во-вторых, потому что это помогает вам, как разработчику, максимально приблизиться к макету, не нарушая разделение ответственности между HTML-разметкой и CSS.
С Tailwind больше не нужно полагаться на BEM. Для меня это действительно хорошая новость!
Опыт разработчика и документация
Источник: pixabay.com
Tailwind: легко настроить и использовать
Это был один из моих первых опытов с Tailwind. То есть, я знал этот проект раньше и уже читал документацию, но у меня не было случая использовать его на деле. Для своего проекта я решил не пользоваться CLI или PostCSS.
Вместо этого я решил попробовать использовать Tailwind с CDN. Я понимаю, что это не лучший вариант для «боевого» сайта, однако моим тестовым целям это отвечало на 100%. Даже с CDN я был поражен тем, насколько просто настроить Tailwind, просто добавив пользовательские цвета и шрифты.
По сравнению с Tailwind, API Bootstrap — это полный бардак. И в документации, и в примерах кода нелегко разобраться, особенно если вы еще не знакомы с пятой версией.
Вот как я настраиваю Tailwind в своем проекте:
<script src="https://cdn.tailwindcss.com"></script>
<script>
tailwind.config = {
theme: {
extend: {
colors: {
viridian: 'hsl(158, 36%, 37%)',
dawnPink: 'hsl(30, 38%, 92%)',
white: 'hsl(0, 0%, 100%)',
ebonyClay: 'hsl(212, 21%, 14%)',
stormGray: 'hsl(228, 12%, 48%)'
},
fontFamily: {
montserrat: ['Montserrat', 'sans-serif'],
fraunces: ['Fraunces', 'serif']
}
}
}
}
</script>
В приведенном выше примере кода я добавил новые цвета и новые семейства шрифтов внутрь tailwind.config.
А вот как я использую его в своем коде:
<p class="font-montserrat font-medium text-xs tracking-[.5em] uppercase
text-stormGray mb-3">
Perfume
</p>
<h1 class="font-fraunces text-3xl font-bold text-ebonyClay mb-4">
Gabrielle Essence Eau de Parfum
</h1>
<p class="font-montserrat font-medium text-sm text-stormGray mb-6">
A floral, solar and voluptuous interpretation composed by Olivier Polge,
Perfumer-Creator for the House of CHANEL.
</p>
Посмотрите, как это просто! Мне не нужно писать пользовательский CSS или Sass-код. Достаточно только вызвать нужные классы. Это очень, очень просто и в то же время мощно!
Tailwind: какая замечательная документация!
Это подводит нас ко второму преимуществу Tailwind: его документации. Я разработчик (думаю, и вы тоже). Чаще всего, когда мы торопимся с проектом, у нас нет времени читать всю документацию. Нам нужны простые, но конкретные примеры, которые мы можем использовать и повторить.
Мы хотим быстро понять, подходит нам этот инструмент или нет. В последние годы я заинтересовался Developer Experience, сокращенно DX. Вот определение, которое я нашел в интернете:
Опыт разработчика (Developer Experience) — это каждое взаимодействие разработчика с API или самим инструментом.
Источник: everydeveloper.com/developer-experience
Говоря о взаимодействии, помните не только о комментариях к коду, красивых именах переменных или следовании соглашениям.
Подумайте также и о документации и о том, насколько легко работать с библиотекой или фреймворком.
Например, я считаю, что опыт разработчика в Symfony и Angular великолепен. Они предоставляют туториал, отличную документацию и примеры кода. Но есть и кое-что еще! Начиная пользоваться ими, вы косвенно узнаете и другие концепции. Например, документация Symfony объясняет принципы Entity и Repository Pattern. Angular знакомит вас с Promises и Observables.
А вот документация по React, напротив, не слишком хороша. В течение долгого времени там не объяснялось, как писать эффективные тесты. Даже по Hooks информации код наплакал. Чаще всего, когда я обсуждаю с коллегами React Hooks, они не понимают, как это работает. Короче говоря, DX очень важен. Важнее, чем кажется. Он может сделать проект успешным, а может и завалить. С Tailwind я справился с проектом всего за один день. Документацию легко читать и использовать, как и сам фреймворк. А что насчет Bootstrap 5?
Bootstrap: гремучая смесь компонентов и утилит
С самого начала своего существования Bootstrap был полностью сосредоточен на компонентах. Существуют компоненты для форм, каруселей (даже если карусель вам не нужна), хлебных крошек, модальных окон и т.д. Это и есть (или была?) самая сильная сторона Bootstrap.
Что, если мне нужно создать заголовок? Я загляну на страницу «Типографика» и найду информацию о классах заголовков и их отображении.
Отлично! Но как насчет страницы «Текст» в разделе «Утилиты», в частности, подраздел «Размеры шрифтов»? О, это еще один способ изменить размер шрифта. Но какой из них лучше использовать? Могу ли я комбинировать оба способа? Что фреймворк хочет, чтобы я сделал? Именно такие вопросы я задаю себе, когда пишу код.
Мое впечатление таково, что Bootstrap сейчас находится между двух стульев, и не знает, на какой из них сесть. С одной стороны, они хотят, чтобы вы придерживались Bootstrap и его библиотеки компонентов. Именно сюда команда разработки вложила так много времени и усилий. С другой стороны, появились утилиты и их API. Но опять же, примеров в документации раз, два, и обчелся.
API утилит Bootstrap: мне потребовалось время, чтобы разобраться в нем
Несколько дней назад я писал решение на Bootstrap для задачи о компоненте продукта и создавал новые классы, которые не использовали утилиты Bootstrap.
Я хотел добавить элементу ширину 90%. Я просмотрел документацию и нашел страницу Sizing в разделе Utilities. По умолчанию ширина была 25, 50, 75 и 100%. Сначала я создал пользовательский класс w-90, который обозначал 90%, но что-то здесь явно было не так.
Код, честно говоря, начал припахивать! Я посмотрел на страницу Utility API, быстро прочитал ее (как это делают многие разработчики) и решил, что все понял. Чтобы использовать этот API с npm, нужно было установить в проект Sass и Bootstrap.
Вполне справедливо! Я установил их.
Затем я перешел на страницу Sass в разделе Customize и оказался перед выбором: либо импортировать всё без разбора и не иметь возможности изменять утилиты, либо импортировать нужное вручную.
// Custom.scss
// Option B: Include parts of Bootstrap
// 1. Include functions first (so you can manipulate colors, SVGs, calc, etc)
@import "../node_modules/bootstrap/scss/functions";
// 2. Include any default variable overrides here
// 3. Include remainder of required Bootstrap stylesheets
@import "../node_modules/bootstrap/scss/variables";
// 4. Include any default map overrides here
// 5. Include remainder of required parts
@import "../node_modules/bootstrap/scss/maps";
@import "../node_modules/bootstrap/scss/mixins";
@import "../node_modules/bootstrap/scss/root";
// 6. Optionally include any other parts as needed
@import "../node_modules/bootstrap/scss/utilities";
@import "../node_modules/bootstrap/scss/reboot";
@import "../node_modules/bootstrap/scss/type";
@import "../node_modules/bootstrap/scss/images";
@import "../node_modules/bootstrap/scss/containers";
@import "../node_modules/bootstrap/scss/grid";
@import "../node_modules/bootstrap/scss/helpers";
// 7. Optionally include utilities API last to generate classes based on the Sass map in `_utilities.scss`
@import "../node_modules/bootstrap/scss/utilities/api";
// 8. Add additional custom code here
После этого я изменил утилиты (я покажу ниже, как это сделать) и скомпилировал Sass в CSS. В первом приближении казалось, что все работает, но я быстро обнаружил, что мои кнопки лишились стилей. Почему, спросите вы? Потому что я забыл импортировать некоторые фрагменты Bootstrap. Посмотрите на пункт 6. Здесь говорится: «Опционально включите любые другие части Boostrap по мере необходимости», но я новичок в Bootstrap 5. Я не знаю, какие части нужны, а какие нет. Помните, что я говорил о DX? По мне, так это очень плохой DX!
Вот что я бы добавил, чтобы заставить его работать:
// Include any default variable overrides here (though functions won't be available)
// Custom variables
$viridian: hsl(158, 36%, 37%);
$dawn-pink: hsl(30, 38%, 92%);
$white: hsl(0, 0%, 100%);
$ebony-clay: hsl(212, 21%, 14%);
$storm-gray: hsl(228, 12%, 48%);
$font-montserrat: 'Montserrat', sans-serif;
$font-fraunces: 'Fraunces', serif;
// Configuration
@import "../node_modules/bootstrap/scss/functions";
// 2. Include any default variable overrides here
$body-bg: $dawn-pink;
$font-weight-normal: 500;
@import "../node_modules/bootstrap/scss/variables";
// 4. Include any default map overrides here
$custom-colors: (
"viridian": $viridian,
"dawn-pink": $dawn-pink,
"white": $white,
"ebony-clay": $ebony-clay,
"storm-gray": $storm-gray
);
// Merge the maps
$theme-colors: map-merge($theme-colors, $custom-colors);
@import "../node_modules/bootstrap/scss/maps";
@import "../node_modules/bootstrap/scss/mixins";
@import "../node_modules/bootstrap/scss/utilities";
// Layout & components
@import "../node_modules/bootstrap/scss/root";
@import "../node_modules/bootstrap/scss/reboot";
@import "../node_modules/bootstrap/scss/type";
@import "../node_modules/bootstrap/scss/images";
@import "../node_modules/bootstrap/scss/containers";
@import "../node_modules/bootstrap/scss/grid";
@import "../node_modules/bootstrap/scss/buttons";
// Import we don't need
@import "../node_modules/bootstrap/scss/tables";
@import "../node_modules/bootstrap/scss/forms";
@import "../node_modules/bootstrap/scss/transitions";
@import "../node_modules/bootstrap/scss/dropdown";
@import "../node_modules/bootstrap/scss/button-group";
@import "../node_modules/bootstrap/scss/nav";
@import "../node_modules/bootstrap/scss/navbar";
@import "../node_modules/bootstrap/scss/card";
@import "../node_modules/bootstrap/scss/accordion";
@import "../node_modules/bootstrap/scss/breadcrumb";
@import "../node_modules/bootstrap/scss/pagination";
@import "../node_modules/bootstrap/scss/badge";
@import "../node_modules/bootstrap/scss/alert";
@import "../node_modules/bootstrap/scss/progress";
@import "../node_modules/bootstrap/scss/list-group";
@import "../node_modules/bootstrap/scss/close";
@import "../node_modules/bootstrap/scss/toasts";
@import "../node_modules/bootstrap/scss/modal";
@import "../node_modules/bootstrap/scss/tooltip";
@import "../node_modules/bootstrap/scss/popover";
@import "../node_modules/bootstrap/scss/carousel";
@import "../node_modules/bootstrap/scss/spinners";
@import "../node_modules/bootstrap/scss/offcanvas";
@import "../node_modules/bootstrap/scss/placeholders";
// Helpers
@import "../node_modules/bootstrap/scss/helpers";
$utilities: map-merge(
$utilities,
(
"width": map-merge(
map-get($utilities, "width"),
(
values: map-merge(
map-get(map-get($utilities, "width"), "values"),
(90: 90%),
),
),
),
"max-width": map-merge(
map-get($utilities, "max-width"),
(
values: map-merge(
map-get(map-get($utilities, "max-width"), "values"),
(600: 680px),
),
),
),
"font-family": map-merge(
map-get($utilities, "font-family"),
(
values: map-merge(
map-get(map-get($utilities, "font-family"), "values"),
(
montserrat: $font-montserrat,
fraunces: $font-fraunces
),
),
),
),
"letter-spacing": (
property: letter-spacing,
class: lt,
responsive: true,
values: (
0: 0px,
5: 5px,
10: 10px
)
)
)
);
// Utilities
@import "../node_modules/bootstrap/scss/utilities/api";
.max-w {
max-width: 300px;
}
Как импортировать пользовательский шрифт
C помощью Tailwind
Сначала импортируйте шрифты. Я использую Google Fonts.
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Fraunces:opsz,wght@9..144,700&family=Montserrat:wght@500;700&display=swap"
rel="stylesheet">
Затем импортируйте Tailwind с CDN и обновите tailwind config. Я добавляю запасные шрифты, а также новые цвета.
<script src="https://cdn.tailwindcss.com"></script>
<script>
tailwind.config = {
theme: {
extend: {
colors: {
viridian: 'hsl(158, 36%, 37%)',
dawnPink: 'hsl(30, 38%, 92%)',
white: 'hsl(0, 0%, 100%)',
ebonyClay: 'hsl(212, 21%, 14%)',
stormGray: 'hsl(228, 12%, 48%)'
},
fontFamily: {
montserrat: ['Montserrat', 'sans-serif'],
fraunces: ['Fraunces', 'serif']
}
}
}
}
</script>
И всё, можно ими пользоваться!
<span class="text-white font-montserrat font-bold text-sm">
Add to Cart
</span>
Все просто, не так ли?
C помощью Bootstrap
Установите Sass с помощью Npm:
{
"dependencies": {
"bootstrap": "^5.2.0",
"sass": "^1.53.0"
},
"scripts": {
"sass": "node_modules/.bin/sass scss/main.scss css/main.css --watch"
}
}
Добавьте Bootstrap через Sass и импортируйте все части Bootstrap.
Затем можно будет удалить те части, которые вам не нужны.
Между строками 9 и 10 я определил свои переменные Sass. Между строками 102 и 113 я обновляю свои утилиты font-family.
// Include any default variable overrides here (though functions won't be available)
// Custom variables
$viridian: hsl(158, 36%, 37%);
$dawn-pink: hsl(30, 38%, 92%);
$white: hsl(0, 0%, 100%);
$ebony-clay: hsl(212, 21%, 14%);
$storm-gray: hsl(228, 12%, 48%);
$font-montserrat: 'Montserrat', sans-serif;
$font-fraunces: 'Fraunces', serif;
// Configuration
@import "../node_modules/bootstrap/scss/functions";
// 2. Include any default variable overrides here
$body-bg: $dawn-pink;
$font-weight-normal: 500;
@import "../node_modules/bootstrap/scss/variables";
// 4. Include any default map overrides here
$custom-colors: (
"viridian": $viridian,
"dawn-pink": $dawn-pink,
"white": $white,
"ebony-clay": $ebony-clay,
"storm-gray": $storm-gray
);
// Merge the maps
$theme-colors: map-merge($theme-colors, $custom-colors);
@import "../node_modules/bootstrap/scss/maps";
@import "../node_modules/bootstrap/scss/mixins";
@import "../node_modules/bootstrap/scss/utilities";
// Layout & components
@import "../node_modules/bootstrap/scss/root";
@import "../node_modules/bootstrap/scss/reboot";
@import "../node_modules/bootstrap/scss/type";
@import "../node_modules/bootstrap/scss/images";
@import "../node_modules/bootstrap/scss/containers";
@import "../node_modules/bootstrap/scss/grid";
@import "../node_modules/bootstrap/scss/buttons";
// Import we don't need
import "../node_modules/bootstrap/scss/tables";
@import "../node_modules/bootstrap/scss/forms";
@import "../node_modules/bootstrap/scss/transitions";
@import "../node_modules/bootstrap/scss/dropdown";
@import "../node_modules/bootstrap/scss/button-group";
@import "../node_modules/bootstrap/scss/nav";
@import "../node_modules/bootstrap/scss/navbar";
@import "../node_modules/bootstrap/scss/card";
@import "../node_modules/bootstrap/scss/accordion";
@import "../node_modules/bootstrap/scss/breadcrumb";
@import "../node_modules/bootstrap/scss/pagination";
@import "../node_modules/bootstrap/scss/badge";
@import "../node_modules/bootstrap/scss/alert";
@import "../node_modules/bootstrap/scss/progress";
@import "../node_modules/bootstrap/scss/list-group";
@import "../node_modules/bootstrap/scss/close";
@import "../node_modules/bootstrap/scss/toasts";
@import "../node_modules/bootstrap/scss/modal";
@import "../node_modules/bootstrap/scss/tooltip";
@import "../node_modules/bootstrap/scss/popover";
@import "../node_modules/bootstrap/scss/carousel";
@import "../node_modules/bootstrap/scss/spinners";
@import "../node_modules/bootstrap/scss/offcanvas";
@import "../node_modules/bootstrap/scss/placeholders";
// Helpers
@import "../node_modules/bootstrap/scss/helpers";
$utilities: map-merge(
$utilities,
(
"width": map-merge(
map-get($utilities, "width"),
(
values: map-merge(
map-get(map-get($utilities, "width"), "values"),
(90: 90%),
),
),
),
"max-width": map-merge(
map-get($utilities, "max-width"),
(
values: map-merge(
map-get(map-get($utilities, "max-width"), "values"),
(600: 680px),
),
),
),
"font-family": map-merge(
map-get($utilities, "font-family"),
(
values: map-merge(
map-get(map-get($utilities, "font-family"), "values"),
(
montserrat: $font-montserrat,
fraunces: $font-fraunces
),
),
),
),
"letter-spacing": (
property: letter-spacing,
class: lt,
responsive: true,
values: (
0: 0px,
5: 5px,
10: 10px
)
)
)
);
// Utilities
@import "../node_modules/bootstrap/scss/utilities/api";
.max-w {
max-width: 300px;
}
Затем я использую их внутри HTML файла:
<p class="text-uppercase text-storm-gray font-montserrat fw-normal lt-5">Perfume</p>
Как добавить межбуквенные интервалы
C помощью Tailwind
Импортируйте Tailwind с помощью этого кода:
<script src="https://cdn.tailwindcss.com"></script>
Используйте пользовательский класс tailwind. Посмотрите на tracking-[.5em].
<p class="font-montserrat font-medium text-xs tracking-[.5em] uppercase text-stormGray mb-3">Perfume</p>
Да, вот так просто!
C помощью Bootstrap
Все так же, как и выше. Я устанавливаю Bootstrap и Sass через Npm.
Затем я обновляю свои утилиты, добавляя новую. Посмотрите на строку 34. Я создаю новую утилиту; она использует класс lt и имеет три значения.
$utilities: map-merge(
$utilities,
(
"width": map-merge(
map-get($utilities, "width"),
(
values: map-merge(
map-get(map-get($utilities, "width"), "values"),
(90: 90%),
),
),
),
"max-width": map-merge(
map-get($utilities, "max-width"),
(
values: map-merge(
map-get(map-get($utilities, "max-width"), "values"),
(600: 680px),
),
),
),
"font-family": map-merge(
map-get($utilities, "font-family"),
(
values: map-merge(
map-get(map-get($utilities, "font-family"), "values"),
(
montserrat: $font-montserrat,
fraunces: $font-fraunces
),
),
),
),
"letter-spacing": (
property: letter-spacing,
class: lt,
responsive: true,
values: (
0: 0px,
5: 5px,
10: 10px
)
)
)
);
Наконец, я использую ее:
<p class="text-uppercase text-storm-gray font-montserrat fw-normal lt-5">Perfume</p>
Фух, это была длинная статья! Длиннее, чем я ожидал, когда начинал ее писать. Прежде чем попрощаться, я хочу сказать несколько слов о Bootstrap. Bootstrap 5 не слишком хорош. Bootstrap 3 и 4 были гораздо лучше. Особенно в плане документации и DX.
Мое впечатление таково, что Bootstrap идет на спад. Он еще не умирает, но кажется, что основная команда потеряла видение проекта и не знает, куда двигаться дальше. Может, я ошибаюсь, но Bootstrap был создан до появления React и полноценных SPA.
Он хорошо работал и продолжает хорошо работать с fullstack-фреймворками, ну, кроме React. По крайней мере, мне так кажется. Возможно, через несколько лет мы вернемся к Bootstrap, но на сегодняшний день я не готов его кому-то советовать…
Вот полный код задачи с Bootstrap и Tailwind.
Комментарии (21)
vconst
02.09.2022 16:11А при чем тут бэм?
Насколько я помню, его создатели преследовали три вещи: полностью избавиться от каскада, который сильно тормозит на БОЛЬШИХ сайтах, сделать код страницы машиногенерируемым и понятным для того, кто только подключился к проекту. «Руками» на бэм не пишут
gBACTAKAHA
02.09.2022 16:21+1Я лет пять назад тоже смотрел в сторону очередной вариации бутстрап, но позже понял, что чтобы мне собрать как надо, нужен только scss и все. Сброс стилей, base, layout, elements, components, utility. Тем более, что большая часть кочует из проекта в проект. Зачем мне вот это вот все. Хотя таилвинд меня по началу впечатлил. Ковырять документацию, когда я могу сам сделать лучше и чище.
Вообще если пользоваться нормально семантикой, то назначать стили и отступы персонально элементам на странице не требуется.
M03G
02.09.2022 16:55+9Очень странно делать перевод статье, в которой большое количество ссылок, не перенося их. Особенно когда по контексту понимаешь, что именно это слово было ссылкой и лезешь за ней в оригинал статьи.
zverttl
02.09.2022 17:05+11Надо бы еще и перевод опровержения сделать ????
medium.com/codex/the-fail-of-tailwind-the-go-to-for-the-ignorant-7b0aaea405bb
boldMahoney
02.09.2022 22:47-4Пожалуйста, не стоит переводить термины которые не имеют широкоизвестных и устоявшихся аналогов в русском. "Хлебные крошки" - что? ????????♂️ Понятнее было бы оставить оригинал "breadcrumbs". Иначе у вас получаются очередные "Ясные Печенья".
Source
02.09.2022 23:12+7С сутью комментария соглашусь. Но конкретно «хлебные крошки» вполне устоявшийся перевод, ни разу не встречал, чтобы их называли breadcrumbs в русской речи.
boldMahoney
02.09.2022 23:56-2Документацию обычно читают на английском (а подчас только в оригинале ибо локализации нет совсем) и там этот стиль контрола называется breadcrumb. И в коде этот класс имеет точно такое же название, поэтому надежнее не переводить термин чтобы не было неоднозначности и толкований.
Source
03.09.2022 00:38+4Так и статью можно на английском прочитать. Дело то не в этом. А в том, что это вполне однозначный и понятный перевод. Погуглите это словосочетание, если сомневаетесь в широте его применения. Есть ещё один более бюрократический - навигационная цепочка, но он реже встречается.
deamondz
03.09.2022 12:00+4Ребят, объясните мне пожалуйста, что делает тейлвинд? я честно пытался понять суть, но не догнал:
если писать этот набор классов в условном html как атрибут, то получается каша; если собирать из них один готовый класс в условном css, то мне проще сразу иметь обычные свойства из css.Bootstrap/Ant/Chakra/Material/Foundation - они ведь про "бери и делай", т.е. не надо запариваться со сборкой стилей, просто берешь и используешь готовое. Или я не прав?
vconst
03.09.2022 12:13Что касается готовых стилей — то на нем только админки клепают. Нормальный сайт на чистом бустрап никто делать не будет, для них по любому надо создавать свой дизайн
Source
03.09.2022 16:50+4Так стили можно переопределить. Смысл того же бутстрапа в том, что там хотя бы семантика есть. А в этом тейлвинде семантики ноль, тупо сокращение того, что можно в style протиписать. Вот только это всегда антипаттерном считалось.
mbobka
03.09.2022 14:42-3Идея в том, что стили и код страницы лежат рядом и не нужно бегать по 1000 разных файлов в поиске того, где именно нужно поправить стиль.
deamondz
03.09.2022 21:29+1ну может когда пользуешься вимом или нано нужно искать, но в вскоде или идее просто переходишь на этот класс/стиль как по ссылке
datacompboy
Погодите... Это что, мы переизобрели style="..."? Только со вкусом жаваскрипта?
Aquahawk
да, причём переизобрели многими разными способами
datacompboy
Скажите, что это сатира. Пожалуйста...
Aquahawk
Кто-то должен сказать правду. Нет, это не сатира.
Aquahawk
Вот эта страница https://habr.com/ru/company/ispmanager/blog/686080/comments/, чисто комменты загружает 3.5 мегабайта (1 мегабайт в архиве) чтобы отобразить наши 4 коммента и немного заголовков внизу. Это ещё немного по современным меркам.
mbobka
Если серьёзно, то это не сатира, а просто непонимание tailwind и попытка поумничать. Это даже не близко style. Это именно css classes. В документации можно найти подробное объяснение.
transcengopher
А чем таким
class="fw-bold"
принципиально отличается отstyle="font-weight:bold;"
? Ну, кроме того, что "fw-bold" вовсе необязательно делает именно то, что я бы предположил, и мне всё равно придётся идти и смотреть определение этого класса, чтобы убедиться, что там именно "bold", а не "normal" или вообще не "margin-left:2px"?