CSS选择符
#myid
).myclassname
)div, h1, p
)h1 + p
)ul > li
)li a
)*
)a[rel = "external"]
)a:hover
, li:nth-child
)可继承的样式: font-size font-family color ul li dl dd dt
;
不可继承的样式:border padding margin width height
;
以下是权重的规则:标签的权重为1,class的权重为10,id的权重为100,以下例子是演示各种定义的权重值:
/*权重为1*/
div{
}
/*权重为10*/
.class1{
}
/*权重为100*/
#id1{
}
/*权重为100+1=101*/
#id1 div{
}
/*权重为10+1=11*/
.class1 div{
}
/*权重为10+10+1=21*/
.class1 .class2 div{
}
如果权重相同,则最后定义的样式会起作用,但是应该避免这种情况出现
优先级就近原则,同权重情况下样式定义最近者为准;
载入样式以最后载入的定位为准;
优先级为:
!important > id > class > tag
important 比 内联优先级高
:not(.input)
:所有 class 不是“input”的节点)举例:
p:first-of-type
选择属于其父元素的首个 元素的每个
元素。
p:last-of-type
选择属于其父元素的最后 元素的每个
元素。
p:only-of-type
选择属于其父元素唯一的 元素的每个
元素。
p:only-child
选择属于其父元素的唯一子元素的每个 元素。
p:nth-child(2)
选择属于其父元素的第二个子元素的每个 元素。
:after
在元素之后添加内容,也可以用来做清除浮动。
:before
在元素之前添加内容
:enabled
/:disabled
控制表单控件的禁用状态。
:checked
单选框或复选框被选中。
::before
和 :after
中双冒号和单冒号 有什么区别?解释一下::before
和::after
这2个伪元素的作用。单冒号(:)用于CSS3伪类,双冒号(::)用于CSS3伪元素。
::before
就是以一个子元素的存在,定义在元素主体内容之前的一个伪元素。并不存在于dom之中,只存在在页面之中。
:before
和 :after
这两个伪元素,是在CSS2.1里新出现的。起初,伪元素的前缀使用的是单冒号语法,但随着Web的进化,在CSS3的规范里,伪元素的语法被修改成使用双冒号,成为::before
和::after
。
因为浏览器的兼容问题,不同浏览器对有些标签的默认值是不同的,如果没对CSS初始化往往会出现浏览器之间的页面显示差异。
当然,初始化样式会对SEO有一定的影响,但鱼和熊掌不可兼得,但力求影响最小的情况下初始化。
最简单的初始化方法: * {padding: 0; margin: 0;}
(强烈不建议)
淘宝的样式初始化代码:
body, h1, h2, h3, h4, h5, h6, hr, p, blockquote, dl, dt, dd, ul, ol, li, pre, form, fieldset, legend, button, input, textarea, th, td { margin:0; padding:0; }
body, button, input, select, textarea { font:12px/1.5tahoma, arial, \5b8b\4f53; }
h1, h2, h3, h4, h5, h6{ font-size:100%; }
address, cite, dfn, em, var { font-style:normal; }
code, kbd, pre, samp { font-family:couriernew, courier, monospace; }
small{ font-size:12px; }
ul, ol { list-style:none; }
a { text-decoration:none; }
a:hover { text-decoration:underline; }
sup { vertical-align:text-top; }
sub{ vertical-align:text-bottom; }
legend { color:#000; }
fieldset, img { border:0; }
button, input, select, textarea { font-size:100%; }
table { border-collapse:collapse; border-spacing:0; }
reset重置浏览器的css默认属性。浏览器的品种不同,样式不同,然后重置,让他们统一。
如果使用import方法对CSS进行导入,会导致某些页面在Windows 下的Internet Explorer出现一些奇怪的现象:以无样式显示页面内容的瞬间闪烁,这种现象称之为文档样式闪烁(Flash of Unstyled Content),简称为FOUC。
IE会先加载整个HTML文档的DOM,然后再去导入外部的CSS文件,因此,在页面DOM加载完成到CSS导入完成中间会有一段时间页面上的内容是没有样式的,这段时间的长短跟网速,电脑速度都有关系。
解决方法: 只要在之间加入一个
或者
元素就可以了。
写在head标签中利于浏览器逐步渲染(resources downloading->CSSOM+DOM->RenderTree(composite)->Layout->paint
)。具体渲染过程请参考
浏览器的渲染机制
写在body标签后由于浏览器以逐行方式对html文档进行解析,当解析到写在尾部的样式表(外联或写在style标签)会导致浏览器停止之前的渲染,等待加载且解析样式表完成之后重新渲染,在windows的IE下可能会出现FOUC现象(即样式失效导致的页面闪烁问题)
从后往前判断。
浏览器先产生一个元素集合,这个集合往往由最后一个部分的索引产生(如果没有索引就是所有元素的集合)。然后向上匹配,如果不符合上一个部分,就把元素从集合中删除,直到真个选择器都匹配完,还在集合中的元素就匹配这个选择器了。
举个例子,有选择器:
body.ready #wrapper > .lol233
先把所有 class 中有 lol233 的元素拿出来组成一个集合,然后上一层,对每一个集合中的元素,如果元素的 parent id 不为 #wrapper
则把元素从集合中删去。 再向上,从这个元素的父元素开始向上找,没有找到一个 tagName 为 body 且 class 中有 ready 的元素,就把原来的元素从集合中删去。
至此这个选择器匹配结束,所有还在集合中的元素满足。
为什么从后往前匹配?
因为效率和文档流的解析方向。效率不必说,找元素的父亲和之前的兄弟比遍历所有儿子快而且方便。关于文档流的解析方向,是因为现在的 CSS,一个元素只要确定了这个元素在文档流之前出现过的所有元素,就能确定他的匹配情况。应用在即使 html 没有载入完成,浏览器也能根据已经载入的这一部分信息完全确定出现过的元素的属性。
为什么是用集合?
主要也还是效率。基于 CSS Rule 数量远远小于元素数量的假设和索引的运用,遍历每一条 CSS Rule 通过集合筛选,比遍历每一个元素再遍历每一条 Rule 匹配要快得多。
(W3C CSS 2.1 规范中的一个概念,它是一个独立容器,决定了元素如何对其内容进行定位,以及与其他元素的关系和相互作用。)
一个页面是由很多个 Box 组成的,元素的类型和 display 属性,决定了这个 Box 的类型。
不同类型的 Box,会参与不同的 Formatting Context(决定如何渲染文档的容器),因此Box内的元素会以不同的方式渲染,也就是说BFC内部的元素和外部的元素不会互相影响。
盒模型:文档中的每个元素被描绘为矩形盒子,渲染引擎的目的就是判定大小,属性——比如它的颜色、背景、边框方面——及这些盒子的位置。
(1)有两种,IE 盒子模型、W3C 盒子模型;
(2)盒模型:内容(content)、填充(padding)、边界(margin)、 边框(border);
(3)区别:IE的content部分把 border 和 padding计算了进去;
box-sizing属性主要用来控制元素的盒模型的解析模式。默认值是content-box。
content-box:让元素维持W3C的标准盒模型。元素的宽度/高度由border + padding + content的宽度/高度决定,设置width/height属性指的是content部分的宽/高
border-box:让元素维持IE传统盒模型(IE6以下版本和IE6~7的怪异模式)。设置width/height属性指的是border + padding + content
padding-box:元素的宽度/高度由 width/height(包含padding) + border决定,设置width/height= padding+content
布局的传统解决方案,基于盒状模型,依赖 display 属性 + position属性 + float属性。它对于那些特殊布局非常不方便,比如,垂直居中就不容易实现。
详细内容请查看Flex 布局教程:语法篇, Flex 布局教程:实例篇
何时应当使用margin
需要在border外侧添加空白时。
空白处不需要背景(色)时。
上下相连的两个盒子之间的空白,需要相互抵消时。如15px+20px的margin,将得到20px的空白。
何时应当时用padding
需要在border内测添加空白时。
空白处需要背景(色)时。
上下相连的两个盒子之间的空白,希望等于两者之和时。如15px+20px的padding,将得到35px的空白。
浏览器兼容性问题
在IE5.x、IE6中,为float的盒子指定margin时,左侧margin可能会变成两倍的宽度。通过改用padding或指定盒子为display:inline可以解决。
display:inline-block
什么时候会显示间隙?(携程)移除空格、使用margin负值、使用font-size:0
、letter-spacing、word-spacing
display:none
或者visibility:hidden
,overflow:hidden
。
display:none;
的缺陷
visibility: hidden;
的缺陷
隐藏的内容会占据他所应该占据物理空间
overflow:hidden;
一个比较合理的方法
例:.texthidden { display:block; overflow: hidden; width: 0; height: 0; }
将宽度和高度设定为0,然后超过部分隐藏,就会弥补上述一、二方法中的缺陷,也达到了隐藏内容的目的
visibility有如下属性值:
属性值 | 属性值描述 |
---|---|
visible | 默认值。元素是可见的。 |
hidden | 元素是不可见的,但此时仍占用页面空间 |
collapse | 当在表格元素中使用时,此值可删除一行或一列,但是它不会影响表格的布局。被行或列占据的空间会留给其他内容使用。如果此值被用在其他的元素上,会呈现为 “hidden”。 |
inherit | 规定应该从父元素继承 visibility 属性的值。 |
在不同浏览器下的区别:
display:none
和 visibility: hidden
的区别display:none
隐藏对应的元素,在文档布局中不再给它分配空间,它各边的元素会合拢,就当他从来不存在。visibility:hidden
隐藏对应的元素,但是在文档布局中仍保留原来的空间。无论属于哪种,都要先找到其祖先元素中最近的 position 值不为 static 的元素,然后再判断:
1、若此元素为 inline 元素,则 containing block 为能够包含这个元素生成的第一个和最后一个 inline box 的 padding box (除 margin, border 外的区域) 的最小矩形;
2、否则,则由这个祖先元素的 padding box 构成。
如果都找不到,则为 initial containing block。
补充:
参考资料:position跟display、margin collapse、overflow、float这些特性相互叠加后会怎么样?
共同点:对内联元素设置float和absolute属性,可以让元素脱离文档流,并且可以设置其宽高。
不同点:float仍会占据位置,absolute会覆盖文档流中的其他元素。
自动变成display:block
浮动可以理解为让某个div元素脱离标准流,漂浮在标准流之上,和标准流不是一个层次。
假如某个div元素A是浮动的,如果A元素上一个元素也是浮动的,那么A元素会跟随在上一个元素的后边(如果一行放不下这两个元素,那么A元素会被挤到下一行);如果A元素上一个元素是标准流中的元素,那么A的相对垂直位置不会改变,也就是说A的顶部总是和上一个元素的底部对齐。
浮动元素脱离文档流,不占据空间。浮动元素碰到包含它的边框或者浮动元素的边框停留。
清除浮动是为了清除使用浮动元素产生的影响。浮动的元素,高度会塌陷,而高度的塌陷使我们页面后面的布局不能正常显示。
清除浮动可以理解为打破横向排列。 clear: none | left | right | both
对于CSS的清除浮动(clear),一定要牢记:这个规则只能影响使用清除的元素本身,不能影响其他元素。
清除浮动的几种方法:
使用空标签清除浮动。
这种方法是在所有浮动标签后面添加一个空标签,定义css clear:both
。 弊端就是增加了无意义标签。
使用overflow。
给包含浮动元素的父标签添加css属性 overflow:auto; zoom:1;
。zoom:1
用于兼容IE6。
使用after伪对象清除浮动。
该方法只适用于非IE浏览器。使用中需注意:该方法中必须为需要清除浮动元素的伪对象中设置 height:0,否则该元素会比实际高出若干像素;
#parent:after{
content:".";
height:0;
visibility:hidden;
display:block;
clear:both;
}
#parent{
zoom:1;
}
zoom:1
的作用: 触发IE下的hasLayout。zoom是IE浏览器专有属性,可以设置或检索对象的缩放比例。
当设置了zoom的值之后,所设置的元素就会扩大或缩小,高度宽度就会重新计算了,这里一旦改变zoom值时其实也会发生重新渲染,运用这个原理,也就解决了ie下子元素浮动时候父元素不随着自动扩大的问题。
把上、左、右三条边隐藏掉(颜色设为 transparent)
#demo {
width: 0;
height: 0;
border-width: 20px;
border-style: solid;
border-color: transparent transparent red transparent;
}
简单的方式:上面的div宽100%,下面的两个div分别宽50%,然后用float或者inline使其不换行即可。
给div设置一个宽度,然后添加margin:0 auto属性
div{
width:200px;
margin:0 auto;
}
居中一个浮动元素
确定容器的宽高 宽500 高 300 的层
设置层的外边距
.div {
width:500px;
height:300px;//高度可以不设
margin: -150px 0 0 -250px; /* 外边距为自身宽高的一半 */
position:relative; /* 相对定位或绝对定位均可 */
background-color:pink; /* 方便看效果 */
left:50%;
top:50%;
}
未知容器的宽高,利用 transform
属性
div {
position: absolute; /* 相对定位或绝对定位均可 */
width:500px;
height:300px;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background-color: pink; /* 方便看效果 */
}
利用 flex 布局,实际使用时应考虑兼容性
.container {
display: flex;
align-items: center; /* 垂直居中 */
justify-content: center; /* 水平居中 */
}
.container div {
width: 100px;
height: 100px;
background-color: pink; /* 方便看效果 */
}
让绝对定位的div居中
position: absolute;
width: 1200px;
background: none;
margin: 0 auto;
top: 0;
left: 0;
bottom: 0;
right: 0;
浮动布局:
left sidebar
Main Content
Title
行框的排列会受到中间空白(回车\空格)等的影响,因为空格也属于字符,这些空白也会被应用样式,占据空间,所以会有间隔,把字符大小设为0,就没有空格了。
对字体进行抗锯齿渲染可以使字体看起来会更清晰舒服。在图标字体成为一种趋势的今天,抗锯齿渲染使用也越来越多。font-smoothing是非标准的CSS定义。它被列入标准规范的草案中,后由于某些原因从web标准中被移除了。但是,我们可以用以下两种定义进行抗锯齿渲染。
/*chrome、safari*/
-webkit-font-smoothing: antialiased;
/*firefox*/
-moz-osx-font-smoothing: grayscale;
偶数字号比较容易和页面中其他部分的字号构成一个比例关系。
使用奇数号字体不好的地方是,文本段落无法对齐。
参考资料:谈谈网页中使用奇数字体和偶数字体
“oblique”与“italic”都是倾斜的意思。而“oblique”就是一种排版术语,就是一种倾斜的文字,但不是斜体。因为“oblique”对于font-style来说是一种合法的属性值,它可和italic进行互换,除非真有一种字体只提供了oblique而没有提供斜体。因为oblique基本上是一种模仿的斜体,而不是真正的斜体。
所以,如果一种字库里没有提供斜体字,当我们使用CSS的font-style:italic时,浏览器实际上是按font-style:oblique显示的。
对于height属性取值百分比,是相对于容器高度的。
对于margin-top、margin-bottom、padding-top、padding-bottom这些竖直方向的内外边距属性的百分比取值,参考的其实是容器的宽度而不是高度。
原理:方法一是整体的元素一直排列下去,假设有5个需要展示的全屏页面,那么高度是500% ,只是展示100%,剩下的可以通过transform进行y轴定位,也可以通过margin-top实现。方法二就是所有的子元素和页面一样,都显示在当前页面。
附:CSS-页面滑屏滚动原理
chrome会默认给自动填充的input表单加上input:-webkit-autofill
私有属性,然后对其赋予以下样式:
input : -webkit-autofill {
background-color: #FAFFBD;
background-image: none;
color: #000;
}
情景一:input文本框是纯色背景的
可以对input:-webkit-autofill
使用足够大的纯色内阴影来覆盖input输入框的黄色背景;如:
input:-webkit-autofill {
-webkit-box-shadow: 0 0 0px 1000px white inset;
border: 1px solid #CCC!important;
}
如果你有使用圆角等属性,或者发现输输入框的长度高度不太对,可以对其进行调整,除了chrome默认定义的background-color,background-image,color不能用!important提升其优先级以外,其他的属性均可使用!important提升其优先级。
思路二: 关闭浏览器自带填充表单功能
设置表单属性 autocomplete="off/on"
关闭自动填充表单,自己实现记住密码
从上到下四条线分别是顶线、中线、基线、底线。
vertical-align属性中有top、middle、baseline、bottom,就是和这四条线相关。
行高是指上下文本行的基线间的垂直距离。
行距是指一行底线到下一行顶线的垂直距离。
半行距是行距的一半,值为(行高-字体size)/2
。
内容区:底线和顶线包裹的区域。
行内框,每个行内元素会生成一个行内框,行内框是一个浏览器渲染模型中的一个概念,无法显示出来,在没有其他因素影响的时候(padding等),行内框等于内容区域,而设定行高时行内框高度不变,半行距【(行高-字体size)/2】分别增加/减少到内容区域的上下两边(深蓝色区域)
行框(line box),行框是指本行的一个虚拟的矩形框,是浏览器渲染模式中的一个概念,并没有实际显示。行框高度等于本行内所有元素中行内框最大的值(以行高值最大的行内框为基准,其他行内框采用自己的对齐方式向基准对齐,最终计算行框的高度),当有多行内容时,每行都会有自己的行框。
line-height 属性设置行间的距离(行高),不能使用负值。该属性会影响行框的布局。在应用到一个块级元素时,它定义了该元素中基线之间的最小距离而不是最大距离。line-height 与 font-size 的计算值之差(行距)分为两半,分别加到一个文本行内容的顶部和底部。可以包含这些内容的最小框就是行框。
参考资料:深入理解line-height
如果你对某个div或模块使用了overflow: scroll属性,在iOS系统的手机上浏览时,则会出现明显的卡顿现象。但是在android系统的手机上则不会出现该问题。
以下代码可解决这种卡顿的问题:-webkit-overflow-scrolling: touch;
,是因为这行代码启用了硬件加速特性,所以滑动很流畅。这个方法的确可以解决ios5.0、android4.0以后系统的滑动卡顿问题。
-webkit-overflow-scrolling: auto | touch;
auto: 普通滚动,当手指从触摸屏上移开,滚动立即停止
touch:滚动回弹效果,当手指从触摸屏上移开,内容会保持一段时间的滚动效果,继续滚动的速度和持续的时间和滚动手势的强烈程度成正比。同时也会创建一个新的堆栈上下文。
兼容写法
over-flow: auto; /* winphone8和android4+ */
-webkit-overflow-scrolling: touch; /* ios5+ */
ps:
1、如果添加了此属性但是不起作用,再添加overflow-y: scroll
,就可以了。
2、当一个元素设置过position: absolute|relative
,后再增加-webkit-overflow-scrolling: touch;
属性后,会发现,滑动几次后就滚动区域会卡住,不能在滑动,这时给元素增加个z-index值就可以了。
position:fixed;
在android下无效怎么处理?设置user-scalable=no
png24位的图片在iE6浏览器上出现背景,解决方案是做成PNG8.
浏览器默认的margin和padding不同。解决方案是加一个全局的* {margin:0;padding:0;}
来统一。
IE6双边距bug:块属性标签float后,又有横行的margin情况下,在ie6显示margin比设置的大。
浮动ie产生的双倍距离 #box{ float:left; width:10px; margin:0 0 0 100px;}
这种情况之下IE会产生20px的距离,解决方案是在float的标签样式控制中加入 ——_display:inline;
将其转化为行内属性。(_这个符号只有ie6会识别)
hack技巧,渐进识别的方式,从总体中逐渐排除局部。
首先,巧妙的使用“\9
”这一标记,将IE游览器从所有情况中分离出来。
接着,再次使用“+
”将IE8和IE7、IE6分离开来,这样IE8已经独立识别。
css
```
.bb{
background-color:#f1ee18;/*所有识别*/
.background-color:#00deff\9; /*IE6、7、8识别*/
+background-color:#a200ff;/*IE6、7识别*/
_background-color:#1e0bd1;/*IE6识别*/
}
```
IE下,可以使用获取常规属性的方法来获取自定义属性,
也可以使用getAttribute()
获取自定义属性; Firefox下,只能使用getAttribute()
获取自定义属性。
解决方法:统一通过getAttribute()
获取自定义属性。
IE下,even对象有x,y属性,但是没有pageX,pageY属性;
Firefox下,event对象有pageX,pageY属性,但是没有x,y属性。
解决方法:(条件注释)缺点是在IE浏览器下可能会增加额外的HTTP请求数。
Chrome 中文界面下默认会将小于 12px 的文本强制按照 12px 显示
可通过加入 CSS 属性 -webkit-text-size-adjust: none;
解决。
超链接访问过后hover样式就不出现了,被点击访问过的超链接样式不在具有hover和active了
解决方法是改变CSS属性的排列顺序:
L-V-H-A : a:link {} a:visited {} a:hover {} a:active {}
上下margin重合问题
ie和ff都存在,相邻的两个div的margin-left和margin-right不会重合,但是margin-top和margin-bottom却会发生重合。
解决方法,养成良好的代码编写习惯,同时采用margin-top或者同时采用margin-bottom。
条件注释:仅适用于IE
特定符号:适用于能识别特定符号的浏览器
内核符号:针对不同浏览器内核
CSS3的动画
JavaScript的动画
多数显示器默认频率是60Hz,即1秒刷新60次,所以理论上最小间隔为1/60*1000ms = 16.7ms
视差滚动(Parallax Scrolling)这种技术通过在网页向下滚动的时候,控制背景的移动速度比前景的移动速度慢来创建出令人惊叹的3D效果。
CSS3实现
优点:开发时间短、性能和开发效率比较好,缺点是不能兼容到低版本的浏览器
jquery实现
通过控制不同层滚动速度,计算每一层的时间,控制滚动效果。
优点:能兼容到各个版本的,效果可控性好
缺点:开发起来对制作者要求高
插件实现方式
例如:parallax-scrolling,兼容性十分好
预处理器例如:LESS、Sass、Stylus,用来预编译Sass或less,增强了css代码的复用性,还有层级、mixin、变量、循环、函数等,具有很方便的UI组件模块化开发能力,极大的提高工作效率。
后处理器例如:PostCSS,通常被视为在完成的样式表中根据CSS规范处理CSS,让其更有效;目前最常做的
是给CSS属性添加浏览器私有前缀,实现跨浏览器兼容性的问题。
CSS Sprites其实就是把网页中一些背景图片整合到一张图片文件中,再利用CSS的“background-image”,“background- repeat”,“background-position”的组合进行背景定位,background-position可以用数字能精确的定位出背景图片的位置。这样可以减少很多图片请求的开销,因为请求耗时比较长;请求虽然可以并发,但是也有限制,一般浏览器都是6个。对于未来而言,就不需要这样做了,因为有了http2
。
通过媒体查询可以为不同大小和尺寸的媒体定义不同的css,适合相应的设备显示;即响应式布局
@media screen and (min-width: 400px) and (max-width: 700px) { … }
@media handheld and (min-width: 20em), screen and (min-width: 20em) { … }
页面的设计和开发应当根据用户行为以及设备环境(系统平台、屏幕尺寸、屏幕定向等)进行相应的响应和调整。具体的实践方式由多方面组成,包括弹性网格和布局、图片、css media query的使用等。无论用户正在使用笔记本还是iPad,我们的页面都应该能够自动切换分辨率、图片尺寸及相关脚本功能等,以适应不同设备;换句话说,页面应该有能力去自动响应用户的设备环境。
响应式网页设计就是一个网站能够兼容多个终端——而不是为每个终端做一个特定的版本。这样,我们就可以不必为不断到来的新设备做专门的版本设计和开发了。
响应式设计的基本原理是通过媒体查询检测不同的设备屏幕尺寸做处理。页面头部必须有meta声明viewport: