跳至主要内容

定义样式

StyleX 使用一个表达力强的 JavaScript API,类似于在 React DOM 中使用内联样式或在 React Native 中使用样式。

约束

由于 StyleX 依赖于提前编译,因此所有样式都必须能够进行静态分析非常重要。这意味着每个“原始样式对象”只能包含

  • 普通对象字面量
  • 字符串字面量
  • 数字字面量
  • 数组字面量
  • nullundefined
  • 常量、简单表达式和内置方法(例如,.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 元素,即用 divspan 等元素替换 ::before::after。这有助于减小 CSS 包的大小。

伪元素是用于定位用户代理提供的原生 HTML 元素中包含的 Shadow DOM 元素的一种方法。例如,::placeholder 引用包含 inputtextarea 元素中占位符文本的元素。要在 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 变量的静态样式,并在运行时设置该变量的值。这意味着,您的任何样式部分都可以是动态的,包括媒体查询和伪类中。