Верстка сайту з використанням Styled Components

Наша компанія займається розробкою, підтримкою та обслуговуванням сайтів будь-якої складності. Від простих односторінкових сайтів до масштабних кластерних систем, побудованих на мікро сервісах. Досвід розробників підтверджено сертифікатами від вендорів.
Розробка та обслуговування будь-яких видів сайтів:
Інформаційні сайти або веб-програми
Сайти візитки, landing page, корпоративні сайти, онлайн каталоги, квіз, промо-сайти, блоги, ресурси новин, інформаційні портали, форуми, агрегатори
Сайти або веб-програми електронної комерції
Інтернет-магазини, B2B-портали, маркетплейси, онлайн-обмінники, кешбек-сайти, біржі, дропшиппінг-платформи, парсери товарів
Веб-програми для управління бізнес-процесами
CRM-системи, ERP-системи, корпоративні портали, системи управління виробництвом, парсери інформації
Сайти або веб-програми електронних послуг
Дошки оголошень, онлайн-школи, онлайн-кінотеатри, конструктори сайтів, портали надання електронних послуг, відеохостинги, тематичні портали

Це лише деякі з технічних типів сайтів, з якими ми працюємо, і кожен із них може мати свої специфічні особливості та функціональність, а також бути адаптованим під конкретні потреби та цілі клієнта.

Пропоновані послуги
Показано 1 з 1 послугУсі 2065 послуг
Верстка сайту з використанням Styled Components
Проста
~2-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

Вёрстка сайта з використанням Styled Components

Styled Components — CSS-in-JS бібліотека, яка створює React-компоненти з інкапсульованими стилями. Кожен компонент отримує унікальний хешований клас, стилі скопійовані та ізольовані. Підтримує темізацію через ThemeProvider, динамічні стилі через props та SSR через серверний рендеринг стилів в <head>.

Установка

npm install styled-components
npm install -D @types/styled-components babel-plugin-styled-components
// babel.config.js або .babelrc
{
  "plugins": [
    ["babel-plugin-styled-components", {
      "displayName": true,      // Ім'я компонента в DevTools
      "fileName": true,
      "meaninglessFileNames": ["index", "styles"],
      "pure": true,             // Tree-shaking
      "ssr": false
    }]
  ]
}

Для Vite:

// vite.config.ts
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';

export default defineConfig({
  plugins: [
    react({
      babel: {
        plugins: ['babel-plugin-styled-components'],
      },
    }),
  ],
});

Система теми

// src/theme/theme.ts
import { DefaultTheme } from 'styled-components';

export const lightTheme: DefaultTheme = {
  colors: {
    primary: '#2563eb',
    primaryHover: '#1d4ed8',
    primaryLight: '#eff6ff',

    background: '#f9fafb',
    surface: '#ffffff',

    textPrimary: '#111827',
    textSecondary: '#6b7280',
    textMuted: '#9ca3af',

    border: '#e5e7eb',
    danger: '#dc2626',
    success: '#16a34a',
  },
  typography: {
    fontFamily: '"Inter", system-ui, sans-serif',
    fontMono: '"JetBrains Mono", monospace',
    fontSizeSm: '0.875rem',
    fontSizeBase: '1rem',
    fontSizeLg: '1.125rem',
    fontSizeXl: '1.25rem',
    fontSize2xl: '1.5rem',
    fontSize3xl: '1.875rem',
    fontSize4xl: '2.25rem',
  },
  spacing: {
    xs: '0.25rem',
    sm: '0.5rem',
    md: '1rem',
    lg: '1.5rem',
    xl: '2rem',
    '2xl': '3rem',
    '3xl': '4rem',
  },
  borderRadius: {
    sm: '4px',
    md: '8px',
    lg: '12px',
    xl: '16px',
    full: '9999px',
  },
  shadows: {
    sm: '0 1px 2px rgb(0 0 0 / 0.05)',
    md: '0 4px 6px -1px rgb(0 0 0 / 0.1)',
    lg: '0 10px 15px -3px rgb(0 0 0 / 0.1)',
  },
  breakpoints: {
    sm: '640px',
    md: '768px',
    lg: '1024px',
    xl: '1280px',
  },
};

export const darkTheme: DefaultTheme = {
  ...lightTheme,
  colors: {
    ...lightTheme.colors,
    background: '#0f172a',
    surface: '#1e293b',
    textPrimary: '#f1f5f9',
    textSecondary: '#94a3b8',
    textMuted: '#64748b',
    border: '#334155',
    primaryLight: '#1e3a5f',
  },
};

// Типізація теми
declare module 'styled-components' {
  export interface DefaultTheme {
    colors: typeof lightTheme.colors;
    typography: typeof lightTheme.typography;
    spacing: typeof lightTheme.spacing;
    borderRadius: typeof lightTheme.borderRadius;
    shadows: typeof lightTheme.shadows;
    breakpoints: typeof lightTheme.breakpoints;
  }
}
// src/App.tsx
import { ThemeProvider } from 'styled-components';
import { lightTheme, darkTheme } from './theme/theme';
import { GlobalStyle } from './theme/GlobalStyle';

const App = () => {
  const [isDark, setIsDark] = useState(false);
  const theme = isDark ? darkTheme : lightTheme;

  return (
    <ThemeProvider theme={theme}>
      <GlobalStyle />
      <Router />
    </ThemeProvider>
  );
};

Глобальні стилі

// src/theme/GlobalStyle.ts
import { createGlobalStyle } from 'styled-components';

export const GlobalStyle = createGlobalStyle`
  *, *::before, *::after {
    box-sizing: border-box;
    margin: 0;
    padding: 0;
  }

  html {
    font-size: 16px;
    scroll-behavior: smooth;
    -webkit-text-size-adjust: 100%;
  }

  body {
    font-family: ${({ theme }) => theme.typography.fontFamily};
    background-color: ${({ theme }) => theme.colors.background};
    color: ${({ theme }) => theme.colors.textPrimary};
    line-height: 1.6;
    -webkit-font-smoothing: antialiased;
  }

  img, video {
    max-width: 100%;
    height: auto;
  }

  a {
    color: inherit;
    text-decoration: none;
  }
`;

Компоненти

// src/components/Button/Button.tsx
import styled, { css } from 'styled-components';

interface ButtonProps {
  variant?: 'primary' | 'ghost' | 'danger';
  size?: 'sm' | 'md' | 'lg';
  fullWidth?: boolean;
}

export const Button = styled.button<ButtonProps>`
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  font-family: inherit;
  font-weight: 500;
  border: 1px solid transparent;
  cursor: pointer;
  transition:
    background-color 150ms ease,
    border-color 150ms ease,
    transform 100ms ease;
  white-space: nowrap;

  &:active { transform: scale(0.98); }
  &:disabled { opacity: 0.5; cursor: not-allowed; }
  &:focus-visible {
    outline: 2px solid ${({ theme }) => theme.colors.primary};
    outline-offset: 2px;
  }

  /* Розміри */
  ${({ size = 'md' }) => ({
    sm: css`
      height: 32px;
      padding: 0 12px;
      font-size: ${({ theme }) => theme.typography.fontSizeSm};
      border-radius: ${({ theme }) => theme.borderRadius.sm};
    `,
    md: css`
      height: 40px;
      padding: 0 16px;
      font-size: ${({ theme }) => theme.typography.fontSizeBase};
      border-radius: ${({ theme }) => theme.borderRadius.md};
    `,
    lg: css`
      height: 48px;
      padding: 0 24px;
      font-size: ${({ theme }) => theme.typography.fontSizeLg};
      border-radius: ${({ theme }) => theme.borderRadius.md};
    `,
  }[size])}

  /* Варіанти */
  ${({ variant = 'primary', theme }) => ({
    primary: css`
      background: ${theme.colors.primary};
      color: #fff;
      &:hover:not(:disabled) { background: ${theme.colors.primaryHover}; }
    `,
    ghost: css`
      background: transparent;
      color: ${theme.colors.primary};
      border-color: ${theme.colors.primary};
      &:hover:not(:disabled) { background: ${theme.colors.primaryLight}; }
    `,
    danger: css`
      background: ${theme.colors.danger};
      color: #fff;
      &:hover:not(:disabled) { background: #b91c1c; }
    `,
  }[variant])}

  ${({ fullWidth }) => fullWidth && css`width: 100%;`}
`;

Адаптивні медіа-запити

// src/theme/media.ts
import { css } from 'styled-components';

export const media = {
  sm: (styles: ReturnType<typeof css>) => css`
    @media (min-width: 640px) { ${styles} }
  `,
  md: (styles: ReturnType<typeof css>) => css`
    @media (min-width: 768px) { ${styles} }
  `,
  lg: (styles: ReturnType<typeof css>) => css`
    @media (min-width: 1024px) { ${styles} }
  `,
};
const HeroContainer = styled.section`
  padding: 3rem 1rem;

  ${media.md(css`
    padding: 5rem 2rem;
  `)}

  ${media.lg(css`
    padding: 8rem 3rem;
  `)}
`;

Терміни

Налаштування ThemeProvider, GlobalStyle, типізації: 2–3 години. Styled Components додає невеликий runtime (~15 КБ) — враховується при оцінці критичності performance. Посадочна сторінка: 1,5–2 дні. Повний сайт: 4–7 днів.