← Назад к вопросам

Как сделать круглые углы у карточки?

1.8 Middle🔥 141 комментариев
#Soft Skills и рабочие процессы

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI3 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Как сделать круглые углы у карточки

Это базовый вопрос о CSS свойстве border-radius. Существует несколько способов реализации в зависимости от фреймворка и требований дизайна.

Базовое решение: border-radius

/* CSS */
.card {
  border-radius: 8px;  /* Все углы одинаково */
  background-color: white;
  padding: 20px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}

/* Или явно указать размер */
.card {
  border-top-left-radius: 8px;
  border-top-right-radius: 8px;
  border-bottom-left-radius: 8px;
  border-bottom-right-radius: 8px;
}

/* Или сокращенная запись */
.card {
  border-radius: 8px 12px 8px 12px; /* top-left top-right bottom-right bottom-left */
}

Решение с Tailwind CSS (рекомендуется для PrepBro)

// Базовая карточка с закругленными углами
function Card({ children, className }: { children: React.ReactNode; className?: string }) {
  return (
    <div className={`bg-white rounded-lg p-4 ${className}`}>
      {children}
    </div>
  );
}

// Или с cn() для лучшей управляемости
import { cn } from '@/lib/utils';

function Card({ children, className }: { children: React.ReactNode; className?: string }) {
  return (
    <div className={cn('bg-white rounded-lg p-4', className)}>
      {children}
    </div>
  );
}

// Tailwind классы для border-radius
// rounded-none    -> 0
// rounded-sm      -> 0.125rem (2px)
// rounded         -> 0.25rem (4px)
// rounded-md      -> 0.375rem (6px)
// rounded-lg      -> 0.5rem (8px) - рекомендуемое
// rounded-xl      -> 0.75rem (12px)
// rounded-2xl     -> 1rem (16px)
// rounded-3xl     -> 1.5rem (24px)
// rounded-full    -> 50% (круг)

// Для отдельных углов
// rounded-t-lg    -> сверху
// rounded-b-lg    -> снизу
// rounded-l-lg    -> слева
// rounded-r-lg    -> справа
// rounded-tl-lg   -> top-left
// rounded-tr-lg   -> top-right
// rounded-bl-lg   -> bottom-left
// rounded-br-lg   -> bottom-right

Варианты закругления в компонентах

// Компонент с разными вариантами border-radius
interface CardProps {
  variant?: 'sm' | 'md' | 'lg' | 'xl' | 'full';
  children: React.ReactNode;
  className?: string;
}

const roundedVariants = {
  sm: 'rounded-sm',      // 2px
  md: 'rounded-md',      // 6px
  lg: 'rounded-lg',      // 8px - дефолт
  xl: 'rounded-xl',      // 12px
  full: 'rounded-full'   // 100% (круг)
};

export function Card({ variant = 'lg', children, className }: CardProps) {
  return (
    <div
      className={cn(
        'bg-white p-4 shadow-sm',
        roundedVariants[variant],
        className
      )}
    >
      {children}
    </div>
  );
}

// Использование
<Card variant="lg">Content</Card>
<Card variant="xl">Big Content</Card>
<Card variant="full">Circle Card (редко)</Card>

Реальный пример из проекта PrepBro

// components/ui/question-card.tsx
import { cn } from '@/lib/utils';

interface QuestionCardProps {
  id: string;
  title: string;
  category: string;
  difficulty: 'easy' | 'medium' | 'hard';
  onClick?: () => void;
  className?: string;
}

export function QuestionCard({
  title,
  category,
  difficulty,
  onClick,
  className
}: QuestionCardProps) {
  return (
    <div
      onClick={onClick}
      className={cn(
        // Базовые стили
        'bg-white rounded-lg p-4 shadow-sm hover:shadow-md',
        // Отступы и размеры
        'border border-border-subtle transition-shadow',
        // Интерактивность
        'cursor-pointer hover:bg-surface-hover',
        className
      )}
    >
      <h3 className="font-medium text-content-primary text-lg mb-2">
        {title}
      </h3>
      <div className="flex items-center justify-between text-sm text-content-secondary">
        <span>{category}</span>
        <span className={cn(
          'px-2 py-1 rounded text-xs font-medium',
          difficulty === 'easy' && 'bg-green-100 text-green-800',
          difficulty === 'medium' && 'bg-yellow-100 text-yellow-800',
          difficulty === 'hard' && 'bg-red-100 text-red-800'
        )}>
          {difficulty}
        </span>
      </div>
    </div>
  );
}

Больше примеров с комбинациями

// Карточка с закругленными только верхними углами
function CardWithRoundedTop() {
  return (
    <div className="rounded-t-lg bg-white p-4">
      Content
    </div>
  );
}

// Полностью закругленная карточка (как аватар)
function AvatarCard() {
  return (
    <div className="rounded-full w-16 h-16 bg-blue-500" />
  );
}

// Карточка с разными углами
function AsymmetricCard() {
  return (
    <div className={cn(
      'bg-white',
      'rounded-tl-2xl rounded-tr-lg',   // Верхние углы разные
      'rounded-bl-lg rounded-br-2xl',   // Нижние углы разные
      'p-4'
    )}>
      Content
    </div>
  );
}

С overflow для содержимого

// Важно: если внутри элемента изображение или другое содержимое,
// нужно скрывать overflow чтобы контент не выступал за углы

function CardWithImage({ imageUrl, title }: { imageUrl: string; title: string }) {
  return (
    <div className="rounded-lg overflow-hidden bg-white shadow-sm">
      {/* overflow-hidden скрывает выступающее содержимое */}
      <img 
        src={imageUrl} 
        alt={title}
        className="w-full h-48 object-cover"
      />
      <div className="p-4">
        <h3 className="font-medium">{title}</h3>
      </div>
    </div>
  );
}

Анимированные карточки

// Карточка с плавным переходом при наведении
function InteractiveCard({ title }: { title: string }) {
  return (
    <div className={cn(
      'bg-white rounded-lg p-4',
      'border border-border-subtle',
      'transition-all duration-200 ease-in-out',  // Плавный переход
      'hover:shadow-md hover:border-border-focused',
      'hover:scale-105',  // Легкое увеличение
      'cursor-pointer'
    )}>
      {title}
    </div>
  );
}

// С focus состоянием (для доступности)
function AccessibleCard({ title }: { title: string }) {
  return (
    <button className={cn(
      'bg-white rounded-lg p-4 text-left',
      'border border-border-subtle',
      'transition-all duration-200',
      'hover:shadow-md',
      'focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2',
      'active:scale-95'
    )}>
      {title}
    </button>
  );
}

Адаптивные углы для разных экранов

// Разные border-radius на мобильных и десктопах
function ResponsiveCard() {
  return (
    <div className={cn(
      'bg-white p-4',
      'rounded-md md:rounded-lg lg:rounded-xl',  // Меньше на мобилке
      'shadow-sm'
    )}>
      Content
    </div>
  );
}

Проверка поддержки

// border-radius поддерживается всеми современными браузерами
// IE 9+, Chrome 1+, Firefox 4+, Safari 5+

const browserSupport = {
  'Chrome': '1+',
  'Firefox': '4+',
  'Safari': '5+',
  'Edge': 'Все версии',
  'IE': '9+',
  'Mobile browsers': 'Все'
};

// Для IE 8 нужны префиксы, но это уже устаревший браузер
.card {
  -webkit-border-radius: 8px;  /* Safari 1-3.2, Chrome 1-25 */
  -moz-border-radius: 8px;     /* Firefox 1-3.6 */
  border-radius: 8px;          /* Opera 10.5, IE 9+, Safari 5+, Chrome 26+, Firefox 4+ */
}

Практические советы

  1. Используй Tailwind классы вместо напрямую CSS
  2. rounded-lg — самый частый выбор (8px)
  3. overflow-hidden нужен если внутри изображения
  4. Комбинируй с тенями для глубины (shadow-sm)
  5. Адаптируй под экраны (мобильные меньше — меньше углы)
  6. Добавляй transition для интерактивности
  7. Тестируй на разных браузерах хотя поддержка отличная
  8. Не переусложняй — обычно 8px (rounded-lg) достаточно

Вывод

Для создания карточки с круглыми углами в проекте PrepBro используй:

<div className="bg-white rounded-lg p-4 shadow-sm">
  {content}
</div>

Это минимальный и правильный способ. Все остальное — вариации этого подхода.