咱们看一下CSS是怎么规范的:使用有意义的或通用的ID和class命名。ID和class的命名应反映该元素的功能或使用通用名称,而不要用抽象的晦涩的命名。反映元素的使用目的是首选;使用通用名称表明该元素不表特定意义,与其同级元素无异,一般是用于辅助命名;使用功能性或通用的名称能够更适用于文档或模版变化的状况。css
经常使用命名(多记多查英文单词):page、wrap、layout、header(head)、footer(foot、ft)、 content(cont)、menu、nav、main、submain、sidebar(side)、logo、banner、 title(tit)、popo(pop)、icon、note、btn、txt、iblock、window(win)、tips等前端
注:类型选择器避免同时使用标签、ID和class做为定位一个元素选择器;从性能上考虑也应尽可能减小选择器的层级。vue
你们都说CSS学和写都简单,那么写了多年CSS的同窗是否有静下来思考过,本身写CSS是有较为系统的和具备必定规范的,而不是草率的写CSS。另外就是本身写的CSS在团队中,别的同窗是否能看到代码就知道您写的是什么?若是没有,那不仿看看这里提到的一些概念与思想,好比:Sass 、SCSS、LESS、BEM、OOCSS、AMCSS等。让咱们一块儿来深刻了解css吧?webpack
首先了解一下BEM(我我的比较喜欢的)程序员
BEM的意思就是块(block)、元素(element)、修饰符(modifier),是由Yandex团队提出的一种前端命名方法论。这种巧妙的命名方法让你的CSS类对其余开发者来讲更加透明并且更有意义。BEM命名约定更加严格,并且包含更多的信息,它们用于一个团队开发一个耗时的大项目。web
命名约定的模式以下:chrome
.block{} // 块便是一般所说的 Web 应用开发中的组件或模块。每一个块在逻辑上和功能上都是相互独立的。
小程序
.block__element{} // 元素是块中的组成部分。元素不能离开块来使用。BEM 不推荐在元素中嵌套其余元素。
浏览器
.block--modifier{} // 修饰符用来定义块或元素的外观和行为。一样的块在应用不一样的修饰符以后,会有不一样的外观。
框架
BEM不是一个框架,它只是一种思想
优势:BEM 的优势在于所产生的 CSS 类名都只使用一个类别选择器,能够避免传统作法中因为多个类别选择器嵌套带来的复杂的属性级联问题。在 BEM 命名规则中,全部的 CSS 样式规则都只用一个类别选择器。所以全部样式规则的特异性(specificity)都是相同的,也就不存在复杂的优先级问题。这能够简化属性值的层叠规则。代码清单中的命名规则的好处在于每一个 CSS 类名都很简单明了,并且类名的层次关系能够与 DOM 节点的树型结构相对应。 缺点: CSS 类名会比较长并且复杂。乍看之下,根据 BEM 命名规则产生的 CSS 类名都会很复杂,但实际上在熟悉了命名规则以后,能够很容易理解其含义。
咱们再看一下OOCSS(面向对象CSS)
OOCSS 表示的是面向对象 CSS(Object Oriented CSS),是一种把面向对象方法学应用到 CSS 代码组织和管理中的实践。 OOCSS最关键的一点就是:提升他的灵活性和可重用性。这个也是OOCSS最重要的一点。OOCSS主张是经过在基础组件中添加更多的类,从而扩展基础组件的CSS规则,从而使CSS有更好的扩展性。
咱们有一个容器是页面page的1/4宽,有一个蓝色的背景,1px灰色的边框,10px的左右边距,5px的上边距,10px的下边距,之前对于这样一个样式,咱们经常给这个容器建立一个类,并把这些样式所有加上。像下面这样。
1 // template 2 3 <div class="size1of4"></div> 4 5 // style 6 7 .size1of4 { 8 9 background: blue; 10 11 border: 1px solid #ccc; 12 13 margin: 5px 10px 10px; 14 15 width: 25%; 16 17 }
然而使用oocss的话,咱们不这样作,我把为这个容器建立更多的类,而且每一个样式对应一个类,这样是为了后面能够重复使用这些组件的样式,避免重复写相同的样式,就拿这个实例来讲,咱们给这个容器增长下面的类:bgBlue,solidGray,mts,mlm,mrm,mbm
1 // template 2 3 <div class="size1of4 bgBlue solidGray mts mlm mrm mbm"></div> 4 5 // style 6 7 .size1of4 {width: 25%;} 8 9 .bgBlue {background:blue} 10 11 .solidGray {border: 1px solid #ccc} 12 13 .mts {margin-top: 5px} 14 15 .mrm {margin-right: 10px} 16 17 .mbm {margin-bottom: 10px} 18 19 .mlm {margin-left: 10px}
OOCSS的优势
减小CSS代码。
具备清洁的HTML标记,有语义的类名,逻辑性强的层次关系。
语义标记,有助于SEO。
更好的页面优化,更快的加载时间(由于有不少组件重用)。
可扩展的标记和CSS样式,有更多的组件能够放到库中,而不影响其余的组件。
能轻松构造新的页面布局,或制做新的页面风格。
OOCSS的缺点
OOCSS适合真正的大型网站开发,由于大型网站用到的可重用性组件特别的多,若是运用在小型项目中可能见不到什么成效。因此用不用OOCSS应该根据你的项目来决定。
若是没用巧妙的使用,建立组件可能对于你来讲是一堆没用的东西,成为一烂摊子,给你的维护带来意想不到的杯具,说不定仍是个维护的噩梦。
最好给每个组件备写一份说明文档,有助于调用与维护。
AMCSS(属性模块)。
属性模块或者说AM,其核心就是关于定义命名空间用来写样式。通俗的讲就是,给一个元素加上属性,再经过属性选择器定位到这个元素。达到避免过多的使用class。
1 // template 2 3 <div am- Row ></div> 4 5 <div am- Column = "12"> Full < /div> 6 7 </ div> <div am- Row > <div am- Column = "4"> Thirds </div> 8 9 <div am- Column = "4"> Thirds </div> 10 11 <div am- Column = "4"> Thirds < /div> </ div> 12 13 // style 14 15 [am- Row ] { /* max-width, clearfixes */ } 16 17 [am- Column ~= "1" ] { /* 1/12th width, floated */ } 18 19 [am- Column ~= "2" ] { /* 1/6th width, floated */ } 20 21 [am- Column ~= "3" ] { /* 1/4th width, floated */ } 22 23 [am- Column ~= "4" ] { /* 1/3rd width, floated */ } 24 25 [am- Column ~= "5" ] { /* 5/12th width, floated */ } /* etc */ 26 27 [am- Column ~= "12" ] { /* 100% width, floated */ }
你会注意到第一件事情就是有am-前缀。这也是AM核心部分,确保属性模块不会与现有属性冲突。你可使用你本身喜欢的任何前缀名,我常使用的是ui-、css-或者其余前缀,但这些示例中使用的是am-前缀。HTML的有效性对你或你的项目来讲是很是重要,就相似于使用data-前缀开头定义的属性相似。 你可能会注意到的第二件事情就是相似于一、4或12这样的值,使用类名变得极为麻烦——形成冲突的机会不少。但定义了咱们本身的命名空间,实际上将空间变得很小,用于工做中不会形成冲突。为了更好的工做,能够自由选择最简明并且有意义的标记。
咱们虽然有这么多的好的方案去解决css的一些难题,可是有没有一种东西或者工具来代替咱们去作这些呢,做为一个程序员咱们不喜欢作太麻烦的事情。那么接下来咱们谈一谈css的构建工具
With :local (without brackets) local mode can be switched on for this selector. :global(.className) can be used to declare an explicit global selector. With :global (without brackets) global mode can be switched on for this selector. webpack会把class分为两种,一种是local(本地的),一种是global(全局的)。默认导出的都是本地的,可是你能够经过 :global(...)开关来控制导出全局。下面咱们看一下栗子。
1 // 输入 2 3 : local (.className) { background: red; } 4 5 : local .className { color: green; } 6 7 : local (.className .subClass) { color: green; } 8 9 : local .className .subClass : global (. global - class -name) { color: blue; } 10 11 // 导出 12 13 ._23_aKvs-b8bW2Vg3fwHozO { background: red; } 14 15 ._23_aKvs-b8bW2Vg3fwHozO { color: green; } 16 17 ._23_aKvs-b8bW2Vg3fwHozO ._13LGdX8RMStbBE9w-t0gZ1 { color: green; } 18 19 ._23_aKvs-b8bW2Vg3fwHozO ._13LGdX8RMStbBE9w-t0gZ1 . global - class -name { color: blue; }
:local(className)被编译为惟一可识别的标示,:global(className)原样输出,固然咱们也能够控制导出的格式。配置以下:
1 { 2 3 test: /\.css$/ , 4 5 use : [ 6 7 { 8 9 loader: 'css-loader', 10 11 options: { 12 13 modules: true , 14 15 localIdentName: '[path][name]__[local]--[hash:base64:5]' 16 17 } 18 19 } 20 21 ] 22 23 }
如今在各类框架中都会有scoped属性,使咱们的css具备模块化性质,不会污染到其余模块,那么scoped是如何实现的呢?咱们一块儿来揭开它神秘的面纱吧?
若是你是一个勤奋好学的同窗,你必定会发如今HTML的style标签中有一个scoped属性。让咱们来一块儿看一下这个属性的神奇吧。
一直以来,文档上的STYLE元素一般都是做用域全局的,选择器按照全局的CSS优先规则来设置的。要实现局部的选择须要先选到容器元素,再用后代选择器来实现。scoped属性可让STYLE元素再也不做用于全局,而从当前STYLE元素所在的容器开始选择后代。
1 <div> 2 3 <style scoped > 4 5 span {color:red;} 6 7 </style> 8 9 <span> 我是第1个DIV内的SPAN </span> 10 11 </div> 12 13 <div> 14 15 <style scoped > 16 17 span {color:green;} 18 19 </style> 20 21 <span> 我是第2个DIV内的SPAN </span> 22 23 </div> 24 25 <div> 26 27 <span> 我是第3个DIV内的SPAN </span> 28 29 </div>
结果:
咱们能够看见第三个div并无被第一及第二个style所感染,也就是说带有scoped属性的css是一个独立的做用域,不会影响到其它模块!!太好了,那咱们之后在style里面加上scoped属性就能够完美解决啦慢!BUT,这种方法只有在火狐浏览器才生效,其它浏览器即便最新的chrome浏览器也不支持哦。我@#¥%……
不要急年轻人,咱们来看一下vue的代码,当咱们在style中加了scoped属性后
咦,这不就是咱们刚刚讲过的AMCSS(属性模块)的应用吗?也就是说vue在编译的时候,把带有scoped属性的的模块,加上了一个惟一的属性,而后经过类名+属性选择器的方法来实现模块化!
其实其余框架也是用的相似的方法,咱们再看一下,小程序wepy框架的实现吧?
这个是咱们刚才讲过OOCSS(面对对象CSS)!!
对的,这样结合框架来说是否是可以更能深入理解咱们刚才讲过的内容了啊?
有时候咱们须要把一些有用的常见的css放到一个common.css里面,可是当咱们项目足够大的时候,common的内容就会变得异常庞大,并且难以维护。
首先咱们不得不说一下当下有几个比较火的CSS预处理器,Less、Sass 、Stylus和postCss,这是一个CSS史上的巨大飞跃。他主要提供了如下功能
嵌套语法
变量
@import
混入
继承
函数
逻辑控制
了解了css预处理器,那么咱们如何优化咱们的common.css呢?
要想解决这个问题,咱们首先来看一看LESS中的mixin是如何运做的。
1 // 你能够混合“类”选择器或者“id”选择器,例如: 2 3 .a, #b { 4 5 color: red; 6 7 } 8 9 .mixin-class 10 11 { 12 13 .a(); 14 15 } 16 17 .mixin-id { 18 19 #b(); 20 21 }
以上将获得:
1 .a, #b { 2 3 color: red; 4 5 } 6 7 .mixin-class 8 9 { 10 11 color: red; 12 13 } 14 15 .mixin-id { 16 17 color: red; 18 19 }
小提示:当你调用混合集的时候,括号可加可不加。
1 .a(); //这两种调用方式效果是同样的 2 3 .a;
若是你想要建立一个混合集,可是却不想让它输出到你的样式中,你能够在混合集的名字后面加上一个括号。
1 .my-mixin { 2 3 color: black; 4 5 } 6 7 .my-other-mixin() { 8 9 background: white; 10 11 } 12 13 .class { 14 15 .my-mixin; 16 17 .my-other-mixin; 18 19 }
输出:
1 .my-mixin { 2 3 color: black; 4 5 } 6 7 .class { 8 9 color: black; 10 11 background: white; 12 13 }
好了,咱们知道这个原理就能够用less中的mixins从新修改咱们的common.less了,并且不会显得很是臃肿,咱们能够按需加载咱们的样式了,是否是很棒啊
咱们的CSS模块化就讲到这里了,有什么意见或建议能够联系我哦!