Повторное использование стилей
Карточка товара занимает десяток классов. Если скопировать её разметку двадцать раз, любое изменение — например, другое скругление — придётся вносить двадцать раз. В Tailwind такие повторы убирают не через CSS, а в шаблонах: разметку пишут один раз, а данные подставляют.
Цикл вместо копий
Если карточки идут подряд, их строят циклом из массива данных. Разметка карточки записана один раз:
<script src="https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4"></script>
<div id="catalog" class="grid grid-cols-3 gap-4"></div>
<script>
const products = [
{ name: 'Наушники', price: 79 },
{ name: 'Колонка', price: 45 },
{ name: 'Зарядка', price: 19 },
];
document.getElementById('catalog').innerHTML = products.map((product) => `
<div class="rounded-xl bg-white p-4 shadow">
<h2 class="font-semibold">${product.name}</h2>
<p class="text-gray-600">$${product.price}</p>
</div>
`).join('');
</script>Под кодом — три одинаково оформленные карточки. Чтобы поменять тень у всех, достаточно исправить одну строку шаблона.
Компонент шаблона
В React, Vue или Svelte повторяющийся кусок выносят в компонент. Например, в проекте Vite с React файл src/components/ProductCard.jsx:
// src/components/ProductCard.jsx
export default function ProductCard({ name, price, image }) {
return (
<div className="overflow-hidden rounded-xl bg-white shadow-lg">
<img src={image} alt={name} className="h-40 w-full object-cover" />
<div className="p-4">
<h2 className="font-semibold text-gray-900">{name}</h2>
<p className="mt-1 text-gray-600">${price}</p>
</div>
</div>
);
}Используют его как обычный тег, передавая данные через атрибуты:
// src/App.jsx
import ProductCard from './components/ProductCard.jsx';
export default function App() {
return (
<div className="grid grid-cols-3 gap-4 p-6">
<ProductCard name="Наушники" price={79} image="/media/photo-400x250.jpg" />
<ProductCard name="Колонка" price={45} image="/media/photo-400x250.jpg" />
</div>
);
}Классы карточки живут в одном файле, а страница собирает её с разными данными. В React атрибут называется className, а не class.
Частичные шаблоны на сервере
Без JavaScript-фреймворка то же делают шаблоны бэкенда: include в PHP, @include или компоненты Blade в Laravel, {% include %} в Django и Twig. Карточку выносят в отдельный файл и подключают в цикле.
Мелкие повторы
Если одинаковые классы стоят у трёх соседних ссылок меню, выносить их никуда не нужно: редактор с множественным курсором правит их за секунду. Компонент нужен, когда кусок разметки повторяется в разных местах или файлах.
Частая ошибка
Сразу переносить классы карточки в CSS через @apply, чтобы «не копировать». Получается класс .product-card в отдельном файле, а разметка карточки — картинка, заголовок, цена — всё равно копируется. Повторяется не набор классов, а кусок разметки, поэтому и выносить надо разметку — в компонент или частичный шаблон.