1、盒模型宽度计算及延伸
问题:offsetWidth的宽度是多少?
<!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">
#div1 {
width: 100px;
padding: 10px;
border: 1px solid #ccc;
margin: 10px;
}
</style>
</head>
<body>
<div id="div1">
this is div1
</div>
<script>
// document.getElementById('div1').offsetWidth
</script>
</body>
</html>
1.offsetWidth ?
=> 122px
bcz: offsetWidth:水平方向 width + 左右padding + 左右border-width
2.知识点延伸
- offsetWidth:水平方向 width + 左右padding + 左右border-width
- offsetHeight:垂直方向 height + 上下padding + 上下border-width
- clientWidth:水平方向 width + 左右padding
- clientHeight:垂直方向 height + 上下padding
- offsetTop:获取当前元素到 定位父节点 的top方向的距离
- offsetLeft:获取当前元素到 定位父节点 的left方向的距离
- scrollWidth:元素内容真实的宽度,内容不超出盒子高度时为盒子的clientWidth
- scrollHeight:元素内容真实的高度,内容不超出盒子高度时为盒子的clientHeight
3.IF offsetWidth = 100px
#div1 {
...
box-sizing: border-box;
}
2、margin纵向重叠问题
问题:AAA和BBB之间的距离是多少?
<!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">
p {
font-size: 16px;
line-height: 1;
margin-top: 10px;
margin-bottom: 15px;
}
</style>
</head>
<body>
<p>AAA</p>
<p></p>
<p></p>
<p></p>
<p>BBB</p>
</body>
</html>
1.AAA和BBB之间的距离?
=> 15px
bcz: margin-top: 10px + margin-bottom: 15px => 15px、 <p><p/> => 0px
2.知识点
- 相邻元素的margin-top和margin-bottom会发生重叠
- 空白内容的< p />也会重叠
3、margin负值问题
问题:margin - top/bottom/left/right分别负值会怎么样?
<!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>
margin - top/bottom/left/right分别负值会怎么样?
- margin-top 和 margin-left 负值,元素向上、向左移动
- margin-right 负值,右侧元素左移,自身不受影响
- margin-bottom 负值,下方元素上移,自身不受影响
4、BFC的理解与应用
问题:什么是BFC, 如何应用?
<!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;
}
.bfc {
overflow: hidden; /* 触发元素 BFC */
}
</style>
</head>
<body>
<div class="container bfc">
<img src="https://www.imooc.com/static/img/index/logo.png" class="left" style="magin-right: 10px;"/>
<p class="bfc">某一段文字……</p>
</div>
</body>
</html>
1.BFC的定义
BFC(Block formatting context)直译为"块级格式化上下文"。它是一个独立的渲染区域,只有Block-level box参与, 它规定了内部的Block-level Box如何布局,并且与这个区域外部毫不相干。
2.如何触发BFC
- float 不为 none
- position 的值不是static或者relative。
- display的值是inline-block、table-cell、flex、table-caption或者inline-flex
- overflow的值不是visible
2.BFC的应用
- 清除浮动
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>清除浮动</title>
<style>
.parent{
width: 350px;
background-color: red;
// overflow: hidden; // 触发BFC
}
.child{
float: left;
width: 100px;
height: 100px;
line-height: 100px;
text-align: center;
background-color: lightblue;
}
</style>
</head>
<body>
<div class="parent">
<div class="child1 child">1</div>
<div class="child2 child">2</div>
<div class="child3 child">3</div>
<div class="child4 child">4</div>
</div>
</body>
</html>
效果:子元素设置了 float 浮动,脱离了文档流,无法撑开父元素
给父元素添加样式 overflow: hidden ,触发BFC
其他方法:
- 在最后一个子元素后面添加一个空元素,并给予样式 clear: both
- 给父元素设置一定的高度
-
margin-top塌陷
通过给子元素添加 margin-top,想让子元素的上边缘与父元素的上边缘拉开一段距离,发现却是父元素整体与上一个元素拉开了距离
解决办法: -
通过给父元素添加一定的样式来触发BFC,使其内部形成一个独立的环境,这样就不会影响到其它元素的布局了
-
对父元素设置一个大小不为0的边框 border
-
垂直方向的margin重叠
在垂直方向上,相邻两个元素若都设置了 margin 值,则按照较大的那个值来布局
为了避免margin重叠,我们可以给每一个子元素的外部添加一个父元素,并对父元素设置样式来触发BFC,那么就不会有上述的问题了
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>margin重叠</title>
<style>
.parent{
width: 200px;
height: 500px;
background-color: red;
}
.child{
width: 100px;
height: 100px;
margin: 0 auto;
line-height: 100px;
text-align: center;
}
.child1{
margin-bottom: 20px;
background-color: lightblue;
}
.child2{
margin-top: 50px;
margin-bottom: 70px;
background-color: lightcoral;
}
.child3{
margin-top: 50px;
background-color: lightgreen;
}
.third{
/*除了overflow: hidden,还可以写:
1. float: left
2. float: right
3. position: absolute
4. ……
*/
overflow: hidden;
}
</style>
</head>
<body>
<div class="parent">
<div class="third">
<div class="child child1">1</div>
</div>
<div class="third">
<div class="child child2">2</div>
</div>
<div class="third">
<div class="child child3">3</div>
</div>
</div>
</body>
</html>
效果
- 自适应布局
效果
这样的布局,都是左侧宽度固定了,右侧的宽度是自适应的
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>自适应布局</title>
<style>
.parent{
height: 100vh;
}
.left{
width: 200px;
height: 100%;
background-color: lightgreen;
text-align: center;
float: left;
}
.right{
height: 100%;
overflow: hidden; /* 触发BFC,不被浮动元素所覆盖 */
text-align: center;
background-color: lightskyblue;
}
</style>
</head>
<body>
<div class="parent">
<div class="left">固定宽度</div>
<div class="right">自适应宽度</div>
</div>
</body>
</html>
css最初设计浮动就是为了实现文字绕图的效果,虽然浮动会覆盖别的元素,但不会覆盖住文字
6、圣杯布局
它的起源不是源于对页面的形象表达。在西方,圣杯是表达“渴求之物”的意思
布局效果
- header和footer各自占领屏幕所有宽度,高度固定
- 中间的container是一个三栏布局
- 三栏布局两侧宽度固定不变,中间部分自动填充整个区域
- 中间部分的高度是三栏中最高的区域的高度。
圣杯布局的三种实现
1.浮动 float
- 先定义好header和footer的样式,使之横向撑满。
- 在container中的三列设为浮动和相对定位(后面会用到),center要放在最前面,footer清除浮动。
- 三列的左右两列分别定宽200px和150px,中间部分center设置100%撑满
- 这样因为浮动的关系,center会占据整个container,左右两块区域被挤下去了
- 接下来设置left的 margin-left: -100%;,让left回到上一行最左侧
- 但这会把center给遮住了,所以这时给外层的container设置 padding-left: 200px;padding-right: 150px;,给left和right空出位置
- 这时left并没有在最左侧,因为之前已经设置过相对定位,所以通过 left: -200px; 把left拉回最左侧
- 同样的,对于right区域,设置 margin-left: -150px; 把right拉回第一行
- 这时右侧空出了150px的空间,所以最后设置 right: -150px;把right区域拉到最右侧就行了。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script src="http://lib.sinaapp.com/js/jquery/2.0.2/jquery-2.0.2.min.js"></script>
</head>
<style>
body {
min-width: 550px; /* 2x leftContent width + rightContent width */
font-weight: bold;
font-size: 20px;
}
#header, #footer {
background: rgba(29, 27, 27, 0.726);
text-align: center;
height: 60px;
line-height: 60px;
}
#footer {
clear: both;
}
#container {
padding-left: 200px; /* leftContent width */
padding-right: 150px; /* rightContent width */
overflow: hidden;
}
#container .column {
position: relative;
float: left;
text-align: center;
height: 300px;
line-height: 300px;
}
#center {
width: 100%;
background: rgb(206, 201, 201);
}
#left {
width: 200px; /* leftContent width */
right: 200px; /* leftContent width */
margin-left: -100%;
background: rgba(95, 179, 235, 0.972);
}
#right {
width: 150px; /* rightContent width */
margin-left: -150px; /* rightContent width */
right: -150px;
background: rgb(231, 105, 2);
}
</style>
<body>
<div id="header">#header</div>
<div id="container">
<div id="center" class="column">#center</div>
<div id="left" class="column">#left</div>
<div id="right" class="column">#right</div>
</div>
<div id="footer">#footer</div>
</body>
</html>
2.弹性盒子 flex
- header和footer设置样式,横向撑满。
- container中的left、center、right依次排布
- 给container设置弹性布局 display: flex;
- left和right区域定宽,center设置 flex: 1
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script src="http://lib.sinaapp.com/js/jquery/2.0.2/jquery-2.0.2.min.js"></script>
</head>
<style>
body {
min-width: 550px;
font-weight: bold;
font-size: 20px;
}
#header, #footer {
background: rgba(29, 27, 27, 0.726);
text-align: center;
height: 60px;
line-height: 60px;
}
#container {
display: flex;
}
#container .column {
text-align: center;
height: 300px;
line-height: 300px;
}
#center {
flex: 1;
background: rgb(206, 201, 201);
}
#left {
width: 200px;
background: rgba(95, 179, 235, 0.972);
}
#right {
width: 150px;
background: rgb(231, 105, 2);
}
</style>
<body>
<div id="header">#header</div>
<div id="container">
<div id="left" class="column">#left</div>
<div id="center" class="column">#center</div>
<div id="right" class="column">#right</div>
</div>
<div id="footer">#footer</div>
</body>
</html>
3.网格布局 grid
- 把body划分成三行四列的网格,其中有5条列网格线
- 给body元素添加display: grid;属性变成一个grid(网格)
- 给header元素设置grid-row: 1; 和 grid-column: 1/5; 意思是占据第一行网格的从第一条列网格线开始到第五条列网格线结束
- 给footer元素设置grid-row: 1; 和 grid-column: 1/5; 意思是占据第三行网格的从第一条列网格线开始到第五条列网格线结束
- 给left元素设置grid-row: 2; 和 grid-column: 1/2; 意思是占据第二行网格的从第一条列网格线开始到第二条列网格线结束
- 给center元素设置grid-row: 2; 和 grid-column: 2/4; 意思是占据第二行网格的从第二条列网格线开始到第四条列网格线结束
- 给right元素设置grid-row: 2; 和 grid-column: 4/5; 意思是占据第二行网格的从第四条列网格线开始到第五条列网格线结束
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script src="http://lib.sinaapp.com/js/jquery/2.0.2/jquery-2.0.2.min.js"></script>
</head>
<style>
body {
min-width: 550px;
font-weight: bold;
font-size: 20px;
display: grid;
}
#header,
#footer {
background: rgba(29, 27, 27, 0.726);
text-align: center;
height: 60px;
line-height: 60px;
}
#header {
grid-row: 1;
grid-column: 1/5;
}
#footer {
grid-row: 3;
grid-column: 1/5;
}
.column {
text-align: center;
height: 300px;
line-height: 300px;
}
#left {
grid-row: 2;
grid-column: 1/2;
background: rgba(95, 179, 235, 0.972);
}
#center {
grid-row: 2;
grid-column: 2/4;
background: rgb(206, 201, 201);
}
#right {
grid-row: 2;
grid-column: 4/5;
background: rgb(231, 105, 2);
}
</style>
<body>
<div id="header">#header</div>
<div id="left" class="column">#left</div>
<div id="center" class="column">#center</div>
<div id="right" class="column">#right</div>
<div id="footer">#footer</div>
</body>
</html>
7、双飞翼布局
圣杯布局和双飞翼布局达到的效果基本相同,都是侧边两栏宽度固定,中间栏宽度自适应。
主要的不同之处就是在解决中间部分被挡住的问题时,采取的解决办法不一样,圣杯布局是在父元素上设置了padding-left和padding-right,在给左右两边的内容设置position为relative,通过左移和右移来使得左右两边的内容得以很好的展现,而双飞翼则是在center这个div中再加了一个div来放置内容,在给这个新的div设置margin-left和margin-right。
布局效果
- header和footer各自占领屏幕所有宽度,高度固定
- 中间的container是一个三栏布局
- 三栏布局两侧宽度固定不变,中间部分自动填充整个区域
- 中间部分的高度是三栏中最高的区域的高度。
双飞翼布局的实现步骤
- left、center、right三种都设置左浮动
- 设置center宽度为100%
- 设置负边距,left设置负边距为100%,right设置负边距为自身宽度
- 设置content的margin值为左右两个侧栏留出空间,margin值大小为left和right宽度
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script src="http://lib.sinaapp.com/js/jquery/2.0.2/jquery-2.0.2.min.js"></script>
</head>
<style>
body {
min-width: 550px;
font-weight: bold;
font-size: 20px;
}
#header,
#footer {
background: rgba(29, 27, 27, 0.726);
text-align: center;
height: 60px;
line-height: 60px;
}
#container {
overflow: hidden;
}
.column {
text-align: center;
height: 300px;
line-height: 300px;
}
#left, #right, #center {
float: left;
}
#center {
width: 100%;
background: rgb(206, 201, 201);
}
#left {
width: 200px;
margin-left: -100%;
background: rgba(95, 179, 235, 0.972);
}
#right {
width: 150px;
margin-left: -150px;
background: rgb(231, 105, 2);
}
.content {
margin: 0 150px 0 200px;
}
</style>
<body>
<div id="header">#header</div>
<div id="container">
<div id="center" class="column">
<div class="content">#center</div>
</div>
<div id="left" class="column">#left</div>
<div id="right" class="column">#right</div>
</div>
<div id="footer">#footer</div>
</body>
</html>
8、手写clearfix - 其他清除浮动方式
使用内容生成的方式清除浮动
.clearfix:after {
content:""; // 生成内容为空
display: block; // 生成的元素以块级元素显示
clear:both; // 清除前面元素浮动带来的影响
}
.clearfix: {
*zoom: 1; // 兼容IE低版本
}
9、flex色子 - 沅一峰
Flex属性
- flex-direction 决定主轴的方向(即项目的排列方向)
- flex-wrap 定义如果一条轴线排不下,如何换行
- flex-flow 是
flex-direction
属性和flex-wrap
属性的简写形式,默认值为row nowrap - justify-content 定义了项目在主轴上的对齐方式
- align-items 定义项目在交叉轴上如何对齐
- align-content 定义了多根轴线的对齐方式。如果项目只有一根轴线,该属性不起作用
①、flex-direction属性
row(默认值):主轴为水平方向,起点在左端。
row-reverse:主轴为水平方向,起点在右端。
column:主轴为垂直方向,起点在上沿。
column-reverse:主轴为垂直方向,起点在下沿。
②、flex-wrap属性
nowrap(默认):不换行。
wrap:换行,第一行在上方。
wrap-reverse:换行,第一行在下方。
③、flex-flow属性
flex-flow属性是flex-direction属性和flex-wrap属性的简写形式,默认值为row nowrap。
④、 justify-content属性
flex-start(默认值):左对齐
flex-end:右对齐
center: 居中
space-between:两端对齐,项目之间的间隔都相等。
space-around:每个项目两侧的间隔相等。所以,项目之间的间隔比项目与边框的间隔大一倍。
⑤、align-items属性
flex-start:交叉轴的起点对齐。
flex-end:交叉轴的终点对齐。
center:交叉轴的中点对齐。
baseline: 项目的第一行文字的基线对齐。
stretch(默认值):如果项目未设置高度或设为auto,将占满整个容器的高度。
⑥、align-content属性
flex-start:与交叉轴的起点对齐。
flex-end:与交叉轴的终点对齐。
center:与交叉轴的中点对齐。
space-between:与交叉轴两端对齐,轴线之间的间隔平均分布。
space-around:每根轴线两侧的间隔都相等。所以,轴线之间的间隔比轴线与边框的间隔大一倍。
stretch(默认值):轴线占满整个交叉轴。
⑴、色子的布局
骰子的一面,最多可以放置9个点。
下面,就来看看Flex如何实现,从1个点到9个点的布局,查看Demo。
<div class="box">
<span class="item"></span>
</div>
上面代码中,div元素(代表骰子的一个面)是Flex容器,span元素(代表一个点)是Flex项目。如果有多个项目,就要添加多个span元素,以此类推。
⑵、单项目(一个点)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Flex色子练习</title>
<style>
* {
box-sizing: border-box;
}
html, body {
height: 100%;
}
body {
display: flex;
align-items: center;
justify-content: center;
vertical-align: center;
flex-wrap: wrap;
align-content: center;
font-family: 'Open Sans', sans-serif;
background: linear-gradient(top, #222, #333);
}
.pip {
display: block;
width: 24px;
height: 24px;
border-radius: 50%;
margin: 4px;
background-color: #333;
box-shadow: inset 0 3px #111, inset 0 -3px #555;
}
[class$="face"] {
margin: 16px;
padding: 4px;
background-color: #e7e7e7;
width: 104px;
height: 104px;
object-fit: contain;
box-shadow:
inset 0 5px white,
inset 0 -5px #bbb,
inset 5px 0 #d7d7d7,
inset -5px 0 #d7d7d7;
border-radius: 10%;
}
/* 单项目 */
.first-face{
display: flex;
/* 左上 */
/* 默认 */
/* 中上 */
/* justify-content: center; */
/* 右上 */
/* justify-content: flex-end; */
/* 中左 */
/* align-items: center; */
/* flex-direction: column; justify-content: center; */
/* 中中 */
/* justify-content: center; */
/* align-items: center; */
/* 中右 */
/* align-items: center; */
/* justify-content: flex-end; */
/* 下左 */
/* flex-direction: column-reverse; */
/* flex-direction: column; justify-content: flex-end; */
/* align-items: flex-end; */
/* 下中 */
/* align-items: flex-end; */
/* justify-content: center; */
/* 下右 */
align-items: flex-end;
justify-content: flex-end;
}
</style>
</head>
<body>
<!-- 单项目 -->
<div class="first-face">
<span class="pip"></span>
</div>
</body>
</html>
⑶、双项目(两点)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Flex色子练习</title>
<style>
* {
box-sizing: border-box;
}
html, body {
height: 100%;
}
body {
display: flex;
align-items: center;
justify-content: center;
vertical-align: center;
flex-wrap: wrap;
align-content: center;
font-family: 'Open Sans', sans-serif;
background: linear-gradient(top, #222, #333);
}
.pip {
display: block;
width: 24px;
height: 24px;
border-radius: 50%;
margin: 4px;
background-color: #333;
box-shadow: inset 0 3px #111, inset 0 -3px #555;
}
[class$="face"] {
margin: 16px;
padding: 4px;
background-color: #e7e7e7;
width: 104px;
height: 104px;
object-fit: contain;
box-shadow:
inset 0 5px white,
inset 0 -5px #bbb,
inset 5px 0 #d7d7d7,
inset -5px 0 #d7d7d7;
border-radius: 10%;
}
/* 双项目 */
.second-face{
display: flex;
/* 上 左右 */
/* justify-content: space-between; */
/* 左 上下 */
/* justify-content: space-between; */
/* flex-direction: column; */
/* 中 上下 */
/* flex-direction: column; */
/* justify-content: space-between; */
/* align-items: center; */
/* 右 上下 */
/* justify-content: space-between; */
/* flex-direction: column; */
/* align-items: flex-end; */
/* 左上 中中 */
/* 第一个点 左上(默认) */
/* 第二个点 外部设置nth样式 */
/* 左上 右下 */
/* 第一个点 左上(默认) */
justify-content: space-between;
/* 第二个点 外部设置nth样式 */
}
/* 第二个点 中中*/
/* .second-face .pip:nth-child(2){
align-self: center;
} */
/* 第二个点 右下 */
.second-face .pip:nth-child(2){
align-self: flex-end;
}
</style>
</head>
<body>
<!-- 双项目 -->
<div class="second-face">
<span class="pip"></span>
<span class="pip"></span>
</div>
</body>
</html>
⑷、三项目(三点)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Flex色子练习</title>
<style>
* {
box-sizing: border-box;
}
html, body {
height: 100%;
}
body {
display: flex;
align-items: center;
justify-content: center;
vertical-align: center;
flex-wrap: wrap;
align-content: center;
font-family: 'Open Sans', sans-serif;
background: linear-gradient(top, #222, #333);
}
.pip {
display: block;
width: 24px;
height: 24px;
border-radius: 50%;
margin: 4px;
background-color: #333;
box-shadow: inset 0 3px #111, inset 0 -3px #555;
}
[class$="face"] {
margin: 16px;
padding: 4px;
background-color: #e7e7e7;
width: 104px;
height: 104px;
object-fit: contain;
box-shadow:
inset 0 5px white,
inset 0 -5px #bbb,
inset 5px 0 #d7d7d7,
inset -5px 0 #d7d7d7;
border-radius: 10%;
}
/* 三项目 */
.third-face{
display: flex;
/* 第一个点默认 */
/* 第二个点 水平&垂直居中 */
/* 第三个点 右下 */
}
.third-face .pip:nth-child(2){
align-self: center;
}
.third-face .pip:nth-child(3){
align-self: flex-end;
}
</style>
</head>
<body>
<!-- 三项目 -->
<div class="third-face">
<span class="pip"></span>
<span class="pip"></span>
<span class="pip"></span>
</div>
</body>
</html>
⑸、四项目(四点)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Flex色子练习</title>
<style>
* {
box-sizing: border-box;
}
html, body {
height: 100%;
}
body {
display: flex;
align-items: center;
justify-content: center;
vertical-align: center;
flex-wrap: wrap;
align-content: center;
font-family: 'Open Sans', sans-serif;
background: linear-gradient(top, #222, #333);
}
.pip {
display: block;
width: 24px;
height: 24px;
border-radius: 50%;
margin: 4px;
background-color: #333;
box-shadow: inset 0 3px #111, inset 0 -3px #555;
}
[class$="face"] {
margin: 16px;
padding: 4px;
background-color: #e7e7e7;
width: 104px;
height: 104px;
object-fit: contain;
box-shadow:
inset 0 5px white,
inset 0 -5px #bbb,
inset 5px 0 #d7d7d7,
inset -5px 0 #d7d7d7;
border-radius: 10%;
}
/* 四项目 */
.fourth-face{
display: flex;
/* 左上 中上 右上 右下 */
/* 无class column */
/* flex-wrap: wrap; */
/* align-content: space-between; */
/* justify-content: flex-end; */
/* 左上 右上 左下 右下 */
flex-direction: column;
justify-content: space-between;
}
.fourth-face .column{
display: flex;
justify-content: space-between;
}
</style>
</head>
<body>
<!-- 四项目 -->
<div class="fourth-face">
<div class="column">
<span class="pip"></span>
<span class="pip"></span>
</div>
<div class="column">
<span class="pip"></span>
<span class="pip"></span>
</div>
</div>
</body>
</html>
⑹、五项目(五点)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Flex色子练习</title>
<style>
* {
box-sizing: border-box;
}
html, body {
height: 100%;
}
body {
display: flex;
align-items: center;
justify-content: center;
vertical-align: center;
flex-wrap: wrap;
align-content: center;
font-family: 'Open Sans', sans-serif;
background: linear-gradient(top, #222, #333);
}
.pip {
display: block;
width: 24px;
height: 24px;
border-radius: 50%;
margin: 4px;
background-color: #333;
box-shadow: inset 0 3px #111, inset 0 -3px #555;
}
[class$="face"] {
margin: 16px;
padding: 4px;
background-color: #e7e7e7;
width: 104px;
height: 104px;
object-fit: contain;
box-shadow:
inset 0 5px white,
inset 0 -5px #bbb,
inset 5px 0 #d7d7d7,
inset -5px 0 #d7d7d7;
border-radius: 10%;
}
/* 五点项目 */
.fifth-face{
display: flex;
/* 左上 右上 中中 左下 右下 */
flex-direction: column;
justify-content: space-between;
}
.fifth-face .column{
display: flex;
justify-content: space-between;
}
.fifth-face .column:nth-child(2){
justify-content: center;
}
</style>
</head>
<body>
<!-- 五项目 -->
<div class="fifth-face">
<div class="column">
<span class="pip"></span>
<span class="pip"></span>
</div>
<div class="column">
<span class="pip"></span>
</div>
<div class="column">
<span class="pip"></span>
<span class="pip"></span>
</div>
</div>
</body>
</html>
⑺、六项目(六点)
①、上下 & 左右
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Flex色子练习</title>
<style>
* {
box-sizing: border-box;
}
html, body {
height: 100%;
}
body {
display: flex;
align-items: center;
justify-content: center;
vertical-align: center;
flex-wrap: wrap;
align-content: center;
font-family: 'Open Sans', sans-serif;
background: linear-gradient(top, #222, #333);
}
.pip {
display: block;
width: 24px;
height: 24px;
border-radius: 50%;
margin: 4px;
background-color: #333;
box-shadow: inset 0 3px #111, inset 0 -3px #555;
}
[class$="face"] {
margin: 16px;
padding: 4px;
background-color: #e7e7e7;
width: 104px;
height: 104px;
object-fit: contain;
box-shadow:
inset 0 5px white,
inset 0 -5px #bbb,
inset 5px 0 #d7d7d7,
inset -5px 0 #d7d7d7;
border-radius: 10%;
}
/* 六项目 */
.sixth-face{
display: flex;
/* 上下各三点 */
/* flex-direction: column; */
/* justify-content: space-between; */
/* 左右各三点 */
justify-content: space-between;
}
.sixth-face .column{
/* 上下各三点 */
/* display: flex; */
/* 左右各三点 */
display: flex;
flex-direction: column;
}
</style>
</head>
<body>
<!-- 六项目 -->
<div class="sixth-face">
<div class="column">
<span class="pip"></span>
<span class="pip"></span>
<span class="pip"></span>
</div>
<div class="column">
<span class="pip"></span>
<span class="pip"></span>
<span class="pip"></span>
</div>
</div>
</body>
</html>
②、叉型
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Flex色子练习</title>
<style>
* {
box-sizing: border-box;
}
html, body {
height: 100%;
}
body {
display: flex;
align-items: center;
justify-content: center;
vertical-align: center;
flex-wrap: wrap;
align-content: center;
font-family: 'Open Sans', sans-serif;
background: linear-gradient(top, #222, #333);
}
.pip {
display: block;
width: 24px;
height: 24px;
border-radius: 50%;
margin: 4px;
background-color: #333;
box-shadow: inset 0 3px #111, inset 0 -3px #555;
}
[class$="face"] {
margin: 16px;
padding: 4px;
background-color: #e7e7e7;
width: 104px;
height: 104px;
object-fit: contain;
box-shadow:
inset 0 5px white,
inset 0 -5px #bbb,
inset 5px 0 #d7d7d7,
inset -5px 0 #d7d7d7;
border-radius: 10%;
}
/* 六项目 - 叉型 */
.sixth2-face{
display: flex;
flex-direction: column;
justify-content: space-between;
}
.sixth2-face .column{
display: flex;
justify-content: space-between;
}
.sixth2-face .column:nth-child(2){
justify-content: center;
}
</style>
</head>
<body>
<!-- 六项目 - 叉型 -->
<div class="sixth2-face">
<div class="column">
<span class="pip"></span>
<span class="pip"></span>
<span class="pip"></span>
</div>
<div class="column">
<span class="pip"></span>
</div>
<div class="column">
<span class="pip"></span>
<span class="pip"></span>
</div>
</div>
</body>
</html>
⑺、九项目(九点)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Flex色子练习</title>
<style>
* {
box-sizing: border-box;
}
html, body {
height: 100%;
}
body {
display: flex;
align-items: center;
justify-content: center;
vertical-align: center;
flex-wrap: wrap;
align-content: center;
font-family: 'Open Sans', sans-serif;
background: linear-gradient(top, #222, #333);
}
.pip {
display: block;
width: 24px;
height: 24px;
border-radius: 50%;
margin: 4px;
background-color: #333;
box-shadow: inset 0 3px #111, inset 0 -3px #555;
}
[class$="face"] {
margin: 16px;
padding: 4px;
background-color: #e7e7e7;
width: 104px;
height: 104px;
object-fit: contain;
box-shadow:
inset 0 5px white,
inset 0 -5px #bbb,
inset 5px 0 #d7d7d7,
inset -5px 0 #d7d7d7;
border-radius: 10%;
}
/* 九项目 */
.ninth-face{
display: flex;
flex-wrap: wrap;
}
</style>
</head>
<body>
<!-- 九项目 -->
<div class="ninth-face">
<span class="pip"></span>
<span class="pip"></span>
<span class="pip"></span>
<span class="pip"></span>
<span class="pip"></span>
<span class="pip"></span>
<span class="pip"></span>
<span class="pip"></span>
<span class="pip"></span>
</div>
</body>
</html>
10、Absolute Relative 定位
Position的属性值有:
- Absolute:绝对定位,是相对于最近的且不是static定位的父元素来定位
- Fixed:绝对定位,是相对于浏览器窗口来定位的,是固定的,不会跟屏幕一起滚动。
- Relative:相对定位,是相对于其原本的位置来定位的。
- Static:默认值,没有定位。
- Inherit:继承父元素的position值。
Absolution:元素会脱离文档流,定位是相对于离它最近的且不是static定位的父元素而言,若该元素没有设置宽度,则宽度由元素里面的内容决定,且宽度不会影响父元素,定位为absolution后,原来的位置相当于是空的,下面的的元素会来占据。
Relative:元素仍处于文档流中,定位是相对于原本自身的位置,若没有设置宽度,则宽度为父元素的宽度,该元素的大小会影响父元素的大小。
11、元素水平垂直居中的方法
⑴、分类
- 内联元素居中布局
- 块级元素居中布局
①、内联元素居中布局
水平居中
- 行内元素可设置:text-align: center
- flex布局设置父元素:display: flex; justify-content: center
垂直居中
- 单行文本父元素确认高度:height === line-height
- 多行文本父元素确认高度:disaply: table-cell; vertical-align: middle
②、块级元素居中布局
水平居中
- 定宽: margin: 0 auto
- 绝对定位+left:50%+margin:负自身一半
垂直居中
- position: absolute设置left、top、margin-left、margin-top(定高)
- display: table-cell
- transform: translate(x, y)
- flex(不定高,不定宽)
- grid(不定高,不定宽),兼容性相对比较差
⑵、常用的六种实现方式
- 利用定位+margin:auto
- 利用定位+margin:负值
- 利用定位+transform
- table布局
- flex布局
- grid布局
①、利用定位+margin:auto
父级设置为相对定位,子级绝对定位 ,并且四个定位属性的值都设置了0,那么这时候如果子级没有设置宽高,则会被拉开到和父级一样宽高
这里子元素设置了宽高,所以宽高会按照我们的设置来显示,但是实际上子级的虚拟占位已经撑满了整个父级,这时候再给它一个margin:auto它就可以上下左右都居中了
<style>
.father{
width:500px;
height:300px;
border:1px solid #0a3b98;
position: relative;
}
.son{
width:100px;
height:40px;
background: #f0a238;
position: absolute;
top:0;
left:0;
right:0;
bottom:0;
margin:auto;
}
</style>
<div class="father">
<div class="son"></div>
</div>
②、利用定位+margin:负值
绝大多数情况下,设置父元素为相对定位, 子元素移动自身50%实现水平垂直居中
<style>
.father {
position: relative;
width: 200px;
height: 200px;
background: skyblue;
}
.son {
position: absolute;
top: 50%;
left: 50%;
margin-left:-50px;
margin-top:-50px;
width: 100px;
height: 100px;
background: red;
}
</style>
<div class="father">
<div class="son"></div>
</div>
实现思路
- 初始位置为方块1的位置
- 当设置left、top为50%的时候,内部子元素为方块2的位置
- 设置margin为负数时,使内部子元素到方块3的位置,即中间位置
这种方案不要求父元素的高度,也就是即使父元素的高度变化了,仍然可以保持在父元素的垂直居中位置,水平方向上是一样的操作
但是该方案需要知道子元素自身的宽高,但是我们可以通过下面transform属性进行移动
③、利用定位+transform
<style>
.father {
position: relative;
width: 200px;
height: 200px;
background: skyblue;
}
.son {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%,-50%);
width: 100px;
height: 100px;
background: red;
}
</style>
<div class="father">
<div class="son"></div>
</div>
translate(-50%, -50%)将会将元素位移自己宽度和高度的-50%
这种方法其实和最上面被否定掉的margin负值用法一样,可以说是margin负值的替代方案,并不需要知道自身元素的宽高
④、table布局
设置父元素为display:table-cell,子元素设置 display: inline-block。利用vertical和text-align可以让所有的行内块级元素水平垂直居中
<style>
.father {
display: table-cell;
width: 200px;
height: 200px;
background: skyblue;
vertical-align: middle;
text-align: center;
}
.son {
display: inline-block;
width: 100px;
height: 100px;
background: red;
}
</style>
<div class="father">
<div class="son"></div>
</div>
⑤、flex弹性布局
<style>
.father {
display: flex;
justify-content: center;
align-items: center;
width: 200px;
height: 200px;
background: skyblue;
}
.son {
width: 100px;
height: 100px;
background: red;
}
</style>
<div class="father">
<div class="son"></div>
</div>
css3中了flex布局,可以非常简单实现垂直水平居中
- display: flex时,表示该容器内部的元素将按照flex进行布局
- align-items: center表示这些元素将相对于本容器水平居中
- justify-content: center也是同样的道理垂直居中
⑥、grid网格布局
gird网格布局和flex弹性布局都简单粗暴
<style>
.father {
display: grid;
align-items:center;
justify-content: center;
width: 200px;
height: 200px;
background: skyblue;
}
.son {
width: 10px;
height: 10px;
border: 1px solid red
}
</style>
<div class="father">
<div class="son"></div>
</div>
12、line-height 的继承性
①、line-height: 百分比(!!!)
body{
font-size:20px;
line-height: 200%;
}
p{
font-size: 16px;
}
此时p元素的 行高是body 计算之后的。line-height = 200% * 20 = 40px;
②、ling-height:固定像素
body{
font-size:20px;
line-height: 24px;
}
p{
font-size: 16px;
}
此时p元素的line-height = 24px
③、line-height: 数值
body{
font-size:20px;
line-height: 1.5;
}
p{
font-size: 16px;
}
此时页面上的 p 原素的行高是 1.5*16px=24px;
④、line-height: em
根据上级don’t-size来的, don’t-size, 一个缩放转换
body{
font-size:20px;
line-height: 1.5em;
}
p{
font-size: 16px;
}
此时p元素的 行高是body 计算之后的。line-height =1.5 * 20 = 24px;
13、em px rem vh vw的区别?
从CSS3开始,浏览器对计量单位的支持又提升到了另外一个境界,新增了rem、vh、vw、vm等一些新的计量单位
利用这些新的单位开发出比较良好的响应式页面,适应多种不同分辨率的终端,包括移动设备等
CSS单位:
- em、ex、ch、rem、vw、vh、vmin、vmax、%
- cm、mm、in、px、pt、pc
核心:
- px:绝对单位,页面按精确像素展示
- em:相对单位,基准点为父节点字体的大小,如果自身定义了font-size按自身来计算,整个页面内1em不是一个固定的值
- rem:相对单位,可理解为root em, 相对根节点html的字体大小来计算
- vh、vw:主要用于页面视口大小布局,在页面布局上更加方便简单
⑴、px
px,表示像素,所谓像素就是呈现在我们显示器上的一个个小点,每个像素点都是大小等同的,所以像素为计量单位被分在了绝对长度单位中
有些人会把px认为是相对长度,原因在于在移动端中存在设备像素比,px实际显示的大小是不确定的。这里之所以认为px为绝对单位,在于px的大小和元素的其他属性无关
⑵、em
em是相对长度单位。相对于当前对象内文本的字体尺寸。如当前对行内文本的字体尺寸未被人为设置,则相对于浏览器的默认字体尺寸(1em = 16px)
为了简化 font-size 的换算,我们需要在css中的 body 选择器中声明font-size= 62.5%,这就使 em 值变为 16px*62.5% = 10px。这样 12px = 1.2em, 10px = 1em, 也就是说只需要将你的原来的px 数值除以 10,然后换上 em作为单位就行了
- em 的值并不是固定的
- em 会继承父级元素的字体大小
- em 是相对长度单位。相对于当前对象内文本的字体尺寸。如当前对行内文本的字体尺寸未被人为设置,则相对于浏览器的默认字体尺寸
- 任意浏览器的默认字体高都是 16px
⑶、rem
rem,相对单位,相对的只是HTML根元素font-size的值
同理,如果想要简化font-size的转化,我们可以在根元素html中加入font-size: 62.5%
html {font-size: 62.5%; } /* 公式16px*62.5%=10px */
这样页面中1rem=10px、1.2rem=12px、1.4rem=14px、1.6rem=16px;使得视觉、使用、书写都得到了极大的帮助
- rem单位可谓集相对大小和绝对大小的优点于一身
- 和em不同的是rem总是相对于根元素,而不像em一样使用级联的方式来计算尺寸
⑷、vh、vw
vw ,就是根据窗口的宽度,分成100等份,100vw就表示满宽,50vw就表示一半宽。(vw 始终是针对窗口的宽);
同理,vh则为窗口的高度
这里的窗口分成几种情况:
- 在桌面端,指的是浏览器的可视区域
- 移动端指的就是布局视口
像vw、vh,比较容易混淆的一个单位是%,不过百分比宽泛的讲是相对于父元素:
- 对于普通定位元素就是我们理解的父元素
- 对于position: absolute;的元素是相对于已定位的父元素
- 对于position: fixed;的元素是相对于 ViewPort(可视窗口)
14、什么是响应式设计?响应式设计的基本原理是什么?如何做?
⑴、什么是响应式设计
响应式网站设计(Responsive Web design)是一种网络页面设计布局,页面的设计与开发应当根据用户行为以及设备环境(系统平台、屏幕尺寸、屏幕定向等)进行相应的响应和调整
响应式网站常见特点:
- 同时适配PC + 平板 + 手机等
- 标签导航在接近手持终端设备时改变为经典的抽屉式导航
- 网站的布局会根据视口来调整模块的大小和位置
⑵、实现方式
响应式设计实现通常会从以下几方面思考:
- 弹性盒子(包括图片、表格、视频)和媒体查询等技术
- 使用百分比布局创建流式布局的弹性UI,同时使用媒体查询限制元素的尺寸和内容变更范围
- 使用相对单位使得内容自适应调节
- 选择断点,针对不同断点实现不同布局和内容展示
响应式设计的基本原理是通过媒体查询检测不同的设备屏幕尺寸做处理,为了处理移动端,页面头部必须有meta声明viewport
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no”>
属性对应如下:
- width=device-width: 是自适应手机屏幕的尺寸宽度
- maximum-scale:是缩放比例的最大值
- inital-scale:是缩放的初始化
- user-scalable:是用户的可以缩放的操作
①、媒体查询
CSS3中的增加了更多的媒体查询,就像if条件表达式一样,我们可以设置不同类型的媒体条件,并根据对应的条件,给相应符合条件的媒体调用相对应的样式表
使用@Media查询,可以针对不同的媒体类型定义不同的样式,如:
@media screen and (max-width: 1920px) { ... }
当视口在375px - 600px之间,设置特定字体大小18px
@media screen (min-width: 375px) and (max-width: 600px) {
body {
font-size: 18px;
}
}
通过媒体查询,可以通过给不同分辨率的设备编写不同的样式来实现响应式的布局,比如我们为不同分辨率的屏幕,设置不同的背景图片
比如给小屏幕手机设置@2x图,为大屏幕手机设置@3x图,通过媒体查询就能很方便的实现
②、百分比
通过百分比单位 " % " 来实现响应式的效果
比如当浏览器的宽度或者高度发生变化时,通过百分比单位,可以使得浏览器中的组件的宽和高随着浏览器的变化而变化,从而实现响应式的效果
height、width属性的百分比依托于父标签的宽高,但是其他盒子属性则不完全依赖父元素:
- 子元素的top/left和bottom/right如果设置百分比,则相对于直接非static定位(默认定位)的父元素的高度/宽度
- 子元素的padding如果设置百分比,不论是垂直方向或者是水平方向,都相对于直接父亲元素的width,而与父元素的height无关。
- 子元素的margin如果设置成百分比,不论是垂直方向还是水平方向,都相对于直接父元素的width
- border-radius不一样,如果设置border-radius为百分比,则是相对于自身的宽度
可以看到每个属性都使用百分比,会照成布局的复杂度,所以不建议使用百分比来实现响应式
③、vw、vh
vw表示相对于视图窗口的宽度,vh表示相对于视图窗口高度。任意层级元素,在使用vw单位的情况下,1vw都等于视图宽度的百分之一
与百分比布局很相似,在以前文章提过与%的区别,这里就不再展开述说
④、rem
在以前也讲到,rem是相对于根元素html的font-size属性,默认情况下浏览器字体大小为16px,此时1rem = 16px
可以利用前面提到的媒体查询,针对不同设备分辨率改变font-size的值,如下:
@media screen and (max-width: 414px) {
html {
font-size: 18px
}
}
@media screen and (max-width: 375px) {
html {
font-size: 16px
}
}
@media screen and (max-width: 320px) {
html {
font-size: 12px
}
}
为了更准确监听设备可视窗口变化,我们可以在css之前插入script标签,内容如下:
//动态为根元素设置字体大小
function init () {
// 获取屏幕宽度
var width = document.documentElement.clientWidth
// 设置根元素字体大小。此时为宽的10等分
document.documentElement.style.fontSize = width / 10 + 'px'
}
//首次加载应用,设置一次
init()
// 监听手机旋转的事件的时机,重新设置
window.addEventListener('orientationchange', init)
// 监听手机窗口变化,重新设置
window.addEventListener('resize', init)
无论设备可视窗口如何变化,始终设置rem为width的1/10,实现了百分比布局
除此之外,我们还可以利用主流UI框架,如:element ui、antd提供的栅格布局实现响应式
⑶、响应式布局优缺点
优点:
- 面对不同分辨率设备灵活性强
- 能够快捷解决多设备显示适应问题
缺点:
- 仅适用布局、信息、框架并不复杂的部门类型网站
- 兼容各种设备工作量大,效率低下
- 代码累赘,会出现隐藏无用的元素,加载时间加长
- 其实这是一种折中性质的设计解决方案,多方面因素影响而达不到最佳效果
- 一定程度上改变了网站原有的布局结构,会出现用户混淆的情况