定义样式
StyleX 使用一个表达力强的 JavaScript API,类似于在 React DOM 中使用内联样式或在 React Native 中使用样式。
约束
由于 StyleX 依赖于提前编译,因此所有样式都必须能够进行静态分析非常重要。这意味着每个“原始样式对象”只能包含
- 普通对象字面量
- 字符串字面量
- 数字字面量
- 数组字面量
null
或undefined
- 常量、简单表达式和内置方法(例如,
.toString()
),这些方法解析为上述内容之一。 - 以及用于动态样式的箭头函数
以下内容**不允许**
- 函数调用(StyleX 函数除外)
- 从其他模块导入的值(使用 StyleX 从
.stylex.js
文件创建的 CSS 变量除外)。
创建样式
样式必须使用 stylex.create
函数创建。您可以定义一个或多个“命名空间”或样式对象。在下面的示例中,有两个“命名空间”——一个名为 base
,另一个名为 highlighted
。名称是任意的,表示用于捕获 create()
函数调用结果的常量。
import * as stylex from '@stylexjs/stylex';
const styles = stylex.create({
base: {
fontSize: 16,
lineHeight: 1.5,
color: 'rgb(60,60,60)',
},
highlighted: {
color: 'rebeccapurple',
},
});
伪类
伪类表示元素的不同状态。在 StyleX 中,伪类的声明嵌套在属性中。例如,假设我们有一个按钮,它当前具有 lightblue
背景。
import * as stylex from '@stylexjs/stylex';
const styles = stylex.create({
button: {
backgroundColor: 'lightblue',
},
});
如果要添加伪类以更改不同状态下的背景颜色,我们将用伪状态对象替换 lightblue
字符串字面量。
import * as stylex from '@stylexjs/stylex';
const styles = stylex.create({
button: {
backgroundColor: {
default: 'lightblue',
':hover': 'blue',
':active': 'darkblue',
},
},
});
伪元素
我们建议尽可能避免使用伪元素,而是依靠实际的 HTML 元素,即用 div
或 span
等元素替换 ::before
和 ::after
。这有助于减小 CSS 包的大小。
伪元素是用于定位用户代理提供的原生 HTML 元素中包含的 Shadow DOM 元素的一种方法。例如,::placeholder
引用包含 input
或 textarea
元素中占位符文本的元素。要在 StyleX 中定位伪元素,必须将其定义为命名空间中的顶级键。
import * as stylex from '@stylexjs/stylex';
const styles = stylex.create({
input: {
// pseudo-element
'::placeholder': {
color: '#999',
},
color: {
default: '#333',
// pseudo-class
':invalid': 'red',
},
},
});
媒体查询(和其他 @
规则)
类似地,媒体查询可以作为样式值中的“条件”。
import * as stylex from '@stylexjs/stylex';
const styles = stylex.create({
base: {
width: {
default: 800,
'@media (max-width: 800px)': '100%',
'@media (min-width: 1540px)': 1366,
},
},
});
组合条件
当您需要组合媒体查询和伪选择器时,您的样式值可以嵌套多层。
import * as stylex from '@stylexjs/stylex';
const styles = stylex.create({
button: {
color: {
default: 'var(--blue-link)',
':hover': {
default: null,
'@media (hover: hover)': 'scale(1.1)',
},
':active': 'scale(0.9)',
},
},
});
编写条件样式时,需要 default
案例。如果您不希望在默认情况下应用任何样式,则可以使用 null
作为值。
对于非 default
条件使用 null
没有任何效果,应视为无效。
后备样式
在 StyleX 中,某些情况下,当您需要为不支持某些新样式属性的浏览器提供后备样式时。
在 CSS 中,您可以执行以下操作
.header {
position: fixed;
position: -webkit-sticky;
position: sticky;
}
使用 JavaScript 对象时,这种语法是不可能的。因此,在 StyleX 中,您可以使用 firstThatWorks
函数来实现相同的功能。
import * as stylex from '@stylexjs/stylex';
const styles = stylex.create({
header: {
position: stylex.firstThatWorks('sticky', '-webkit-sticky', 'fixed'),
},
});
关键帧动画
您可以使用 stylex.keyframes()
函数定义关键帧动画。
import * as stylex from '@stylexjs/stylex';
const fadeIn = stylex.keyframes({
from: {opacity: 0},
to: {opacity: 1},
});
const styles = stylex.create({
base: {
animationName: fadeIn,
animationDuration: '1s',
},
});
动态样式
动态样式是一项高级功能,应谨慎使用。对于大多数用例,条件样式 应该足够了。
StyleX 在编译时生成所有样式,这意味着您也需要提前知道所有这些样式。但有时您直到运行时才知道需要什么。
对于这种情况,您可以将样式定义为函数而不是对象,并将所需样式的动态组件作为参数传递。
注意:函数体必须是对象字面量。您不能使用包含多个语句的函数体。
import * as stylex from '@stylexjs/stylex';
const styles = stylex.create({
// Function arguments must be simple identifiers
// -- No destructuring or default values
bar: (height) => ({
height,
// The function body must be an object literal
// -- { return {} } is not allowed
}),
});
function MyComponent() {
// The value of `height` cannot be known at compile time.
const [height, setHeight] = useState(10);
return <div {...stylex.props(styles.bar(height))} />;
}
在幕后,StyleX 将生成依赖于 CSS 变量的静态样式,并在运行时设置该变量的值。这意味着,您的任何样式部分都可以是动态的,包括媒体查询和伪类中。