最近阅读了《精通CSS: 高级Web标准解决方案》,书的内容不错,初学者可以用来入门,有经验的人也可以用来查漏补缺,上面对于浏览器兼容和常见bug的解决方案值得参考。
选择器的层叠和特殊性
对于同一个元素,可能会有多个规则,为了解决规则之间的冲突,CSS 会利用 层叠 给每个规则分配一个重要度:
1、标有 !important 的用户样式
2、标有 !important 的作者样式
3、作者样式
4、用户样式
5、浏览器/用户代理应用的样式
层叠优先级依次降低,优先级相同的规则,后定义的规则优先。为了计算规则的特殊性,可以给每种选择器分配一个数值,然后,将规则的每个选择器的值加在一起,计算出规则的特殊性。
对于一个选择器,其特殊性分为4个成分等级:a, b, c 和 d
1、如果样式是行内样式,那么a=1
2、b是ID选择器的个数
3、c是类、伪类和属性选择器的个数
4、d是类型/标签选择器和伪元素选择器的个数
通配符和继承得到的CSS属性对特殊性没有影响。看一个 demo: 选择器规则
h2
的最终颜色是灰色的,从规则的特殊性分析一下(从左至右依次是abcd的值)
选择器 | 特殊性 | 以10为基数的特殊性 |
---|---|---|
#content div#main-content h2 | 0,2,0,2 | 202 |
#content #main-content>h2 | 0,2,0,1 | 201 |
body #content div[id='main-content'] h2 | 0,1,1,3 | 113 |
#main-content div.news-story h2 | 0,1,1,2 | 112 |
#main-content [class='news-story'] h2 | 0,1,1,1 | 111 |
div#main-content div.news-story h2.first-child | 0,1,2,3 | 123 |
从上表可知,第一个选择器的特殊性最高,所以 h2
的颜色最终为灰色(gray)。
一篇文章: How CSS Specificity Works
外边距叠加
当块元素的 Top 和 Bottom 外边距相遇时,它们将形成一个外边距。合并后的外边距的高度等于两个发生合并的外边距的高度中的较大者,称为 Margin Collapsing(Margin 塌陷)。
Margin Collapsing 基于三种情况:
1、上下相邻的块元素
上一个块元素出现在另一个块元素之上时,如果设置了 margin
,二者的 margin-bottom
和 margin-top
会发生叠加:
Demo
2、父元素和第一个或最后一个子元素
如果父块元素和第一个子元素之间没有边框、内边距、内联内容和 间距 分开,若设置了 margin
,则二者的 margin-top
会叠加;或者父块元素和最后一个子元素之间没有边框、内边距、内联内容和高度设置(height/min-height/max-height),若设置了 margin
,则二者的 margin-bottom
会叠加。
Demo
可以给父元素增加 border、设置 padding、填充内容等方式来解决,还可以通过 overflow:hidden
来解决:
<div> /**填充内容**/ <p>margin-top</p> </div> div{ overflow:hidden; //padding:10px; //border:1px solid transparent; }
3、空的块元素
对于没有边框、内边距、内联内容和高度设置(height/min-height)的空块元素,如果设置了 margin
,则顶底外边距会发生叠加:
如果这个外边距碰到另一个空元素的外边距,则还会发生叠加,合并成一个外边距。但是 浮动和绝对定位的元素是不会发生 Margin Collapse 现象的。
两篇文章:
深入理解BFC和Margin Collapse
Mastering margin collapsing定位
CSS 中的定位主要跟 position
属性有关, MDN 上关于 position
的语法如下:
/* Keyword values */ position: static; position: relative; position: absolute; position: fixed; position: sticky; /* Global values */ position: inherit; position: initial; position: unset;
(1) static
静态定位, position
的默认值,各元素的位置由元素在 HTML 的位置决定
(2) relative
相对定位的元素会根据 top,left,bottom,right 的值相对于该元素处于静态定位时(普通文档流)的位置进行偏移。
相对定位的元素仍会占据原来的空间,因而,该元素偏移会覆盖其它框。
(3) absolute
绝对定位的元素会脱离文档流,是相对于距离它最近的那个已经定位(非 static)的祖先元素确定的,如果没有已定位的祖先元素,则相对于初始的包含块定位。 绝对定位的元素不会产生 Margin Collapse 现象。
相对于最初包含块偏移
相对于定位的祖先元素定位 因为绝对定位的元素与文档流无关,所以会覆盖页面的其它元素,并可以通过 z-index
属性来控制元素的堆叠顺序,其值越大,元素越在上层。 z-index
只再非静态定位的元素中有效。
另外,对于绝对定位的行内元素,会改变其显示形态,变成“块元素”,能对其设置宽高、外边距、边框等属性。
span 具有“块元素” 了
(4) fixed
固定定位是绝对定位的一种,差异在于固定定位的元素的包含块是视口(viewport),这使得改元素总是出现在窗口中的相同位置。
(5) sticky
这是 CSS3 的一个新属性,它的表现类似 position:relative 和 position:fixed 的合体,在目标区域在屏幕中可见时,它的行为就像 position:relative; 而当页面滚动超出目标区域时,它的表现就像 position:fixed,它会固定在目标位置。其兼容性如下:
在 Firefox 或 Safari 中查看 sticky 的 Demo
一篇文章: CSS position
浮动
与浮动相关的属性是 float
。浮动元素和绝对定位元素一样,也会脱离文档流,不会占据空间:
<div class='news'> <img src='http://ww3.sinaimg.cn/bmiddle/8d522661gw1ey1rotf8t6j205k03hjr9.jpg' /> <p>some text</p> <div> //css .news{ border:1px solid red; } img{ float: left; } p{ float: right; }
Demo
由于图片和文本都不占空间,所以 div
并没有被撑开,就看到了图示的效果。那么,如何让包围元素再视觉上包围浮动元素呢?
1、增加空行清除浮动
<p>some text</p> <br class='clear' /> //css .clear{ clear: both; }
Demo1
这种方式不会受到子元素大小的限制,但会增加额外的标签和代码。
2、利用伪元素
.news:after{ display: block; height: 125px; content: ''; }
Demo2
这种方式不用增加额外的标签和代码,但是会受子元素大小的限制。
3、对包含元素添加浮动
.news{ float: left; }
Demo3
这种方式不会增加额外的标签和代码,也不会受到子元素大小的限制,但是下一个元素会受此元素浮动的影响
4、利用 overflow
.news{ border:1px solid red; overflow: hidden; }
Demo4
这种方式会自动清理包含的任何浮动元素,但在某些情况下,会影响盒子的显示,产生滚动条或者阶段内容。
一篇文章: 详解 CSS float 属性
背景图像定位
雪碧图(CSS Sprite)是网站优化的一种方式,将多张背景图合并到一张大图上,从而减少 HTTP 请求数。对雪碧图进行定位的相关属性是 background-position
。
背景图片被放置在元素的 背景放置区(background positioning area) 内,放置区指定了背景图片将被放置的区域,用一套坐标体系来控制位置。因为默认的放置区是在 填充框 内,所以默认情况放置区的坐标原点在 填充框左上角 。这意味着当你为元素应用背景图片的时候,浏览器从填充框的左上角开始放置第一张以及随后的图片。
background-position
有两个值:第一个值表示水平位置,第二个值表示垂直位置。位置的值可以用关键字(top/left/right/bottom/center)、百分比和像素表示,也可以混合,但规范不建议这么做。
当使用关键字的时候,若只指定了一个值,则另一个值默认是 center
。
如果使用像素设置背景位置,则是图像左上角到背景放置区左上角的距离;
如果使用百分比设置背景位置,则是相对于图像上的定点进行定位。
使用像素,则图像出现在放置区的左上角下面20px,左边20px;使用百分比,则是图像上相对于图像左上角20%的定点到放置区左上角20%的位置。
两篇文章:
CSS 中的百分比
CSS中的background-position常见Bug的处理
主要是一些 IE8 以下的bug,如果还要去IE6,IE7的兼容,还不如辞职,如果你不想辞职,就看这篇文章喽: http://www.dengzhr.com/frontend/css/296