0%

CSS 布局

盒模型

盒模型就是 margin border padding content

因为存在 margin,border和padding,元素可能会变得和预想的不一样大小,在 CSS 中加入以下代码能避免这样的事

1
2
3
4
5
* {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}

使用* 通配符选择器,选择所有元素,加上 border-box,元素就会变得以设置的长度会显示标准, margin会在 width 之外, border 和padding 会在 width 以内

position

1
2
3
4
5
6
7
8
9
10
11
12
.fancy {
width: 500px;
border: 1px solid seagreen;
width: 500px;
margin: 20px auto;
padding: 50px;
border-width: 10px;
}
<!--position: relative;-->
<!--top: -20px;-->
<!--left: 20px;-->
<!--background-color: sienna;-->

static:

static 是 position 的默认值,意思是不会被 position 特殊定位,只按正常的方式定位

relative: 它的偏移是相对于原先在文档流中的位置

relative是相对定位,相对参考值是他本来position:static 时的位置.其他的元素的位置则不会受该元素的影响发生位置改变来弥补它偏离后剩下的空隙。

fixed: 它的偏移量是相对于视窗的

fixed是固定定位.一个固定定位(position属性的值为fixed)元素会相对于视窗来定位,这意味着即便页面滚动,它还是会停留在相同的位置。和 relative 一样, top 、 right 、 bottom 和 left 属性都可用。
不一样的是 relative 的参考对象是原来它应该在的地方, fixed 是绝对定位,参考对象是整个浏览器当前显示的部分

absolute:它的偏移量是相对于最近一级position不是static的祖先元素的

absolute 是最棘手的position值。首先先记住“positioned”元素是指 position 值不是 static 的元素。然后是 absolute 的规则:
absolute 与 fixed 的表现类似,但是它不是相对于视窗而是相对于最近的“positioned”祖先元素。如果绝对定位(position属性的值为absolute)的元素没有“positioned”祖先元素,那么它是相对于文档的 body 元素,并且它会随着页面滚动而移动。

这里的主块是relative,1是absolute,2是relative

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
.main {
position: relative;
top: 100px;
position: relative;
max-width: 600px;
margin: 0 auto;
}

.simple {
position: absolute;
top: 100px;
border: 1px solid salmon;
width: 500px;
margin: 20px auto;
}

.fancy {
position: 2;
top: -20px;
left: 20px;
background-color: sienna;
width: 500px;
border: 1px solid seagreen;
width: 500px;
margin: 20px auto;
padding: 50px;
border-width: 10px;
}

float

浮动也是一种经常用来布局的属性.Float 可用于实现文字环绕图片,就像 word 里面那种一样.

1
2
3
4
img {
float: right;
margin: 0 0 1em 1em;
}

clear

clear 是个很神奇的东西,在块元素中加入float 之后,这个块就会变成一个浮动的块,在它后面的元素会根据他的存在而变化,但是如果我们想换行,不让第一个浮动元素影响自己的话,就需要加上 clear: both; ,然后第二个元素就会跑到下一行里,按原来的性质来定位.

clearfix hack

我们知道,一个块级元素如果没有设置height,其height是由子元素撑开的。对子元素使用了浮动之后,子元素会脱离标准文档流,也就是说,父级元素中没有内容可以撑开其高度,这样父级元素的height就会被忽略,这就是所谓的高度塌陷。要解决这样的问题,我们就是要使用清除浮动。

这个图片比包含它的元素还高, 而且它是浮动的,于是它就溢出到了容器外面

这个时候需要在他的容器上加上这一句

1
2
overflow: auto;  //或者
overflow: hidden; // 或者在需要结尾处增加一个清除浮动的块元素,例如:
1
2
3
<div style="clear: both;"></div>
clear: both;
当然也可以加载下面第一个不需要浮动的元素里,但由于代码最好是可复用的,所以增加这个清楚浮动块元素更加好

如何使用 float 做布局

左边用 float: left;width: 100px; 右边用 margin-right:100px;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
.container {
overflow: auto;
border: 1px solid black;
}

.left {
float: left;
width: 100px;
border: 1px solid saddlebrown;
}

.right {
border: 1px solid red;
width: auto;
margin-left: 100px;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<body>
<div class="container">
<div class="left">
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
</ul>
</div>
<div class="right">
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
</ul>
</div>
<div class="right">
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
</ul>
</div>
</div>
</body>

还可以用百分比控制宽度,但是不能长度超过100%,因为经常还要算上边框的宽度,50%加上50%就会超出屏幕宽度,这时就会自动换行

inline-block

如果是要做成一行连续的浮动元素,可以用display: inline-block;行内块元素

1
2
3
4
5
6
7
8
9
.box {
float: left;
width: 200px;
height: 100px;
margin: 1em;
}
.after-box {
clear: left;
}


这个时候如果用内行块元素:

1
2
3
4
5
6
.box2 {
display: inline-block;
width: 200px;
height: 100px;
margin: 1em;
}

效果完全相同,而且下一行的元素也不需要加上 clear: left;
如果用 inline-block 来布局要注意一下几点:

  • vertical-align 属性会影响到 inline-block 元素,你可能会把它的值设置为 top 。
  • 你需要设置每一列的宽度
  • 如果HTML源代码中元素之间有空格,那么列与列之间会产生空隙
  • 解决换行符导致是空隙:在inline-block的父元素中设置样式font-size:0;letter-spacing: -4px; 然后设置inline-block的所有兄弟元素 font-size:值;letter-spacing: 值px; 恢复正常的显示。
  • 如果用百分比做长度,注意如果有边框,那么两个长度的百分比相加可能会大于100%,从而第二个元素跑到第二行去.(30%+1px+70%+1px>100%)
  • inline-block默认是基线对齐的,而inline-block的基线又跟文本基线一致,所以在内容不同的时候并不能水平对齐。只需要用vertical-align显式声明一下top/bottom/middle对齐即可

这里补充一下基线的内容,没你想的那么简单哦。分有文字和无文字两种情况:

  • 无文字:容器的margin-bottom下边缘。与容器内部的元素没一毛钱关系。
  • 有文字:最后一行文字的下边缘,跟文字块(p,h等)的margin、padding没关系!注意是最后一行,无论文字在什么子对象容器内在什么位置都没关系,浏览器会找到最后一行文字对齐底部。

你们感受一下:

警示

inline-block的基线是最后一行文字的底部,flex里面的基线是第一行文字的底部