Chakra UI строится на принципах системы дизайна, где каждый компонент имеет предопределённые стили, но также допускает расширение через пропсы и кастомизацию. Конфликты стилей возникают, когда несколько источников стилей перекрывают друг друга, создавая непредсказуемый визуальный результат. Основные источники конфликтов:
Встроенные стили компонента (defaultProps и
baseStyle) Каждый компонент Chakra UI имеет набор
базовых стилей, определённых в теме (theme). Эти стили
задают размеры, отступы, цвета и поведение при взаимодействии. Например,
компонент Button имеет базовые значения
padding, borderRadius и
backgroundColor.
Стили, переданные через пропсы
(props) Chakra UI позволяет задавать стили
напрямую через пропсы, такие как bg, color,
fontSize, m, p и другие. Эти
стили имеют более высокий приоритет по сравнению с
базовыми стилями компонента, что может вызвать конфликт при попытке
перекрыть значение из темы.
Стили из кастомной темы
(extendTheme) Пользовательская тема может
переопределять глобальные параметры (colors,
fonts, components) и задавать новые
variants и sizes для компонентов. Конфликты
появляются, когда значения темы перекрываются с локальными пропсами, что
требует понимания приоритета источников
стилей.
CSS-свойства через sx или
css Свойства, переданные через sx или
css, позволяют использовать полный потенциал CSS-in-JS. Эти
стили обладают самым высоким приоритетом, что делает их
мощным инструментом, но при неправильном использовании создаёт
непредсказуемость.
Chakra UI использует иерархию стилей, которая определяет, какие значения будут применены в конечном рендере:
baseStyle компонента из темыvariant компонента, если указанsize компонента, если указанbg, color,
p, m и т.д.)sx или cssВажно учитывать, что каждый уровень иерархии полностью
перекрывает предыдущий, а не объединяется с ним. Например, если
в variant задан цвет текста red.500, а в
пропсе color="blue.500", итоговый цвет будет
blue.500.
1. Конфликт размеров и отступов Компонент может
иметь предопределённые размеры (size="lg"), которые
устанавливают padding и fontSize. Если
одновременно заданы пропсы p или fontSize,
возникает противоречие. Лучший подход — либо использовать только
size, либо полностью переопределять padding и
fontSize.
2. Конфликт цветов Цвета могут задаваться в теме
через colors и в пропсах компонента. Также возможны
конфликты с hover или focus стилями.
Например:
<Button bg="blue.500" _hover={{ bg: "green.500" }} />
Если в теме определён другой variant с
_hover, пропс _hover в компоненте имеет
приоритет.
3. Конфликты с кастомными темами Переопределение
defaultProps в кастомной теме может неожиданно изменить
внешний вид всех компонентов. Например, если для Button в
теме установлен size="sm" по умолчанию, но в компоненте
используется size="lg", итоговый размер будет
lg, поскольку пропсы локального компонента перекрывают
тему.
sx.sx только для
уникальных случаев, чтобы не ломать общую систему дизайна.variants и sizes из
темы вместо ручного задания padding,
fontSize и borderRadius._hover, _focus
и _active, так как они могут конфликтовать с
локальными пропсами или глобальной темой.import { Button, extendTheme, ChakraProvider } from "@chakra-ui/react";
// Создание кастомной темы
const theme = extendTheme({
components: {
Button: {
baseStyle: { fontWeight: "bold" },
sizes: { lg: { px: 8, py: 6 } },
variants: { solid: { bg: "red.400", color: "white" } },
defaultProps: { size: "lg", variant: "solid" },
},
},
});
function App() {
return (
<ChakraProvider theme={theme}>
<Button color="yellow.500" _hover={{ bg: "blue.500" }}>
Конфликт стилей
</Button>
</ChakraProvider>
);
}
В этом примере:
baseStyle устанавливает fontWeightsize="lg" задаёт большие отступыvariant="solid" задаёт bg и
colorcolor="yellow.500" перекрывает цвет темы_hover={{ bg: "blue.500" }} перекрывает
variant hoverТаким образом, итоговые стили формируются на основе иерархии источников.
Понимание конфликтов стилей в Chakra UI требует:
sx или _hover только при
необходимостиСоблюдение этих принципов позволяет создавать интерфейсы, где стили предсказуемы, масштабируемы и легко поддерживаются.