在CSS中,所有元素被“ 盒子 ”所包围,利用盒模型的基本原理来实现CSS准确布局,元素排列等处理
CSS广泛使用的两种盒子,其在页面流和元素之间的关系表现为不同的行为:
对于定义为块级盒子(block)的元素会表现出以下行为:
对于定义为内联盒子(inline)的元素会表现出以下行为:
通过对盒子设置display的属性值,来控制盒子的外部显示类型
外部显示类型与内部显示类型
外部显示类型:决定盒子是块级还是内联,即决定了盒子之间的布局方式
内部显示类型:决定了盒子内部的元素是如何布局的,默认情况是按照正常文档流布局,也可以通过设置display值为flex和grid来改变内部元素之间的布局方式
不同显示类型的例子
block:
图中段落里的 <span>word </span>被设置为 display:block
因此其独占一行,宽度填满整个父元素
flex:
图中的列表被设置为 display:block ,每个列表是一个块级元素 —— 像段落一样 —— 会充满整个容器的宽度并且换行
inline-flex与inline
图中的列表被设置为 display:inline-flex ,使得在一些flex元素外创建一个内联框
最后设置两个段落为 display: inline , inline flex 容器和两个段落在同一行上,而不是像块级元素一样换行
CSS组成一个盒模型需要以下几个部分:
在标准模型中,如果你给盒设置 width 和 height,实际设置的是 content box。 padding 和 border 再加上设置的宽高一起决定整个盒子的大小
如果使用标准模型宽度 = 410px (350 + 25 + 25 + 5 + 5),高度 = 210px (150 + 25 + 25 + 5 + 5),padding 加 border 再加 content box
如果使用替代模型,一切都将变得简单很多,此时的 width 和 height 就是盒子可见的宽度与高度,无论怎么改变 padding 或 border 的值,都会通过压缩 conten box 的大小来保持 width 和 height 的值不变
如需使用,只需要声明以下CSS样式:
外边距是盒子周围一圈看不到的空间。它会把其他元素从盒子旁边推开。 外边距属性值可以为正也可以为负。设置负值会导致和其他内容重叠。无论使用标准模型还是替代模型,外边距总是在计算可见部分后额外添加
CSS:
html:
结果如下:因为上外边距设置为负值,所以两个边框会重叠
外边距折叠
理解外边距的一个关键是外边距折叠的概念。如果你有两个外边距相接的元素,这些外边距将合并为一个外边距,即最大的单个外边距的大小
结果如下,中间间隔的部分为50px
如下图所示,对内联盒子设置 width 和 height 都不会生效,虽然margin,padding和border会生效,但不会改变与其它内联盒子的关系,因此其内边距和边框会与段落的其它元素重叠
要避免上述情况,只需要将内联盒子的display值设置为inline-block即可
设置之后的效果为:
但因其保留有inline的特征,所以它不会跳转到新行
float可以使得当前元素脱离正常文本流,并吸附到父元素的左边(left)或者右边(right)正常布局中位于该浮动元素之下的内容,此时会围绕着浮动元素进行排列
基本的常见用途在于图片与文字环绕排版以及首字母下沉:
重点是这个,元素浮动具有一定的规则与限制
设置如下三个盒子(均以块级元素方式呈现):
将box1设置为向右浮动:
因为box1脱离正常文档流,所以box2和box3会向上填补box1的空位,box1浮动到父元素(body)的最右边
设置box1向左浮动:
同理,box1脱离正常文档流,box2与box3向上填补box1的空位,此时box1浮动到父元素(body)的最左边,所以会覆盖掉box2(浮动元素在正常流文档的上方)
设置box2向左浮动:
可以看到box3因为box2脱离正常文档流而向上填充其空位,box2因为浮动到左边覆盖了box3,然而box1仍处于正常文档流中,并且在html文件中最先声明,所以box2只能在box1的下方进行浮动(即使box2设置为向右浮动也是一样)
设置box1、box2与box3都向左浮动:
可以看到三个盒子均向左浮动,直到碰到前一个浮动框的边缘为止(对于box1来说是碰到父元素的边缘),因此呈现如此的排列状况
如果当父元素太窄,无法包含三个盒子的宽度,则无法容纳的元素向下移动,直到有足够的空间使得其能向某个方向浮动,如下图所示:
如果浮动元素的高度不同,那么当它们向下移动时可能被其它浮动元素“卡住”
相关参考:
https://zhuanlan.zhihu.com/p/21286019?refer=miaomiaoji
https://www.jianshu.com/p/fe1052f1a8b6
浮动的规则先讨论到此
高度塌陷
在父元素container内设置一个盒子box1,此时没有设置浮动,box1会撑起父元素container的高度
如果此时设置box1浮动,因为其脱离了正常文档流,无法撑起盒子的高度,所以将发生高度塌陷:
为了解决这个问题,在此提供三种方法:
1. 添加额外标签
首先在父元素内添加空白内容的额外标签clearfix
然后再CSS规则中添加以下内容:
通过清除父元素内空白元素的浮动,使得父元素边框重新包含浮动内容
2. 父级元素添加overflow属性
直接在父元素内添加overflow属性:
同样可以清除浮动,结果如下:
3. after伪元素
html文档改为:
在CSS规则里添加:
弹性盒模型决定一个盒子在其他盒子中的分布方式以及如何处理可用的空间。这与XUL(火狐使用的用户交互语言)相似,其它语言也使用相同的盒模型,如XAML、GladeXML。使用该模型,可以很轻松的创建自适应浏览器窗口的流动布局或自适应字体大小的弹性布局。例子使用以下的HTML代码:123传统的盒模型基于HTML流在垂直方向上排列盒子。使用弹性盒模型可以规定特定的顺序,也可以反转之。要开启弹性盒模型,只需设置拥有子盒子的盒子的display的属性值为box(或inline-box)即可。displaybox水平或垂直分布“box-orient”定义分布的坐标轴:vertical和horizional。这两个值定义盒子如何显示body{displayboxbox-orienthorizontal}反向分布“box-direction”可以设置盒子出现的顺序。默认情况下,只需定义分布坐标轴——box随html流分布。如果为水平坐标轴,则从左到右分布;垂直坐标轴则从上到下分布。定义“box-direction”的属性值为“reverse”,则反转盒子的排列顺序。body{displayboxbox-orientverticalbox-directionreverse}具体分布属性“box-ordinal-group”定义盒子分布的顺序。可以随意的控制其分布顺序。这些组以一个从“1”开始的数字定义,盒模型将首先分布这些组,所有这些盒子将在每个组中。分布将从小到大排列。body{displayboxbox-orientverticalbox-directionreverse}#box1{box-ordinal-group2}#box2{box-ordinal-group2}#box3{box-ordinal-group1}盒子尺寸默认情况下,盒子并不具有弹性,如果box-flex的属性值至少为1时,则变得富有弹性。如果盒子不具有弹性,它将尽可能的宽使其内容可见,且没有任何溢出,其大小由“width”和“height”来决定(或min-height、min-width、max-width、max-height)。如果盒子是弹性的,其大小将按下面的方式计算:具体的大小声明(width、height、min-width、min-height、max-width、max-height);父盒子的大小和所有余下的可利用的内部空间如果盒子没有任何大小声明,那么其大小将完全取决于父box的大小。即:盒子的大小等于父级盒子的大小乘以其box-flex在所有子盒子box-flex总和中的百分比(子盒子的大小=父盒子的大小*子盒子的box-flex/所有子盒子的box-flex值的和)。如果一个或更多的盒子有一个具体的大小声明,那么其大小将计算其中,余下的弹性盒子将按照上面的原则分享剩下的可利用空间。看看下面的例子,理解起来更容易。所有盒子都是弹性的下面的例子中,box1的大小为box2的两倍,box2与box3大小一样。看起来好像是用百分比定义盒子的大小,但是有一个区别:使用弹性盒模型,增加一个盒子,无须重新计算其大小。body{displayboxbox-orienthorizontal}#box1{box-flex2}#box2{box-flex1}#box3{box-flex1}一些盒子有固定大小下面的例子中,box3并不是弹性的,宽度为160px;这样box1和box2将有240px的可利用空间。因此,box1的宽度为160px(240*2/3),box2的宽度为80px(240*1/3)。body{displayboxbox-orienthorizontalwidth400px}#box1{box-flex2}#box2{box-flex1}#box3{width160px}溢出管理因为是弹性盒子、非弹性盒子混排,有可能所有盒子的尺寸大于或小于父盒子的尺寸。这样就有可能空间太多或空间不足。空间太多如何处理可利用空间的分布取决于两个属性值:box-align和box-pack。属性“box-pack”管理水平方向上的空间分布,有以下四个可能属性:start、end、justify、orcenter。start所有盒子在父盒子的左侧,余下的空间在右侧;end所有盒子在父盒子的右侧,余下的空间在左侧;justify余下的空间在盒子间平均分配;center可利用的空间在父盒子的两侧平均分配。属性“box-align”管理垂直方向上的空间分布,有以下五个可能属性之:start、end、center、baseline和stretch。start每个盒子沿父盒子的上边缘排列,余下的空间位于底部;end每个盒子沿父盒子的下边缘排列,余下的空间位于顶部;center可用空间平均分配,上面一半,下面一半;baseline所有盒子沿着它们的基线排列,余下的空间可前可后;stretch每个盒子的高度调整到适合父盒子的高度body{displayboxbox-orienthorizontalwidth400px}#box1{box-flex2}#box2{box-flex1}#box3{width160px}空间不足怎么办与传统的盒模型一样,overflow属性用来决定其显示方式。为了避免溢出,你可以设置box-lines为multiple使其换行显示。弹性盒模型看起来很不错,Gecko和WebKit对该模型都有一些尝试性的测试。在这些属性之前加上-moz和-webkit即可使用该属性。也即是说,firefox、safari、chrome可以使用这些特性,可以看看这个弹性盒模型的demo。