Chakra UI 默认主题对象中包含很多样式的预设值。
打印 theme
对象:
在使用样式属性设置样式的时候,Chakra 会先从主题对象中获取对应的预设值,如果不存在,则将值作为 CSS 的值去设置。
例如:
会找到 theme.colors.gray.200
即 #E2E8F0
。
没有对应的预设值,最终则会设置为 gray
。文档:
可以通过 extendTheme(theme)
重写或扩展主题对象,它接收一个对象,会将这个对象和默认对象进行深层次合并:
import {
extendTheme } from '@chakra-ui/react'
const theme = extendTheme({
colors: {
gray: {
10: 'gray', // 向 theme.colors.gray 添加一个预设
50: '#333' // 重写 theme.colors.gray.50
},
blue: 'blue' // 重写 theme.colors.blue
},
bigSize: '1000px' // 向 theme 添加一个预设
})
主题对象中默认有一个 breakpoints
对象,它表示响应式断点。
响应式断点是 Chakra 提供的为元素添加响应式样式的方式,来替代在代码中手动添加 @media
和嵌套样式。
theme.breakpoints
的值是一个对象:
// 默认主题的 breakpoints
{
2xl: "96em",
base: "0em",
lg: "62em",
md: "48em",
sm: "30em",
xl: "80em",
}
Chakra UI 会将 breakpoints
中定义的值转换成数组,并按升序排列:
// 内部转换成这样
["0em", "30em", "48em", "62em", "80em", "96em"]
通过给样式属性传递一个对象或数组,来响应对应的值:
<Box w={
{
base: '300px', md: '600px', lg: '1000px' }} h="100px" bg="pink">
<Text fontSize={
['14px', null, '20px', '40px']}>在数组中使用 null 跳过断点,避免生成不必要的CSS</Text>
</Box>
Chakra UI 使用 @media(min-width)
媒体查询来保证移动优先。
所以上面示例 Box
的宽度取值是:
base(0em)
以上md(48em)
以上lg(62em)
以上Text
字号的取值是:
base(0em)
以上md(48em)
以上lg(62em)
以上可以使用 @chakra-ui/theme-tolls
的 createBreakpoints
定义自定义断点,并通过 extendTheme
重写主题。
createBreakpoints
接收一个对象:
sm
、md
、lg
等px
或 em
,不要混合使用。base: 0em
,不用手动设置,也不用担心单位混用问题,当然也可以重写它。返回的对象会替换 theme.breakPoints
(不是合并)。
npm i @chakra-ui/theme-tools
// theme.js
import {
createBreakpoints } from '@chakra-ui/theme-tools'
import {
extendTheme } from '@chakra-ui/react'
const breakPoints = createBreakpoints({
sm: '768px',
md: '1000px'
})
const theme = extendTheme({
breakPoints })
console.log(theme)
export default theme
function Example() {
return <Box w={
['100%', '50%', '25%']}
}
如果向createBreakpoints
传递一个数组,则会以下标为名创建对象(因为数组就是以下标为名的对象):
const breakPoints = createBreakpoints(['768px','1000px'])
chakra
是一个支持 Chakra 的 JSX 元素的对象,也是一个可以用来支持自定义组件接收 Chakra 样式属性的函数。
使用 chakra.
创建可以传递 Chakra 样式属性的普通 HTML 元素组件。
import {
chakra } from '@chakra-ui/react'
function App() {
return (
<chakra.div p="10px" w="200px" h="100px" bg="gray.600">
<chakra.p color="white">可以使用 Chakra 样式属性的普通 HMLT 元素组件</chakra.p>
</chakra.div>
)
}
export default App
使用 chakra
方法可以封装非 Chakra 组件,使其可以传递 Chakra 样式属性。
实际上内部使用了 Emotion,所以包装的组件需要能接收并设置 className
属性。
import {
chakra } from '@chakra-ui/react'
function Foo({
className, children}) {
// 确保正确接收 className
return <div className={
className}>{
children}</div>
}
// 封装的组件
const ChakraFoo = chakra(Foo)
function App() {
return (
<ChakraFoo p="10px" w="200px" h="100px" bg="gray.600">
<chakra.p color="white">自定义 Chakra 组件</chakra.p>
</ChakraFoo>
)
}
export default App
可以为自定义的 Chakra 组件定义初始样式:
import {
chakra } from '@chakra-ui/react'
function Foo({
className, children}) {
// 确保正确接收 className
return <div className={
className}>{
children}</div>
}
// 包装的组件
const ChakraFoo = chakra(Foo, {
baseStyle: {
p: '10px',
w: '200px',
h: '100px',
bg: 'gray.600'
}
})
function App() {
return (
<ChakraFoo>
<chakra.p color="white">带有初始样式的自定义 Chakra 组件</chakra.p>
</ChakraFoo>
)
}
export default App
也可以创建带有初始样式的普通HTML组件:
import {
chakra } from '@chakra-ui/react'
const ChakraDiv = chakra('div', {
baseStyle: {
p: '10px',
w: '200px',
h: '100px',
bg: 'gray.600'
}
})
function App() {
return (
<ChakraDiv>
<chakra.p color="white">带有初始样式的普通 HTML 元素组件</chakra.p>
</ChakraDiv>
)
}
export default App