BEM类型
StyleSheet maker 函数可以使用特殊类型描述生成的样式,因此在使用它们时,TypeScript 会提示可用的 CSS 选择器。此功能结合了 BEM 方法论和 TypeScript 泛型,将样式的实现隐藏在外部接口之后。
建议使用类型时不要严格遵循特定的方法论。更多信息请参见CSS-in-TS部分。
风格描述
使用 EffCSS 开发样式的第一步是将提供的功能声明为一种类型,该类型在 BEM 方法论的三个层级上描述您的样式。
- 积木(1 层),
- 元素(第二级),
- 修饰符(3 级)。
对于所有级别,建议使用以 lowerCamelCase 格式编写的有意义的名称。
WARNING
名称中不要使用点号和下划线,因为这些字符用于输出 EffCSS 的选择器和属性。
INFO
您不必使用全部三个层级。如果您不想使用 BEM 描述样式,只需在单个代码块层级描述您的选择器即可。
export type TCustomMaker = {
/**
* Default block
*/
'': {
/**
* Logo element
*/
logo: {
/**
* Spin animation
*/
spin: '';
/**
* Logo scale
*/
scale: 1 | 2;
};
/**
* Body element
*/
body: {
/**
* Padding size
*/
p: 's' | 'm' | 'l';
};
/**
* Footer element
*/
footer: {
/**
* Is footer hidden
*/
hidden: '';
};
};
/**
* Panel block
*/
panel: {
/**
* Default block
*/
'': {
/**
* Is panel modal
*/
modal: '';
/**
* Max panel width
*/
max: 'vw' | 'parent';
};
/**
* Close button block
*/
closeBtn: {};
}
};代码块不必包含元素。元素不必包含修饰符。
请注意,块修饰符也在带有 "" 键的元素内的 3 级中进行描述。带有 "" 键的块被视为默认块或主块。有时,样式会描述一些不与特定块和/或元素关联的实用程序(例如在 Tailwind 中),这时以下描述就派上用场了。
export type TCustomMaker = {
'': {
'': {
/**
* Width
*/
w: 's' | 'm' | 'l';
/**
* Height
*/
h: 's' | 'm' | 'l';
}
};
};样式实现
使用 EffCSS 开发样式的第二步是在 StyleSheet maker 函数中实现所述功能。EffCSS 使用 bem 工具生成 BEM 选择器。由于 bem 是一个通用工具,它还会检查已实现的 CSS 选择器的有效性。
每个选择器都是通过用点连接块、元素、修饰符和修饰符值(如果不是布尔值)的名称而形成的。
import { TStyleSheetMaker } from 'effcss';
export type TCustomMaker = {...};
const maker: TStyleSheetMaker = ({
bem,
}) => {
return {
// the default block selector
[bem<TCustomMaker>('')]: {...},
// selector for an element inside the default block
[bem<TCustomMaker>('.logo')]: {...},
// element boolean modifier selector
[bem<TCustomMaker>('.logo.spin')]: {}
// selector for a block modifier with a specific value
[bem<TCustomMaker>('panel..max.vw')]: {}
}
};
export default maker;样式的使用
可以通过将相应的 StyleSheet maker 函数传递给 Style provider 对象的 use 方法来使用现成的 EffCSS 样式。其用法与 bem 工具类似——系统也会检查输入的参数是否符合 TCustomMaker 类型。
import { IStyleProvider } from 'effcss';
import { default as customStyle, TCustomMaker } from './styles/custom';
const getStyle = (use: IStyleProvider['use']) => {
// EffCSS v3 returns a resolver function,
// and EffCSS v4 returns an array of resolvers
const [css] = use(customStyle);
return {
block: css<TCustomMaker>(''),
logo: css<TCustomMaker>('.logo'),
spinLogo: css<TCustomMaker>('.logo.spin'),
footer: css<TCustomMaker>('.footer'),
body: css<TCustomMaker>('.body.p.m'),
};
};您还可以传递一个对象来一次性生成多个选择器。
import { IStyleProvider } from 'effcss';
import { default as customStyle, TCustomMaker } from './styles/custom';
const getStyle = (use: IStyleProvider['use']) => {
// EffCSS v3 returns a resolver function,
// and EffCSS v4 returns an array of resolvers
const [css] = use(customStyle);
return css<TCustomMaker>({
'': {
logo: {
spin: '',
scale: 2
};
}
});
};或者你可以传递一个字符串数组。
import { IStyleProvider } from 'effcss';
import { default as customStyle, TCustomMaker } from './styles/custom';
const getStyle = (use: IStyleProvider['use']) => {
// EffCSS v3 returns a resolver function,
// and EffCSS v4 returns an array of resolvers
const [css] = use(customStyle);
return css<TCustomMaker>(['.logo.spin', '.logo.scale.2']);
};或者,您可以先获取 MonoResolver 对象,然后根据需要对其进行细化。
import { IStyleProvider } from 'effcss';
import { default as customStyle, TCustomMaker } from './styles/custom';
const getStyle = (use: IStyleProvider['use']) => {
// EffCSS v3 returns a resolver function,
// and EffCSS v4 returns an array of resolvers
const [css] = use(customStyle);
const block = css<TCustomMaker>();
const logo = block.e('logo');
const logoSpin = logo.m({
spin: ''
});
return {
block: block.$,
logo: logo.$,
spinLogo: logoSpin.$,
footer: block.e('footer').$,
body: block.e('body').m({
p: 'm'
}).$,
};
};使用你最喜欢的方式。
属性生成模式
Style provider 组件可以通过 2 个属性影响 BEM 选择器的生成:
mode- 可以取值a(使用data-*属性)和c(使用class属性),min是一个布尔属性,允许您缩小 BEM 选择器。
CSS 类生成更具可预测性,而数据属性生成则允许你在视觉上区分不同的样式表。选择你最喜欢的方式即可。
代码压缩会在选择器中保留唯一的前缀,因此不同表格的样式将保持隔离,同时选择器的长度将显著减少。
益处
所描述的方法可以将契约与实现分离。在开发过程中,您一开始就知道应该提供哪些 CSS 选择器,任何第三方开发人员都可以导入您的 TCustomMaker 类型并获取所需的样式,而无需查看您的 StyleSheet maker 函数。考虑到 JS 文件通常会在编译过程中被压缩,这种方法可以节省大量时间。
此外,EffCSS 会为每个样式表生成自己独特的 BEM 选择器,从而消除重新定义它们的风险。
因此,EffCSS 允许您超越通常的 CSS 创建,接近 CSS-in-TS 的角色。