第一种布局方式:标准流(文档流)
标准流即为元素默认的显示方式。如块级元素独占一行,行内元素可以在一行显示。
第二种布局方式:浮动,float属性
浮动对应的css属性是float:left/right;
设置了浮动的元素会脱标,效果就是其后面的元素就当其不存在而占用其原来的地方,按照原来文档流布局方式布局。注意是其后面的元素,对前面的元素无影响。
示例:
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
<style>
body {
padding: 0px;
margin: 0px;
}
.red {
width: 100px;
height: 100px;
background-color: red;
float: left;
}
.green {
width: 100px;
height: 100px;
background-color: green;
}
</style>
</head>
<body>
<div class="red"> </div>
<div class="green"> </div>
</body>
</html>
由于红色div设置了向左浮动,将脱标,而之后的绿色div将顶到body的左上角,红色的div把绿色div覆盖住,整个页面只看得见红色div。
如果把红色div的向左浮动设置成向右浮动即float:right;,则页面上将看到左上角是绿色div,右上角是红色div。
如果去除红色div的浮动,而给绿色div设置向左浮动,发现页面上左上角是红色div,下面是绿色div,为什么红色div没有把绿色div覆盖住呢或者绿色div没有把红色div覆盖住呢?这是因为绿色div在红色div的后面,只有绿色div后面的元素才会占据绿色div的位置。
假如红色div和绿色div都设置了向左浮动,则会看到页面上左上角是红色div,右边是绿色div,这说明浮动可以让块级元素在一行显示,在实际开发中,经常利用这个特性,例如制作导航栏,页面布局等等。
制作导航栏时,一般用到div元素、ul+li元素及a元素。
ul元素默认是上下外边距16px,左内边距是40px的,且在每个li前面都有一个圆点,我们必须先清除这些属性。
示例如下:
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
<style>
body {
padding: 0px;
margin: 0px;
}
.nav {
width: 800px;
height: 50px;
background-color: pink;
/*让导航栏div水平居中*/
margin: 5px auto;
}
ul {
margin: 0px;
padding: 0px;
list-style: none;
}
li.left-nav {
float: left;
}
li.right-nav {
float: right;
}
a {
display: inline-block;
height: 50px;
font-size: 20px;
line-height: 50px;
text-decoration: none;
padding: 0px 10px;
}
a:hover {
background-color: red;
}
</style>
</head>
<body>
<div class="nav">
<ul>
<li class="left-nav">
<a href="#">百度</a>
</li>
<li class="left-nav">
<a href="#">百度一下</a>
</li>
<li class="right-nav">
<a href="#">百度</a>
</li>
<li class="right-nav">
<a href="#">百度一下</a>
</li>
</ul>
</div>
</body>
</html>
此外,浮动还可以让行内元素变为行内块元素,例如给span元素设置了浮动之后,就可以手动设置宽高了,但是一般不推荐用这种方式让行内元素变为行内块元素,还是用display:inline-block;好一点,因为这样还是标准流。
浮动带来的问题:当子元素设置了浮动,父元素没有高度的时候,造成页面布局混乱。这种情况下进行清除浮动。
清除浮动两种方法:
1.给父盒子设置overflow:hidden;,这触发了BFC
2.给父盒子多设置一个class属性值,比如说是clearfix,在后面插入内容,设置clearfix:after如下:
*父盒子在后面插入内容*/
.clearfix:after {
/*内容随便写*/
content: "42314丙";
/*dispay必须为block*/
display: block;
/*左右浮动都清除*/
clear: both;
/*height和line-height必须要有一个,否则会多出文字的高度;*/
height: 0;
line-height: 0;
/*visibility必须设为hidden,否则内容会在页面上显示的*/
visibility: hidden;
}
第三种布局方式:定位,position属性
1.绝对定位 position:absolute;
当给一个单独的元素设置绝对定位时,该盒子不占位置(脱标),且left/right属性值是以浏览器边框为基准的。示例:
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<style>
.father {
width: 200px;
height: 200px;
background-color: blue;
position: absolute;
left: 20px;
}
.father2 {
width: 300px;
height: 300px;
background-color: yellow;
margin-left: 20px;
}
</style>
<body>
<div class="father"></div>
<div class="father2"></div>
</body>
</html>
作为副作用的是,如果给行内元素设置绝对定位,则该该元素会转化为行内块元素。但是,如果单纯只是想把元素从行内元素变成行内块元素的话,不推荐使用这种方式,还是建议使用display:inline-block;
当盒子发生嵌套关系的时候,如果父盒子设置了定位(可以是绝对定位,相对定位或者绝对定位),则子盒子设置绝对定位时将以父盒子左上角为基准,否则还是以浏览器左上角为基准。示例:
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<style>
body {
padding: 0;
margin: 0;
}
.father1 {
width: 300px;
height: 300px;
background-color: gray;
position: absolute;
right: 100px;
top: 100px;
}
/*父盒子设置了绝对定位,子盒子的绝对定位将以父盒子的左上角为基准*/
.son1 {
width: 100px;
height: 100px;
background-color: black;
position: absolute;
right: 100px;
top: 100px;
}
.father2 {
width: 300px;
height: 300px;
background-color: orange;
}
/*父盒子没有设置定位,子盒子的绝对定位任意浏览器左上角基准*/
.son2 {
width: 100px;
height: 100px;
background-color: red;
position: absolute;
left: 100px;
top: 100px;
}</style>
<body>
<div class="father1">
<div class="son1"></div>
</div>
<div class="father2">
<div class="son2"></div>
</div>
</body>
</html>
2.相对定位 position:relative;
元素设置了相对定位后还是占原来的位置,不脱标,且是以自己的位置为基准。示例:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<style>
.father {
width: 200px;
height: 200px;
background-color: blue;
margin: 50px;
position: relative;
left: 50px;
bottom: 50px;
}
.father2 {
width: 200px;
height: 200px;
background-color: red;
margin: 50px 100px;
}
</style>
</head>
<body>
<div class="father"></div>
<div class="father2"></div>
</body>
</html>
常用模式:子绝父相(子元素设置绝对定位,父元素设置相对定位)。示例:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<style>
body {
padding: 0px;
margin: 20px;
}
.father {
width: 200px;
height: 200px;
background-color: blue;
margin: 50px;
/*父盒子设置相对定位*/
position: relative;
}
.son {
width: 100px;
height: 100px;
background-color: red;
/*子盒子设置绝对定位*/
position: absolute;
left: 50px;
top: 50px;
}
</style>
</head>
<body>
<div class="father">
<div class="son"></div>
</div>
</body>
</html>
让子盒子在父盒子水平居中,如果是标准流的话,则直接margin:0 auto;即可,但是这个设置只对标准流有效。
那么如何让定位的盒子居中呢?方法是:水平方向上,先用left让子盒子往右移动父盒子宽度的一半,然后再用margin-left往左移动子盒子宽度的一半。竖直方向上,先用top让子盒子向下移动父盒子高度的一半,再用margin-top向上移动子盒子高度的一半。示例:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<style>
.father {
width: 300px;
height: 200px;
background-color: gray;
position: relative;
}
.son {
width: 200px;
height: 100px;
background-color: orange;
position: absolute;
left: 50%;
top: 50%;
margin-top: -50px;
/*如果想让子盒子靠下,不设置top,而设置bottom为即可*/
/*bottom: 0;*/
margin-left: -100px;
}
</style>
</head>
<body>
<div class="father">
<div class="son"></div>
</div>
</body>
</html>
3.固定定位 position:fixed; 拉动浏览器滚动条,元素位置看起来不变。
设置固定定位的元素会脱标,副作用是也会将行内元素转化为行内块元素。示例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<style type="text/css">
.box {
width: 200px;
height: 200px;
background: red;
position: fixed;
}
.box2 {
width: 250px;
height: 200px;
background: blue;
}
span {
position: fixed;
width: 300px;
height: 300px;
background: orange;
}
</style>
</head>
<body>
<div class="box"></div>
<div class="box2"></div>
<span></span>
</body>
</html>
与定位相关的一个属性:z-index
z-index的值是一个不带任何单位的整数,可以是负数。z-index表示层叠的优先级,如果多个设置了定位的元素有层叠,对于层叠部分来说,z-index值大的元素才会被我们看到,其他的都被这个遮住了。
示例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<style type="text/css">
.box {
width: 200px;
height: 200px;
background: red;
position: fixed;
z-index: 10;
}
span {
width: 300px;
height: 300px;
background: orange;
position: fixed;
z-index: 9;
}
</style>
</head>
<body>
<div class="box"></div>
<span></span>
</body>
</html>
如上例,div元素和span元素都设置了固定定位,但是两个都没有具体设置top/right/left/bottom值,所以都是在浏览器左上角(贴近浏览器边框的位置),会发生层叠。因为span元素在div元素的后面,所以如果不设置z-index的话,span会遮住div,即在层叠部分我们看到的是span的部分。上例中为两个元素都设置了z-index值,且div的z-index的值大于span的z-index的值,此时,层叠部分我们看到的是div的部分。
布局设计原则:
尽量使用标准流,标准流解决不了的使用浮动,浮动解决不了的使用定位。