- 一个元素总宽高为50px,要怎么在调整边框大小的时候,不需要重新计算和设置width/height呢?
- 为什么给一些元素设置宽高,但是却不生效?
- 如何将一个元素固定在页面的某个位置,具体怎么做?
- 为什么将某个元素z-index设置为9999999,但是它依然被其他元素遮挡住了呢?
页面布局的基本规则
- 盒模型
- 内联元素与块状元素
- 文档流布局
- 元素堆叠
盒模型
什么是盒模型?浏览器对文档进行布局的时候,会将每个元素都表示为这样一个盒子。
盒模型是根据元素的样式来进行计算的,我们可以通过调整元素的样式来改变盒模型。上图中的盒模型来自下面这个<div>元素,我们给这个元素设置了margin、padding和border:
<style>
.box-model-sample {
margin: 10px;
padding: 10px;
border: solid 2px #000;
}
</style>
<div class="box-model-sample">this is a div</div>
- 盒模型会发生margin外边距叠加,叠加后的值会以最大边距为准。 需要注意的是,并不是所有情况下都会发生外边距叠加,比如行内框、浮动框或绝对定位框之间的外边距不会叠加。
<style>
.box-model-sample {
margin: 10px;
padding: 10px;
border: solid 2px #000;
}
.large-margin {
margin: 20px;
}
</style>
<div class="box-model-sample">这是一个div</div>
<div class="box-model-sample">这是另一个div</div>
<div class="box-model-sample large-margin">这是一个margin大一点的div</div>
- 盒模型计算效果有多种,比如元素宽高是否包括了边框。我们可以通过
box-sizing
属性进行设置盒模型的计算方式,正常的盒模型默认值是content-box
。使用box-sizing
属性可以解决问题 1(调整元素的边框时,不影响元素的宽高),我们可以将元素的box-sizing
属性设置为border-box
:
<style>
.box-model-sample {
height: 50px;
margin: 10px;
padding: 5px;
border: solid 2px #000;
}
.border-box {
box-sizing: border-box;
}
</style>
<div class="box-model-sample">这是一个div(content-box)</div>
<div class="box-model-sample border-box">这是另一个div(border-box)</div>
对于默认content-box
的元素来说,元素所占的总宽高为设置的元素宽高(width/height
)等于:content + padding + border
,因此这里该元素总高度为50 + 5 * 2 + 2 * 2 = 64px
。
内联元素与块状元素
盒模型可以解决我们如何精确控制元素大小问题, 但设置有时候会不生效, 这时候需要我们考虑 元素本身性质。
在浏览器中,元素可分为内联元素和块状元素。比如,<a>
元素为内联元素,<div>
元素为块状元素,我们分别给它们设置宽高示例页面:
<style>
a,
div {
width: 100px;
height: 20px;
}
</style>
<a>a-123</a><a>a-456</a><a>a-789</a>
<div>div-123</div>
<div>div-456</div>
<div>div-789</div>
效果:
可以看到,<a>
元素和<div>
元素最主要的区别在于:
-
<a>
元素(内联元素)可以和其他内联元素位于同一行,且宽高设置无效; -
<div>
元素(块状元素)不可和其他元素位于同一行,且宽高设置有效。
所以当我们给某个元素设置宽高不生效,是因为该元素为内联元素。那么有没有办法解决这个问题呢?
我们可以通过设置display的值来对元素进行调整。
设置为block块状元素,此时可以设置宽度width和高度height。
设置为inline内联元素,此时宽度高度不起作用。
设置为inline-block,可以理解为块状元素和内联元素的结合,布局规则包括:
-
位于块状元素或者其他内联元素内;
-
可容纳其他块状元素或内联元素;
-
宽度高度起作用。
inline-block
可以很方便解决一些问题:使元素居中、给inline元素(<a>/<span>
)设置宽高、将多个块状元素放在一行等。
文档流和元素定位
如何将一个元素定位在页面某个位置 ?这个问题涉及文档流的布局和元素定位的样式设置。
什么是文档流呢?正常的文档流在 HTML
里面为从上到下,从左到右的排版布局。
文档流布局方式可以使用position
样式进行调整,包括:
static
(默认值)inherit
(继承父元素)relative
(相对定位)absolute
(相对非static父元素绝对定位)fixed
(相对浏览器窗口进行绝对定位)
- 元素
position
样式属性值为static
(默认值)时,元素会忽略top/bottom/left/right
或者z-index
声明,比如我们给部分元素设置position: static
的样式以及left
和top
定位 :
a, p, div {
border: solid 1px red;
}
.static {
position: static;
left: 100px;
top: 100px;
}
postion static 示例页面我们可以看到给position: static
的元素添加定位left: 100px; top: 100px;
是无效的。
- 元素
position
样式属性值为relative
时,元素会保持原有文档流,但相对本身的原始位置发生位移,且会占用空间,比如我们给部分元素设置position: relative
样式以及left
和top
定位:
a, p, div {
border: solid 1px red;
}
.relative {
position: relative;
left: 100px;
top: 100px;
}
在postion relative 示例页面中,我们可以看到position: relative
的元素相对于其正常位置进行定位,元素占有原本位置(文档流中占有的位置与其原本位置相同),因此下一个元素会排到该元素后方。
-
元素
position
样式属性值为absolute
、且设置了定位(top/bottom/left/right
)时,元素会脱离文档流,相对于其包含块(第一个postion
不为static
的父级元素)来定位,且不占位。 postion absolute 示例页面 -
元素
position
样式属性值为fixed
时,元素脱离文档流、且不占位,相对于相对于浏览器窗口进行定位。postion fixed 示例页面
元素堆叠 z-index
元素的堆叠方式和顺序,除了与position定位有关,也与z-index有关。通过设置z-index值,我们可以设置元素的堆叠顺序,比如我们给同级的元素添加z-index值:
在z-index 示例页面 中,我们可以看到:
-
当同级元素不设置
z-index
或者z-index
相等时,后面的元素会叠在前面的元素上方; -
当同级元素
z-index
不同时,z-index
大的元素会叠在z-index
小的元素上方。 -
z-index
样式属性比较常用于多个元素层级控制的时候,比如弹窗一般需要在最上层,就可以通过设置较大的z-index
值来控制。
除了同级元素以外,z-index
值的设置效果还会受到父元素的z-index值的影响。z-index
值的设置只决定同一父元素中的同级子元素的(BFC)堆叠顺序。因此,即使将某个元素z-index
设置为9999999
,它依然可能因为父元素的z-index
值小于其他父元素同级的元素,而导致该元素依然被其他元素遮挡。
总结
-
盒模型主要用来描述元素所占空间的内容;
-
一个元素属于内联元素还是块状元素,会影响它是否可以和其他元素位于同一行、宽高设置是否有效;
-
正常的文档流在 HTML 里面为从上到下、从左到右的排版布局,使用
position
属性可以使元素脱离正常的文档流; -
使用
z-index
属性可以设置元素的堆叠顺序
拓展资料 布局方式
css flex:
-
https://css-tricks.com/snippets/css/a-guide-to-flexbox/
-
https://flexbox.help/