一、CSS简介
网页实际上是一个多层的结构,通过CSS
(层叠样式表)可以分别为网页的每一个层来设置样式,而最终我们能看到只是网页的最上边一层,总之一句话,CSS
用来设置网页中元素的样式,使用CSS
来修改元素样式的方式大致可以分为3种:
① 内联样式(行内样式)
在标签内部通过style
属性来设置元素的样式
<p style="color:red;font-size:60px;">内联样式(行内样式)</p>
问题:使用内联样式,样式只能对一个标签生效。如果希望影响到多个元素,必须在每一个元素中都复制一遍;并且当样式发生变化时,我们必须要一个一个的修改,非常的不方便。(注意:开发时绝对不要使用内联样式)
② 内部样式表
将样式编写到head
中的style
标签里然后通过css
的选择器来选中元素并为其设置各种样式可以同时为多个标签设置样式,并且修改时只需要修改一处即可。内部样式表更加方便对样式进行复用
<style>
p{
color:green;
font-size:50px;
}
</style>
问题:我们的内部样式表只能对一个网页起作用,它里边的样式不能跨页面进行复用
③ 外部样式表
可以将css
样式编写到一个外部的CSS
文件中,然后通过link
标签来引入外部的CSS
文件
<link rel="stylesheet" href="./style.css">
外部样式表需要通过link
标签进行引入,意味着只要想使用这些样式的网页都可以对其进行引用使样式,可以在不同页面之间进行复用
将样式编写到外部的CSS
文件中,可以使用到浏览器的缓存机制,从而加快网页的加载速度,提高用户的体验
④ CSS 基本语法
语法:选择器 声明块
选择器:通过选择器可以选中页面中的指定元素
- 比如
p
的作用就是选中页面中所有的p
元素声明块
声明块:通过声明块来指定要为元素设置的样式
- 声明块由一个一个的声明组成,声明是一个名值对结构
- 一个样式名对应一个样式值,名和值之间以
:
连接,以;
结尾
h1{
color: green;
}
二、CSS 选择器
2.1 通配选择器(Universal selector)
- 作用:选中页面中的所有元素
- 语法:
*
- 例子:
*{}
*{
color: red;
}
2.2 元素选择器(Type selector)
也叫类型选择器、标签选择器
- 作用:根据标签名来选中指定的元素
- 语法:
elementname{}
- 例子:
p{}
、h1{}
、div{}
p{
color: red;
}
h1{
color: green;
}
2.3 类选择器(Class selector)
- 作用:根据元素的
class
属性值选中一组元素 - 语法:
.classname
- 例子:
.blue{}
.blue{
color: blue;
}
.size{
font-size: 20px;
}
class
是一个标签的属性,它和id
类似,不同的是class
- 可以重复使用
- 可以通过
class
属性来为元素分组 - 可以同时为一个元素指定多个
class
属性
<p class="blue size"> 类选择器(Class selector)</p>
2.4 ID选择器(ID selector)
- 作用:根据元素的
id
属性值选中一个元素 - 语法:
#idname{}
- 例子:
#box{}
、#red{}
#red{
color: red;
}
2.5 属性选择器(Attribute selector)
- 作用:根据元素的属性值选中一组元素
- 语法1:[属性名] 选择含有指定属性的元素
- 语法2:[属性名=属性值] 选择含有指定属性和属性值的元素
- 语法3:[属性名^=属性值] 选择属性值以指定值开头的元素
- 语法4:[属性名$=属性值] 选择属性值以指定值结尾的元素
- 语法5:[属性名*=属性值] 选择属性值中含有某值的元素
- 例子:
p[title]{}
、p[title=e]{}
、p[title^=e]{}
、p[title$=e]{}
、p[title*=e]{}
p[title]{
color: orange;
}
p[title=e]{
color: orange;
}
p[title^=e]{
color: orange;
}
p[title$=e]{
color: orange;
}
p[title*=e]{
color: orange;
}
2.6 复合选择器
① 交集选择器
- 作用:选中同时复合多个条件的元素
- 语法:
选择器1选择器2选择器3选择器n{}
- 注意点:交集选择器中如果有元素选择器,必须使用元素选择器开头
div.red{
font-size: 30px;
}
.a.b.c{
color: blue;
}
② 并集选择器(选择器分组)
- 作用:同时选择多个选择器对应的元素
- 语法:
选择器1,选择器2,选择器3,选择器n{}
- 例子:
#b1,.p1,h1,span,div.red{}
h1,span{
color: green;
}
2.7 关系选择器
- 父元素:直接包含子元素的元素叫做父元素
- 子元素:直接被父元素包含的元素是子元素
- 祖先元素:直接或间接包含后代元素的元素叫做祖先元素;一个元素的父元素也是它的祖先元素
- 后代元素:直接或间接被祖先元素包含的元素叫做后代元素;子元素也是后代元素
- 兄弟元素:拥有相同父元素的元素是兄弟元素
① 子元素选择器(Child combinator)
- 作用:选中指定父元素的指定子元素
- 语法:父元素 > 子元素
- 例子:
A > B
div.box > p > span{
color: orange;
}
② 后代元素选择器(Descendant combinator)
- 作用:选中指定元素内的指定后代元素
- 语法:祖先 后代
- 例子:
A B
div span{
color: skyblue;
}
③ 兄弟元素选择器(Sibling combinator)
- 作用:选择下一个兄弟
- 语法:前一个 + 下一个 前一个 ~ 下一组
- 例子1:
A1 + A2
(Adjacent sibling combinator)A1之后的第一个A2兄弟元素 - 例子2:
A1 ~ An
(General sibling combinator)A1之后的所有A2兄弟元素
p + span{
color: red;
}
p ~ span{
color: red;
}
2.8 伪类选择器
伪类(不存在的类,特殊的类),伪类用来描述一个元素的特殊状态,比如:第一个子元素、被点击的元素、鼠标移入的元素.…
伪类一般情况下都是使用:
开头
:first-child
:第一个子元素:last-child
:最后一个子元素:nth-child()
:选中第n个子元素n
:第n
个,n的范围0到正无穷2n
或even
:选中偶数位的元素2n+1
或odd
:选中奇数位的元素
以上这些伪类都是根据所有的子元素进行排序的
:first-of-type
:同类型中的第一个子元素:last-of-type
:同类型中的最后一个子元素:nth-of-type()
:选中同类型中的第n个子元素
这几个伪类的功能和上述的类似,不同点是他们是在同类型元素中进行排序的
:not()
否定伪类,将符合条件的元素从选择器中去除
/* ul下所有li,黑色 */
ul>li {
color: black;
}
/* ul下第偶数个li,黄色 */
ul>li:nth-child(2n) {
color: yellow;
}
/* ul下第奇数个li,绿色 */
ul>li:nth-child(odd) {
color: green;
}
/* ul下第一个li,红色 */
ul>li:first-child {
color: red;
}
/* ul下最后一个li,黄色 */
ul>li:last-child {
color: orange;
}
:link
:未访问的链接:visited
:已访问的链接- 由于隐私的原因,所以
visited
这个伪类只能修改链接的颜色
- 由于隐私的原因,所以
:hover
:鼠标悬停的链接:active
:鼠标点击的链接
/* unvisited link */
a:link {
color: red;
}
/* visited link */
a:visited {
color: yellow;
}
/* mouse over link */
a:hover {
color: green;
}
/* selected link */
a:active {
color: blue;
}
2.9 伪元素选择器
伪元素,表示页面中一些特殊的并不真实的存在的元素(特殊的位置)
伪元素使用::
开头
::first-letter
:表示第一个字母::first-line
:表示第一行::selection
:表示选中的内容::before
:元素的开始::after
:元素的最后::before
和::after
必须结合content
属性来使用
/* 段落首字母设置大小为30px */
p::first-letter{
font-size: 30px;
}
/* 段落第一行设置为黄色背景 */
p::first-line{
background-color: yellow;
}
/* 段落选中的部分变绿色 */
p::selection{
background-color: green;
}
/* div前加上内容 */
div::before{
content: 'BEFORE';
color: red;
}
/* div后加上内容 */
div::after{
content: 'AFTER';
color: blue;
}
三、样式继承与其他概念
3.1 继承
样式的继承,我们为一个元素设置的样式,同时也会应用到它的后代元素上
继承是发生在祖先后后代之间的,继承的设计是为了方便我们的开发
利用继承,我们可以将一些通用的样式,统一设置到共同的祖先元素上。这样只需设置一次即可让所有的元素都具有该样式
注意,并不是所有的样式都会被继承: 比如背景相关的,布局相关等的这些样式都不会被继承。
3.2 选择器的权重
当我们通过不同的选择器,选中相同的元素,并且为相同的样式设置不同的值时,此时就发生了样式的冲突。
发生样式冲突时,应用哪个样式由选择器的权重(优先级)决定选择器的权重
选择器 | 权重 |
---|---|
内联样式 | 1, 0, 0, 0 |
ID选择器 | 0, 1, 0, 0 |
类和伪类选择器 | 0, 0, 1, 0 |
元素选择器 | 0, 0, 0, 1 |
通配选择器 | 0, 0, 0, 0 |
继承的样式 | 没有优先级 |
比较优先级时,需要将所有的选择器的优先级进行相加计算,最后优先级越高,则越优先显示(分组选择器是单独计算的)
选择器的累加不会超过其最大的数量级,类选择器再高也不会超过ID选择器
如果优先级计算后相同,此时则优先使用靠下的样式
可以在某一个样式的后边添加!important
,则此时该样式会获取到最高的优先级,甚至超过内联样式,注意:在开发中一定要慎用!
<style>
#box1{
background-color: orange;
}
div{
background-color: yellow;
}
.red{
background-color: red;
}
</style>
<div id="box1" class="red" style="background-color: skyblue;">选择器的权重</div>
3.3 长度单位
① 像素
我们先来看下某度上关于像素(pixel
,缩写px
)的介绍
像素是指由图像的小方格组成的,这些小方块都有一个明确的位置和被分配的色彩数值,小方格颜色和位置就决定该图像所呈现出来的样子。
可以将像素视为整个图像中不可分割的单位或者是元素。不可分割的意思是它不能够再切割成更小单位抑或是元素,它是以一个单一颜色的小格存在 [1] 。每一个点阵图像包含了一定量的像素,这些像素决定图像在屏幕上所呈现的大小
也就是说,显示器屏幕实际上是由一个一个的小点(单位色块,即像素)构成的
② 屏幕分辨率
例如,屏幕分辨率是1920×1080,则该屏幕水平方向有1920个像素,垂直方向有1080个像素
- 不同屏幕的像素大小是不同的,也就是说像素大小不像我们现行的长度单位(如米/m)那样有着固定的国际标准
- 所以同样的像素大小在不同的设备上显示效果是不一样的,像素越小的屏幕显示的效果越清晰
③ 图像分辨率
例如,一张图片分辨率是300x200,则该图片在屏幕上按1:1缩放时,水平方向有300个像素,垂直方向有200个像素点
- 图片分辨率越高,1:1缩放时面积越大
- 图片分辨率越低,1:1缩放时面积越小
同一台设备像素大小是不变的,那把图片放大超过100%时占的像素点就多了,但是图像也会变得模糊
④ 百分比
也可以将属性值设置为相对于其父元素属性的百分比,可以使子元素跟随父元素(暂且先理解成父元素,后面会详细说)的改变而改变
em
em
是相对于元素的字体大小来计算的,1em = <self>.font-size * 10
,也就说em
值会根据元素本身的字体大小的改变而改变
rem
rem
是相对于根元素的字体大小来计算,1em = <root>.font-size * 10
,也就说em
值会根据根元素的字体大小的改变而改变
style>
* {
font-size: 24px;
}
.box1{
width: 200px;
height: 200px;
background-color: orange;
}
.box2{
width: 50%;
height: 50%;
background-color: aqua;
}
.box3{
font-size: 20px;
width: 10em;
height: 10em;
background-color: greenyellow;
}
.box4 {
font-size: 20px;
width: 10rem; /*当时用rem时,不管怎么改本元素的font-size都是不会变的。需要定义root元素的font-size才可以 */
height: 10rem;
background-color: red;
}
</style>
<div class="box1">
<div class="box2"></div>
</div>
<div class="box3"></div>
<div class="box4"></div>
3.4 浏览器的默认样式
通常情况,浏览器都会为元素设置一些默认样式。
默认样式的存在会影响到页面的布局,通常情况下编写网页时必须要去除浏览器的默认样式(PC
端的页面)。我们可以尝试编写css样式,以去除浏览器的默认样式,如:
body {
margin: 0;
}
完美解决方案:引入外部样式reset.css和normalize.css
四、盒模型
4.1 文档流(normalflow)
网页是一个多层的结构,一层摁着一层。通过CSS
可以分别为每一层来设置样式,作为用户来讲只能看到最顶上一层。
这些层中,最底下的一层称为文档流。文档流是网页的基础我们所创建的元素默认都是在文档流中进行排列
对于我们来元素主要有两个状态
- 在文档流中
- 不在文档流中(脱离文档流)
那么元素在文档流中有什么特点,我们接着往下看
4.2 块元素和行内元素
块元素
- 块元素会在页面中独占一行
- 默认宽度是父元素的全部(会把父元素撑满)
- 默认高度是被内容撑开(子元素)
行内元素
- 行内元素不会独占页面的一行,只占自身的大小
- 行内元素在页面中左向右水平排列(书写习惯一致)
- 如果一行之中不能容纳下所有的行内元素,则元素会换到第二行继续自左向右排列
- 行内元素的默认宽度和高度都是被内容撑开
4.3 盒子模型
网页设计中常听的属性名:内容(content
)、内边距(padding
)、边框(border
)、外边距(margin
), CSS
盒子模型都具备这些属性。
这些属性我们可以用日常生活中的常见事物——盒子作一个比喻来理解,所以叫它盒子模型。
CSS
盒子模型就是在网页设计中经常用到的CSS
技术所使用的一种思维模型。
Margin
(外边距):清除边框外的区域,外边距是透明的Border
(边框):围绕在内边距和内容外的边框Padding
(内边距):清除内容周围的区域,内边距是透明的Content
(内容) :盒子的内容,显示文本和图像
① 内容区(content)
内容区是盒子模型的中心,它呈现了盒子的主要信息内容,这些内容可以是文本、图片等多种类型
元素中的所有的子元素和文本内容都在内容区中, width
和height
设置排列内容区的大小
.box1{
width: 200px;
height: 200px;
background-color: #bfa;
}
② 边框(border)
边框属于盒子边缘,边框里边属于盒子内部,出了边框都是盒子的外部。注意:边框的大小会影响到整个盒子的大小。
- border-width 边框的宽度:默认3px
- border-top-width 上边框的宽度
- border-right-width 右边框的宽度
- border-bottom-width 下边框的宽度
- border-left-width 左边框的宽度
- border-color 边框的颜色:默认使用color的颜色值
- border-top-color 上边框的颜色
- border-right-color 右边框的颜色
- border-bottom-color 下边框的颜色
- border-left-color 左边框的颜色
- border-style 边框的样式:没有默认值,必须指定
- border-top-style 上边框的样式
- border-right-style 右边框的样式
- border-bottom-style 下边框的样式
- border-left-style 左边框的样式
.box1{
border-width: 10px;
border-color: red;
/*
solid 实线
dotted 点状虚线
dashed 虚线
double 双线
*/
border-style: solid;
}
不论是border-width
、border-color
、border-style
还是其衍生出来的属性写法,都可以指定每个方向的边框情况。设定几个值就决定了对应方向的宽度、颜色或样式
- 四个值:上 右 下 左
- 三个值:上 左右 下
- 两个值:上下 左右
- 一个值:上下左右
其实不管设置几个值,只要记住:其顺序是按顺时针方向设置的,剩下的可以由矩形的对称性推导出来。
border
:简写属性,通过该属性可以同时设置边框所有的相关样式,并且没有顺序要求
- border-top 上边框的宽度、颜色和样式
- border-right 右边框的宽度、颜色和样式
- border-bottom 下边框的宽度、颜色和样式
- border-left 左边框的宽度、颜色和样式
.box1{
border: 10px red solid;
}
③ 内边距(padding)
内边距,也叫填充,是内容区和边框之间的空间
- padding-top 上内边距
- padding-right 右内边距
- padding-bottom下内边距
- padding-left 左内边距
padding
内边距的简写属性,可以同时指定四个方向的内边距,规则和边框中属性值设置一样
<style>
.outer{
width: 200px;
height: 200px;
border: 10px orange solid;
padding-right: 100px;
padding-bottom: 100px;
padding-left: 100px;
}
.inner {
width: 200px;
height: 200px;
background-color: greenyellow;
}
</style>
<div class="outer">
<div class="inner"></div>
</div>
可以看出,当内外div
宽度和高度一样时,由于outer
设置了一个padding
属性,其盒子大小被“撑大了”。
盒子可见框的大小,由内容区、内边距和边框共同决定,所以在计算盒子大小时,需要将这三个区域加到一起计算。
④ 外边距(margin)
外边距,也叫空白边,位于盒子的最外围,是添加在边框外周围的空间。空白边使盒子之间不会紧凑地连接在一起,是CSS
布局的一个重要手段
注意:外边距不会影响盒子可见框的大小,但是外边距会影响盒子的位置和占用空间
一共有四个方向的外边距:
- margin-top 上外边距
- 设置正值,元素自身向下移动
- 设置负值,元素自身向上移动
- margin-right 右外边距
- 设置正值,其右边的元素向右移动
- 设置负值,其右边的元素向左移动
- 上述说法并不准确,对于块元素,设置margin-right不会产生任何效果
- margin-bottom 下外边距
- 设置正值,其下边的元素向下移动
- 设置负值,其下边的元素向上移动
- 上述说法并不准确,对于块元素,会有垂直方向上的边距重叠问题(后面会细说)
- margin-left 左外边距
- 设置正值,元素自身向右移动
- 设置负值,元素自身向左移动
元素在页面中是按照自左向右的顺序排列的,所以默认情况下,如果我们设置的左和上外边距则会移动元素自身, 而设置下和右外边距会移动其他元素。
4.4 水平方向布局
元素在其父元素中水平方向的位置由以下几个属性共同决定:margin-left
、border-left
、padding-left
、width
、padding-right
、border-right
、margin-right
。
一个元素在其父元素中,水平布局必须要满足以下的等式:
margin-left + border-left + padding-left + width + padding-right + border-right + margin-right = 其父元素的宽度
以上等式必须满足,如果相加结果使等式不成立,则称为过渡约束,则等式会自动调整调整的情况:
- 如果这七个值中没有
auto
的情况,则浏览器会自动调整margin-right
值以使等式满足100 + 0 + 0 + 200 + 0 + 0 + 0 = 800 ==> 100 + 0 + 0 + 200 + 0 + 0 + 500 = 800
- 如果这七个值中有
auto
的情况,则会自动调整auto
值以使等式成立
这七个值中有三个值可以设置为auto
:width
、margin-left
、maring-right
- 如果某个值为
auto
,则会自动调整auto
的那个值以使等式成立200 + 0 + 0 + auto + 0 + 0 + 200 = 600 ==> 200 + 0 + 0 + 400 + 0 + 0 + 200 = 800
auto + 0 + 0 + 200 + 0 + 0 + 200 = 600 ==> 400 + 0 + 0 + 200 + 0 + 0 + 200 = 800
200 + 0 + 0 + 200 + 0 + 0 + auto = 600 ==> 200 + 0 + 0 + 200 + 0 + 0 + 400 = 800
- 如果宽度为
auto
,则宽度会调整到最大,其他auto
的外边距会自动设置为0auto + 0 + 0 + auto + 0 + 0 + 200 = 600 ==> 0 + 0 + 0 + 600 + 0 + 0 + 200 = 800
200 + 0 + 0 + auto + 0 + 0 + auto = 600 ==> 200 + 0 + 0 + 600 + 0 + 0 + 0 = 800
auto + 0 + 0 + auto + 0 + 0 + auto = 600 ==> 0 + 0 + 0 + 800 + 0 + 0 + 0 = 800
- 如果外边距都为
auto
,则auto
的外边距会自动均分以使等式成立auto + 0 + 0 + 200 + 0 + 0 + auto = 600 ==> 300 + 0 + 0 + 200 + 0 + 0 + 300 = 800
- 如果某个值为
4.5 垂直方向布局
元素溢出:子元素是在父元素的内容区中排列的,如果子元素的大小超过了父元素,则子元素会从父元素中溢出
使用overflow
/overflow-x
/overflow-y
属性来设置父元素如何处理溢出的子元素,可选值:///
visible
: 溢出内容会在父元素外部位置显示,默认值hidden
:溢出内容会被裁剪,不会显示scroll
:生成两个滚动条,通过滚动条来查看完整的内容auto
:根据需要生成滚动条
4.6 边距折叠
垂直外边距的重叠(折叠):相邻的垂直方向外边距会发生重叠现象
① 兄弟元素
兄弟元素间的相邻,垂直外边距会取两者之间的较大值(两者都是正值)
特殊情况:
- 如果相邻的外边距一正一负,则取两者的和
- 如果相邻的外边距都是负值,则取两者中绝对值较大的
案例:
.box1,.box2{
width:200px;
height:200px;
font-size:100px;
}
.boxl{
background-color: #bfa;
margin-bottom: 100px;
}
.box2{
background-color: orange;
margin-top: 100px;
}
效果:
② 父子元素
父子元素间相邻外边距,子元素会传递给父元素(上外边距)
实例:达到下面效果
代码:
<style>
.box1 {
width: 200px;
height: 100px;
background-color: aqua;
}
.box2 {
width: 100px;
height: 100px;
background-color: orange;
margin-top: 100px;
}
</style>
<div class="box1">
<div class="box2"></div>
</div>
实际效果如下:父子外边距的折叠会影响到页面的布局,必须要进行处理
处理方式1:
.box1 {
width: 200px;
height: 199px;
background-color: aqua;
border-top: 1px solid aqua;
}
.box2 {
width: 100px;
height: 100px;
background-color: orange;
margin-top: 100px;
}
使用了border
属性,就让子元素的外边距不去传递给父元素了,这是为什么呢?
如果父盒子没有设置border
,那么他的子元素无法利用margin-top
来远离父元素的上边框;如果使用了margin-top会使子元素和父元素一起往下移
父不设置border
边框则离得是流不是父盒子,使用了border
让元素脱离了文档流(margin
塌陷)
处理方式2:
.box1 {
width: 200px;
height: 100px;
background-color: aqua;
padding-top:100px;
}
.box2 {
width: 100px;
height: 100px;
background-color: orange;
}
4.7 行内元素的盒模型
行内元素盒模说明:
- 行内元素不支持设置宽度和高度
- 行内元素可以设置
padding
,但是垂直方向padding
不会影响页面的布局 - 行内元素可以设置border,垂直方向的border不会影响页面的布局
- 行内元素可以设置margin,垂直方向的margin不会影响页面的布局
如果我就是想要行内元素对页面布局产生影响呢?
使用display
属性用来设置元素显示的类型
inline
:将元素设置为行内元素block
:将元素设置为块元素inline-block
:将元素设置为行内块元素行内块,既可以设置宽度和高度又不会独占一行table
:将元素设置为一个表格none
:元素不在页面中显示
另一个属性visibility
用来设置元素的显示状态
visible
:默认值,元素在页面中正常显示hidden
:元素在页面中隐藏不显示,但是依然占据页面的位置
4.8 盒模型补充
① 盒子大小
默认情况下,盒子可见框的大小由内容区、内边距和边框共同决定。box-sizing
用来设置盒子尺寸的计算方式(设置width
和height
的作用)。
.box {
width: 200px;
height: 200px;
background-color: yellow;
border: 10px red solid;
/* box-sizing: content-box; */
box-sizing: border-box;
}
可选值:
content-box
:默认值,宽度和高度用来设置内容区的大小
border-box
: 宽度和高度用来设置整个盒子可见框的大小
② 轮廓
outline
用来设置元素的轮廓线,用法和border
一模一样。轮廓和边框不同点是,轮廓不会影响盒子的布局。
.box {
width: 200px;
height: 200px;
background-color: yellow;
outline: 10px red solid;
}
可以很明显看到outline
与border
的区别。我们一般不会直接这么设置轮廓,而是下面这种场景。
.box:hover {
outline: 10px red solid;
}
③ 阴影
box-shadow
属性用于在一个元素的框架周围添加阴影效果,你可以设置多个由逗号分隔的效果。一个盒状阴影由相对于元素的X
和Y
的偏移量、模糊和扩散半径以及颜色来描述
box-shadow
用来设置元素的阴影效果,阴影不会影响页面布局。
.box {
width: 200px;
height: 200px;
background-color: yellow;
box-shadow: 10px 10px orange;
}
④ 圆角
border-radius
属性使一个元素的外边框边缘的角变圆,你可以设置一个半径来做圆角,或者设置两个半径来做椭圆角。
border-radius
用来设置圆角,圆角设置的是圆的半径大小。
- border-top-left-radius
- border-top-right-radius
- border-bottom-left-radius
- border-bottom-right-radius
border-radius: 20px;
border-radius
可以分别指定四个角的圆角
- 四个值:左上 右上 右下 左下
- 三个值:左上 右上/左下 右下
- 两个值:左上/右下 右上/左下
- 一个值:左上/右上/右下/左下
这里同样不需要死记硬背,只要记住遵循顺时针方向和矩形中心点对称原则。与border
不同的是,border
是从上开始顺时针设置,而圆角是从左上开始。
圆
原理很简单,就是绘制正方形,并将四个圆角半径设置为正方形的一半
.box {
width: 200px;
height: 200px;
background-color: yellow;
border-radius: 50%;
}
五、浮动
5.1 浮动介绍
通过浮动可以使一个元素向其父元素的左侧或右侧移动。
使用float
属性来设置于元素的浮动
- none:默认值,元素不浮动
- left:元素向左浮动
- right:元素向右浮动
注意
- 元素设置浮动以后,水平布局的等式便不需要强制成立
- 元素设置浮动以后,会完全从文档流中脱离,不再占用文档流的位置,所以元素下边的还在文档流中的元素会自动向上移动
① 浮动的特点
- 浮动元素会完全脱离文档流,不再占据文档流中的位置
- 设置浮动以后,元素会向父元素的左侧或右侧移动
- 浮动元素默认不会从父元素中移出
<style>
.box1 {
width: 200px;
height: 200px;
background-color: gold;
float: left;
}
.box2 {
width: 300px;
height: 300px;
background-color: green;
}
</style>
<div class="box1"></div>
<div class="box2"></div>
- 浮动元素向左或向右移动时,不会超过前边的浮动元素(先来后到的顺序)
<style>
.box1, .box2, .box3 {
width: 200px;
height: 200px;
float: left;
}
.box1 {
background-color: gold;
}
.box2 {
background-color: green;
}
.box3 {
background-color: red;
}
</style>
<div class="box1"></div>
<div class="box2"></div>
<div class="box3"></div>
- 浮动元素不会超过上边的浮动的兄弟元素,最多就是和它一样高
- 如果浮动元素的上边是一个没有浮动的块元素,则浮动元素无法上移
- 浮动元素不会盖住文字,文字会自动环绕在浮动元素的周围,所以我们可以利用浮动来设置文字环绕图片的效果
简单总结:
- 浮动目前来讲它的主要作用就是让页面中的元素可以水平排列,通过浮动可以制作一些水平方向的布局
- 元素设置浮动以后,将会从文档流中脱离,从文档流中脱离后,元素的一些特点也会发生变化
② 脱离文档流的特点
块元素:
- 块元素不再独占页面的一行
- 脱离文档流以后,块元素的宽度和高度默认都被内容撑开
行内元素:
- 行内元素脱离文档流以后会,特点和块元素一样
5.2 高度塌陷
在浮动布局中,父元素的高度默认是被子元素撑开的
当子元素浮动后,其会完全脱离文档流,子元素从文档流中脱离将会无法撑起父元素的高度,导致父元素的高度丢失
父元素高度丢失以后,其下的元素会自动上移,导致页面的布局混乱
所以高度塌陷是浮动布局中比较常见的一个问题,这个问题我们必须要进行处理!
5.3 BFC
BFC
(Block Formatting Context
)块级格式化环境
BFC
是一个CSS
中的一个隐含的属性,可以为一个元素开启BFC
- 开启
BFC
该元素会变成一个独立的布局区域
元素开启BFC
后的特点:
- 不会被浮动元素覆盖
- 父子元素外边距不会重叠
- 可以包含浮动的元素
可以通过一些特殊方式来开启元素的BFC
:
- 设置为浮动(不推荐):很明显下方元素被覆盖了,总不能让所有元素都浮动吧
- 设置为行内块元素(不推荐):不再独占一行,宽度变了,同时与下方元素产生了一点空隙
- 设置
overflow
为非visible
值:既没有覆盖元素,也保持了独占一方的特性(保持了宽度),与下方元素也保持了最初的间隙。常用的方式为元素设置overflow:hidden
(overflow:auto
也是 ok 的) 开启其BFC
, 以使其可以包含浮动元素overflow:scroll
会有滚动条,可能并不需要的,所以不太推荐
总结
- 可以通过变成浮动元素,来防止自身被浮动元素覆盖(有点“以毒攻毒”那味了)
- 可以设置行内块,来防止自身及其他元素被浮动元素覆盖(如果说浮动是“独善其身”,那行内块就有点“兼济天下”的意思)
- 可以设置
overflow
属性,包含浮动元素(既“独善其身”,又“兼济天下”,但仍有缺陷)
5.4 clear
我们这里设计三个兄弟元素,对前两个元素进行float
的浮动属性设置,看下效果
由于box1
的浮动,导致box3
位置上移也就是box3
受到了box1
浮动的影响,位置发生了改变(注意,这里文字并没有被覆盖,是由于“文字环绕”的问题)
如果我们不希望某个元素因为其他元素浮动的影响而改变位置,可以通过clear属性来清除浮动元素对当前元素所产生的影响
clear
作用:清除浮动元素对当前元素所产生的影响(本质是为元素添加一个margin-top
属性,值由浏览器自动计算),可选值:
- left 清除左侧浮动元素对当前元素的影响
- right 清除右侧浮动元素对当前元素的影响
- both 清除两侧中影响较大一侧元素的影响(注意,这里不是同时清除两侧的影响)
5.5 after
我们学习了上面知识后,了解了高度塌陷问题的解决方式,其中主要有:
- 通过
overflow: hidden
等可以为元素开启BFC
- 通过
clear: both
等可以清除浮动对元素产生的影响
同时也了解到,这两种方式都有一定的弊端和隐患。那有没有一种更好的方式去解决高度塌陷的问题呢?我们直接上效果图
Q1:这里使用了一个伪元素选择器::after,那有人会问了,跟在box2下直接定义一个box3有什么区别呢?
A:我们知道,网页的结构思想是:结构+表现+行为。在box2
下直接定义一个box3
,属于结构;而使用伪元素选择器,属于表现。
而高度塌陷问题属于表现问题,定义box3
的目的是为了撑起box1
的内容,属于表现,而不是结构,所以在css
中定义::after
更符合网页的编程思想
Q2:为什么需要使用display: block呢?
A:因为默认情况下,::after
伪元素是一个行内元素,如果不转为块元素,将仍然撑不起box1
的高度
5.6 clearfix
我们在前面《4.6-边距折叠》一节中说过垂直布局中边距重叠的问题:相邻的垂直方向外边距会发生重叠现象。
如上图所示,子元素设置了一个margin-top
之后,父元素跟随子元素一起进行了移动.即我们之前说的父子元素间相邻外边距,子元素会传递给父元素(上外边距)。
聪明的小伙伴已经想到了,用刚才说的伪元素选择器啊,好,我们先来看下效果
Q1:为什么没有使用clear属性?
A:不是说了吗?clear
是为了清除浮动对布局的影响,我们现在没有浮动的元素啊,我们要讨论的也不是浮动的问题
Q2:display不是还有一个none属性么,为什么不用呢?
A:none
属性是不占据位置,但是也不能让元素相邻的外边距分离啊
Q3:为什么table值就可以呢?
A:这个问题问的非常好,算是问到点上了!我们上面在讲开启BFC
的一些方法的时候,也提到了该属性。而且,应该牢记的是,元素开启BFC
后的其中一个特点就是 父子元素外边距不会重叠。当然,这里也需要合理选择伪元素选择器,使其外边距不相邻才行
当你在遇到高度塌陷和外边距重叠的问题时,直接使用clearfix
这个类即可,他就可以帮你轻松搞定css
中的两大难题
其中.clearfix::before是为了解决外边距重叠问题;.clearfix::after是为了解决高度塌陷问题
.clearfix::before,
.clearfix::after{
content: '';
display: table;
clear: both;
}
六、定位
定位是一种更加高级的布局手段,通过定位可以将元素摆放到页面的任意位置,使用position
属性来设置定位:
static
:不开启定位,元素是静止的,默认值relative
:开启元素的相对定位absolute
:开启元素的绝对定位fixed
:开启元素的固定定位sticky
:开启元素的粘滞定位
6.1 相对定位
当元素的position
属性值设置为relative
时,则开启了元素的相对定位。
① 偏移量(offset)
当元素开启相对定位以后,可以通过偏移量来设置元素的位置
offset属性 | 含义 |
---|---|
top | 定位元素和定位位置的上边距离 |
bottom | 定位元素和定位位置的下边距离 |
left | 定位元素和定位位置的左侧距离 |
right | 定位元素和定位位置的右侧距离 |
定位元素垂直方向的位置由top
和bottom
两个属性控制,通常情况下只会使用其中之一
top
值越大,定位元素越靠下bottom
值越大,定位元素靠上
定位元素水平方向的位置由left
和right
两个属性控制,通常情况下只会使用其中之一
left
越大,定位元素越靠右right
越大,定位元素越靠左
.box2 {
width: 100px;
height: 100px;
background-color: green;
position: relative;
left: 100px;
bottom: 100px;
}
我们给box2
设置相对定位,就得到了我们想要的页面效果
可以看出,使用了相对定位后,只会移动自身的布局位置,而不会对已存在的其他元素产生任何影响。现在我们所举的例子不是很明显,但当页面布局比较复杂,特别是页面元素很多的时候,其优越性就可以大大体现出来
② 相对定位的特点
- 当元素开启相对定位以后,如果不设置偏移量元素,则元素不会发生任何变化(这里注意,不仅仅是位置)
- 相对定位是参照于元素在文档流中的位置进行定位的(可以理解为相对于自身原始位置)
- 相对定位会提升元素的层级(表现为可以覆盖其他元素)
- 相对定位不会改变元素的性质:块还是块,行内还是行内
Q1:如果给上述三个div都设置相对定位,那么它们的层级关系会是什么样的呢?或者说谁会被谁覆盖呢?
可以看到覆盖关系是:box3 >> box2 >> box1
我们再稍微调整下box3
和box2
的前后位置
会发现覆盖关系变成了:box2 >> box3 >> box1
在后续学习我们会知道:没有设置层级或层级z-index设置相同值时,优先显示靠下的元素
Q2:相对定位的第三个特点相对定位会提升元素的层级,是不是就类似于浮动一样脱离了文档流?
A:我们可以对比下,浮动和相对定位的区别
- 参考系不同:浮动的参考系是其父元素;相对定位是相对于自身
- 可移动方向不同:浮动只能左右移动;相对定位是上下左右移动
- 影响不同:浮动会影响页面布局(包括下方元素位置影响和高度塌陷问题);相对定位不对影响页面布局
- 性质不同:浮动会改变元素的性质(不再独占一行,其宽高都会被内容撑开);相对定位不会改变元素的性质
- 文字环绕:浮动不会覆盖文字;相对定位可以覆盖文字(这个可以自行验证,不再赘述)
当然,浮动和相对定位也有其相似之处
- 浮动和相对定位都是移动位置(貌似是废话)
- 浮动和相对定位不会从父元素中移出
可以看出,浮动和相对定位的区别是更多的
最后回答一点:浮动脱离了文档流,不再占据页面位置;相对定位仍然占据页面位置
Q3:相对定位的第四个特点相对定位不会改变元素的性质:块还是块,行内还是行内,但是上述例子中元素开启相对定位后好像就不再独占一行了,这个怎么理解?
A:相比于浮动元素的特点,相对定位不会改变元素的性质其实是一个相对不容易理解的问题。但其实也不难,可以把相对定位认为是元素的灵魂出窍。其位置发生改变以后,布局并没有产生影响,因为它的肉体(结构)仍然占据着原来的那个位置。只是其灵魂(内容)发生了移动。
6.2 绝对定位
当元素的position
属性值设置为absolute
时,则开启了元素的绝对定位
① 绝对定位的特点
- 开启绝对定位后,如果不设置偏移量,元素的位置不会发生变化
- 开启绝对定位后,元素会从文档流中脱离
- 绝对定位会改变元素的性质:行内变成块,块的宽高被内容撑开(与相对定位相反)
- 绝对定位会使元素提升一个层级
- 绝对定位元素是相对于其包含块进行定位的(与相对定位不同)
② 包含块(containing block)
正常情况下:
- 包含块就是离当前元素最近的开启了定位的祖先块元素
- 如果所有的祖先元素都没有开启定位,则
html
(根元素、初始包含块)就是它的包含块
<body>
<!-- 如果box1开启定位,则box2的包含块是box1,否则就是body -->
<div class="box1">
<div class="box2"></div>
</div>
<!-- 如果box3开启定位,则em的包含块是box3,否则就是body -->
<div class="box3">
<span>
<em>hello</em>
</span>
</div>
</body>
示例:
<div class="box2">2
<div class="box3">3
<div class="box4">4</div>
</div>
</div>
- 不给
box1
、box2
开起定位,box3
的包含块是html - 只给
box2
开启定位之后,box3
的包含块是box2
- 只给
box1
开启定位之后,box3
的包含块是box1
- 给
box1
、box2
都开起定位之后,box3
的包含块是box2
注意:这里上述的条件是开启定位,也就是说只要position
不是static
(默认值),那么就满足了其成为包含块的必要条件
③ 水平方向的布局
我们之前说过,水平方向的布局等式:
margin-left + border-left + padding-left + width + padding-right + border-right + margin-right = 其父元素的宽度
当使用绝对定位时,需要添加left
和right
两个值(此时规则和之前一样,只是多添加了两个值):
left + margin-left + border-left + padding-left + width + padding-right + border-right + margin-right + right = 其父元素的宽度
当发生过度约束时:
- 如果9个值中没有
auto
,则自动调整right
值以使等式满足(之前7个值是margin-right
) - 如果9个值中有
auto
,则自动调整auto
的值以使等式满足
可设置auto
的值:margin-left
/margin-right
/width
/left
/right
因为left
和right
的值默认是auto
,所以如果没有设置left
和right
,当等式不满足时,则会自动调整这两个值。
④ 垂直方向的布局
垂直方向布局的等式的也必须要满足:
top + margin-top + border-top + padding-top + height + padding-bottom + border-bottom + margin-bottom + top = 其父元素的高度
6.3 固定定位
将元素的position
属性设置为fixed
,则开启了元素的固定定位
固定定位的特点:
固定定位也是一种绝对定位,所以固定定位的大部分特点都和绝对定位一样
唯一不同的是,固定定位永远参照于浏览器的视口(viewport
,可视窗口)进行定位,不会随网页的滚动条滚动
相信到这里,大家应该又进一步地理解了固定定位与绝对定位的区别
因为固定定位跟绝对定位除了具有上述差别之后,其他的特点跟绝对定位是一样的,所以这里便不再赘述了
6.4 粘滞定位
将元素的position
属性设置为sticky
,则开启了元素的固定定位。这次,我们换个方式,直接来看粘滞定位的效果:
粘滞定位的特点:
- 粘滞定位和相对定位的特点基本一致(视频中说是和相对定位一致,不过我对比了一下,很多特点是不同的,感觉倒是和固定定位更相似,这里存疑)
- 不同的是粘滞定位可以在元素到达某个位置时将其固定
需要注意的是,sticky
属性并不兼容IE
。
6.5 几种定位的对比
我们通过上面的学习,知道position
属性有五个可选值。但static
是默认值,即不开启定位,所以我们只需要对比4种定位方式即可
定位方式 | 是否不设置偏移量,元素不会发生改变 | 是否脱离文档流 | 是否改变元素性质 | 是否提升元素层级 | 参考系 |
---|---|---|---|---|---|
relative(相对定位) | √ | × | × | √ | 参照于元素在文档流中的位置 |
absolute(绝对定位) | × | √ | √ | √ | 参照于其包含块 |
fixed(固定定位 | × | √ | √ | √ | 参照于浏览器的视口 |
sticky(粘滞定位) | × | √ | √ | √ | 参照于浏览器的视口 |
6.6 元素层级
对于开启了定位元素,可以通过z-index
属性来指定元素的层级
z-index
需要一个整数作为参数,值越大元素的层级越高,元素的层级越高越优先显示- 如果元素的层级一样,则优先显示靠下的元素
- 祖先的元素的层级再高,也不会盖住后代元素
Q:浮动也有层级概念吗?如果有,浮动和定位的层级关系是什么样的?
A:
- 给
float
设置z-index
多大都没用,还是会被覆盖 - 默认情况,没有设置
z-index
或设置z-index
大小≥0时,浮动层级没有定位的层级高 - 设置
z-index
<0时,浮动层级可以定位的层级高
一般情况下,页面的整体结构大多采用浮动、块进行布局,页面某些模块结构一般采用定位进行微调
七、字体
① color
用来设置字体颜色
② font-size
字体的大小
em
相当于当前元素的一个font-size
rem
相对于根元素的一个font-size
③ font-family
字体族(字体的格式)
④ @font-face
我们除了可以使用系统自带的字体样式外,还可以在服务器端自定义字体位置,@font-face
可以将服务器中的字体直接提供给用户去使用
@font-face {
/* 指定字体名字 */
font-family: 'myFont1';
/* 服务器中字体路径 */
src: url('/font/ZCOOLKuaiLe-Regular.woff'),
url('/font/ZCOOLKuaiLe-Regular.otf'),
url('/font/ZCOOLKuaiLe-Regular.ttf') format('truetype');/* 指定字体格式,一般不写 */
}
p {
font-size: 30px;
color: salmon;
font-family: myFont1;
}
问题
- 加载速度:受网络速度影响,可能会出现字体闪烁一下变成最终的字体
- 版权:有些字体是商用收费的,需要注意
- 字体格式:字体格式也有很多种(
woff
、otf
、ttf
),未必兼容,可能需要指定多个
⑤ 行高line height
文字占有的实际高度,可以通过line-height来设置行高
- 可以直接指定一个大小
px
/em
- 也可以直接为行高设置一个小数(字体大小的倍数)
行高经常还用来设置文字的行间距:行间距 = 行高 - 字体大小
字体框就是字体存在的格子,设置font-size实际上就是在设置字体框的高度,行高会在字体框的上下平均分配
⑥ 文本对齐方式
text-align
文本对齐方式:
属性值 | text-align 属性值 |
---|---|
left | 左侧对齐 |
right | 右侧对齐 |
center | 居中对齐 |
justify | 两端对齐 |
left
左侧对齐
right
右侧对齐
center
居中对齐
justify
两端对齐
⑦ 垂直对齐
vertical-align
设置元素垂直对齐的方式
属性值 | 对齐方式说明 |
---|---|
baseline | 基线对齐 |
top | 顶部对齐 |
bottom | 底部对齐 |
middle | 居中对齐 |
baseline
基线对齐
top
顶部对齐
bottom
底部对齐
middle
居中对齐
八、弹性盒
8.1 基本概念
① 弹性盒
flex
(弹性盒、伸缩盒)是css
中的又一种布局手段,它主要用来代替浮动来完成页面的布局,flex
可以使元素具有弹性,让元素可以跟随页面的大小的改变而改变。
② 弹性容器
要使用弹性盒,必须先将一个元素设置为弹性容器,我们通过display
来设置弹性容器
- display:flex 设置为块级弹性容器
- display:inline-flex 设置为行内的弹性容器
③ 弹性元素
弹性容器的子元素是弹性元素(弹性项),弹性元素可以同时是弹性容器
8.2 弹性容器的属性
主轴:弹性元素的排列方向称为主轴;侧轴:与主轴垂直方向的称为侧轴
8.2.1 主轴属性
① 排列方式
flex-direction
指定容器中弹性元素的排列方式
- row默认值,弹性元素在容器中水平排列(自左向右)
- row-reverse 弹性元素在容器中反向水平排列(自右向左)
- column 弹性元素纵向排列(自上向下)
- column-reverse 弹性元素反向纵向排列(自下向上)
② 自动换行
flex-wrap
设置弹性元素是否在弹性容器中自动换行
- nowrap 默认值,元素不会自动换行
- wrap 元素沿着辅轴方向自动换行
③ 简写属性
flex-flow
是wrap
和direction
的简写属性
flex-flow: row wrap;
** ④ 空白空间**
justify-content
如何分配主轴上的空白空间(主轴上的元素如何排列)
- flex-start 元素沿着主轴起边排列
- flex-end 元素沿着主轴终边排列
- center 元素居中排列
- space-around 空白分布到元素两侧
- space-between 空白均匀分布到元素间
- space-evenly 空白分布到元素的单侧
8.2.2 辅轴属性
① 辅轴对齐
align-items
元素在辅轴上如何对齐
- stretch 默认值,将元素的长度设置为相同的值
- flex-start 元素不会拉伸,沿着辅轴起边对齐
- flex-end 沿着辅轴的终边对齐
- center 居中对齐
- baseline 基线对齐
② 空白空间
align-content 如何分配辅轴上的空白空间(辅轴上的元素如何排列)
- flex-start 元素沿着辅轴起边排列
- flex-end 元素沿着辅轴终边排列
- center 元素居中排列
- space-around 空白分布到元素两侧
- space-between 空白均匀分布到元素间
- space-evenly 空白分布到元素的单侧
8.2.3 弹性居中
利用弹性盒对元素进行水平垂直双方向居中
justify-content: center;
align-items: center;
8.3 弹性元素的属性
① 伸展系数
flex-grow
指定弹性元素的伸展系数,默认值为0
- 当父元素有多余空间的时,子元素如何伸展
- 父元素的剩余空间,会按照比例进行分配
li:nth-child(1) {
background-color: #bfa;
flex-grow: 1;
}
li:nth-child(2) {
background-color: red;
flex-grow: 2;
}
li:nth-child(3) {
background-color: green;
flex-grow: 3;
}
② 缩减系数
flex-shrink
指定弹性元素的收缩系数,默认值为1
- 当父元素中的空间不足以容纳所有的子元素时,如何对子元素进行收缩
- 缩减系数的计算方式比较复杂,缩减多少是根据缩减系数和元素大小来计算
li:nth-child(1) {
background-color: #bfa;
flex-shrink: 1;
}
li:nth-child(2) {
background-color: red;
flex-shrink: 2;
}
li:nth-child(3) {
background-color: green;
flex-shrink: 3;
}
③ 基础长度
flex-basis
指定的是元素在主轴上的基础长度
- 如果主轴是横向的,则该值指定的就是元素的宽度
- 如果主轴是纵向的,则该值指定的就是元素的高度
- 默认值是
auto
,表示参考元素自身的高度或宽度 - 如果传递了一个具体的数值,则以该值为准
li:nth-child(1) {
background-color: #bfa;
flex-basis: 200px;
}
简写属性
flex
可以设置弹性元素所有的三个样flex: 增长 缩减 基础
- initial:flex: 0 1 auto
- auto:flex: 1 1 auto
- none:flex: 0 0 auto 弹性元素没有弹性
④ 排列顺序
order
决定弹性元素的排列顺序
li:nth-child(1) {
background-color: #bfa;
order: 2;
}
li:nth-child(2) {
background-color: red;
order: 3;
}
li:nth-child(3) {
background-color: green;
order: 1;
}
`
⑤ 覆盖辅轴
align-self
用来覆盖当前弹性元素上的align-items
li:nth-child(1) {
background-color: #bfa;
align-self: flex-end;
}