Реализация Utility-First CSS подхода для сайта

Наша компания занимается разработкой, поддержкой и обслуживанием сайтов любой сложности. От простых одностраничных сайтов до масштабных кластерных систем построенных на микро сервисах. Опыт разработчиков подтвержден сертификатами от вендоров.

Разработка и обслуживание любых видов сайтов:

Информационные сайты или веб-приложения
Сайты визитки, landing page, корпоративные сайты, онлайн каталоги, квиз, промо-сайты, блоги, новостные ресурсы, информационные порталы, форумы, агрегаторы
Сайты или веб-приложения электронной коммерции
Интернет-магазины, B2B-порталы, маркетплейсы, онлайн-обменники, кэшбэк-сайты, биржи, дропшиппинг-платформы, парсеры товаров
Веб-приложения для управления бизнес-процессами
CRM-системы, ERP-системы, корпоративные порталы, системы управления производством, парсеры информации
Сайты или веб-приложения электронных услуг
Доски объявлений, онлайн-школы, онлайн-кинотеатры, конструкторы сайтов, порталы предоставления электронных услуг, видеохостинги, тематические порталы

Это лишь некоторые из технических типов сайтов, с которыми мы работаем, и каждый из них может иметь свои специфические особенности и функциональность, а также быть адаптированным под конкретные потребности и цели клиента

Предлагаемые услуги
Показано 1 из 1 услугВсе 2065 услуг
Реализация Utility-First CSS подхода для сайта
Простая
от 1 рабочего дня до 3 рабочих дней
Часто задаваемые вопросы

Наши компетенции:

Этапы разработки

Последние работы

  • image_website-b2b-advance_0.png
    Разработка сайта компании B2B ADVANCE
    1262
  • image_web-applications_feedme_466_0.webp
    Разработка веб-приложения для компании FEEDME
    1171
  • image_websites_belfingroup_462_0.webp
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    874
  • image_ecommerce_furnoro_435_0.webp
    Разработка интернет магазина для компании FURNORO
    1094
  • image_crm_enviok_479_0.webp
    Разработка веб-приложения для компании Enviok
    831
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Разработка веб-сайта для компании ФИКСПЕР
    851

Реализация Utility-First CSS подхода для сайта

Utility-First — писать стили прямо в классах HTML-элементов, используя готовые утилиты: flex, items-center, text-lg, bg-blue-500. Не придумывать имена классов (.card-header-wrapper), не переключаться между HTML и CSS файлами. Tailwind CSS — реализация этого подхода.

Это работает быстрее не потому что классы красивые, а потому что CSS не растёт: каждый новый компонент переиспользует те же утилиты. Bundle CSS перестаёт линейно расти с проектом.

Установка Tailwind CSS 4

Tailwind CSS 4 полностью переработал конфигурацию — теперь всё через CSS, без tailwind.config.ts:

npm install tailwindcss @tailwindcss/vite
// vite.config.ts
import tailwindcss from '@tailwindcss/vite'
import { defineConfig } from 'vite'

export default defineConfig({
  plugins: [tailwindcss()],
})
/* src/styles/globals.css */
@import 'tailwindcss';

/* Кастомные токены прямо в CSS */
@theme {
  --color-primary: #2563eb;
  --color-primary-foreground: #ffffff;
  --color-secondary: #f1f5f9;
  --color-secondary-foreground: #0f172a;
  --color-destructive: #ef4444;
  --color-muted: #f8fafc;
  --color-border: #e2e8f0;

  --radius-sm: 4px;
  --radius-md: 8px;
  --radius-lg: 12px;
  --radius-full: 9999px;

  --font-sans: 'Inter', system-ui, sans-serif;
  --font-mono: 'JetBrains Mono', monospace;

  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.05);
  --shadow-md: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1);
}

/* Базовые стили */
@layer base {
  *, *::before, *::after { box-sizing: border-box; }

  body {
    font-family: var(--font-sans);
    color: var(--color-foreground);
    background: var(--color-background);
    -webkit-font-smoothing: antialiased;
  }

  h1, h2, h3, h4, h5, h6 {
    font-weight: 600;
    line-height: 1.25;
    letter-spacing: -0.025em;
  }
}

Tailwind CSS 3 (стабильная версия)

npm install -D tailwindcss postcss autoprefixer
npx tailwindcss init -p
// tailwind.config.ts
import type { Config } from 'tailwindcss'

export default {
  content: ['./index.html', './src/**/*.{ts,tsx}'],
  darkMode: ['selector', '[data-theme="dark"]'],
  theme: {
    extend: {
      colors: {
        primary: {
          DEFAULT: '#2563eb',
          50: '#eff6ff',
          100: '#dbeafe',
          500: '#3b82f6',
          600: '#2563eb',
          700: '#1d4ed8',
          900: '#1e3a8a',
        },
      },
      fontFamily: {
        sans: ['Inter', 'system-ui', 'sans-serif'],
        mono: ['JetBrains Mono', 'monospace'],
      },
      borderRadius: {
        DEFAULT: '8px',
      },
      boxShadow: {
        card: '0 1px 3px rgb(0 0 0 / 0.08), 0 1px 2px rgb(0 0 0 / 0.04)',
      },
      animation: {
        'fade-in': 'fade-in 200ms ease',
        'slide-up': 'slide-up 300ms ease',
      },
      keyframes: {
        'fade-in': { from: { opacity: '0' }, to: { opacity: '1' } },
        'slide-up': {
          from: { opacity: '0', transform: 'translateY(12px)' },
          to: { opacity: '1', transform: 'translateY(0)' },
        },
      },
    },
  },
} satisfies Config

Компоненты с Tailwind

Типичная карточка:

function ProductCard({ product }: { product: Product }) {
  return (
    <article className="group flex flex-col bg-white rounded-xl border border-slate-200 overflow-hidden shadow-card hover:shadow-md transition-shadow duration-200">
      <div className="relative aspect-video overflow-hidden bg-slate-100">
        <img
          src={product.image}
          alt={product.name}
          className="w-full h-full object-cover group-hover:scale-105 transition-transform duration-300"
        />
        {product.badge && (
          <span className="absolute top-3 left-3 px-2 py-0.5 text-xs font-semibold bg-primary-600 text-white rounded-full">
            {product.badge}
          </span>
        )}
      </div>

      <div className="flex flex-col gap-3 p-5 flex-1">
        <h3 className="font-semibold text-slate-900 leading-snug line-clamp-2">
          {product.name}
        </h3>
        <p className="text-sm text-slate-500 line-clamp-3 flex-1">
          {product.description}
        </p>
        <div className="flex items-center justify-between pt-2 border-t border-slate-100">
          <span className="text-xl font-bold text-slate-900">
            {product.price} ₽
          </span>
          <button className="px-4 py-2 text-sm font-medium bg-primary-600 text-white rounded-lg hover:bg-primary-700 active:scale-95 transition-all">
            В корзину
          </button>
        </div>
      </div>
    </article>
  )
}

@apply — вынесение в компоненты

Для повторяющихся наборов классов — @apply:

@layer components {
  .btn {
    @apply inline-flex items-center gap-2 rounded-lg font-medium transition-all duration-150;
    @apply disabled:opacity-50 disabled:pointer-events-none;
    @apply active:scale-95;
  }

  .btn-primary {
    @apply btn bg-primary-600 text-white hover:bg-primary-700 px-4 py-2 text-sm;
  }

  .btn-secondary {
    @apply btn bg-slate-100 text-slate-700 hover:bg-slate-200 px-4 py-2 text-sm;
  }

  .card {
    @apply bg-white rounded-xl border border-slate-200 shadow-card p-6;
  }

  .input {
    @apply w-full rounded-lg border border-slate-300 bg-white px-3 py-2 text-sm;
    @apply placeholder:text-slate-400;
    @apply focus:outline-none focus:ring-2 focus:ring-primary-500 focus:border-transparent;
    @apply disabled:bg-slate-50 disabled:text-slate-500;
  }
}

@apply использовать умеренно — только для устойчивых паттернов. Злоупотребление возвращает к проблемам BEM/OOCSS.

Адаптивность

Tailwind использует mobile-first: без префикса — все экраны, с префиксом — от указанной ширины:

<!-- Стек на мобильных, 3 колонки от md, 4 от xl -->
<div class="grid grid-cols-1 gap-4 md:grid-cols-3 xl:grid-cols-4">
  <!-- карточки -->
</div>

<!-- Текст: маленький на мобильных, больше на десктопах -->
<h1 class="text-2xl font-bold sm:text-3xl lg:text-4xl xl:text-5xl">
  Заголовок
</h1>

<!-- Скрыть на мобильных, показать от md -->
<aside class="hidden md:block w-64 shrink-0">
  <!-- сайдбар -->
</aside>

Производительность

При правильной настройке content в конфиге Tailwind анализирует файлы статически и генерирует только используемые классы. Типичный результат — 8–25KB CSS в gzip для среднего проекта.

Динамические классы через конкатенацию строк (bg-${color}-500) статический анализ не поймёт. Решение — полные строки в коде:

// Неправильно — Tailwind не поймёт:
const cls = `bg-${variant === 'danger' ? 'red' : 'blue'}-500`

// Правильно:
const cls = variant === 'danger' ? 'bg-red-500' : 'bg-blue-500'

Что входит в работу

Установка и конфигурация Tailwind (v3 или v4), настройка дизайн-токенов (цвета, типографика, отступы), базовые компоненты через @apply или CVA, настройка dark mode, адаптивная сетка, рефакторинг существующих CSS при миграции.

Срок: 0.5 дня на настройку. Миграция существующего проекта — 1–3 дня в зависимости от объёма CSS.