不会真有人不知道 BEM 规范?

您所在的位置:网站首页 css命名规范bem 不会真有人不知道 BEM 规范?

不会真有人不知道 BEM 规范?

2023-08-07 03:20| 来源: 网络整理| 查看: 265

小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。

本文同时参与 「掘力星计划」  ,赢取创作大礼包,挑战创作激励金

背景

传统写 css 类名是这么写:

.container .form .input .warpper .icon { /*写入你需要的css*/ } .container .form .text { /*写入你需要的css*/ } .page .warpper .layout .content{ /*写入你需要的css*/ } 复制代码

上面这种存在以下问题:

维护css的时候,只看HTML,我们无法知道当前css的作用范围,css的表现不够一目了然 如果我要覆盖css的样式,可能我就需要利用css的优先级的规则去覆盖原有的css,这样就会导致css优先级竞争 css编写的时候复用性不高,当存在多个样式一致的时候,我们可能会选择减少命名空间的方式来提升当前css的作用范围,但是可能会导致css样式冲突的问题 BEM B - block,表示1个块 E - element,表示1个元素 M - modifier,表示块或元素的修饰符 如下,对于 navbar 组件的划分:

image.png

整个navbar组件为1个block,类名定为 .navbar,左右侧、中间标题是 element,类名定为 .navbar__left, .navbar__right, .navbar__title,如果 navbar 可以设置为深色模式,则在 .navbar 上再加个 .navbar--dark,这个类名为 modifier。

BEM 的类名写法有 .b .b__e .b__e–m .b–m 这四种写法。 BEM写法好处 class 的样式层级只有1层,方便用高优先级的样式轻松覆盖原来的样式 通过块、元素、修饰符去定义一个块,类似于组件的拆解设计,容易知道某个类名是作用域哪个地方 SCSS 实现 BEM 类名自动生成

通过使用 SCSS 的 mixin 语法,可以让其自动生成 BEM 类名。

_config.scss

/** * SCSS 配置项:命名空间以及BEM */ $namespace: 'wd'; // 前缀命名空间可以修改,根据自己需要来 $elementSeparator: '__'; $modifierSeparator: '--'; $state-prefix: 'is-'; 复制代码

_function.scss

/** * 辅助函数 */ @import 'config'; /* 转换成字符串 */ @function selectorToString($selector) { $selector: inspect($selector); $selector: str-slice($selector, 2, -2); @return $selector; } /* 判断是否存在 Modifier */ @function containsModifier($selector) { $selector: selectorToString($selector); @if str-index($selector, $modifierSeparator) { @return true; } @else { @return false; } } /* 判断是否存在伪类 */ @function containsPseudo($selector) { $selector: selectorToString($selector); @if str-index($selector, ':') { @return true; } @else { @return false; } } 复制代码

_mixin.scss

/** * 混合宏 */ @import 'config'; @import 'function'; /** * BEM */ @mixin b($block) { $B: $namespace + '-' + $block !global; .#{$B} { @content; } } /* 对于伪类,会自动将 e 嵌套在 伪类 底下 */ @mixin e($element...) { $selector: &; $selectors: ''; @if containsPseudo($selector) { @each $item in $element { $selectors: #{$selectors + '.' + $B + $elementSeparator + $item + ','}; } @at-root { #{$selector} { #{$selectors} { @content; } } } } @else { @each $item in $element { $selectors: #{$selectors + $selector + $elementSeparator + $item + ','}; } @at-root { #{$selectors} { @content; } } } } @mixin m($modifier...) { $selectors: ''; @each $item in $modifier { $selectors: #{$selectors + & + $modifierSeparator + $item + ','}; } @at-root { #{$selectors} { @content; } } } /* 对于需要需要嵌套在 m 底下的 e,调用这个混合宏,一般在切换整个组件的状态,如切换颜色的时候 */ @mixin me($element...) { $selector: &; $selectors: ''; @if containsModifier($selector) { @each $item in $element { $selectors: #{$selectors + '.' + $B + $elementSeparator + $item + ','}; } @at-root { #{$selector} { #{$selectors} { @content; } } } } @else { @each $item in $element { $selectors: #{$selectors + $selector + $elementSeparator + $item + ','}; } @at-root { #{$selectors} { @content; } } } } /* 状态 */ @mixin when($state) { @at-root { &.#{$state-prefix + $state} { @content; } } } /** * 常用混合宏 */ /* 单行超出隐藏 */ @mixin lineEllipsis { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } /* 多行超出隐藏 */ @mixin multiEllipsis($lineNumber: 3) { display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: $lineNumber; overflow: hidden; } /* 清除浮动 */ @mixin clearFloat { &::after { display: block; content: ''; height: 0; clear: both; overflow: hidden; visibility: hidden; } } /* 0.5px 边框 */ @mixin halfPixelBorder($direction: 'bottom', $left: 0) { &::after { position: absolute; display: block; content: ''; width: 100%; height: 1px; left: $left; @if ($direction == 'bottom') { bottom: 0; } @else { top: 0; } transform: scaleY(0.5); background: $-color-border-light; } } @mixin buttonClear { outline: none; -webkit-appearance: none; -webkit-tap-highlight-color: transparent; background: transparent; } 复制代码

scss import 支持忽略文件名前面的 _ 以及后缀名

使用:

@include b(navbar) { /* 样式 */ @include m(dark) { /* 样式 */ /* 该修饰符下元素的样式,不支持再嵌套,只能写类名全名 .wd-navbar__left {} .wd-navbar__right {} } @include e(left) { /* 样式 */ &::before { /* 支持直接写伪元素和伪类 */ } } @include e(right) { /* 样式 */ /* 支持另一种修饰写法,生成 .wd-navbar__right.is-icon */ @include when(icon) { /* 样式 */ } } } 复制代码

上面的代码最后生成css如下:

.wd-navbar {} .wd-navbar--dark {} .wd-navbar--dark .wd-navbar__left {} .wd-navbar--dark .wd-navbar__right {} .wd-navbar__left {} .wd-navbar__left::before {} .wd-navbar__right {} .wd-navbar__right.is-icon {} 复制代码

点赞支持、手留余香、与有荣焉,动动你发财的小手哟,感谢各位大佬能留下您的足迹。

11.png

往期精彩推荐

前端如何做国际化

React 开发规范

Vue 开发规范

移动端横竖屏适配与刘海适配

移动端常见问题汇总

前端常用的几种加密方法

不懂 seo 优化?一篇文章帮你了解如何去做 seo 优化

【实战篇】微信小程序开发指南和优化实践

聊一聊移动端适配

前端性能优化实战

聊聊让人头疼的正则表达式

获取文件blob流地址实现下载功能

Vue 虚拟 DOM 搞不懂?这篇文章帮你彻底搞定虚拟 DOM

Git 相关推荐

通俗易懂的 Git 入门

git 实现自动推送

面试相关推荐

前端万字面经——基础篇

前端万字面积——进阶篇

更多精彩详见:个人主页



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3