CSS Reset
1.作用
(1)清除浏览器默认样式
(2)全局样式定义
2.特别注意
(1)项目开发初期就定义好
(2)reset.css
在引入的时候一定要放在第一位
(3)不同的产品reset.css
不一样
3.table合并边框间距
table {
border-collapse: collapse; // 合并边框
border-spacing: 0; //边框间距。当 `border-collapse` 值为 `seperate` 时生效
}
4.一个并不完整也并不通用的reset.css样例
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,aside,nav,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/1.14 arial,simsun;color:#333;outline:0;}
body{background:#fff;}
a,a:hover{color:#333;}
布局解决方案
居中布局
1.水平居中
父元素和子元素宽度未知。
<div class="parent">
<div class="child">child</div>
</div>
要达到的效果是这样:
方法一:flex + justify-content
主要代码:
.parent {
display: flex;
justify-content: center;
}
没啥好解释,直接看 神奇的flex实现栗子 吧 (~ ̄▽ ̄)~
方法二:absolute + transform
主要代码:
.parent { position: relative; }
.child {
position: absolute;
left: 50%;
transform: translateX(-50%);
}
原理是:left: 50%;
在子元素的左侧添加了一段距离,这段距离是父元素宽度的50%,接着因为translateX(50%) 设置百分比时的参照物是自身宽度,所以向左偏移了自身宽度的50%,就居中啦 ╮(‵▽′)╭
方法三:inline-block + text-align
主要代码:
.parent { text-align: center; }
.child { display: inline-block; }
这种方法有一个问题是:parent
设置了text-align: center;
后, 因为这个属性可继承,会导致child
中的文字也会居中,而这个效果是我们未必需要的,所以我们很多时候需要在.child
中加一句 text-align: left;
方法四:table + margin
主要代码:
.child { display: table; margin: 0 auto; }
table的特点:宽度为内容宽度 的块状元素,所以也可以用margin: 0 auto;
居中。
优点:只设置子元素样式就可以了,不需关心父元素。
不喜欢这第四个方案,table是辣么有语义的一个样式,为什么随便把人家变成table ( ̄. ̄)
2.垂直居中
父元素和子元素高度未知。
意欲达到的效果:
方法一:flex+ align-items
.parent {
display: flex;
align-items: center;
}
同水平居中的方法一
方法二:absolute + transform
.parent { position: relative; }
.child {
position: absolute;
top: 50%;
transform: translateY(-50%);
}
同水平居中的方法二
方法三:table-cell + vertical-align
.parent {
display: table-cell;
vertical-align: middle;
}
vertical-align 可以作用在 inline
元素,inline-table
元素,以及table-cell
元素上。
3.水平垂直居中
父元素和子元素宽高都未知。
方法一:flex + justify-content + align-items
.parent {
display: flex;
justify-content: center;
align-items: center;
}
综合了水平居中和垂直居中的方法一
方法二: absolute + transform
.parent { position: relative; }
.child {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
综合了水平居中和垂直居中的方法二
方法三: absolute + margin: auto; (常用)
.parent { position: relative; }
.child {
position: absolute;
margin: auto;
top: 0;
bottom: 0;
left: 0;
right: 0;
}
方法四:[inline-block + text-align] + [table-cell + vertical-align]
.parent {
display: table-cell;
vertical-align: middle;
text-align: center;
}
.child {
display: inline-block;
}
多列布局
1.一列定宽 + 一列自适应
<div class="parent">
<div class="left"><p>left</p></div>
<div class="right">
<p>right</p>
<p>right</p>
</div>
</div>
方法1:float + margin
.left {float: left; width: 100px;}
.right { margin-left: 120px;} //有20px是间距
方法2:(对方法一的改进)float + margin + (fix)
因为方法1在低版本浏览器有兼容性问题,所以改进一下。
// 首先在right外面加了right-fix这个div
<div class="parent">
<div class="left"><p>left</p></div>
<div class="right-fix">
<div class="right">
<p>right</p>
<p>right</p>
</div>
</div>
</div>
CSS改动:
STEP1:
// .left 和 .right 设置暂时不变
.right-fix {float: right; width: 100%;}
效果为:(注意:我们把right-fix设置为白色背景,只是为了方便观察。)
STEP2:
可以看到,由于right-fix宽度为100%,所以跑到了left下面一行。想要回到同一行,需要给right-fix设置一个负的margin-left值-100px。
.right-fix { margin-left: -100px; }
关于为什么设置了margin-left: 100px;
就可以使得回到同一行呢?是因为设置了负的margin-left值之后,浏览器计算right-fix元素的宽度后,会加上-100px,也就是减掉100px,这也就是left的宽度,所以left 与 right-fix 加起来没有超过整行的宽度。
想要进一步了解负的margin值可以参考这篇文章:CSS布局奇淫巧计之-强大的负边距
效果如图:
STEP3:
不幸的是,因为html文档中right-fix处于left后面,所以left被right-fix遮住了,实际应用中right-fix虽然没有背景色,但是我们还是不会希望它覆盖在left上面。
所以,我们需要提高 left 的层级。如何提高呢?由于设置了position: relative;的元素层级要高于普通元素,所以加上这样一条:
.left{ position: relative; }
具体可以参考张鑫旭写的一篇讲解position:relative;
很详细的文章:CSS 相对/绝对(relative/absolute)定位系列(四)
最终达到我们要的效果:
方法3:float + overflow
.left{
width: 100px;
margin-right: 20px;
}
.right {
overflow: hidden;
}
原理是:设置了overflow:hidden; 之后,会触发BFC模式,而BFC模式内部的布局不受外部影响,所以不会受浮动影响,不会围绕left而是跑到left右边去了。
方法4:table
.parent{
display: table;
width: 100%;
table-layout: fixed; //加速table渲染,实现了布局优先
}
.left, .right {
display: table-cell;
}
.left {
width: 100px;
padding-right: 20px;//因为table-cell不能设margin,所以设置padding来加间距
}
根据table的特性,left设置了100px后,right就占了剩余宽度。
方法5:flex
.parent{ display: flex; }
.left{ width: 100px; margin-right: 20px; }
.right{ flex: 1; }
So easy.
2.多列定宽 + 一列自适应
再加一列定宽就行啦 o(≧v≦)o
3.不定宽 + 一列自适应
不定宽意思是:
1.可以随意更改宽度:比如改为100px,200px,同时不需要更改其他样式也可以做到两列自适应布局。
2.或不设置宽度而是由里面子元素的宽度决定。
以下方法对应 [一列定宽+一列自适应] 中的方法
方法1: float + margin ?
不好意思,做不到。
方法2: float + margin +(fix) ?
不好意思,也做不到。
方法3: float + overflow ?
阔以!right的样式没有依赖于width的宽度。代码量也少,很棒棒哦!
方法4:table
阔以!right的样式没有依赖于width的宽度,即不关心width的宽度。
方法5:flex
强大的flex当然可以~(傲娇脸 )
4.两列不定宽 + 一列自适应
没错,跟你想的一样,加一列不定宽的就行了,样式都一样 ㄟ( ▔, ▔ )ㄏ
5.等分布局
C + G = 4*(W + G)
以下例子假设间距G = 20px
结构:
<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>
方法1:float
.parent{ margin-left: -20px; }//就是上面公式中等号左边的G
.column{
float: left;
width: 25%;
padding-left: 20px;//这里要注意,因为我们用padding来表示间距,所以如果你是给p元素设置了background-color,会发现没有间距,p标签的width才是上图中的W
box-sizing: border-box;
}
方法2:table
<div class="parent-fix">
<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>
</div>
.parent-fix{
margin-left: -20px;
}
.parent {
display: table;
width: 100%;
}
.column {
display: table-cell;
padding-left: 20px;//因为单元格不能设置margin,所以间距只能用padding来做。
}
因为table的width默认是随内容宽度变化的,所以需要手动设置width: 100%;
。又因为明确设置了宽度的元素就没办法用将margin设为负值的方式增加20px宽度了,所以需要在外面加一个父元素parent-fix
。
这里大家可以自己试试比较一下给parent-fix
设置width为100%与不设置width时parent-fix实际宽度(用调试工具里的查看元素看)的区别来理解。
方法3:flex
.parent { display: flex; }
.column { flex: 1; }
.column + .column { margin-left: 20px; }//好用的兄弟选择器 (??`ω′?)
6.一列定宽+一列自适应(当其中较高的一列高度变化,另一列同步变化)
右侧变高,左侧高度随之变化:
↓↓
方法1:table
table的列之间有天然等高的特性。
就是上面 1.一列定宽 + 一列自适应中的方法4:table。
方法2:flex
flex也是天然的等高 <( ̄︶ ̄)> 因为它默认的align-items为stretch,即在交叉轴上默认拉伸占满整个容器。
仍旧是上面1.一列定宽 + 一列自适应中的方法5:flex。
方法3:float
仍旧是参照上面1.一列定宽 + 一列自适应中的方法3:float + overflow,float并没有天然等高,所以要在这个基础上做改动。
.left{
width: 100px;
margin-right: 20px;
}
.right {
overflow: hidden;
}
//增加部分
.left, .right{
padding-bottom: 9999px;//使得有背景色的部分变的很高
margin-bottom: -9999px;//用负的margin抵消掉很高的padding,让高度变回left和right中较高的那部分的内容高度,以便parent用overflow: hidden;去隐藏掉超出部分
}
.parent {
overflow: hidden;//隐藏掉超出边界的部分
}
其实left的实际高度并没有变,是一种伪等高,只是背景变高。
7.全等四宫格
这是练习题,置几试试吧。
<div class="parent">
<div class="outer">
<div class="column">1</div>
<div class="column">2</div>
</div>
<div class="outer">
<div class="column">3</div>
<div class="column">4</div>
</div>
</div>
方法1:flex
.parent {
display: flex;
flex-wrap: wrap;
align-content: space-between;
}
.outer {
flex-basis: 100%;
display: flex;
justify-content: space-between;
}
方法2:float
方法3:table
全屏布局
1.定宽(px)+自适应
只有主内容区 right 随内容滚动。
方法1.position
<div class="parent">
<div class="top">top</div>
<div class="left">left</div>
<div class="right"><div class="help-right">right</div></div>
<div class="bottom">bottom</div>
</div>
html, body, .parent {height: 100%; overflow: hidden;}//为了让整个页面不滚动
.top {
position: absolute;
top: 0;
left: 0; right: 0; //注意这个很棒的设置!可以自动占满整行 ヾ(o???)?
height: 100px;
}
.left {
position: absolute;
left: 0;
top: 100px; bottom: 50px;
width:200px;
}
.right {
position: absolute;
left: 200px; right: 0;
top: 100px; bottom: 50px; //这也是上下占满除了top和bottom之外的所有高度
overflow: auto;//让主内容区可以滚动
}
.help-right {//假装有很多内容
width: 1000px;
height: 1000px;
}
.bottom{
position: absolute;
bottom: 0;
left: 0; right: 0;
height: 50px;
}
方法2.flex
<div class="parent">
<div class="top">top</div>
<div class="middle">
<div class="left">left</div>
<div class="right"><div class="help-right">right</div></div>
</div>
<div class="bottom">bottom</div>
</div>
html, body, .parent {height: 100%; overflow: hidden;}
.parent {display: flex; flex-direction: column;}
.top { height: 100px; }
.middle {flex: 1; display: flex;}
.left { width:200px; }
.right { flex: 1; overflow: auto; }
.help-right { width: 1000px; height: 1000px; }
.bottom{ height: 50px; }
2.百分比定宽(%)+自适应
方法1.position , 方法2.flex :
把原来的用px写的定宽改成百分比就可以了。是相对于body的高度和宽度来变化的。感觉top和bottom高度设置百分比不是很实用。
3.自适应+自适应
方法1.position
定宽的高度和宽度影响旁边栏的布局,所以实现不了 - 。-
方法2.flex
阔以实现,而且相当简单 ╮(╯▽╰)╭ 把刚刚设置了高度和宽度的地方去掉就可以了 ∑(っ °Д °;)っ
方法3.Grid
阔以实现,但是因为还是W3C的草案,所以会经常变化,不稳定,而且浏览器支持也不好。
响应式
想要达到的效果
只写一个网站,在多个终端显示,在小屏幕上会隐藏部分元素。
现在的情况
在PC端浏览器中可以正常访问的网站,到了手机上之后,内容就会变得特别小。
原因:所有的移动设备都有一个viewport(视窗),这个视窗不是手机屏幕大小,而是一个虚拟的窗口,比如iPhone4的viewport宽度为980px(如下图所示)。显示的时候再按照比例将这980px的内容压缩显示到实际的屏幕宽度中。
所以为防止让页面缩小,在移动设备中,我们会做如下设置
<meta name="viewport" content="
width=device-width //让宽度等于设备宽度,因为不同的移动设备宽度不同 iphone4为320px
,initial-scale=1.0 //初始缩放1.0, 即不缩放,网站就不会被缩小了
,user-scalable=no //防止用户手动缩放
">
设置结束之后,如何具体开发?
方法1.宽度尽量自适应,而不要用定宽。
方法2.用媒体查询 @media
@media screen and (max-width: 320px) {
//最大宽度为320px,即视窗宽度小于等于320px
div{..}
.class-name{...}
}
@media screen and (min-width: 320px) and (max-width: 769px){
//最小宽度为320px,最大宽度为769px,即视窗宽度大于320px,小于769px
}
页面优化
目的
减少卡顿
利于SEO
便于代码维护
方法
1. 减少页面请求
减少css文件请求
(1)多个css文件合并成一个
(2)少量css样式内联
(3)避免用import的方式引入css文件,因为每个import语句都会产生一个css请求,并且是同步的请求。
2.减少资源文件大小
(1)减少图片大小
选择合适的图片格式,小尺寸、半透明的用png,大尺寸、色彩绚丽用jpg(因为jpg会对图片进行压缩)
压缩图片
(2)css值缩写
margin,padding,border,font,border-radius等属性
(3)省略值为0 的单位
margin: 0 10px;
line-height: .5;
background-position: 50% 0;
(4)颜色值最短表示
red
rgb(0,0,0)
rgba(0,0,0,0)
#000000
#000
(5)css选择器合并
.left, .right {...}
(6)文件压缩
用工具对文件进行自动压缩,去掉空格。
3.提升页面性能
加载顺序
css通常放在head中,而js通常放在body底部,因为js会阻碍其他资源加载。
减少标签数量。
选择器长度
body .menu ul li a { ... } //太长了
.menu a { ... } //更好
避免耗性能属性
比如:
expression
filter
border-radius
box-shadow
gradients
给图片设置固定宽高,并且图片实际宽高与设置宽高相同,否则浏览器会回流设置多次宽高
所有表现用css实现
4.通过规范提高代码可读性,可维护性
(1)规范:缩进,变量名等
(2)语义化:除了标签,css、id名最好也尽量有意义
(3)尽量避免Hack,一定要用也要统一的标识,比如IE7用*
(4)模块化:相关联的结构做成一个个模块,复用性更强
(5)添加注释
规范与模块化
规范
1.注释的文字两侧需加空格,防止因编码问题导致注释失效
2.为避免命名污染,可以给class加前缀,比如:
g- 布局命名
m- 模块命名
3.语义化命名
//结构化命名
top { ... }
//改用语义化命名
nav { ... }
4.属性的书写顺序
模块化
什么是模块化
一系列相关联的结构组成的整体
带有一定的语义,而非表现
比如,翻页器(或叫分页器paging)、轮播图。
怎么做?
为模块分类命名(如.m-, .md-)
以一个主选择器开头(模块根节点)
使用以主选择器开头的后代选择器(模块子节点)
<div class="m-nav">
<ul>
<li class="z-crt"><a>链接</a></li>
<li><a>链接</a></li>
</ul>
</div>
//根节点
.m-nav { ... }
//子节点
.m-nav ul{ ... }
.m-nav li{ ... }
.m-nav a{ ... }
.m-nav .z-crt a{ ... }/* 交互状态变化 */
若有一个模块只是比上述模块多了一个按钮,其余部分完全相同,怎么办?
怎样扩展?
为根节点加一个class就好了,这里我们加一个 m-nav-1
。
<div class="m-nav m-nav-1">
<ul>
<li class="z-crt"><a>链接</a></li>
<li><a>链接</a></li>
</ul>
<a class="btn">我是新加的a标签</a>
</div>
//变化的部分在 .m-nav-1 这个新class中写
.m-nav-1 { ... }
.m-nav-1 a{ ... }
.m-nav-1 .btn{ ... }
网易的规范和代码库
规范页:包含了CSS规范、HTML规范和工程师规范
代码库:包含了常用的布局方式、常见模块和元件的实现以及一些bug、技巧等
——————
教是最好的学。