背景
之前有幸见识到一个项目css一塌糊涂,各种样式覆盖,全局样式五六个文件,important满天飞,搞得很是头大。
CSS中可能存在的问题
- 冗余:小明想实现一个水平垂直居中,但是不想找现在有没有共享的样式,反正不麻烦,自己写一个好了
- 命名不规范:没有命名规范,个人风格差异大
- 缺少注释:懂的都懂
- 重复的覆盖:一个样式,全局有,局部有,还可能用了无数的 important(别问我如何知道的)
CSS设计模式
一、OOCSS
OOCSS(Object Oriented CSS)并不是一种特定的命名规范,而是一种CSS编写的思想和原则。它的目标是通过应用面向对象编程(OOP)中的设计原则,使CSS代码更加易于管理和维护。
1、优点
- 高度重用:OOCSS追求组件的复用,尽量不使用继承选择符,而是通过创建可重用的对象来减少代码的冗余。这种方式使得CSS代码更加简洁,易于维护,并且文件加载速度会更快。
- 易于维护:OOCSS通过清晰的类结构来组织代码,使得开发者能够更容易地定位问题并进行修改。同时,由于代码的重用性,修改一处即可全局生效,降低了维护难度。
- 可扩展性强:OOCSS的核心思想之一是结构和皮肤分离,这意味着新的视觉样式可以轻松地应用到现有的结构上。此外,新模块可以通过组合现有模块轻松创建,未来需求变化也能轻松应对。
2、核心思想
- 结构和皮肤分离:在OOCSS中,结构和皮肤被明确地区分开来。结构指的是HTML元素的布局和定位等属性(如height、width、position、margin、overflow等),而皮肤则指的是元素的视觉样式(如background、border、color等)。通过将结构和皮肤分离,可以使得视觉样式作为单独的“主题”来应用,而不必覆盖结构属性。
- 容器与内容分离:OOCSS强调不要在CSS中模仿HTML的结构。换句话说,不要在样式表中引用标签或ID。相反,应该尝试创建和应用描述相关标签使用的类。通过这种方式,可以减少对HTML结构的依赖,增加CSS class的重用性。
3、应用
在实际项目中应用OOCSS时,需要注意以下几点:
- 避免过度嵌套:过多的嵌套会增加代码的复杂性并降低可读性。因此,在编写OOCSS代码时,应尽量保持嵌套的简洁性。
- 命名规范:为了提高代码的可读性和可维护性,应遵循一定的命名规范。例如,可以使用有意义的类名来描述元素的功能或状态。
- 利用预处理器:使用CSS预处理器(如Sass、Less等)可以更方便地编写和维护OOCSS代码。预处理器提供了变量、函数、混合(mixin)等高级功能,可以帮助开发者更高效地编写可重用的CSS代码。
4、示例
假设有两个大小、外边距相同的div,但它们的背景色和字体大小不同。我们可以使用OOCSS的方法来编写CSS代码。
-
结构与皮肤分离
在OOCSS中,我们首先将结构和皮肤属性分开。结构属性包括位置、尺寸等,而皮肤属性包括字体、颜色等。
.box { width: 30%; margin-left: 35%; height: 300px; margin-top: 50px; text-align: center; line-height: 300px; color: white; } /* 皮肤样式 */ .skin-purple { background-color: #8A2BE2; font-size: 22px; } .skin-blue { background-color: blue; font-size: 23px; }在HTML中,我们可以这样应用这些样式:
<div class="box skin-purple">Box 1</div> <div class="box skin-blue">Box 2</div>通过这种方式,我们可以轻松地改变div的皮肤样式,而不需要修改其结构样式。
-
容器与内容分离
OOCSS还强调容器与内容的分离。这意味着子元素即使离开了容器也应该能正确显示。在上述示例中,
.box是容器,而内容(文本)是放置在容器中的。由于我们使用了结构与皮肤分离的方法,所以内容(文本)的样式(如字体大小和颜色)是通过皮肤样式(.skin-purple和.skin-blue)来定义的,而不是直接定义在容器样式(.box)中。因此,即使我们将内容移动到其他容器中,也只需要确保新的容器具有相同的结构样式(.box),并为其应用相应的皮肤样式即可。
二、BEM
BEM(Block Element Modifier)通过特定的命名规范和组织结构来提高CSS代码的可读性、可重用性、可维护性和可扩展性。
1、基本概念
-
Block(块) :
- 定义为页面中的独立实体,具有独立的意义。每个页面都可以看作是由多个Block组成的。
- 示例:一个导航栏、一个按钮组件、一个轮播图等都可以被视为一个Block。
- 命名规则:没有特定的前缀,多个单词使用连字符(-)连接。
-
Element(元素) :
- 是Block的一部分,没有独立的意义,是组件下的一个元素。多个Element形成一个完整的Block。
- 示例:在导航栏Block中,每个导航项都可以被视为一个Element。
- 命名规则:在Block的类名后,使用双下划线(__)连接Element的名称。
-
Modifier(修饰符) :
- 是Block或Element上的标记,用于描述其属性或状态。同一Block或Element可以有多个Modifier。
- 示例:一个按钮Block可以有“成功”、“失败”等不同的Modifier来表示不同的状态。
- 命名规则:在Block或Element的类名后,使用双连字符(--)连接Modifier的名称。
2、特点
-
清晰的结构:可以清晰地反映HTML文档的结构,使得开发者能够快速地定位和理解样式。
-
易于维护:BEM规范使得CSS代码具有高度的可维护性。由于类名具有明确的含义和层级关系,开发者可以轻松地找到和修改相应的样式。
-
高可重用性:通过BEM的Block和Element定义,组件和元素可以被多次使用,提高了样式的重用性。
-
可扩展性:由于BEM的Modifier定义,组件和元素可以轻松地扩展出不同的状态或版本,满足不同的需求。
3、示例
以ElementUI的按钮组件为例:
- Block(块) :
.el-button表示一个按钮组件。 - Element(元素) :
.el-button__icon表示按钮中的图标元素。 - Modifier(修饰符) :
.el-button--primary表示主要按钮样式;.el-button--round表示圆形按钮样式。
三、SMACSS
SMACSS(Scalable and Modular Architecture for CSS)是一种面向模块化的CSS架构方法,旨在提高CSS代码的可读性、可维护性和可扩展性。
1、核心概念
- 模块化:SMACSS鼓励将整个页面结构划分为小型、独立的模块,并为每个模块创建独立的CSS文件。这样可以使样式更容易管理,并且减少了CSS文件的大小。
- 工具类(Mixins) :Mixins是可以被复用的CSS规则,用于为模块添加主题、样式或功能。它们可以组合在一起,并在不同的模块中重用。
- 深度优先:SMACSS鼓励开发者使用深度优先规则,即在同一深度级别内,越具体的类名越前面展示。这有助于避免冲突,并提高CSS的可读性。
- 目的className:SMACSS推荐为每个类名提供一个明确的描述,即目的className,这样有助于理解该类名的用途。
- Innateario:这是一个帮助开发者获取元素前缀(如:before、after或::before、::after)的工具类。
2、项目引入SMACSS的步骤
- 对整个页面进行模块化。
- 开始使用工具类(Mixins)来添加主题、样式或功能。
- 使用深度优先规则来避免样式冲突。
- 为每个类名提供一个明确的描述。
- 使用Innateario来获取元素前缀。
3、SMACSS的分类
SMACSS的核心是分类,具体将项目的样式分为五类:
- Base(基础) :定义了元素全局的默认样式。
- Layout(布局) :处理页面结构和布局。
- Module(模块) :包含页面中可复用的组件或元素。
- State(状态) :定义元素在不同状态下的样式(如:hover、active等)。
- Theme(主题) :允许开发者为项目定义多个主题。
4、SMACSS的优势
- 可读性和可维护性:由于SMACSS鼓励使用深度优先规则和目的className,样式文件变得更加可读和可维护。
- 可扩展性:由于SMACSS的模块化和工具类,样式文件可以轻松地增加或修改模块,这使得项目可以在未来扩展得更加容易。
- 性能:由于SMACSS的模块化和深度优先规则,样式文件的大小变得更加小巧,这可以提高页面加载速度。
5、示例
以下是一个使用SMACSS的例子,来展示其如何组织和管理CSS代码。
1. Base(基础)
Base规则里一般放置默认样式。这些默认样式基本上都是元素选择器,也可以包含属性选择器、伪类选择器、孩子选择器和兄弟选择器。
示例:
/* 重置浏览器默认样式 */
body, h1, h2, h3, p, ul, ol, li {
margin: 0;
padding: 0;
}
/* 设置基础字体样式 */
body {
font-family: Arial, sans-serif;
color: #333;
}
2. Layout(布局)
Layout规则定义了页面的整体布局结构。
示例:
/* 定义页眉样式 */
.header {
background-color: #f8f9fa;
padding: 20px;
}
/* 定义页脚样式 */
.footer {
background-color: #343a40;
color: #fff;
padding: 20px;
text-align: center;
}
3. Module(模块)
Module规则定义了可复用的组件样式。
示例:
/* 定义一个卡片模块 */
.card {
border: 1px solid #ccc;
border-radius: 5px;
padding: 15px;
margin-bottom: 10px;
}
/* 卡片模块中的标题 */
.card__title {
font-size: 18px;
margin-bottom: 10px;
}
/* 卡片模块中的描述 */
.card__description {
font-size: 14px;
color: #6c757d;
}
4. State(状态)
State规则定义了组件在不同状态下的样式。
示例:
/* 定义一个激活状态的按钮 */
.btn--active {
background-color: #007bff;
color: #fff;
}
/* 定义一个禁用状态的按钮 */
.btn--disabled {
background-color: #6c757d;
color: #fff;
cursor: not-allowed;
}
5. Theme(主题)
Theme规则定义了整个应用或页面的主题样式。
示例:
/* 定义一个暗色主题 */
.theme--dark {
background-color: #343a40;
color: #fff;
}
/* 在暗色主题下,修改卡片模块的样式 */
.theme--dark .card {
border-color: #6c757d;
background-color: #495057;
}
总结
通过使用SMACSS,我们可以将CSS代码分解成多个可复用的模块,并按照Base、Layout、Module、State和Theme这五个部分进行组织。这样的架构方法使得CSS代码更加模块化、结构化和可维护,同时也提高了代码的可扩展性和复用性。
6、注意事项
虽然SMACSS带来了许多优势,但也可能存在学习曲线较陡、增加代码复杂性(特别是在项目较小或简单的情况下)以及可能导致过度设计的问题。因此,在使用SMACSS时,需要根据项目的具体需求和团队的实际情况进行权衡和选择。
四、ITCSS
1、核心概念
ITCSS (Inverted Triangle CSS Architecture) 是一种 CSS 架构或方法论,旨在帮助开发者更有效地组织和管理他们的 CSS 代码。这个架构强调代码的可维护性、可扩展性和可重用性。
ITCSS 的基本思想是:将 CSS 规则按照特定的优先级和重要性进行分层,确保每个层级的规则都能在其预期的范围内应用,而不会对其他层级的规则造成干扰。
2、层级结构
以下是 ITCSS 的基本层级结构(从高到低优先级):
- Settings(设置) :全局变量、配置开关等。
- Tools(工具) :CSS 函数、mixin、helpers 等。
- Generic(通用) :重置和盒模型等全局默认样式。
- Base(基础) :HTML 元素的默认样式,如
<body>,<p>,<a>等。 - Objects(对象) :无类名的、可重用的设计模式,如布局、网格等。
- Components(组件) :具体的界面元素,如按钮、表单、卡片等。
- Trumps(盖帽) :覆盖其他所有层级的规则,如
.is-hidden、.u-text-center等。
这个结构的好处是:
- 清晰的组织:每个层级的规则都有明确的作用域和优先级,使得代码更加清晰易懂。
- 可维护性:由于每个层级的规则都是独立的,因此可以很容易地对它们进行修改、添加或删除。
- 可扩展性:新的规则可以很容易地添加到适当的层级中,而不会影响其他层级的规则。
- 可重用性:对象和组件可以在整个项目中重复使用,减少了代码的冗余。
3、示例
在项目中使用ITCSS架构时,可以遵循其分层结构来组织和管理CSS代码。以下是一个示例,展示了如何在项目中应用ITCSS的层级结构:
1. Settings(设置)
-
作用:定义全局变量、配置开关等。
-
示例:
/* settings.css */ :root { --main-color: #333; --secondary-color: #fff; --font-stack: Helvetica, sans-serif; }
2. Tools(工具)
-
作用:包含CSS函数、mixin、helpers等。
-
示例:
/* tools.css */ @mixin clearfix { &::after { content: ""; display: table; clear: both; } }
3. Generic(通用)
-
作用:全局默认样式,如CSS重置。
-
示例:
/* generic.css */ *, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
4. Base(基础)
-
作用:HTML元素的默认样式。
-
示例:
/* base.css */ body { font-family: var(--font-stack); color: var(--main-color); background-color: var(--secondary-color); } h1, h2, h3 { /* ... */ } p { /* ... */ }
5. Objects(对象)
-
作用:无类名的、可重用的设计模式。
-
示例:
/* objects.css */ .grid { display: flex; flex-wrap: wrap; } .grid__item { flex: 1 0 200px; }
6. Components(组件)
-
作用:具体的界面元素。
-
示例:
/* components/button.css */ .button { display: inline-block; padding: 10px 20px; background-color: var(--main-color); color: var(--secondary-color); border: none; border-radius: 4px; @include clearfix; /* 使用之前定义的mixin */ } .button--primary { background-color: var(--some-other-color); }
7. Trumps(盖帽)
-
作用:覆盖其他所有层级的规则。
-
示例:
/* trumps.css */ .hide { display: none !important; } .text-center { text-align: center !important; }
总结
- 在项目中,确保按照ITCSS的层级结构来组织CSS文件。
- 每个层级的CSS文件都应只包含该层级特定的规则。
- 通过使用预处理器(如Sass)的
@import功能,可以按照正确的顺序导入这些文件。 - 这种结构有助于保持代码的清晰、可维护和可扩展。
请注意,这个示例仅用于说明目的,并且可能需要根据具体项目的需求进行调整。
五、ACSS
ACSS (Atomic CSS) 是一种 CSS 架构或方法论,它强调将 CSS 规则分解为尽可能小的、可重用的、独立的单元(通常被称为“原子”),然后通过类名组合这些单元来构建复杂的界面样式。ACSS 的主要目标是减少 CSS 的复杂性和冗余,提高样式的可重用性和可维护性。
1、ACSS 的特点
- 原子化:CSS 规则被分解为最小的、可重用的单元。
- 组合性:通过组合多个原子类来构建复杂的样式。
- 可重用性:原子类可以在整个项目中重复使用,减少了样式的冗余。
- 可维护性:由于每个原子类都是独立的,因此可以更容易地修改、添加或删除它们。
2、ACSS 的使用示例
假设你有一个 ACSS 系统,其中包含以下原子类:
/* Atomic CSS classes */
.padding-xs { padding: 4px; }
.padding-sm { padding: 8px; }
.padding-md { padding: 16px; }
.bg-red { background-color: red; }
.text-center { text-align: center; }
.font-bold { font-weight: bold; }
然后,你可以通过组合这些原子类来创建一个按钮的样式:
<button class="padding-md bg-red text-center font-bold">Click Me!</button>
在这个例子中,按钮有中等内边距(padding-md)、红色背景(bg-red)、文本居中对齐(text-center)和粗体文本(font-bold)。这些样式都是通过组合原子类来实现的,而不是在一个单独的、复杂的 CSS 规则中定义的。
3、ACSS 的优缺点
优点:
- 易于维护:由于每个样式都是独立的,因此可以更容易地修改和扩展它们。
- 可重用性高:原子类可以在整个项目中重复使用,减少了代码的冗余。
- 灵活性:通过组合不同的原子类,可以轻松地创建复杂的样式。
缺点:
- HTML 标记变得冗长:由于需要添加多个类名来实现一个复杂的样式,HTML 标记可能会变得冗长和难以阅读。
- 可能增加选择器的复杂性:如果过度使用 ACSS,可能会导致选择器的复杂性增加,从而影响性能。
- 需要谨慎设计原子类:需要仔细设计原子类,以确保它们足够通用且可重用,同时避免创建太多冗余的类。
4、总结
ACSS 是一种将 CSS 规则分解为最小、可重用单元的 CSS 架构。它强调通过组合原子类来构建复杂的样式,从而提高样式的可重用性和可维护性。然而,使用 ACSS 时需要谨慎设计原子类,并注意 HTML 标记的冗长性和选择器的复杂性。
总结
个人简单总结:
- BEM更加侧重于通过规则的命名约定去编写样式。
- OOCSS更侧重于分离的概念:结构和皮肤分离,容器和内容分离
- SMACSS和ITCSS更注重从文件的角度去进行分离css
- ACSS则是最小原子的概念去组合css