1. HTML语义化
1.1 语义化和非语义化对比
<!-- 非语义化 -->
<div>标题</div>
<div>
<div>一段文字</div>
<div>
<div>列表一</div>
<div>列表二</div>
</div>
</div>
<!-- 语义化 -->
<h1>标题</h1>
<div>
<p>一段文字</p>
<ul>
<li>列表一</li>
<li>列表二</li>
</ul>
</div>
两段代码可以看出,使用了语义化标签可以更清晰分辨出标题、段落和列表。同时,也有利于SEO优化。
- 让人更容易读懂(代码可读性高)
- 让搜索引擎更易读懂
2. HTML默认情况下的块级元素和内联元素
2.1 块级元素
- display: block/table;
- div h1~h6 table ul ol p等
- 独占一行
2.2 内联元素
- display: inline/inline-block;
- span img input button等
- 特点:不会独占一行,相邻的内联元素会挨在同一行,直到浏览器边缘才会换行
3. CSS布局
3.1 盒模型的宽度计算
3.1.1 如下代码,div1的offsetWidth是多大
<style>
#div1{
width: 100px;
padding: 10px;
border: 1px solid #ccc;
margin: 10px;
}
</style>
<div id="div1"></div>
- offsetWidth = (内容宽度 + 内边距 + 边框),不包含外边距
- 因此,offsetWidth = (100+10+10+1+1)px
3.2.1 如何让以上代码div的offsetWidth = 100px
<!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>
#div1{
width: 100px;
padding: 10px;
border: 1px solid #ccc;
margin: 10px;
box-sizing: border-box; /*ie浏览器的怪异盒模型*/
}
</style>
</head>
<body>
<div id="div1">
div1
</div>
</body>
<script>
let width = document.getElementById('div1').offsetWidth;
console.log(width); // 100
</script>
</html>
如下图:内容、内边距以及边框都包含再div里面
3.2 margin纵向重叠问题
3.2.1 如下代码AAA与BBB之间的距离
<style>
p{
font-size: 16px;
line-height: 1;
margin-top: 10px;
margin-bottom: 15px;
}
</style>
<p>AAA</p>
<p></p>
<p></p>
<p></p>
<p>BBB</p>
- 相邻元素的margin-top和margin-bittom会发生重叠,且取大的值
- 空内容的元素会被忽略margin发生重叠
- 因此,AAA与BBB的距离为15px
3.3 margin负值问题
3.3.1 代码如下
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>margin 负值</title>
<style type="text/css">
body {
margin: 20px;
}
.float-left {
float: left;
}
.clearfix:after {
content: '';
display: table;
clear: both;
}
.container {
border: 1px solid #ccc;
padding: 10px;
}
.container .item {
width: 100px;
height: 100px;
}
.container .border-blue {
border: 1px solid blue;
}
.container .border-red {
border: 1px solid red;
}
</style>
</head>
<body>
<p>用于测试 margin top bottom 的负数情况</p>
<div class="container">
<div class="item border-blue">
this is item 1
</div>
<div class="item border-red">
this is item 2
</div>
</div>
<p>用于测试 margin left right 的负数情况</p>
<div class="container clearfix">
<div class="item border-blue float-left">
this is item 3
</div>
<div class="item border-red float-left">
this is item 4
</div>
</div>
</body>
</html>
运行结果
3.3.2 margin-top设置负值
给item1的margin-top设置负值
<!-- 在style中给item1的margin-top设置负值 -->
.item1{
margin-top: -20px;
}
运行结果,item1与item2都向上移了20px
3.3.3 margin-bottom设置负值
<!-- 在style中给item1margin-bottom设置负值 -->
.item1{
margin-bottom: -20px;
}
运行结果,item1没动,item2向上移了20px
3.3.4 margin-left设置负值
给item3的margin-left负值
<!-- 在style中给item3margin-left设置负值 -->
.item3{
margin-left: -20px;
}
运行结果: item3与item4都向左移动20px
3.3.5 margin-right设置负值
给item3的margin-right负值
<!-- 在style中给item3margin-right设置负值 -->
.item3{
margin-right: -20px;
}
运行结果: item3没动,item4向左移了20px
3.4 BFC的理解和应用
3.4.1 什么是BFC
- Block format context,块级格式化上下文
- 一块独立的渲染区域,内部元素的渲染不会影响边界以外的元素
3.4.2 常见形成的BFC条件
- float不是none
- position是absolute/fixed
- overflow不是visible
- display是flex/inline-block
3.4.3 BFC的应用
3.4.3.1 清除浮动
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style type="text/css">
.container {
background-color: #f1f1f1;
}
.left {
float: left;
}
.box {
display: inline-block;
width: 50px;
height: 50px;
line-height: 50px;
border: 1px solid #333;
}
</style>
</head>
<body>
<div class="container bfc">
<div class="box left">box</div>
<p class="bfc">某一段文字……</p>
</div>
</body>
</html>
给box加浮动以后,box不在container里,即脱离了文档流,影响布局
此时,给容器添加触发BFC的条件,box就不会因为浮动而脱离父级container
.bfc{
overflow: hidden;
}
效果 如下
3.5 float布局
3.5.1 使用float实现圣杯布局和双飞翼布局
- 三栏布局,中间一栏最先渲染和加载,目的是为了第一时间显示重要的内容
- 两侧内容固定,中间内容随着宽度自适应
- 主要用于PC网页
3.5.1.1 圣杯布局的实现
- 使用float
- 使用position
- 使用margin负值
- 通过父容器给两边留白
基础样式布局
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>圣杯布局</title>
<style type="text/css">
body {
min-width: 550px;
}
#header {
text-align: center;
background-color: #f1f1f1;
}
#center {
background-color: #ccc;
width: 100%;
}
#left {
background-color: yellow;
width: 200px;
}
#right {
background-color: red;
width: 150px;
margin-right: -150px;
}
#footer {
text-align: center;
background-color: #f1f1f1;
}
</style>
</head>
<body>
<div id="header">this is header</div>
<div id="container">
<div id="center" class="column">this is center</div>
<div id="left" class="column">this is left</div>
<div id="right" class="column">this is right</div>
</div>
<div id="footer">this is footer</div>
</body>
</html>
代码效果
实现圣杯布局步骤以及详情代码如下
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>圣杯布局</title>
<style type="text/css">
*{
margin: 0;
padding: 0;
}
body {
min-width: 550px;
}
#header {
text-align: center;
background-color: #f1f1f1;
}
#center {
background-color: #ccc;
width: 100%;
}
#left {
background-color: yellow;
width: 200px;
}
#right {
background-color: red;
width: 150px;
}
#footer {
text-align: center;
background-color: #f1f1f1;
}
/*1.为container里面的left/center/right元素添加浮动*/
#container .column {
float: left;
}
/*2.将container容器设置左右内边距,为两侧留白*/
#container {
padding-left: 200px;
padding-right: 150px;
}
/*
*3. 由于浮动,container容器元素脱离文档流,导致容器高度塌陷
*因此容器需要清除浮动
*/
.clearfix::after {
content: ' ';
display: block;
clear: both;
}
/*4.为left设置margin-left为负值*/
#left{
margin-left: -100%; /*-100%是相对父级内容宽度,即除去内边距之后的宽度*/
}
/*5.left设置相对定位,并将其左移自己的宽度*/
#left {
position: relative;
right: 200px;
}
/*6.为right元素设置margin-right*/
#right {
margin-right: -150px; /*当margin-right设置为负值,父容器会忽略自身的宽度*/
}
</style>
</head>
<body>
<div id="header">this is header</div>
<div id="container" class="clearfix">
<div id="center" class="column">this is center</div>
<div id="left" class="column">this is left</div>
<div id="right" class="column">this is right</div>
</div>
<div id="footer">this is footer</div>
</body>
</html>
代码实现效果
3.5.1.2 双飞翼布局实现
基础结构代码如下
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>双飞翼布局</title>
<style type="text/css">
body {
min-width: 550px;
}
#main {
width: 100%;
height: 200px;
background-color: #ccc;
}
#left {
width: 190px;
height: 200px;
background-color: #0000FF;
}
#right {
width: 190px;
height: 200px;
background-color: #FF0000;
}
</style>
</head>
<body>
<div id="main" class="col">
<div id="main-wrap">
this is main
</div>
</div>
<div id="left" class="col">
this is left
</div>
<div id="right" class="col">
this is right
</div>
</body>
</html>
双飞翼布局的关键点
- 使用flot布局
- 中间容器(#main)的子容器(#main-wrap)设置margin-left/margin-right为左右两栏留白
- 左边容器设置margin-left: -100%;
- 右边容器设置margin-left: 负的自身宽度
以下是实现双飞翼布局的步骤代码
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>双飞翼布局</title>
<style type="text/css">
body {
min-width: 550px;
}
#main {
width: 100%;
height: 200px;
background-color: #ccc;
}
#left {
width: 190px;
height: 200px;
background-color: #0000FF;
}
#right {
width: 190px;
height: 200px;
background-color: #FF0000;
}
/*1. 为三个容器设置左浮动*/
.col {
float: left;
}
/*2. 设置中间容器子元素的左右外边距,目的是给两侧留白*/
#main-wrap {
margin-left: 190px;
margin-right: 190px;
}
/*3. 将left容器margin-left设置为-100%*/
#left {
margin-left: -100%;
}
/*4. 将left容器margin-left设置为-190px*/
#right {
margin-left: -190px;
}
</style>
</head>
<body>
<div id="main" class="col">
<div id="main-wrap">
this is main
</div>
</div>
<div id="left" class="col">
this is left
</div>
<div id="right" class="col">
this is right
</div>
</body>
</html>
3.6 flex
3.6.1 flex常用的语法
- flex-direction // 设置主轴的方向
- justify-content // 主轴对齐方式
- align-items // 交叉轴的对齐方式
- flex-wrap // 是否换行
- align-self // 子元素在交叉轴的对齐方式
具体可以学习 阮大神的flex教程
3.6.2 flex布局小案例
实现三点骰子
<!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>三点骰子</title>
<style>
.container{
width: 240px;
height: 240px;
padding: 10px;
background-color: #5596ff;
border-radius: 10px;
}
.item{
width: 70px;
height: 70px;
border-radius: 50%;
background-color: #fff;
}
</style>
</head>
<body>
<div class="container">
<div id="child1" class="item"></div>
<div id="child2" class="item"></div>
<div id="child3" class="item"></div>
</div>
</body>
</html>
代码要点
- 将container设置为flex布局,并设置子元素的对齐方式
- 设置子元素在交叉轴上的对齐方式
具体代码步骤如下
<!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>三点骰子</title>
<style>
.container{
width: 240px;
height: 240px;
padding: 10px;
background-color: #5596ff;
border-radius: 10px;
/*1. 将容器设置为flex布局*/
display: flex;
justify-content: space-around; /*子元素在主轴上的对齐方式为:两端对齐,项目之间的间隔都相等。*/
align-items: center;/*子元素在交叉轴上的对齐方式为: 中间对齐*/
}
.item{
width: 70px;
height: 70px;
border-radius: 50%;
background-color: #fff;
}
/*2. child1设置:交叉轴的起点对齐*/
#child1{
align-self: flex-start;
}
/*3. child3设置:交叉轴的终点对齐*/
#child3{
align-self: flex-end;
}
</style>
</head>
<body>
<div class="container">
<div id="child1" class="item"></div>
<div id="child2" class="item"></div>
<div id="child3" class="item"></div>
</div>
</body>
</html>
4. CSS定位
4.1 absolute和relative
4.1.1 relative
- relative根据自身定位
- 不会对外界元素有影响
4.1.2 absolute
- absolute依据最近一层的定位元素定位,如果没有找到则依据body元素定位
- position设置为relative/absolute/fixed的元素策称为定位元素
4.2 居中对齐有哪些方式
4.2.1 水平居中
- inlin元素:text-align: center;
- block元素: margin: auto;
- absolute元素:left: 50%; margin-left: 负值(自身宽度的一半);
4.2.2 垂直居中
- inlin元素:line-height: 容器的height值;
- absolute元素:top: 50%; margin-top: 负值(自身高度的一半);
- absloute元素:transform: translate(-50%, -50%);
- absloute元素:top,left,bottom,right设置为0; margin: auto;
5. CSS图文样式
5.1 line-height继承
5.1.1 继承数值
<style>
body{
font-size: 20px;
line-height: 20px;
}
p{
font-size: 16px;
}
</style>
<body>
<p>ABC</p>
</body>
上面的代码,body元素line-height为20px,此时p标签的line-height会直接继承这个数值20px。
5.1.2 继承比例
<style>
body{
font-size: 20px;
line-height: 1.5;
}
p{
font-size: 16px;
}
</style>
<body>
<p>ABC</p>
</body>
上面的代码,body元素line-height为1.5,即font-size的1.5倍,body的line-height为30px;此时,p标签继承的是body的line-height比例倍数,p标签的line-height = (自身的font-size) * (继承的line-height比例倍数),因此,上面的代码p标签的line-height为24px。
5.1.3 继承百分比
<style>
body{
font-size: 20px;
line-height: 200%;
}
p{
font-size: 16px;
}
</style>
<body>
<p>ABC</p>
</body>
上面的代码,body元素line-height为200%,此时,body元素的line-height为40px。由于是百分比,p标签继承的是父级元素body计算后的line-height结果,所以上面的代码p标签的line-height最终为40px。
6. CSS响应式
常见的长度单位
- px,绝对长度单位,由于是绝对长度,所以无法做响应式
- em,相对长度单位,相对于父元素的font-size
- rem,相对长度单位,相对于根元素的font-size
这里主要介绍rem
6.1 rem
0.16rem结果如下
0.32rem结果如下
0.48rem结果如下
6.2 响应式的常见方案
6.2.1 使用media-query(媒体查询)和rem实现
media-query(媒体查询),根据不同的屏幕宽度设置不同的font-size。如下代码,通过媒体查询为不同的手机设置根元素的font-size:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>响应式布局</title>
<style type="text/css">
@media only screen and (max-width: 374px) {
/* iphone5 或者更小的尺寸,以 iphone5 的宽度(320px)比例设置 font-size */
html {
font-size: 86px;
}
}
@media only screen and (min-width: 375px) and (max-width: 413px) {
/* iphone6/7/8 和 iphone x */
html {
font-size: 100px;
}
}
@media only screen and (min-width: 414px) {
/* iphone6p 或者更大的尺寸,以 iphone6p 的宽度(414px)比例设置 font-size */
html {
font-size: 110px;
}
}
body {
font-size: 0.16rem;
}
#div1 {
width: 1rem;
background-color: #ccc;
}
</style>
</head>
<body>
<div id="div1">
this is div
</div>
</body>
</html>
6.2.2 使用vw-vh实现响应式
- vh网页视口高度的1/100
- vw网页视口宽度的1/100
- vmax取两者(vh\vw)最大值,vmin取两者(vh\vw)最小值
- 解决了rem阶梯性问题