1. CSS Reset
为什么需要 CSS Reset
浏览器对于各个 html 都赋予了默认的样式, 并且不同的浏览器默认的样式不同, 而通常我们的产品设计中样式都是不同于浏览器默认样式的, 所以我们在开发中经常要去覆盖默认的样式, 针对不同的浏览器需要写不同的覆盖代码确保兼容性.
image.PNG
如果一开始我们就清除掉浏览器默认的样式, 后面的开发就可以完全根据设计进行而不需要考虑浏览器默认样式的影响, 从而提高开发效率.
怎么做 CSS Reset
浏览器默认的样式定义在标签上, 所以 CSS Reset 里面也使用标签选择器来覆盖默认样式.
示例:
- HTML,body,h1,h2,h3,h4,h5,h6,div,dl,dt,dd,ul,ol,li,p,blockquote,pre,hr,figure,table,caption,th,td,form,fieldset,legend,input,button,textarea,menu{
- margin:0;padding:0;
- }
- header,footer,section,article,asidejnav,hgroup,address,figure,figcaption,menu,details{
- display:block;
- }
- table{
- border-collapse:collapse;border-spacing:0;
- }
- caption,th{
- text-align: left;font-weight: normal;
- }
- HTML,body,fieldset,img,iframe,abbr{
- border:0;
- }
- i,cite,em,var,address,dfn{
- font-style:normal;
- }
- [hidefocus],summary{
- outline:0;
- }
- li{
- list-style:none;
- }
- h1,h2,h3,h4,h5,h6,small{
- font-size:100%;
- }
- sup,sub{
- font-size:83%;
- }
- pre,code,kbd,Samp{
- font-family:inherit;
- }
- q:before,q:after{
- content: none;
- }
- textarea{
- overflow:auto;resize:none;
- }
- label,summary{
- cursor: default;
- }
- a,button{
- cursor:pointer;
- }
- h1,h2,h3,h4,h5,h6,em,strong,b{
- font-weight: normal;
- }
- del, ins,u,s,a,a:hover{
- text-decoration:none;
- }
- body,textarea,input,button,select,keygen,legend{
- font:12px/l.14 arial,simsun;color:#333;outline:0;
- }
- body{
- background: #fff;
- }
- a,a:hover{
- color:#333;
- }
- Tips
代码优化: 示例中将同一个标签的样式分布为几处, 这样可以节省代码
CSS reset 并不是统一一成不变的, 在实际项目中, 可以根据设计中的大部分相同样式可以在 reset 中定义好, 作为全局样式定义, 减少后续的样式重写
CSS reset 最好在项目初期就制定好, 后期再来修改会带来大的 UI 风险, 因为 reset 里面是一个全局样式
reset CSS 应该放在最前面引用
2. 页面布局解决方案
示例 HTML 代码
- <div class="parent">
- <div class="child">Hello Word</div>
- </div>
自适应宽度水平居中
inline-block + text-align 方案
CSS 代码:
- .parent{
- text-align: center;
- }
- .child{
- display: inline-block;
- }
原理: inline-block 使元素自适应内容宽度, text-align:center 设在块级元素中, 可以对里面的 inline 级别的元素起作用
缺点: text-align 属性会继承, 如果不希望子元素里面内容居中, 需要在子元素里面覆盖
table + margin 方案
CSS 代码:
- .child{
- display: table;
- margin: 0 auto;
- }
原理: table 本身是块级元素, 可以应用 margin, 默认宽度会根据内容自适应(与 div 不同之处)
absolute + transform 方案
CSS 代码:
- .parent{
- position: relative;
- }
- .child{
- position: absolute;
- left: 50%;
- transform: translateX(-50%);
- }
原理: absolute 会使元素宽度根据内容自适应, left 偏移量相对父元素, translate 偏移量相对自身
flex + justify-content 方案
CSS 代码:
- .parent{
- display: flex;
- justify-content: center;
- }
- .parent{
- display: flex;
- }
- .child{
- margin: 0 auto;
- }
只设置父元素 (代码片段 1) 或者同时设置子元素的 margin(代码片段 2), 都可以达到效果
原理: flex-item 默认使元素宽度自适应
自适应高度垂直居中
table-cell + vertical-align 方案
CSS 代码:
- .parent{
- display: table-cell;
- vertical-align: middle;
- }
原理: 利用 table 单元格的特性, 使内容垂直居中
absolute+transform 方案
CSS 代码:
- .parent{
- position: relative;
- }
- .child{
- position: absolute;
- top: 50%;
- transform: translateY(-50%);
- }
原理同水平居中
flex + align-items 方案
CSS 代码:
- .parent{
- display: flex;
- align-items: center;
- }
原理: 利用 flex 特性, 默认 align-items 是 strech, 会充满整个父元素, 设置为 center 就会居中
水平垂直都居中
结合水平, 垂直居中原理, 组合实现
inline-block + text-align + table-cell + vertical-align
CSS 代码:
- .parent{
- text-align: center;
- display: table-cell;
- vertical-align: middle;
- }
- .child{
- display: inline-block;
- }
- absolute + transform
CSS 代码:
- .parent{
- position: relative;
- }
- .child{
- position: absolute;
- left: 50%;
- top: 50%;
- transform: translate(-50%,-50%);
- }
- flex + justify-content + align-items
CSS 代码:
- .parent{
- display: flex;
- justify-content: center;
- align-items: center;
- }
多列布局
示例 HTML:
- <div class="parent">
- <div class="left">
- <p>Left</p>
- </div>
- <div class="right">
- <p>right</p>
- <p>right</p>
- </div>
- </div>
定宽 + 自适应
float + margin
CSS 代码:
- .left{
- float: left;
- width: 100px;
- }
- .right{
- margin-left: 120px;
- }
margin 的值需要大于等于定宽的宽度
float + overflow
CSS 代码:
- .left{
- float: left;
- width: 100px;
- margin-right: 20px;
- }
- .right{
- overflow: hidden;
- }
利用 BFC 原理
table
CSS 代码:
- .parent{
- display: table;
- width: 100%; // 如果不设置, 宽度默认根据内容自适应
- table-layout: fixed; // 设置布局优先, 否则宽度会受内容影响, 即使设置了宽度
- }
- .left,.right{
- display: table-cell;
- }
- .left{
- width: 100px; // 默认单元格是根据内容比例分配的
- padding-right: 20px; // margin 对单元格不起作用
- }
- flex
CSS 代码:
- .parent{
- display: flex; // 子元素默认宽度自适应
- }
- .left{
- width: 100px; // 设置定宽, 不参与缩放分配
- margin-right: 20px;
- }
- .right{
- flex: 1; // left 不参与分配, 剩余空间都分配给 right
- }
不定宽 + 自适应
float + overflow
CSS 代码:
.left{ float: left; margin-right: 20px; } .right{ overflow: hidden; } table
CSS 代码:
.parent{ display: table; width: 100%; } .left,.right{ display: table-cell; } .left{ width: 0.1%; // 默认单元格会根据内容宽度按比例分配, 设置一个很小的宽度使得单元格宽度刚刚包裹内容, 没有设置 table 布局优先, 所以虽然宽度很小, 但是会被内容撑开 padding-right: 20px; }
去掉了 table-layout:fixed, 宽度由内容来决定
flex
CSS 代码:
.parent{ display: flex; } .left{ margin-right: 20px; } .right{ flex: 1; }
left 宽度由内容决定, 剩下的空间都分配给 right
等分布局
示例 HTML:
<div class="parent"> <div class="column"> <p>1</p> </div> <div class="column"> <p>2</p> </div> <div class="column"> <p>3</p> </div> <div class="column"> <p>4</p> </div> </div> float
CSS:
.parent{ margin-left: -20px; } .column{ float: left; width: 25%; padding-left: 20px; box-sizing: border-box; }
父容器需要增加一定宽度, 增加的宽度 = 列之间的距离
关键设置 box-sizing, 使 padding 的距离包含在元素自身的宽度里面
只能针对已知列数来布局, 如果是动态列则不适用
table 方式
CSS:
.parent-fix{ margin-left: -20px; } .parent{ display: table; width:100%; table-layout: fixed; } .column{ display: table-cell; padding-left: 20px; }
需要外面再嵌套一个容器来辅助增加宽度, 因为 table 布局, parent 设置宽度 100% 无法再增加宽度了
table-layout 设置使得单元格等分
flex
CSS:
.parent{ display: flex; } .column{ flex: 1; } // 选择前面还有一个 column 的元素 .column+.column{ margin-left:20px; }
等高布局
table 方式, 代码同以上多列布局, table 单元格默认都是等高的
增加以下 CSS 形成左右间距:
.left { border-right: 20px solid transparent; background-clip:padding-box; }
flex 方式, 代码同以上多列布局, 默认等到, align-items 默认 strech
float 方式, 伪等高
CSS:
.left{ float: left; width: 100px; margin-right: 20px; } .right{ overflow: hidden; } .left, .right{ padding-bottom: 9999px; margin-bottom:-9999px; } .parent{ overflow: hidden; }
仅上左右背景颜色看上去一样高, 实际高度不等
3. 模块化 & 组件化
模块化
什么是模块化?
一系列关联的结构组成的整体
结合产品需求来理解, 具有产品语义
如何实现模块化?
HTML 上, 一个模块看成一个整体, 应该在一个容器里
CSS 也作为一个整体, 写在一个地方
通过父容器的 class 作为模块选择器, 如图中. nav
外观相似, 语义相同的模块, 看成一个模块, 通过扩展的方式改变样式, 扩展方法, 通过模块 class 加后缀的形式, 如图中. nav-1
image.PNG
组件化
什么是组件?
与模块类似, 也是一系列关联的结构组成的整体
是对多模块内通用部分的抽象
组件是脱离产品语义的, 可以应用到不同产品, 项目团队可以长期积累创造自己的组件库
如何实现组件化
实现方法和模块化类似, 同样支持扩展
<span class="button button-1"> 按钮 </span> <span class="button button-1 disabled"> 按钮 </span> .button{} .button:hover{} .button.disabled{} .button-1{}
模块, 组件以及其扩展应该写在一起, 方便后期维护
为什么使用模块化和组件化
方便多人协同
可以扩展, 重用
可读性好, 可维护性好
规范
模块化和组件化在团队中实施时, 必须要靠规范来落地
文件规范
规范文件位置结构, 可分为通用类, 业务类
-- 通用类可以放置全局 base 文件 (如 reset.CSS) 和第三个框架 CSS 文件
-- 业务类根据自己产品的业务来区分
命名规范
分类, 比如区分开模块 (.m-xxx) 和组件(.u-xxx)
扩展, 在模块和组件类名加后缀(.m-xx-x), 按照自己团队的需求和习惯制定自己的规范
语义, 团队形成共识
格式规范
1. 定义, 文本格式, 属性定义顺序等
image.PNG
注释规范, 单行注释, 多行注释
单行注释星号前后需要后空格, 否则如果出现编码问题会影响 CSS 生效
来源: http://www.jianshu.com/p/e0af80cbff79