一、CSS三大特性
1.层叠性
简单来说就是后设置的样式会覆盖前设置的样式,但是只有冲突的样式会覆盖。像下面这种情况,颜色黑会被红色覆盖掉,但是字体大小却不会有变化。
div {
color: black;
font-size: 15px;
}
div {
color: red;
}
2.继承性
子标签继承父标签的某些样式,主要是text、font、line等开头的以及color属性。如下面这样设置的话,p标签中的文字也会变成黑色15px,继承了div中的属性
div {
color: black;
font-size: 15px;
}
<div>
<p>并不是所有的属性都继承,只继承文字相关的属性</p>
</div>
行高的继承:
在定义行高时,我们可以像下面这样写,font:字体大小/绝对行高
body {
color: black;
font: 15px/24px 'Microsoft YaHei'
}
但是,更常用的写法是font:字体大小/相对行高,这里的1.5是指字体大小的1.5倍
font: 15px/1.5 'Microsoft YaHei';
此时我如果在body下面再定义子标签div,并把它的css设置为:
div {
font-size: 24px;
}
这时div中字体的行高就会变成24px的1.5倍(其他没有指定文字大小的标签会默认继承body中的文字大小)
3.优先级
选择器权重如下表所示:
案例:元素选择器<类选择器<id选择器<标签内style样式<!important
div {
color: red !important;
}
.demo {
color: greenyellow;
}
#demo {
color: brown;
}
<div class="demo" id="demo" style="color:blue">
<p>并不是所有的属性都继承,只继承文字相关的属性</p>
</div>
优先级这里的注意事项:子元素继承的权重是0,如果该元素没有直接选中,那么不管父元素权重有多高,子元素得到的权重都是0。这句话啥意思呢?举个例子
div {
#demo {
color: red;
}
<div id="demo">
<p>并不是所有的属性都继承,只继承文字相关的属性</p>
<a href="#">这是一个链接</a>
</div>
这个运行最终结果应该是一段红色的文字,如果此时我们把css改成
div {
#demo {
color: red;
}
p {
color:yellow;
}
那么结果就会变成黄色,理论上来说p是一个元素选择器,应该比不上id选择器#demo的优先级,但是此时因为我们单独对p进行了设置,所以会优先显示p的样式。就像如果我在div里加一个a标签,那么a标签也不会单独继承div的红色,因为a标签默认设置是蓝色加下划线。
3.1 优先级中权重的叠加问题
复合选择器会有权重叠加的问题,元素会选择权重高的去使用,比如我定义了下面这个样式
ul li {
color: red;
}
元素选择器ul是0,0,0,1 li是0,0,0,1 两个叠加变成0,0,0,2
我再用类选择器定义另一个样式
.nav li {
color: purple;
}
类选择器.nav是0,0,1,0 元素选择器li是0,0,0,1 两个做加法最终结果0,0,1,1
此时如果要对下面的li进行操作,那么结果肯定会变成purple
<ul class="nav">
<li>1111</li>
<li>2222</li>
<li>3333</li>
</ul>
权重问题举例:在默认以下样式下,如果我想把下面的第一个li变成蓝色加粗,怎么搞?
.nav li {
color: purple;
}
<ul class="nav">
<li class="one">1111</li>
<li>2222</li>
<li>3333</li>
</ul>
像下面这样搞行吗?
.one {
color: yellow;
font-weight: 700;
}
显然不行,这样只会加粗,但还是紫色,这是因为.nav li 的权重是11,而.one的权重是10,导致修改失败,但是如果我这样写的话:
.nav .one {
color: goldenrod;
}
两个权重加起来是20,那必然就修改成功了。当然你也可以用id选择器
二、盒子模型
盒子模型本质上是一个盒子,主要包括border边框、外边距margin、内边距padding,内容content
1.border边框的属性
主要包括border-width(边框宽度,以px为单位),border-style(边框样式,常用的有实线solid,虚线dashed,点线dotted),border-color(边框颜色)
div {
width: 200px;
height: 300px;
border-width: 5px;
border-style: solid;
/* border-style: dashed; */
/* border-style: dotted; */
border-color: purple;
}
边框属性的复合写法,border:粗细 样式 颜色,也可以单独设置上、下、左、右
border: 1px dashed red;
border-left: 1px dotted yellow;
border-top: 2px solid pink;
border-right: 3px solid grey;
border-bottom: 4px dashed orange;
如何实现细线边框?这里用到的是border-collapse: collapse; 表示相邻边框合并在一起,这样就不会很宽了(不过这个属性好像只针对表格才起作用,奇怪)
table, td {
border: 1px solid red;
/* 合并相邻的边框 */
border-collapse: collapse;
}
最后提醒大家注意,边框会影响盒子的实际大小噢,边框会撑大盒子
2.内边距padding
padding是指盒子边框和内容之间的距离,上下左右都可以调
div {
width: 100px;
height: 300px;
padding-left: 20px;
padding-right: 30px;
padding-top: 20px;
padding-bottom: 30px;
background-color: greenyellow;
}
当然,上面这种写法看起来比较复杂,有没有简单一点的写法呢?当然有,下面这四种都要重点记住:
这里要注意最后一个,是上右下左的顺序
padding: 20px 30px 40px 50px;
这里也要注意,和边框border一样,如果盒子已经指定了!!宽度和高度!!,此时如果设置padding,会撑大盒子,这一点要尤其注意!!!!!!!!!!!!!
2.1新浪导航栏案例:如何巧妙利用padding会撑开盒子的特性?
假设要做一个新浪导航栏,那么如果我们让每个盒子宽度高度相同,然后往里填字,这样行吗?
显然不是那么美观,但是此时如果利用padding内边距,使每个盒子左右内边距固定一个数值,就非常nice
代码实现如下:
.nav a {
text-decoration: none;
color: #4c4c4c;
display: inline-block;
height: 41px;
/* 上下是0,左右时20 */
padding: 0 20px;
}
.nav a:hover {
background-color: bisque;
color: #ff8500;
}
.nav {
border-top: 3px solid #ff8500;
border-bottom: 1px solid #edeef0;
height: 41px;
background-color: #fcfcfc;
line-height: 41px;
}
<div class="nav">
<a href="#">设为首页</a>
<a href="#">新浪客户端</a>
<a href="#">微博</a>
<a href="#">关注我</a>
</div>
这里要注意几个点,第一个是关于行内元素a,需要转换成行内块元素,使用display: inline-block; 这样就可以增加a的点击范围,而且可以调整a的高度和宽度,如果是display:block转换成块元素,则a会竖着放。第二个就是这个padding:0 20px; 0是不能省略的,上下0,左右20
什么情况下padding不会撑开盒子?
在盒子内部没有指定width属性,就不会撑开盒子,或者如果父元素指定了width,那么在子元素中没有指定width,就不会撑开盒子。
3.外边距margin
margin和padding类似,都有上下左右,简写形式代表的意义也一样
margin-left: 20px;
margin-right: 20px;
margin-top: 20px;
margin-bottom: 20px;
margin: 20px 30px 40px 50px;
margin的一个典型应用是块级盒子水平居中,用到的是margin:0 auto;意思是上下是0,左右居中。 注意,盒子必须有宽度才行噢
margin: 0 auto;
/* 或者margin: auto;
再或者margin-left: auto; margin-right: auto; */
上面是针对块级盒子来说的,那么如果我想要让行内元素(如span)或者行内块元素(如img)也水平居中对齐呢?很简单,给其父元素添加text-align: center; 就可以了
3.1外边距合并问题
如果有两个盒子,上面的盒子指定:
margin-bottom: 100px;
下面的盒子指定:
margin-top: 200px;
那么最终两个边距会合并,盒子之间距离为200px,而不是300px
3.2块元素套娃时的塌陷问题
如果我们在大盒子中加了一个小盒子
<div class="father">
<div class="son">儿子娃娃</div>
</div>
此时设置父元素margin-top为10,我想让里面的小盒子在大盒子里往里靠靠,于是子元素margin-top设置为30,但是最终小盒子没有往里面走,反而大盒子往下靠了30,奇怪。
.father {
width: 200px;
height: 200px;
margin-top: 10px;
background-color: red;
}
.son {
width: 100px;
height: 100px;
margin-top: 30px;
background-color: skyblue;
}
这就是典型的嵌套块元素塌陷问题,可以有以下解决方案
(1)为父元素定义上边框,transparent是透明
border-top: 1px solid transparent;
(2)为父元素定义上内边距
padding-top: 1px;
(3)使用overflow:hidden;
overflow: hidden;
除此之外还有浮动,固定,绝对定位等方法,这三个方法都是脱标的,也就是说脱标的元素是不会出现外边距合并和塌陷的问题的。
4.清除内外边距
网页元素中很多都带有默认的内外边距,不同浏览器默认的也不一样,我们在布局前,需要清除内外边距。
* {
margin: 0;
padding: 0;
}
除此之外,行内元素为了照顾兼容性,尽量只设置左右内外边距,不设置上下内外边距,因为设置了基本上也没啥用。如果转换为块元素或者行内块元素就可以随便设置了。
三、产品模块的案例
实现下面这个效果:
代码如下:
/* 这个不要丢掉 */
* {
margin: 0;
padding: 0;
}
a {
color: black;
text-decoration: none;
}
/* 对整个大盒子进行样式设置 */
.box {
width: 298px;
height: 415px;
background-color: white;
margin: 10px auto;
border: 2px solid #e2e5e3;
}
/* 让图片正好按照盒子的宽度缩放 */
.box img {
width: 100%;
}
/* 第一行字 因为块级元素div是和父元素box宽度一样,这里不设置width,使用padding不会撑开盒子 */
/* 但是这里指定了高度,如果继续使用padding设置上下边距,会撑大盒子,所以上下边距要用margin来调节 */
.review {
height: 70px;
font-size: 14px;
padding: 0 28px;
/* 这里设置的外边距30比大盒子的10是多20的,但是没有出现塌陷,是因为大盒子
设置了上边框,还有一个原因是text1上面是一个a标签 */
margin-top: 30px;
}
.appraise {
color: #cfd0cf;
font-size: 12px;
padding: 0 28px;
/* 这里又没有塌陷,是因为塌陷只发生在嵌套元素中,而p和div是兄弟关系(这里不太懂,留个疑点) */
margin-top: 20px;
}
.info {
padding: 0 28px;
margin-top: 20px;
font-size: 14px;
}
.info h5 {
display: inline-block;
font-weight: 400;
}
.info em {
/* 让斜线变成竖的 */
font-style: normal;
padding-left: 15px;
padding-right: 10px;
color: #cfd0cf;
}
.info span {
color: orange;
font-size: 14px;
}
<div class="box">
<a href="#">
<img src="./images/picture.jpg" alt="快买我兄弟">
</a>
<div class="review"><a href="#">快递牛,整体不错蓝牙秒连.红米给力给力给力给力嗷嗷嗷</a></div>
<p class="appraise">来自于1246486788的评论</p>
<div class="info">
<h5><a href="#">Redmi AirDots真无线蓝牙...</a></h5>
<em>|</em>
<span>99.9</span>
</div>
</div>
四、快报模块案例
实现下面这个效果:
* {
margin: 0;
padding: 0;
}
a {
color: rgb(145, 143, 143);
text-decoration: none;
}
.box {
width: 320px;
height: 212px;
border: 2px solid #d5d8d5;
margin: 100px auto;
}
.title {
padding: 14px 20px;
border-bottom: 2px dotted #d5d8d5;
}
.box p {
line-height: 30px;
padding: 0 28px;
}
.top {
margin-top: 3px;
}
.box p:hover {
text-decoration: underline;
}
<div class="box">
<div class="title">
品优购快报
</div>
<p class="top"><a href="#">【特惠】爆款耳机5折秒!</a></p>
<p><a href="#">【特惠】华为平板只要9块9!</a></p>
<p><a href="#">【特惠】3080显卡只需要9.9</a></p>
<p><a href="#">【特惠】杭州房价限时100块钱1平</a></p>
<p><a href="#">【特惠】天呐,买房送法拉利</a></p>
</div>
这个也可以用列表ul li 来做,用列表需要加上一句list-style: none; 把列表前面的小圆点去掉
两个案例跟着做下来的感受:还是应该多自己动手敲,之前很多知识点当时听懂了,但是到用的时候才发现各种问题都不清晰,比如元素为什么会塌陷,这个地方为什么用margin不用padding等等,前端知识很多,这才刚刚开始,共勉。