内容简介:上面这样写样式有很大的问题,主要是我们在样式书写时默认的继承到了之前的样式,但在特殊化的样式时,为了让自己的样式生效,又要新写样式进行覆盖。所以列举一下可能的问题是下面的:在之前的章节中,我们讲到了css不同的模块化方案,那么对于上面描述的问题,其实可以很简化的去解决。
h2{ } #sidebar h2{ background:red; } #sidebar .calendar h2{ background:green; } 复制代码
上面这样写样式有很大的问题,主要是我们在样式书写时默认的继承到了之前的样式,但在特殊化的样式时,为了让自己的样式生效,又要新写样式进行覆盖。
所以列举一下可能的问题是下面的:
- 选择器的优先级:选择合适的优先级,查询效率高,方便其他人样式覆盖的需求
- 颜色重置:要恢复到原来的颜色,需要进行不断的重置或者赋值
- 位置依赖:如果我们的样式移到其他位置,那么样式代码就会失效,因为严格依赖dom的结构和顺序,不能很好的解耦
- 多重继承:最终元素的样式可能是层层嵌套得到的最终样式代码,非常不可复用,当改变主体的样式时,子元素都会受到影响
- 深层嵌套:效率非常低
现代化的模块方案
在之前的章节中,我们讲到了css不同的模块化方案,那么对于上面描述的问题,其实可以很简化的去解决。
案例代码
你根据以上的需求按照模块的方案和命名,去除各种依赖,最大程度使用class命名方式,减少继承,更大程度的使用独立样式代码块,轻松解决了以上的问题。
<h2 class="content_title"></h2> <div class="sidebar"> <h2 class="content_title--reversed"></h2> <div class="calendar"> <h2 class="calendar_title"></h2> </div> </div> 复制代码
// 组件文件夹 .content_title{} // 不用恢复重置样式 .contitle_title--reverse{} // 特殊组件的title定义 .calendar_title{ } 复制代码
单一职责原则
比如我们在定义标题的时候,可能有两个模块都用到了标题。
<div class="calendar"> <h2 class="primary-title"></h2> </div> <div class="blog"> <h2 class="primary-title"></h2> </div> <style> .primary-title{ } </style> 复制代码
可能的问题,是我们需要在日历或者博客的时候需要去修改这个样式,于是你的样式可能变成这样的。
.primary-title{ } .blog .primary-title{} 复制代码
这样的问题是会导致选择器过多,于是我们按照bem进一步优化。
.calendar_header{} .blog_header{} 复制代码
这样维护之后,每个样式块都只负责自己的内容,除了导致代码的重复之外没有任何坏处。好处是如果项目严格执行单一职责方式,当我们改动任何代码的时候,不会担心对全局造成的影响。那么重复的代码怎么解决,这个其实webpack的部分和gzip的部分已经能把我们的代码进行优化了。
延伸思考:如果压缩打包的角度可以去掉重复代码的部分,那么更多角度考虑代码的可持续、可维护就好了。
单一样式来源
简单来讲,就是你的样式代码应该来源于尽可能少的组件,最好是维护在一个class中,保证整个样式代码是可追溯的,也可以预想效果的。
案例
<div class="blog"> <div class="blog-header"></div> </div> <div class="calendar"> <div class="calendar-header"></div> </div> 复制代码
/* calendar css*/ .calendar-header{ } /* blog css*/ .blog-header{ } .blog .blog-header{} 复制代码
以blog进行title的限定,主要是限制让字号小一点,这种的主要问题是当项目积累下来,会有很多样式代码散落在各个组件,这样导致不可追溯。(补充个常识,以父元素为什么进行修饰子元素,这个称为样式上下文)
那么建议的方式是将散落在各处的代码完全控制在一个组件内。
组件修饰符
虽然单一组件的原则让我们对组件的样式代码封装的很好,但还是有一些特殊的需求,那我们如何设计这方面的代码呢?通过皮肤或者子模块来实现,也可以称为组件修饰符。
比如我们针对日历的组件,我们需要追加一个特殊的样式,可以这样实现。
.calendar-header{ } .calendar--nested .calendar-header{ } 复制代码
通过这样的方式,我们不但可以实现皮肤的需求,也可以实现对上下文的解耦,我们只要关注组件需要什么样的特殊样式,进行组件修饰即可,而不用依赖耦合在父容器里。
element-ui的css
以下以element的2.4.11版本为例,根据其api文档以及源码的角度为大家分析element-ui是如何解决这些问题的。
el-button分析
-
api设计规范:可以看到button的暴露的api主要是基于属性的
参数 说明 类型 可选值 默认值 size 尺寸 string medium / small / mini — type 类型 string primary / success / warning / danger / info / text — plain 是否朴素按钮 boolean — false round 是否圆角按钮 boolean — false circle 是否圆形按钮 boolean — false loading 是否加载中状态 boolean — false disabled 是否禁用状态 boolean — false icon 图标类名 string — — autofocus 是否默认聚焦 boolean — false native-type 原生 type 属性 string button / submit / reset button -
class的设计,虽然组件的设计是基于属性的,但实际不同的属性最终都是表现为class的。那么基于这样的角度去设计样式是element-ui的首创或者是vue组件的创新么?其实早在bootstrap里就是这样设计的。
class 说明 el-button-group 按钮组的样式,作为外部容器,不对el-button产生任何样式代码,但对其内含有的el-button会产生垂直居中的效果,还有向右的间距, .el-button-group .el-button--primary:first-child{}
el-button el-button--default 基本样式,修饰符,生效规则el-button--default也是直接定义其样式规则,不依赖于el-button el-button el-button--medium el-button--medium 修饰符中直接定义好尺寸的全部代码 el-button el-button--default is-circle 基本样式,smacss状态样式 ,其中is-circle包含这个原型的全部样式,其生效的条件是与el-button同时生效,is-disabled同理 icon="el-icon-edit" 带icon的部分不在button里做特殊样式,其样式属于基本样式,但是dom结构是通过组件进行添加的,那么其图标的字号来源于哪里呢?来源于el-button的基本样式14px,所以这部分进行了解耦,不用单独设置 -
组件内如何根据属性进行返回对应的class.
class="el-button" // 可以看到其根据传入的各个type属性分别将class追加到class数组之中 :class="[type ? 'el-button--' + type : '',buttonSize ? 'el-button--' + buttonSize : '',{'is-disabled': buttonDisabled,'is-loading': loading,'is-plain': plain,'is-round': round,'is-circle': circle}]" //根据为loading 显示出固定的loading图标 <i class="el-icon-loading" v-if="loading"></i> // 根据传入的icon以及没有loading显示出对应type的icon <i :class="icon" v-if="icon && !loading"></i> 复制代码
轻度定制的element
经常有场景我们需要引入element-ui之后需要对其ui进行皮肤化的开发样式,虽然element-ui有暴露其对应的组件样式,我们也可以进行对应的详细的源码的fork并开发,但在大多数中小公司其实不用小题大做。我们只需要根据自己的情况,针对一样的样式进行全局样式覆盖即可。那么,我们项目中针对按钮的皮肤化改变会是这样的。
// 定义variables.scss的主题变量 // 主题色相关变量 $color-thin:rgba(60,191,196,0.1); $color:rgba(60,191,196,1); // customer-element.scss 主要定义已使用饿了么组件样式的修改 @import './variables'; // 一个按钮样式的全局覆盖 .el-button--primary{ &:hover,&:focus{ background:$color; border-color:$color; } background:$color; border-color:$color; } 复制代码
bootstrap的css
我们同样也是分析bootstrap里的样式使用,基本也是使用class拼盘理论的。
<div class="btn-group" role="group" aria-label="..."> <button type="button" class="btn btn-default">Left</button> <button type="button" class="btn btn-default">Middle</button> <button type="button" class="btn btn-default">Right</button> </div> 复制代码
button.less样式文件节选,可以看到其基本样式、嵌套内伪类的样式,button-size的方法类,修饰符的(子模块的)维护方式,这都是值得我们借鉴的科学规范思想。
// Base styles // -------------------------------------------------- .btn { display: inline-block; ...... .button-size(@padding-base-vertical; @padding-base-horizontal; @font-size-base; @line-height-base; @btn-border-radius-base); .user-select(none); &, &:active, &.active { &:focus, &.focus { .tab-focus(); } } &:hover, &:focus, &.focus { color: @btn-default-color; text-decoration: none; } a& { &.disabled, fieldset[disabled] & { pointer-events: none; // Future-proof disabling of clicks on `<a>` elements } } } // Alternate buttons // -------------------------------------------------- .btn-default { .button-variant(@btn-default-color; @btn-default-bg; @btn-default-border); } .btn-primary { .button-variant(@btn-primary-color; @btn-primary-bg; @btn-primary-border); } 复制代码
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- 微服务公用代码组织实践
- Go包-代码组织者
- [译] 微服务架构下 Go 包的代码组织实践
- 污水 (MuddyWater) APT组织新武器MuddyC3代码泄露分析
- APT组织污水(MuddyWater)新武器MuddyC3代码泄露与分析
- 伊朗APT组织的网络间谍工具源代码和攻击者被泄露和曝光
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
淘宝天猫店是如何运营的
贾真 / 电子工业出版社 / 2017-5 / 49.8
《淘宝天猫店是如何运营的——网店从0到千万实操手册》是由天猫行业Top10卖家、电商圈知名讲师贾真写就的一本运营干货书籍。《淘宝天猫店是如何运营的——网店从0到千万实操手册》的最大卖点就是作者把自己运营店铺的经验系统地总结出来,把碎片化的“干货”形成一个系统的知识体系。句句易懂,读后受益! 现在网上能看到的电商经验,大多是碎片化知识,零散不成体系,其实很难系统地给卖家提供帮助。《淘宝天猫店是......一起来看看 《淘宝天猫店是如何运营的》 这本书的介绍吧!