惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

aimingoo的专栏
aimingoo的专栏
S
Securelist
博客园 - Franky
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
IT之家
IT之家
GbyAI
GbyAI
Microsoft Azure Blog
Microsoft Azure Blog
The Cloudflare Blog
云风的 BLOG
云风的 BLOG
N
News and Events Feed by Topic
AI
AI
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
Schneier on Security
Schneier on Security
Attack and Defense Labs
Attack and Defense Labs
Vercel News
Vercel News
腾讯CDC
Google DeepMind News
Google DeepMind News
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
M
MIT News - Artificial intelligence
WordPress大学
WordPress大学
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
N
Netflix TechBlog - Medium
量子位
S
Schneier on Security
Hacker News: Ask HN
Hacker News: Ask HN
Cyberwarzone
Cyberwarzone
S
Security Affairs
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
N
News and Events Feed by Topic
T
Tenable Blog
PCI Perspectives
PCI Perspectives
MyScale Blog
MyScale Blog
L
Lohrmann on Cybersecurity
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
C
Cyber Attacks, Cyber Crime and Cyber Security
W
WeLiveSecurity
N
News | PayPal Newsroom
P
Proofpoint News Feed
O
OpenAI News
C
CERT Recently Published Vulnerability Notes
B
Blog
Cisco Talos Blog
Cisco Talos Blog
Microsoft Security Blog
Microsoft Security Blog
V
Visual Studio Blog
MongoDB | Blog
MongoDB | Blog
大猫的无限游戏
大猫的无限游戏
A
Arctic Wolf
Y
Y Combinator Blog
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Spread Privacy
Spread Privacy

Jay Zangwill

前端该如何选择图片的格式 移动端适配 扒一扒浏览器缓存机制 line-height和vertical-align采坑记 分享个人前端学习路线及面试经验 搜狗实习总结 vue-cli-multipage 记一次我看红宝书对继承加深的理解 四月北京面试之旅 常用的mongodb命令 几个让我印象深刻的面试题(二) 几个让我印象深刻的面试题(一) javscript的数据类型 angular学习笔记(3) angular学习笔记(2) angular学习笔记(1) 初尝vue sass基础 hexo+github快速搭建个人博客
css盒模型与定位
Jay Zangwill · 2016-12-15 · via Jay Zangwill

说到css的盒子模型和定位相信大家一定都听说过,因为它们是css中的基础,同时也是难点,这篇文章的作用在于基础知识的扫盲。

先来说说盒子模型吧

什么是盒子模型

简单地说每个html标签都是一个方块,然后这个方块又包着几个小方块。分别是:margin、border、padding、content。它们的关系是margin包着border包着padding包着content。就像盒子一层一层地包着一样,这就是我们所说的盒模型。
嗯,看上面的文字有点文绉绉的,我们直接上图吧。
打开谷歌浏览器,按下F12,然后把右边栏的滚动条拉到最下面你就会看到一个东西:

盒模型

这就很直观给我们展示了什么是盒子模型!

盒子有多大

我相信这个问题肯定会问倒很多人,这个问题是个非常经典的问题。我在百度上查都能查到有很多人写的博客上都在这方面有错误,所以,我觉得我有必要在这篇文章上讲清楚盒子到底有多大。
老规矩,先上代码

.red{
    width:200px;
    height:200px;
    background-color:red;
}

补全html代码就会在页面左上角出现这么个玩意儿:

红色方块

对应的盒子模型:

红色方块的盒子模型

很明显这个时候的盒子大小就是content的大小。来,我们继续往下走,我们给这个方块加上padding:

.red{
    width:200px;
    height:200px;
    padding:10px;
    background-color:red;
}

这时你就会发现这个方块比原来稍微胖了那么一点:

加上padding的红色方块

对应的盒模型:

加上padding的红色方块的盒子模型

这个时候将鼠标移到控制台上的这个元素你就会发现:

加上padding的红色方块的长宽

下面写有盒子的长宽变成了220x220,很明显,padding是能够改变盒子的大小的,这时盒子大小就等于content+padding。

接下来,我们给盒子加上边框:

.red{
    width:200px;
    height:200px;
    padding:10px;
    border:10px solid black;
    background-color:red;
}

这个时候变成了下面这样:

加上border的红色方块

盒模型:

加上border的红色方块的盒模型

它的长宽:

加上border的红色方块的长宽

可以发现长宽变为了240x240,所以这时盒子大小就等于content+padding+border。

接下来讲margin。在给这个方块加margin之前为了方便观察我们加个类名为blue的div,并且加上样式:

.blue{
    width:100px;
    height:100px;
    background-color:blue;
}

效果图:

加个蓝色方块

因为div是块级元素,所以新加的蓝色div自动跑到红色的下面。
接下来给红色方块加上margin-bottom:

.red{
    width:200px;
    height:200px;
    padding:10px;
    margin-bottom:10px;
    border:10px solid black;
    background-color:red;
}

效果图:

加上margin

可以发现,盒子的底部产生了10px的空白。

对应的盒模型

加上margin的红色方块的盒模型

方块的长宽

加上margin的红色方块的长宽

很明显盒子的大小并没有变大,还是原来的240x240

所以,最终盒子的大小为content+padding+border即内容的(width)+内边距的再加上边框,而不加上margin。

看到网上很多文章都把margin算进去了,如果按照他们所说的,上面盒子的大小应该是240x250,然而实际情况并不是。从这里可以看出,很多人对盒模型有误解。把margin算进去的那是盒子占据的位置,而不是盒子的大小!

其实盒模型一共分为两种,一种是上面讲的标准盒模型,还有一种是怪异盒模型,这两种盒模型的区别在于width/height。前者width/height指的是content区域的宽度和高度,后者width/height指的是content+padding+border。

在ie8+浏览器中使用哪个盒模型可以由box-sizing控制,默认值为content-box,即标准盒模型;如果将box-sizing设为border-box则用的是怪异盒模型。如果在ie6,7,8中DOCTYPE缺失会触发怪异模式。

我们可以把上面的红色方块的box-sizing设为border-box发现,无论我们怎么改border和padding盒子大小始终是定义的width和height:

box-sizing

定位

定位(position)有四个值:

  1. static
  2. relative
  3. absolute
  4. fixed

static

一般如果我们不设置position的话它的默认值就是static,这个时候left、top、bottom、right是不起作用的
,现在有如下两个div,他们的关系是兄弟关系:

.red{
    width:200px;
    height:200px;
    left:100px;
    top:100px;
    background-color:red;
}
.blue{
    width:100px;
    height:100px;
    background-color:blue;
}

效果图:

static

可以发现,并没有什么变化。红色方块的lefttop加不加都一样。

relative

但是,现在我们给红色方块加个position:relative

.red{
    position:relative;
    width:200px;
    height:200px;
    left:100px;
    top:100px;
    background-color:red;
}

嘿嘿,变这样了:

relative

可以发现,红色方块跑到蓝色方块的右边了,左边缘和顶边缘都距离原来100px,但是蓝色方块还是在原来的地方不动,现在可以得出一个结论:使用相对定位给元素加left/top/right/buttom元素会以原来的位置为基础加上这些值,即以原来的位置为基础定位,并且没有脱离文档流

嗯,是不是看起来有点文绉绉的,那来个形象的比喻吧:

假如position:static是一个活人的话,并且拥有灵魂,这个时候我想给他加个left:100px想让他的灵魂出来,但是并没有效果。当这个人刚去世而且尸体还没火化的时候(相当于position:relative),这时我加个left:100px灵魂就可以移动了,并且灵魂往尸体的右边移动了100px。因为尸体还没火化,所以这个人还是占一定的空间的。

absolute

现在,我们把position改为absolute

.red{
    position:absolute;
    width:200px;
    height:200px;
    left:100px;
    top:100px;
    background-color:red;
}

效果图:

absolute

可以发现蓝色方块如我们所愿移动到了红色方块的上面,说明红色方块已经脱离文档流。虽然红色方块的位移和relative一样但是,红色方块位移的参考不再是原来的位置而是body只不过红色方块的位置刚好在body的最左上角,刚好碰巧位移一样,上面的这个例子可能看不出来,让我们来改改代码。

首先将html结构改成:

<div class="red">
    <div class="blue"></div>
</div>

然后红色方块的absolute改回relative

效果图:

absolute

然后蓝色方块代码改为:

.blue{
    position:absolute;
    top:100px;
    left:100px;
    width:100px;
    height:100px;
    background-color:blue;
}

absolute

可以发现在给蓝色方块添加position:absolute前,蓝色方块像我们想的那样在红色方块的左上角;当我们给蓝色方块添加position:absolute并且添加lefttop时,蓝色方块就跑到了红色方块的右下角。

那么这次这个蓝色方块是以谁为参考进行位移的?刚刚你说的以body为参考又是什么情况?

好,我这里就给大家说清楚,当给一个元素设置position:absolute时,这个元素的位置就是以他父代元素position不为static的元素作为参考,如果他的父代元素都是position:static那就以body作为参考。刚刚红色方块的情况就是他父代元素没有position不为static的元素,所以只能以body作为参考。

嗯,讲的文绉绉的,我不喜欢。来,举个例子:

还是刚刚那个人与灵魂的例子,当设置position:absolute时,就相当于人死了,尸体已经火化了,只剩下灵魂和骨灰,所以是不占空间的(就是已经脱离文档流)。这个时候灵魂可以乱飘了,但是有个限制,只能相对于骨灰飘。

fixed

现在让我们再来创建一个绿色方块:

.green{
    position:fixed;
    top:150px;
    left:150px;
    width:100px;
    height:100px;
    background-color:green;
}

效果图:

fixed

这个看起来貌似没有什么特别的,现在我们来给body加个height:2000px(这个高度随意,但是要使浏览器右边出现滚动条),然后把浏览器的滚动条往下拉,一个神奇的事情发生了:绿色方块固定在我们定义的位置上屏幕上不动了!

scroll

这个fixed我们见得最多的就是网页中顽固的小广告,不管我们怎么拖拽滚动条,它总是固定在那,就是一个升级版的absolute

用上面的例子来说就是人已经成仙了,可以不受限制地乱飘,而且不管你怎么拉,都拉不动他,他就在那不动了!

z-index

说到定位,肯定少不了z-index。用上面的例子来说z-index就是灵魂飘的高度,设置得越大,自然就飘得越高,既然扯到了灵魂,z-index肯定是对活人(static)无效的了。

正常情况下(没有加z-index),元素是按照后来居上原则进行堆叠。在这个例子上的html元素是这样的:

<div class="red">
        <div class="blue"></div>
    </div>
<div class="green"></div>

按照后来居上原则,红色方块最先被浏览器渲染到,所以在最下面,其次到蓝色,最后到绿色。

如果我们想让红色方块显示到前面我们可以给它加个z-index:1,结果:

z-index

发现绿色方块“消失了”。其实绿色方块并没有消失,你可以将滚动条往下拉,或者看盒子模型:

z-index

可以发现它并没有消失,只是被盖在了红色方块下面。由于红色方块与蓝色方块是父子关系,红色的上来了,蓝色肯定的上来啊。

现在我有个想法,想让蓝色方块弄到红色方块下面该怎么办?很多人可能会想到简单啊,直接给蓝色方块加个z-index:-1不就得了吗?但是很可惜,没用。

要解释这个现象就得扯到层叠上下文的东西了。解释这东西又得花些篇幅来讲,具体的可以看这里

这里我就一笔带过了,用最通俗易懂的例子来解释了,老爸的灵魂包着儿子的灵魂飘到了一楼(z-index:1),但是儿子想下到-1楼(z-index:-1)这是不行的因为儿子的灵魂已经被老爸的灵魂包着了(当z-index为数值时,会产生层叠上下文),如果儿子想下到一楼,得先不让老爸的灵魂包着儿子的灵魂(不设置红色方块的z-index或者设置为z-index:auto),这样就能下到-1楼了这样蓝色方块就被红色方块挡住了。

但是不设置红色的z-index的话,绿色方块又出来作怪了,这个时候只能设置绿色方块z-index:-1,红色方块就没谁能挡得住了!

总结

  1. css的盒模型由content(内容)、padding(内边距)、border(边框)、margin(外边距)组成。
  2. 在w3c和模型中,设置的width/height是content的宽度/高度,在怪异模式中width/height设置的是content+padding+border宽度/高度。
  3. 在w3c盒子模型中盒子的大小由content、padding、border决定,在在怪异模式中盒子大小由width和height决定。
  4. 定位有四个值static(静止)、relative(相对)、absolute(绝对)、fixed(固定)。
  5. left、top、right、bottom、z-index不能对static起作用。

有什么问题可以在下面留言哦,会及时给出答复的。