1:盒子模型
2:CSS定位与居中问题
3:CSS浮动
盒子模型
div盒子模型
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>div盒子模型</title>
<style type="text/css">
*{
padding: 0;
margin: 0;
}
.div-box{
width: 100px;
height: 100px;
background: #000;
padding: 10px;
border: 10px solid red;
margin: 10px;
}
</style>
</head>
<body>
<div class="div-box"></div>
</body>
</html>
margin 外边距的合并
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>margin外边距的合并</title>
<style type="text/css">
*{
padding: 0;
margin: 0;
}
.div-box1{
width: 100px;
height: 100px;
padding: 10px;
border: 10px solid red;
margin: 10px;
}
.div-box2{
width: 100px;
height: 100px;
padding: 10px;
border: 10px solid red;
margin: 10px;
}
</style>
</head>
<body>
<div class="div-box1">div</div>
<div class="div-box2">div</div>
</body>
</html>
上述代码中,两个div块的上下左右外边距margin均为10px,在外边距合并后,div和div上下边框之间的距离会取最大的margin值,本例中margin数值相同,上下div的border间的距离则为10px而非加和的20px。效果如图所示:
span"盒子模型"
内联元素在页面布局中并不像块级元素一样能够使用盒子模型中所有的属性,但是一些属性也是能够进行的控制的。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>span</title>
<style type="text/css">
*{
padding: 0;
margin: 0;
}
.span1{
border: 1px solid blue;
margin: 10px;
}
.span2{
padding: 100px;
border: 1px solid red;
}
div{
border: 1px solid green;
}
</style>
</head>
<body>
<span class="span1">span</span><span class="span2">span</span>
<div>1111111111111111111111111</div>
</body>
</html>
上面的代码在页面中的展示效果如下:
width 宽度属性以及 height 高度属性 仅在块级元素以及替换元素中适用。通过上面的代码可以看到,第二个span元素虽然设置了padding但是仅仅在left,right,以及bottom方向起了作用,并且在bottom方向上,虽然将border撑开了,但是下面的div元素仍然无视了撑开的高度,在第二行排布。在span元素中适用的盒子属性仅有左右方向上的属性,即:margin-left,margin-right,padding-left,padding-right,border-left,border-right。因为,span就是一个内联元素(行内元素),只有行内的属性会起到作用。在上述元素中,通常只会使用到 margin-left 以及 margin-right。
display:inline-block
display属性可以将块级元素转换为行内元素,同样也可以将行内元素转换为块级元素。inline-block属性值则是使一些行内元素具有块级元素的某些属性。如代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style type="text/css">
*{
padding: 0;
margin: 0;
}
.span1{
display: inline-block;
width: 100px;
height: 100px;
margin: 10px;
border: 1px solid blue;
}
.span2{
display: inline-block;
width: 100px;
height: 100px;
margin: 10px;
border: 1px solid red;
}
div{
width: 100px;
height: 100px;
border: 1px solid green;
margin: 10px;
}
</style>
</head>
<body>
<span class="span1">span</span><span class="span2">span</span>
<div>div</div>
</body>
</html>
页面展示效果如下:
可以看到span内设置了display: inline-block;
属性后,不仅盒模型的所有属性都可以使用,且两个span元素在一行进行了显示。两个span元素之间的margin为20px ,因为左右margin不会产生合并,但是注意的是,span和 下一行的div之间的margin同样为20px,说明在上下方向,span与div的margin并没有合并!
box-sizing: border-box;
测试代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style type="text/css">
*{
padding: 0;
margin: 0;
}
div{
width: 100px;
height: 100px;
padding: 10px;
border: 10px solid red;
margin: 10px;
box-sizing: border-box;
}
</style>
</head>
<body>
<div>div</div>
</body>
</html>
上述代码在网页显示的效果为:
CSS属性
box-sizing: border-box;
可以将原来的content-box(width,height作用在content上)转换为border-box(width ,height作用在border以内)。简单的来说,这个盒子模型的宽度和高度的100px,是content+padding+boder的和。
CSS定位与居中问题
居中是页面布局最常被用到的需求,处理居中问题往往有多种解决方式,本篇博客将介绍CSS定位以及常用的几种解决居中问题的思路。
static
position: static;
指定了元素使用正常的布局行为,即元素在文档常规流中当前的布局位置。此时 top, right, bottom, left 和 z-index 属性无效。什么叫文档流呢?文档流就是元素在页面中的流动方向,即:行内元素从左到右,块级元素自上至下。
relative
relative最大的作用就是使元素成为可定位的祖先元素。被设置为relative定位属性值的元素可以使用top,right,bottom,left,z-index等属性值进行相对定位,且相对定位的元素不会离开常规流。那么relative相对定位,到底是相对哪个元素进行定位的呢?实际上,就是相对于自己原本常规流中的位置进行相对定位的。示例如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>relative相对定位</title>
<style type="text/css">
*{
padding: 0;
margin: 0;
}
.box {
display: inline-block;
width: 100px;
height: 100px;
background: red;
color: white;
}
#two {
position: relative;
top: 20px;
left: 20px;
background: blue;
z-index: -1;
}
</style>
</head>
<body>
<div class="box" id="one">One</div>
<div class="box" id="two">Two</div>
<div class="box" id="three">Three</div>
<div class="box" id="four">Four</div>
</body>
</html>
示例在页面的效果为:
四个div均设置了
display: inline-block;
属性,可以看到蓝色的div块相对于自己常规流中的位置 偏移了top: 20px;left: 20px;
,但是Two块并没有脱离常规流,而是在常规流中占据了自己原来的"一亩三分地"。这里设置了z-index: -1;
,z-index可以控制元素堆叠的顺序,通常来说 z-index 较大的元素会覆盖较小的一个。所以Two块会被 Three块压在下面。
absolute
绝对定位元素相对于最近的 非 static 祖先元素定位。通常这个祖先元素设置为relative,被设置了absolute的元素会相对于 设置了relative的祖先元素进行定位,倘若没有这样一个祖先元素,那么它就会相对于body定位。被设置position: absolute;
的元素会脱离文档流,示例1:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>absolute绝对定位</title>
<style type="text/css">
*{
padding: 0;
margin: 0;
}
.div1{
color: #FFFFFF;
display: inline-block;
width: 100px;
height: 100px;
background: red;
}
.div2{
color: #FFFFFF;
display: inline-block;
width: 100px;
height: 100px;
background: red;
position: relative;
}
.child{
display: inline-block;
width: 100px;
height: 100px;
background: blue;
position: absolute;
left: 30px;
top: 30px;
}
</style>
</head>
<body>
<div class="div1">div1</div>
<div class="div2">
div2
<div class="child"></div>
</div>
</body>
</html>
在页面中的效果为:
蓝色的block相对于设置了相对定位的父元素div2 发生了偏移。示例2:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>absolute绝对定位</title>
<style type="text/css">
*{
padding: 0;
margin: 0;
}
.box {
display: inline-block;
border: 1px solid #000000;
background: red;
width: 100px;
height: 100px;
float: left;
color: white;
}
#three {
background: blue;
position: absolute;
top: 20px;
left: 20px;
}
</style>
</head>
<body>
<div class="box" id="one">One</div>
<div class="box" id="two">Two</div>
<div class="box" id="three">Three</div>
<div class="box" id="four">Four</div>
</body>
</html>
示例效果:
由上面的例子可以看到,绝对定位元素脱离了文档流,并且当设置了绝对定位的元素如果没有非static的祖先元素,就会相对于body进行定位。设置了absolute,fixed的元素会自动转换为inline-block,也就是说即使在代码中没有添加
display: inline-block;
,只要有position: absolute;
,那么这个元素就会变为一个inline-block。使用绝对定位在处理页面元素居中问题上除了可以设置top,left,right,bottom属性的具体值来达到水平居中,垂直居中,还可以将属性设置为top:0;bottom:0;left:0;right:0;margin:auto;
来达到居中的效果。示例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>absolute居中妙招</title>
<style type="text/css">
*{
padding: 0;
margin: 0;
}
.outer {
width: 300px;
height: 300px;
border: 1px solid red;
position: relative;
}
.inner{
width: 100px;
height: 100px;
border: 1px solid blue;
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
margin: auto;
}
</style>
</head>
<body>
<div class="outer">
<span class="inner"></span>
</div>
</body>
</html>
页面显示效果为:
通过示例可以看到,即使div内层为span元素,但是设置了绝对定位后,可以添加width和height属性,在代码中,我们虽然没有添加
display: inline-block;
,但是,默认地 span这个行内元素 变成了 一个 inline-block。并且看到span元素相对于父元素水平居中且垂直居中。
用 absolute定位画一个旋转的太极
- 在线效果预览:点击预览
- 使用在线工具:colorzilla
- 参考:keyframes
- 参考:animation-iteration-count
- 参考: animation-timing-function
使用absolute定位画一个匀速旋转的太极,代码如下(非在线预览的代码):
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>line-height</title>
<style type="text/css">
*{
padding: 0;
margin: 0;
}
body{
background: #666;
}
@keyframes spin {
from{
transform: rotate(0deg);
}
to{
transform: rotate(360deg);
}
}
.yinyang{
width: 200px;
height: 200px;
border-radius: 50%;
background: linear-gradient(to bottom, #ffffff 0%,#ffffff 50%,#000000 51%,#000000 100%);
position: relative;
animation-duration: 3s;
animation-name: spin;
animation-iteration-count: infinite;
animation-timing-function: linear;
margin: 0 auto;
top: 200px;
}
.yinyang::before{
content: '';
position: absolute;
width: 100px;
height: 100px;
border-radius: 50%;
background: #FFFFFF;
box-sizing: border-box;
border: 40px solid black;
left: 0;
top: 25%;
}
.yinyang::after{
content: '';
position: absolute;
width: 100px;
height: 100px;
border-radius: 50%;
background: #000;
box-sizing: border-box;
border: 40px solid #FFFFFF;
left: 50%;
top: 25%;
}
</style>
</head>
<body>
<div class="yinyang"></div>
</body>
</html>
fixed
fixed和absolute可谓是"本是同根生",因为它和absolute一样,固定定位元素会脱离文档流,但fixed和 absolute的参照物不同,fixed 会参照 viewport 视口 做绝对定位。例如在网页中,我们滚动页面,但一直固定在视口的广告,这些悬浮的广告就是使用fixed固定定位来实现的。
sticky
sticky即粘性定位,粘性定位可以被认为是相对定位和固定定位的混合。粘性定位的元素如果产生了偏移,原位置仍然会在常规流中。它的偏移标尺是最近的有滚动的祖先元素(设有overflow: scroll;
),如果没有,那么它的标尺就是viewport即:视口。示例如下:
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<style type="text/css">
div{
height: 100px;
border: 1px solid red;
position: sticky;
top: 50px;
}
</style>
</head>
<body>
<p>111</p><p>111</p><p>111</p><p>111</p><p>111</p>
<p>111</p><p>111</p><p>111</p><p>111</p><p>111</p>
<p>111</p><p>111</p><p>111</p><p>111</p><p>111</p>
<p>111</p><p>111</p><p>111</p><p>111</p><p>111</p>
<p>111</p><p>111</p><p>111</p><p>111</p><p>111</p>
<div>div</div>
<p>111</p><p>111</p><p>111</p><p>111</p><p>111</p>
<p>111</p><p>111</p><p>111</p><p>111</p><p>111</p>
<p>111</p><p>111</p><p>111</p><p>111</p><p>111</p>
<p>111</p><p>111</p><p>111</p><p>111</p><p>111</p>
<p>111</p><p>111</p><p>111</p><p>111</p><p>111</p>
</body>
</html>
本例中,div元素相对于viewport粘性定位,在视口top:50px
处,可以想象生成了一个高度为100px的"矩形"。在div没有和"矩形"重合前,div元素处在文档流,随着页面滚轮向下滚动,div与"矩形"完成了"重合"。这时,div则出现了固定定位的效果,即以视口为参照,固定在相对于视口top:50px
处,但是div文档流的位置仍然保留。
处理元素居中的问题
页面布局中,最频繁需要处理的问题就是元素居中的问题。无论是水平居中,还是垂直居中,常规的解决思路为:
- 搞清楚,谁相对于谁居中
- 将问题转换为一个块级元素相对于另一个块级元素居中的问题
例如使用属性 margin: 0 auto
水平居中:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>居中问题</title>
<style type="text/css">
*{
padding: 0;
margin: 0;
}
.out{
width: 300px;
height: 300px;
border: 1px solid black;
}
.inner{
width: 100px;
height: 100px;
border: 1px solid red;
margin: 0 auto;
}
</style>
</head>
<body>
<div class="out">
<div class="inner"></div>
</div>
</body>
</html>
除了利用margin进行居中,还可以使用相对定位和绝对定位,只要计算出偏移量就可以让内部的div相对于外部的div块水平居中。偏移量left=父级块的width×50%-内部块的width×50%
,本例中为left:100px
;偏移量top=父级块的height×50%-内部块的height×50%
,本例为:top:100px
。本例使用CSS定位水平居中及垂直居中,代码为:
*{
padding: 0;
margin: 0;
}
.out{
width: 300px;
height: 300px;
border: 1px solid black;
position: relative;
}
.inner{
width: 100px;
height: 100px;
border: 1px solid red;
position: absolute;
top: 100px;
left: 100px;
}
除了上面计算具体的偏移量,还可以使用这样的写法:
*{
padding: 0;
margin: 0;
}
.out{
width: 300px;
height: 300px;
border: 1px solid black;
position: relative;
}
.inner{
width: 100px;
height: 100px;
border: 1px solid red;
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
margin: auto;
}
当然,这只是一般的解决思路,并不能处理所有的问题,或者说,有些属性和方法在使用上,更加便捷。例如:text-align属性。text-align:center;
text-align 属性只有在块级元素内使用才能生效,CSS属性定义行内文本如何相对它的块父元素对齐,它并不能控制块元素自己的对齐,只能控制它的行内内容的对齐。如:<div><span>span</span></div>
如果希望行内的文本"span" 在行内水平居中,在块级标签内使用text-align即:div{text-align: center;}
即可。如果一个div块包裹着一个img图片,也可以用text-align来设置图片水平居中,但是一般情况下不会这么做。因为text-align 属性顾名思义,是用来设置文本的一个属性(text)。设置图片水平居中的方法往往是在img标签外部再嵌套一个div标签。解决居中问题,更多的还需要不断摸索和尝试。
CSS浮动
- 案例一:使用浮动完成如下左右布局的效果:
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>案例一</title>
<style type="text/css">
*{
padding: 0;
margin: 0;
}
body{
background: #EFEFEF;
}
.clearfix:after{
content: '';
display: block;
clear: both;
}
.skills{
width: 940px;
margin: 0 auto;
}
.skills h2{
font-size: 30px;
color: #3D4451;
text-align: center;
margin-top: 60px;
margin-bottom: 30px;
}
.skills ol{
list-style: none;
background-color: #FFFFFF;
padding: 50px;
box-shadow: 0px 2px 8px 0px rgba(0,0,0,0.75);
}
.skills ol>li{
width: 47%;
color: #3D4451;
box-sizing: border-box;
float: left;
margin-bottom: 30px;
}
.skills ol>li:nth-child(even){
float: right;
}
.skills ol>li:nth-child(5),
.skills ol>li:nth-child(6){
margin-bottom: 0;
}
.skills ol li .progressBar{
height: 5px;
background-color: #FAEAEA;
border-radius: 3px;
margin-top: 5px;
}
.skills ol li .progressBar>.progress{
width: 70%;
height: 100%;
background-color: #E6686A;
border-radius: 3px;
}
</style>
</head>
<body>
<section class="skills">
<h2>技能</h2>
<ol class="clearfix">
<li>
HTML5 & CSS3
<div class="progressBar">
<div class="progress"></div>
</div>
</li>
<li>
JavaScript
<div class="progressBar">
<div class="progress"></div>
</div>
</li>
<li>
jQuery
<div class="progressBar">
<div class="progress"></div>
</div>
</li>
<li>
Vue
<div class="progressBar">
<div class="progress"></div>
</div>
</li>
<li>
React
<div class="progressBar">
<div class="progress"></div>
</div>
</li>
<li>
HTTP
<div class="progressBar">
<div class="progress"></div>
</div>
</li>
</ol>
</section>
</body>
</html>
本案例使用在线shadow生成器:cssmatic。
本案例中使用了浮动,完成了示例的左右排布的效果,使用浮动后,元素会脱离文档流,出现"浮动溢出",也叫"高度塌陷",需要在元素浮动后"清除浮动"。清除浮动有以下几种常用方法:
- 方法一
在浮动元素后,使用一个空元素例如:<div class="clear"></div>
- 方法二
给浮动元素添加overflow: hidden;
- 方法三
使用CSS3的:after伪元素
这也是现在清除浮动最常用的方法。具体为在浮动的元素的父级元素添加class="clearfix"
属性,然后添加CSS清除浮动代码:
.clearfix:after{
content: '';
display: block;
clear:both;
}
- 案例二:使用浮动完成如下布局:
案例效果为:点击"所有","原生JS&CSS","框架",底部的滚动条发生滚动。代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>absolute绝对定位</title>
<style type="text/css">
*{
padding: 0;
margin: 0;
}
body{
background-color: #EFEFEF;
}
.clearfix:after{
content: '';
display: block;
clear: both;
}
.portfolio{
width: 940px;
margin: 60px auto 0;
text-align: center;
}
.portfolio h2{
color: #3D4451;
font-size: 30px;
margin-bottom: 30px;
}
.portfolio nav{
text-align: center;
display: inline-block;
cursor: pointer;
}
.portfolio ol{
list-style-type: none;
margin-bottom: 5px;
}
.portfolio ol>li{
font-size: 17px;
float: left;
margin-right: 40px;
}
.portfolio ol>li:nth-child(3){
margin-right: 0;
}
.progressBar{
height: 5px;
background: #FFFFFF;
border-radius: 3px;
}
.progressBar .progress{
width: 15%;
height: 100%;
background-color: #E6686A;
border-radius: 3px;
transition: all 0.5s;
}
.progressBar.state-1 .progress{
margin-left: 0;
width: 15%;
}
.progressBar.state-2 .progress{
margin-left: 74px;
width: 39%;
}
.progressBar.state-3 .progress{
margin-left: 209px;
width: 18%;
}
</style>
</head>
<body>
<section class="portfolio">
<h2>作品集</h2>
<nav>
<ol class="clearfix">
<li id="li1">所有</li>
<li id="li2">原生JS & CSS</li>
<li id="li3">框架</li>
</ol>
<div id="progressBar" class="progressBar state-1">
<div class="progress"></div>
</div>
</nav>
<script>
li1.onclick = function () {
progressBar.className = 'progressBar state-1'
}
li2.onclick = function () {
progressBar.className = 'progressBar state-2'
}
li3.onclick = function () {
progressBar.className = 'progressBar state-3'
}
</script>
</section>
</body>
</html>