CSS学习笔记(3):CSS概述
CSS简介
CSS:Cascading Style Sheet,层叠样式表。CSS 的作用就是给 HTML 页面标签添加各种样式,定义网页的显示效果。CSS 将网页内容和显示样式进行分离,提高了显示功能。
HTML 的缺陷:
- 不能够适应多种设备。
- 要求浏览器必须智能化足够庞大。
- 数据和显示没有分开。
- 功能不够强大。
CSS 优点:
- 使数据和显示分开。
- 降低网络流量。
- 使整个网站视觉效果一致。
- 使开发效率提高了(耦合性降低,一个人负责写 html,一个人负责写 css)。
CSS语法
基本语法
CSS样式通过选择器来设置样式属性:
- 选择器代表页面上的某类元素,选择器后一定是大括号。
- 属性名后必须用冒号隔开,属性值后用分号(最后一个属性可以不用分号,但最好还是加上分号)。
- 冒号和属性值之间可以留一个空格(编程习惯的经验)。
- 如果一个属性有多个值的话,那么多个值用空格隔开。
格式如:
1 |
|
注释
CSS只有块注释,即注释要包含在/* */中。不支持以//开头的行注释。
使用CSS
在HTML中使用CSS的方式有三种:
- 行内样式:在某个特定的标签里采用 style属性。范围只针对此标签。
- 内嵌样式表:在页面的 head 里采用<style>标签。范围针对此页面。
- 引入外部样式表 css 文件的方式。这种引入方式又分为两种:
- 采用<link>标签。
- 采用 import,必须写在<style>标签中,并且必须是第一句。
行内样式
采用 style 属性。范围只针对此标签适用。该方式比较灵活,但是对于多个相同标签的同一样式定义比较麻烦,适合局部修改。如:
1 |
|
内联样式表
在 head 标签中加入<style>标签,对多个标签进行统一修改,范围针对此页面。该方式可以对单个页面的样式进行统一设置,但对于局部不够灵活。如:
1 |
|
外部样式表
即从外部引入CSS文件。
引入样式表文件的方式又分为两种:
- 采用<link>标签。例如:
<link rel = "stylesheet" type = "text/css" href = "a.css"></link>
- 采用 import,必须写在<style>标签中,并且必须是第一句。例如:
@import url(a.css);
<link>标签具有rel属性,其属性值有以下两种:
- stylesheet:定义的样式表。
- alternate stylesheet:候选的样式表。
设置候选样式表的同时要设置它们的title,这样才可以在浏览器中切换。
选择器
基本选择器
CSS有四种基本选择器:
- 标签选择器:针对一类标签。
- ID 选择器:针对某一个特定的标签使用。
- 类选择器:针对你想要的所有标签使用。
- 通用选择器(通配符):针对所有的标签都适用(不建议使用)。
标签选择器
选择器的名字代表 html 页面上的标签,标签选择器,选择的是页面上所有这种类型的标签,所以经常描述“共性”,无法描述某一个元素的“个性”。如:
1 |
|
该选择器的意思是:所有的<p>标签里的内容都将显示 14 号字体。
ID选择器
使用#加id的选择器,选择某一id的元素,只针对某一标签使用。如:
1 |
|
任何的 HTML 标签都可以有 id 属性。表示这个标签的名字。id命名的规则:
- 只能有字母、数字、下划线。
- 必须以字母开头。
- 不能和标签同名。比如 id 不能叫做 body、img、a。
- 同一个HTML页面不能出现相同的 id,哪怕他们不是一个类型。
类选择器
使用小圆点加类名的选择器,选择某一类的元素。针对你想要的所有标签使用,优点是灵活。如:
1 |
|
同一个标签可以拥有多个类名,类名之间用空格隔开。
类上样式,id上行为。意思是说,class属性交给CSS使用,id属性交给JS使用。
通配符
即星号*,匹配所有标签,一般不使用。
效率不高,如果页面上的标签越多,效率越低。
如:
1 |
|
高级选择器
CSS中的高级选择器主要有:
- 后代选择器:用空格隔开。
- 交集选择器:选择器之间紧密相连。
- 并集选择器(分组选择器):用逗号隔开。
- 伪类选择器。
后代选择器
多个选择器用空格隔开,表示它们是祖先和后代关系。如:
1 |
|
要注意这里可以是隔代后代,而不是严格的父子关系。
交集选择器
定义交集选择器的时候,两个选择器之间紧密相连。一般是以标签名开头,比如div.haha,代表选择既是div标签又具有类名haha的元素。
交集选择器没有空格,所以,没有空格的div.red(交集选择器)和有空格的div .red(后代选择器)意义完全不同。
交集选择器可以连续交,如h3.special.zhongyao,但最好不要这么写,容易出现兼容性问题。
并集选择器
使用逗号隔开的若干选择器,三种基本选择器都可以放进来。如:
1 |
|
并集选择器表示若干选择器使用同样的样式属性。
伪类选择器
伪类:同一个标签,根据其不同的种状态,有不同的样式。这就叫做“伪类”。伪类用冒号来表示。
分类
伪类选择器分为两种:
(1)静态伪类:只能用于超链接的样式:
- :link 超链接点击之前
- :visited 链接被访问过之后
(2)动态伪类:针对所有标签都适用的样式:
- :hover “悬停”:鼠标放到标签上的时候。
- :active “激活”: 鼠标点击标签,但是不松手时。
- :focus 是某个标签获得焦点时的样式(比如某个输入框获得焦点)。
静态伪类
a标签有4种伪类(即对应四种状态),非常重要,如下:
- :link “链接”:超链接点击之前。
- :visited “访问过的”:链接被访问过之后。
- :hover “悬停”:鼠标放到标签上的时候。
- :active “激活”: 鼠标点击标签,但是不松手时。
在CSS中,这四种状态必须按照固定的顺序写:a:link 、a:visited 、a:hover 、a:active。
即 “爱恨准则” :love hate,必须先爱,后恨。如果不按照顺序,那么将失效。
重要!a{}和a:link{}的区别:
- a{}定义的样式针对所有的超链接(包括锚点)。
- a:link{}定义的样式针对所有写了href属性的超链接(不包括锚点)。
在写a:link、a:visited这两个伪类的时候,要么同时写,要么同时不写,可以省略。
动态伪类
下面这三种动态伪类,针对所有标签都适用。
- :hover “悬停”:鼠标放到标签上的时候
- :active “激活”: 鼠标点击标签,但是不松手时。
- :focus 是某个标签获得焦点时的样式(比如某个输入框获得焦点)。
而其他标签还有其特殊的伪类。
CSS继承与层叠
继承性
有一些属性,当给自己设置的时候,自己的后代都继承上了,这个就是继承性。继承性是从自己开始,直到最小的元素。
关于一个属性是否有继承性,主要有以下规则:
- 关于文字样式的属性,都具有继承性。这些属性包括:color、 text-开头的、line-开头的、font-开头的。
- 关于盒子、定位、布局的属性,都不能继承。
当我们谈到css有哪些特性的时候,我们要首先想到继承性。而且,要知道哪些属性具有继承性、哪些属性没有继承性。
层叠性
CSS像艺术家一样优雅,像工程师一样严谨。
由于一个标签可以被多个选择器选择,设置的属性可能会有冲突,所以这时候就要考虑哪个属性生效。
当多个选择器选择上了同一个元素的时候,要按照如下顺序统计权重:
- id 选择器。
- 类选择器、属性选择器、伪类选择器。
- 标签选择器、伪元素选择器。
即对于相同方式的样式表,其选择器排序的优先级为:ID选择器 > 类选择器 > 标签选择器。
对于某个属性设置的不同的值,要看该属性对应的若干选择器的权重,权重高的属性覆盖权重低的,权重相同则后者覆盖前者。
在实战中,假如列表中的若干项,我希望其中一个特殊项的字体颜色是红色,而其他是蓝色,就可以这样:
1 |
|
即后一个选择器复制前一个选择器并加上一个权重,确保后一个的效果能覆盖前一个。
同时要注意一点:如果不能直接选中某个元素,通过继承性影响的话,那么权重是0。即选择器要选中了包含文本的最内层标签,否则通过继承性影响的属性是不计算权重的。
总结:
- 选择上了,数权重,(id的数量,类的数量,标签的数量)。如果权重一样,谁写在后面听谁的。
- 没有选择上,通过继承影响的,就近原则,谁描述的近听谁的。如果描述的一样近,比选择器权重,如果权重还一样重,谁写在后面听谁的。
“离得近”是指CSS的就近原则。注意就近原则是样式表的远近,标签里多个并列的类名的先后顺序是没什么影响的。
如果强制为某个属性提高优先级,使用!important标记,使用了该标记的属性权重被认为是无穷大。如:
1 |
|
但是注意!important标记对继承无影响,只影响层叠性的权重。
盒模型
盒子模型,就是里面可以放东西。无论是div、span、还是a都是盒子。
但是,图片、表单元素一律看作是文本,它们并不是盒子。这个很好理解,比如说,一张图片里并不能放东西,它自己就是自己的内容。
属性
一个盒子中主要的属性就5个:width、height、padding、border、margin。如下:
- width和height:内容的宽度、高度(不是盒子的宽度、高度)。
- padding:内边距。
- border:边框。
- margin:外边距。
盒模型从内到外的顺序为:内容、padding、边框、margin。
<body>标签也有margin,整个网页最大的盒子是<document>,即浏览器。而<body>是<document>的儿子。浏览器给<body>默认的margin大小是8个像素,此时<body>占据了整个页面的一大部分区域,而不是全部区域。
兼容性
大多浏览器都使用标准盒模型,只有IE浏览器的盒模型与标准盒模型不同,主要区别在于width和height上:
- 在 标准盒模型中,width 和 height 指的是内容区域的宽度和高度。增加内边距、边框和外边距不会影响内容区域的尺寸,但是会增加元素框的总尺寸。
- IE盒模型中,width 和 height 指的是内容区域+border+padding的宽度和高度。
padding
padding是4个方向的,可以分别描述4个方向的padding:
1 |
|
也可以使用上、右、下、左的顺序将它们合写为padding属性。
一些元素,默认带有padding,比如ul标签。
margin
margin塌陷与叠加
标准文档流中,竖直方向的margin不叠加,取较大的值作为竖直方向的margin,即margin塌陷。
而水平方向的margin是可以叠加的,即水平方向没有塌陷现象。
此外,如果不在标准流,比如盒子都浮动了,那么两个盒子之间即使在竖直方向上也是没有塌陷现象的。
居中
margin的值可以为auto,表示自动,会使margin值尽可能大。当left、right两个方向都是auto的时候,盒子就居中了:
1 |
|
可以简写为:
1 |
|
即上下margin为0,左右margin为auto。
要注意:
(1)只有标准流的盒子,才能使用margin:0 auto;
居中。也就是说,当一个盒子浮动了、绝对定位了、固定定位了,都不能使用margin:0 auto;
(2)使用margin:0 auto;
的盒子,必须有明确的width。如果没有明确的witdh,那么它的witdh就是霸占整行的(水流特性),这时居中没有意义。
(3)margin:0 auto;
是让盒子居中,不是让盒子里的文本居中。文本的居中,要使用text-align:center;
父子陷阱
margin这个属性,本质上描述的是兄弟和兄弟之间的距离; 最好不要用这个marign表达父子之间的距离。如果要表达父子之间的距离,我们一定要善于使用父亲的padding,而不是儿子的margin。
如对于div1内嵌套div2的例子,如果为div2设定margin-top: 20px;
并不能使得div2距离div1上边界20px,反而会使div1和div2同时下移20px,如果要解决这一问题,可以为父元素使用overflow: hidden;
,当然更正确的做法是使用父元素的padding,margin应当用于兄弟之间。
兼容性问题
(1)IE6的双倍margin的bug:
当出现连续浮动的元素,携带与浮动方向相同的margin时,队首的元素,会双倍marign。
解决方式是使浮动的方向和margin的方向相反:
1 |
|
前端开发工程师,已经把这个当做习惯了。
当然也可以为队首元素单独设置格式,可以但太麻烦,没必要这样。
(2)IE6的margin-right多3px的bug:
为儿子设置margin-right,实际表现的效果父子之间的距离比设置值多了3px。
盒子尺寸
CSS3 对盒模型做出了新的定义,即允许开发人员指定盒子宽度和高度的计算方式。
这就需要用到 box-sizing属性。它的属性值可以是:content-box、border-box。
如果使用:
1 |
|
表示设置height和width时是针对内容盒子设置的,这也是默认值。而:
1 |
|
则是让height和width对边框盒子生效。
文档流
web页面和photoshop等设计软件有本质的区别:web页面的制作,是个“流”,必须从上而下,像“织毛衣”。而设计软件,想往哪里画个东西,都能画。
文档流特性
空白折叠现象
无论多少个空格、换行、tab,都会折叠为一个空格。多个空白符需要使用转义字符。
反而,如果我们想让标签之间没有空隙,必须让内容紧密连接:
1 |
|
底边对齐
即高矮不齐,底边对齐,不同高度的内容在同一行时,他们的底边是对齐的。
自动换行
页面内容会自动换行,一行写不满就会换行写。
行内元素和块级元素
行内元素和块级元素的区别:(非常重要)
- 行内元素:
- 与其他行内元素并排;
- 不能设置宽、高。默认的宽度,就是文字的宽度。
- 块级元素:
- 霸占一行,不能与其他任何元素并列;
- 能接受宽、高。如果不设置宽度,那么宽度将默认变为父亲的100%。
行内元素和块级元素的分类:
在HTML中,标签分为文本级、容器级标签:
- 文本级标签:p、span、a、b、i、u、em。
- 容器级标签:div、h系列、li、dt、dd。
这里为什么说p是文本级标签呢?因为p里面只能放文字&图片&表单元素,p里面不能放h和ul,p里面也不能放p。
现在,从CSS的角度讲,p的分类就不一样了,p属于块级元素:
- 行内元素:除了p之外,所有的文本级标签都是行内元素。
- 块级元素:所有的容器级标签和p标签都是块级元素。
行内元素和块级元素的相互转换:
通过display属性将块级元素和行内元素进行相互转换。display即“显示模式”。
块级元素可以转换为行内元素,只需要给一个块级元素(比如div)设置:
1 |
|
那么,这个标签将立即变为行内元素,此时它和一个span无异。也就是说:
- 此时这个div不能设置宽度、高度;
- 此时这个div可以和别人并排了。
同样的道理,一旦给一个行内元素(比如span)设置:
1 |
|
那么,这个标签将立即变为块级元素,此时它和一个div无异。block”是“块”的意思。也就是说:
- 此时这个span能够设置宽度、高度。
- 此时这个span必须霸占一行了,别人无法和他并排。
- 如果不设置宽度,将撑满父亲。
浮动
标准流里面的限制非常多,导致很多页面效果无法实现。如果非要并排,就是要设置宽高,使用的方法是脱离标准流。CSS中一共有三种手段,使一个元素脱离标准文档流:
- 浮动
- 绝对定位
- 固定定位
绝对定位和固定定位已经在定位属性里介绍,剩下的就是浮动。浮动是CSS里面布局用的最多的属性。
性质
浮动的元素脱标
脱标即脱离标准流,在标准流中将没有元素的位置。
一旦一个元素浮动了,那么,将能够并排了,并且能够设置宽高了。无论它原来是个div还是个span。所有标签,浮动之后,已经不区分行内、块级了。标准流的特性已经不能约束它了。
浮动的元素互相贴靠
我们给三个div均设置了float: left;
属性之后,三个div就都靠左浮动了,然后设置宽高。当改变浏览器窗口大小时,可以看到div的贴靠效果:
但是要注意三号没有位置去贴左墙的时候并不会向上贴一号div:
同样,float还有一个属性值是right,这个和属性值left是对称的,表示向右浮动。
文字环绕
当盒子浮动了之后脱离文档流,会盖住文档流里的东西,但是不会盖住文字,文字会自然环绕在浮动的盒子四周,即标准流中的文字不会被浮动的盒子遮挡住,文字在这里就像水一样。
为避免混乱,要浮动,大家都一起浮动,这样才方便布局。
收缩
一个浮动的元素,如果没有设置width,那么将自动收缩为内容的宽度(这点非常像行内元素)。
块级元素,如果不设置width,它会单独霸占整行,就像水流自然地在容器中铺开。
所以说,浮动就好像是让一个元素由水结成了冰、由流动的水变成了漂浮在水面的盒子。
浮动清除
解决方案
(1)对于一个div1,它有两个孩子div2和div3,div1不浮动而div2和3是浮动的,如果给div1设置的宽度大于两个孩子的宽度之和,两个孩子会正常并排在div1中,而如果div1的宽度小于两个孩子之和,div3会掉下来。这就像div1也有一个文档流一样,两个孩子是在div1的文档流中浮动,浮动的效果取决于div1的宽度,而之前的例子是元素浮动在全局的文档流中,改变浏览器的宽度才会影响浮动效果。
(2)要想一个元素浮动,那么它的祖先元素一定要有高度。有高度的盒子才能关住浮动,否则浮动的元素会漂出来在离它最近的有高度的祖先的文档流中浮动,如果它的祖先都没有高度,就会最终漂到全局文档流中浮动。
(3)对于(2)中的情况,如果不想给祖先设置设置高度怎么办?就给浮动元素使用clean属性清除浮动:clear:both;
。both是指左右浮动都清除掉,也可以只清除掉一侧的浮动。清除浮动实际上就是不允许它的左右侧有浮动的元素,这样即使高度为0,关不住浮动,浮动的元素也不会往外漂了。
(4)还可以使用隔墙法,为两个div中添加一堵墙,使得两个没有高度的div隔开,这样它们的浮动元素也就不会漂出来了,这堵墙实际上也是一个带有clear:both属性的div。这样就可以顺便为这个div设置height来决定隔开空隙的大小了。
(5)内墙法:一个父亲是不能被浮动的儿子撑出高度的。在div中放一个有宽高的p,div会被撑出高度,但是一旦这个p开始浮动,那么这个div瞬间就没了高度。这时,我们可以在div的里面、p的后面再放一个放一个带有clear:both属性的div,就又给div撑出了高度,这个插入的div就叫做内墙。与外墙法相比,内墙法的优势(本质区别)在于内墙法可以给它所在的家撑出高度,而外墙法虽然一道墙可以把两个div隔开,但是这两个div还是没有高的。
(6)使用偏方:overflow:hidden;
。这本来是用来清除溢出到盒子外面的文字,但后来发现给父亲设置这个属性可以让父亲被浮动的孩子撑出高度,因此在这里可以作为偏方使用。这一方法和内墙法一样能使父亲获得高度,也是和外墙法的区别。
例子
对于以下的HTML代码:
1 |
|
和CSS代码:
1 |
|
没有清除浮动:
- 新闻标题1 日期1
- 新闻标题2 日期2
使用overflow: hidden;
清除了浮动:
这就是一个使用overflow: hidden清除浮动的例子。如果没有加overflow:hidden,那么第二行的li会和第一行li在一起浮动,因为li和ul都没有高度,关不住浮动的孩子。
兼容性问题
(1)IE6不支持小于12px的盒子,任何小于12px的盒子,在IE6中看都大。即IE 6不支持微型盒子。
解决方法:设置字体大小小于盒子的高:
1 |
|
这样就可以使得盒子高度正常了,这里的字体大小属性之所以加下划线是因为想让它只对IE6浏览器生效,加下划线的是其私有属性,只被IE6所识别,不会干扰其它浏览器的效果。
(2)IE6不支持用overflow:hidden;来清除浮动。
解决方法:
1 |
|
这样的加下划线为解决兼容性问题的属性叫做伴生属性,它们总是相伴使用。