、、
内联盒子:不会产生换行,width 和 height 属性不会起作用,并且只有水平方向的内边距、外边距以及边框会被应用且会把其他处于 inline 状态的盒子推开。用做链接的 、 、 以及 标签都是默认处于 inline 状态的。
通过对盒子display 属性的设置,比如 inline 或者 block ,来控制盒子的外部显示类型。
完整的 CSS 盒模型应用于块级盒子,内联盒子只使用盒模型中定义的部分内容。CSS 中一个块级盒子有四个部分,如下图所示。
对于块级盒子,如果你给盒设置 width 和 height,实际设置的是 content。padding 和 border 再加上设置的宽高一起决定整个盒子的大小。margin 不计入实际大小,当然,它会影响盒子在页面所占空间,但是影响的是盒子外部空间。盒子的范围到边框为止。盒子还有一个outline,outline是绘制于元素周围的一条线,位于边框边缘的外围,可起到突出元素的作用。和margin一样,outline也不计入盒子的实际大小。
对于内联盒子,例如由元素创建的那些内联盒子,只有部分属性会生效。
在下面的示例中,我们在一个段落中使用了,并对其应用了宽度、高度、边距、边框和内边距。可以看到,宽度和高度被忽略了。外边距、内边距和边框是生效的,但它们不会改变其他内容与内联盒子的关系,因此内边距和边框会与段落中的其他单词重叠。
<p>
I am a paragraph and this is a <span>spanspan> inside that paragraph. A span is an inline element and so does not respect width and height.
p>
span {
margin: 20px;
padding: 20px;
width: 80px;
height: 50px;
background-color: lightblue;
border: 2px solid blue;
}
如果不希望一个项切换到新行,但希望它可以设定宽度和高度,并避免上面看到的重叠。可以使用display 一个特殊的值—inline-block,它在内联和块之间提供了一个中间状态。
内联-块级盒子:如果一个盒子使用 display: inline-block,那么这个盒子不会换行,但是设置width 和height 属性会生效,并且padding、margin以及border 会推开其他元素。
在下面的示例中,将 display: inline-block 添加到 元素中,查看显示模型中的差异。可以发现宽度和高度都生效了,并且也不会出现重叠现象。
<p>
I am a paragraph and this is a <span>spanspan> inside that paragraph. A span is an inline element and so does not respect width and height.
p>
span {
margin: 20px;
padding: 20px;
width: 80px;
height: 50px;
background-color: lightblue;
border: 2px solid blue;
display: inline-block;
}
当在父内容里面垂直居中一个块内容,或者使容器的所有子项占用等量的可用宽度/高度,又比如使多列布局中的所有列采用相同的高度,遇到这样的问题,我们可能无法从前面所学的盒模型来完成这样的任务。这个时候,就需要使用一种新的盒模型—弹性盒子,弹性盒子使得很多布局任务变得更加容易。
弹性盒子:设置display: flex。如果是内联元素,则设置display:inline-flex。沿着两个轴来布局,分别是主轴和交叉轴。主轴是沿着 flex 元素放置的方向延伸的轴(比如页面上的横向的行、纵向的列)。该轴的开始和结束被称为 main start 和 main end。交叉轴是垂直于 flex 元素放置方向的轴。该轴的开始和结束被称为 cross start 和 cross end。
弹性盒子提供了 flex-direction 这样一个属性,它可以指定主轴的方向(弹性盒子子类放置的地方)— 它默认值是 row,这使得它们在按你浏览器的默认语言方向排成一排(在英语/中文浏览器中是从左到右)。
<div class="box">
<div>Onediv>
<div>Twodiv>
<div>Threediv>
div>
.box {
display: flex;
}
还可以使用 column、row-reverse 和 column-reverse 值将那些元素设置为列布局或者反向排列 flex 项目。
<div class="box">
<div>Onediv>
<div>Twodiv>
<div>Threediv>
div>
.box {
display: flex;
flex-direction: row-reverse;
}
使用 justify-content 可以控制 flex 项在主轴上的位置。默认值是 flex-start,这会使所有 flex 项都位于主轴的开始处。也可以用 flex-end 来让 flex 项到结尾处。center 在 justify-content 里也是可用的,可以让 flex 项在主轴居中。而值 space-around 是很有用的——它会使所有 flex 项沿着主轴均匀地分布,在任意一端都会留有一点空间。还有一个值是 space-between,它和 space-around 非常相似,只是它不会在两端留下任何空间。
<div class="box">
<div>Onediv>
<div>Twodiv>
<div>Threediv>
div>
.box {
display: flex;
justify-content: center;
}
使用 align-items 可以控制 flex 项在交叉轴上的位置。默认的值是 stretch,其会使所有 flex 项沿着交叉轴的方向拉伸以填充父容器。如果父容器在交叉轴方向上没有固定宽度(即高度),则所有 flex 项将变得与最长的 flex 项一样长(即高度保持一致)。也可以设置诸如 flex-start、center 或 flex-end 这样使 flex 项在交叉轴的开始、中间或结束处对齐所有的值。
<div class="box">
<div>Onediv>
<div>Twodiv>
<div>Three
<br>has
<br>extra
<br>text
div>
div>
.box {
display: flex;
align-items: flex-end;
}
当在布局中使用定宽或者定高的时候,可能会出现问题即处于容器中的 弹性盒子子元素会溢出,破坏了布局。可以使用flex-wrap: wrap来解决溢出问题。存在着flex-direction 和 flex-wrap的缩写 flex-flow。比如,你可以将flex-direction: row,flex-wrap: wrap 替换成 flex-flow: row wrap。
<div class="box">
<div>Onediv>
<div>Twodiv>
<div>Threediv>
div>
.box {
display: flex;
flex-wrap: wrap;
}
弹性盒子也有可以改变 flex 项的布局位置的功能,而不会影响到源顺序(即 dom 树里元素的顺序)。这也是传统布局方式很难做到的一点。使用order属性来进行flex项排序,所有 flex 项默认的 order 值是 0,order 值大的 flex 项比 order 值小的在显示顺序中更靠后。相同 order 值的 flex 项按源顺序显示。所以假如你有四个元素,其 order 值分别是 2,1,1 和 0,那么它们的显示顺序就分别是第四,第二,第三,和第一。也可以给 order 设置负值使它们比值为 0 的元素排得更前面。
为了更好地控制 flex 元素,有三个属性可以作用于它们flex-grow、flex-shrink、flex-basis。在考虑这几个属性的作用之前,需要先了解一下 可用空间 available space 这个概念。这几个 flex 属性的作用其实就是改变了 flex 容器中的可用空间的行为。同时,可用空间对于 flex 元素的对齐行为也是很重要的。
假设在 1 个 500px 的容器中,我们有 3 个 100px 宽的元素,那么这 3 个元素需要占 300px 的宽,剩下 200px 的可用空间。在默认情况下,flexbox 的行为会把这 200px 的空间留在最后一个元素的后面。
如果期望这些元素能自动地扩展去填充满剩下的空间,那么我们需要去控制可用空间在这几个元素间如何分配,这就是元素上的那些 flex 属性要做的事。
flex-basis 定义了该元素的空间大小(the size of that item in terms of the space),flex 容器里除了元素所占的空间以外的富余空间就是可用空间 available space。该属性的默认值是 auto 。此时,浏览器会检测这个元素是否具有确定的尺寸。在上面的例子中,所有元素都设定了宽度(width)为 100px,所以 flex-basis 的值为 100px。
如果没有给元素设定尺寸,flex-basis 的值采用元素内容的尺寸。这就解释了:我们给只要给 Flex 元素的父元素声明 display: flex ,所有子元素就会排成一行,且自动分配小大以充分展示元素的内容。
flex-grow 若被赋值为一个正整数,flex 元素会以 flex-basis 为基础,沿主轴方向增长尺寸。这会使该元素延展,并占据此方向轴上的可用空间(available space)。如果有其他元素也被允许延展,那么他们会各自占据可用空间的一部分。
如果我们给上例中的所有元素设定 flex-grow 值为 1,容器中的可用空间会被这些元素平分。它们会延展以填满容器主轴方向上的空间。
flex-grow 属性可以按比例分配空间。如果第一个元素 flex-grow 值为 2,其他元素值为 1,则第一个元素将占有 2/4(上例中,即为 200px 中的 100px), 另外两个元素各占有 1/4(各 50px)。
flex-grow属性是处理 flex 元素在主轴上增加空间的问题,相反flex-shrink属性是处理 flex 元素收缩的问题。如果我们的容器中没有足够排列 flex 元素的空间,那么可以把 flex 元素flex-shrink属性设置为正整数来缩小它所占空间到flex-basis以下。与flex-grow属性一样,可以赋予不同的值来控制 flex 元素收缩的程度 —— 给flex-shrink属性赋予更大的数值可以比赋予小数值的同级元素收缩程度更大。
你可能很少看到 flex-grow,flex-shrink,和 flex-basis 属性单独使用,而是混合着写在 flex 简写形式中。 Flex 简写形式允许你把三个数值按这个顺序书写 — flex-grow,flex-shrink,flex-basis。看到的 flex: 1 或者 flex: 2 等等。它相当于flex: 1 1 0。元素可以在flex-basis为 0 的基础上伸缩。
<div class="box">
<div class="one">Onediv>
<div class="two">Twodiv>
<div class="three">Threediv>
div>
.box {
display: flex;
}
.one {
flex: 2 1 auto;
}
.two {
flex: 2 1 auto;
}
.three {
flex: 1 1 auto;
}