目录
1.CSS三大特性
1.1层叠性(就近原则)
当给相同的选择器设置相同的样式,其中一个样式会覆盖掉另一个样式,而且是哪个样式离结构更近就执行哪个样式。
1.2 继承性(子承父业)
当给一个标签设置样式时,该标签的子系标签都会被设置一样的样式(一般继承和文字相关的样式)
特殊:行高继承时的特殊写法。
运行后检查:
可见正好是21px。
1.3 优先级
1.3.1基础选择器
当两个选择器类型不同,但是修改的样式相同时,则要依据选择器的优先级来判断执行哪个。
(来源04-CSS三大特性之优先级_哔哩哔哩_bilibili)
优先级4个位之间没有进制,即0,0,1,0>0,0,0,9999。
可以记为:选择器作用范围越大,则权重越低;作用范围越小,权重越高。
红框标出的是当前标签中权重最大的,运行:
特别的,!important 能强行使某个选择器的优先级为最优先,具体用法如下:
运行:
注意:继承的权重是0。示例如下:
如上图所示的代码,请判断最终输出的数字颜色是红色还是棕色。
答案:红色。因为666三个数字的样式color:brown是继承所得的,所以color:brown 的权重是0,而标签选择器p 的权重是0,0,0,1,因此优先显示color:red。
从这里我们也可以解释为什么<a>连接的样式需要单独指定才能生效,因为浏览器默认给a定义了这样一个样式:color:blue;text-decoration:underline,其优先级高于继承,因此指定<a>标签的父系的样式不会改变<a>标签的样式。在我们单独指定了<a>的样式后,由于CSS的层叠性,优先显示我们指定的样式,因此<a>的样式发生改变。
1.3.2 复合选择器
当遇到复合选择器时,采用优先级叠加之后再判断优先级的方式。示例:
请读者判断最终的数字显示的颜色是什么。答案是黄色:
这是因为div p { }是由两个标签选择器组成的复合选择器,其权重是0,0,0,2;大于0,0,0,1,因此优先级大于color:red;
注意:a:hover的权重是0,0,1,1(a视作一个标签选择器,hover是链接伪类选择器)
优先级相关练习:
请读者考虑,若想让666变成绿色并且字体加粗,应该怎么写?
错解:
可以看到只改变了字体粗细,没改变字体颜色,这是因为color:green的优先级不如color:red的优先级。 计算可知,color:red的权重=0,0,1,1;而color:green的权重=0,0,1,0.
正解:
或许有人认为.nav .green{} 这种写法在最终的输出结果上等价于div .green{} ,这种想法理论上可以是对的,明显div .green{}的权重等于.nav p{},所以如果想使用div .green{}的写法,则需要利用CSS的层叠性,将div .green{}写在.nav p{}的后面。如下图:
但是考虑到可读性和检查的便利性,还是建议采用两个类选择器复合的写法。
2. 盒子模型
2.1组成
盒子模型主要由4部分组成,分别是:内容、边框、内边距(padding)、外边距(margin)。
其中,内边距决定了内容与边框的距离,外边距决定了盒子与盒子之间的距离。
2.1.1 边框
边框由三部分组成:边框粗细(border-width=Ypx)、边框样式(border-style)、边框颜色(border-color)。
其中,边框样式常用的值包括:solid(实线)、dashed(虚线)、doted(点线 )
边框也存在复合写法,不过边框的简写和一样是没有简写顺序的,一般可以采用width、style、color的顺序书写,如:border:5px、solid、pink;
边框还能4条边分开写,分别是border-top、border-bottom、boder-left、boder-right。
边框与CSS层叠性:
如果想要得到一个上边框是红色,其余边框是蓝色的盒子,最简单的写法是什么呢?如下:
这个例子说明,层叠性不仅在两个不同的选择器之间体现,在同一个选择器的内部也存在。
细线边框
前面我们制作小说排行榜案例时,采用行内样式border=Ypx的方式给单元格加上了边框,细心的读者在实践时应该能发现,这种写法在vscode上是被标红了的,也就是编译器不提倡这种写法,如今学习了CSS的边框,就可以利用CSS来控制表格的内外格线了。
写法也很简单,只需用复合标签选择器如:table,td,th(表格头部也需要线) {} 即可,但这种写法仍然存在一些缺陷,就是相邻的单元格由于都具有边框线,导致两个表格的边框线合在一起时,边框线的宽度将会是我们设定的宽度的2倍(1px+1px=2px),为了消除这种不协调,引入了细线边框“border-collapse”这种属性。border-collapse属性控制浏览器绘制表格的方式,他控制相邻单元格的边框合并在一起显示,写法:border-collapse:collapse。
边框的大小会影响盒子的实际大小
例如在一个200*200的盒子中,设定其边框为10px,用于存放内容的200*200大小固定不变,边框会占据外部空间,则最终整个盒子视觉上的大小就是220*220,因此在实际测量时要考虑其中的误差,只测量盒子不包括边框部分的长、宽度。
2.1.2 内边距
内边距的属性:
(图源:15-盒子模型内边距padding_哔哩哔哩_bilibili)
用这种方式实现侧边栏导航,比我们之前采用text-indent缩进的方式更显然、更专业,而且能实现更详细的需求。
内边距的复合属性:
(图源同上)
可以将顺序记为顺时针(当属性值为2个或3个时,认为左右边距是一个整体,因此沿顺时针方向到右边距时同时设定了左右边距)。
padding也会影响盒子的实际大小
影响盒子大小的方式同边框,即存放内容的部分大小固定不变,内边距会额外占据外部空间,从而撑大了盒子。在实际应用中,由于内边距的宽度测量不出来,因此只能测量整个盒子的大小,然后再让width/height减去多出来的内边距大小(记得乘2)。例如:在200*200的盒子中想加入20px的内边距,但是要求最终盒子视觉大小仍为200*200,则令width=160px;height=160px;padding=20px;
padding应用案例——导航栏
(图源同上)
可以看到,当导航栏的多个小盒子中的字数不同,如果直接设定小盒子的宽度,最终会导致导航栏之间的间隙不同,影响美观;但如果设定盒子的padding,则能保证相邻导航栏文字之间的距离一定相等。
实践案例——导航栏
实现以下导航栏效果:
错误代码:
当笔者信心满满的写到这里时,运行代码却发现,没有实现a链接所在的一块距离在鼠标经过时都变暗的效果。重新检查代码才发现原来是a链接没有转为行内块元素,而是找了一个span盒子(实际上是一个行内元素,无法设定宽、高)装着a链接,所以盒子中除了链接以外的区域还是div的,并不属于a链接的一部分,因此a:hover没法对整个盒子起作用。正确代码应该如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
div {
height: 41px;
border-top: 3px solid #ff8500;
border-bottom: 1px solid #edeef0;
background-color: #fcfcfc;
}
.bg a {
display: inline-block;
line-height: 41px;
text-decoration: none;
color: #4c4c4c;
padding: 0px 20px;
}
.bg a:hover {
background-color: #eee;
color: #ff8500;
}
</style>
</head>
<body>
<div class="bg">
<a href="#">设为首页</a>
<a href="#">手机新浪网</a>
<a href="#">移动客户端</a>
<a href="#">博客</a>
<a href="#">微博</a>
<a href="#">关注我</a>
</div>
</body>
</html>
让padding不撑开盒子的方法:
如果盒子本身没有指定width/height属性,则此时padding不会撑开盒子大小。
举例:
运行:
设定padding:
运行:
2.1.4 外边距
(图源同上)
margin的复合写法:
规则与padding一样:
外边距典型应用:
利用外边距可以使块级盒子水平居中,但是必须满足两个条件:
(i)盒子必须指明width(否则独占一行,居中没有意义);
(ii)盒子左右的外边距都设置为auto。
常用写法是 margin:0 auto;上下边距根据实际需要设定即可。
拓展:
让行内元素和行内块元素水平居中的方法:
给其父元素添加text-align:center即可。(对图片和文本都起作用)
外边距合并——嵌套块元素塌陷
1.相邻块元素(即兄弟块元素之间)的合并,意即当两个兄弟块元素相邻,上面的块元素存在margin-bottom,下面的块元素存在margin-top,结果二者相遇之后,二者的垂直距离竟然不是一般认为的margin-bottom+margin-top,而是取二者中最大的那个值。
解决方法:只给其中的一个盒子加上外边距。
2.嵌套块元素的塌陷
以上三种方法中,前两中方法的思路近似于将父块元素和子块元素隔绝开(利用border或者padding都可以),这样就不会发生塌陷。实际使用更多的是第三种方法,可以采用通配符选择器将所有的嵌套块元素塌陷问题全部规避。
2.1.5清除内外边距
网页元素的很多都带有默认的内外边距,而且不同浏览器的默认值也不同,因此在布局之前,我们需要清除网页元素的内外边距。(ul里的li呈现出来的文本有很明显的左边距,那个就是默认边距的体现)
清除的方式其实很简单,只需要用通配符选择器*{margin:0 ;padding:0;}即可。
2.1.6兼容性
行内元素为了照顾兼容性,只设置左右内外边距,上下边距即使设置了也不显示。想设置的话只需转化为块元素和行内块元素即可。