主题对象
使用
Chakra UI 默认主题对象中包含很多样式的预设值。
打印 theme
对象:
在使用样式属性设置样式的时候,Chakra 会先从主题对象中获取对应的预设值,如果不存在,则将值作为 CSS 的值去设置。
例如:
<Box bg="gray.200"></Box>
会找到theme.colors.gray.200
即#E2E8F0
。<Box bg="gray"></Box>
没有对应的预设值,最终则会设置为gray
。
文档:
- 详细的预设查看 Default Theme。
- 具体哪些样式属性可以用哪些预设查看 Style Props
扩展
可以通过 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
的宽度取值是:
- 300px:文档宽度
base(0em)
以上 - 600px:文档宽度
md(48em)
以上 - 1000px:文档宽度
lg(62em)
以上
Text
字号的取值是:
- 14px:文档宽度
base(0em)
以上 - 20px:文档宽度
md(48em)
以上 - 40px:文档宽度
lg(62em)
以上
自定义
可以使用 @chakra-ui/theme-tolls
的 createBreakpoints
定义自定义断点,并通过 extendTheme
重写主题。
createBreakpoints
接收一个对象:
- Chakra 建议使用常见的别名,如
sm
、md
、lg
等 - 确保 css 单位相同,全部使用
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 Factory
chakra
是一个支持 Chakra 的 JSX 元素的对象,也是一个可以用来支持自定义组件接收 Chakra 样式属性的函数。
普通 HTML 元素组件
使用 chakra.<element>
创建可以传递 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 组件,使其可以传递 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