FrankKai.github.io
FrankKai.github.io copied to clipboard
简单理解CSS layout和Flex布局?
- CSS layout存在的意义是什么?
- CSS layout包含哪些东西?
- display
- Normal Flow
- Flexbox
- css-tricks的flex指南
CSS layout存在的意义是什么?
Place your boxes in the right place in relation to the viewport
CSS layout包含哪些东西?
- Different display settings
- Normal(document) flow
- modern layout tools(flexbox,CSS grid)
- positioning
- legacy technique
display
- change default display behaviour.
- 可以改变任何元素的display,保证html semantic化。
- 有些display属性值,需要调用其他属性进行配合,例如display:flex和display:grid。
Normal Flow
Normal Flow也可以理解为document flow(文档流)。
- normal flow是在没有人为修改layout的情况下,元素自己排列的规则,很有必要掌握
- 可以改变element在一个normal flow下的position
- 可以将element从一个normal flow中移除出来
- normal flow是为了readable document设计的
css盒模型细节是怎样的?
独立的一个元素盒子,先由content占据内容,然后再添加padding,border和margin。
individual元素默认是怎么布局的?
- 块级元素宽度继承自父元素的100%,高度是自己的content。代际遗传明显,财大气粗的二代。
- 行内元素宽度高度都是自己的content,且不能修改,只能完全升级为block或者inline-block才行。完全靠自己打拼,一无所有的一代。
- 行内元素位于块级元素的content内。
elements interact with one another的如何布局?
- normal layout flow 指的是一个系统,它控制元素在浏览器的viewport下如何布局
- 默认情况下,块级元素按照document的writing mode布局,每一个新块紧紧跟着前一个块下面布局,并且可以被之间设置的margin隔离开。
- writing-mode CSS属性:注意,这个属性有2个含义。前半部分是block content内的inline元素的排列方向,或者说文字方向;后半部分是block 流的方向。 默认值为horizontal-tb,也就是说,inline元素的排列方向是水平,而block流方向为top-bottom。
一个清晰解释writing-mode属性的例子
这个例子对于理解normal flow(标准流)非常有用。
<div style="writing-mode: horizontal-tb;">
<div>
<span>foo</span>
<span>bar</span>
<span>baz</span>
</div>
<div>2</div>
<div>3</div>
<div>4</div>
</div>
- horizontal为inline flow direction
- tb为block flow direction
既然是行内元素,标签可以写在一行吗?
不行。 否则当子inline元素太多,超出父block元素的宽度时,inline不能执行writing-mode制定的horizontal-tb规则,将超出的子inline元素按照top-bottom的方式排列。
一张理解Normal Flow的图
Flexbox
- Flexbox是一个行列方向的一维矩阵布局方法。
- 具有flex特性的item会调整额外的space和shrink去适应小空间。
- Flexbox是一个layout system,将其当做一个system,需要系统性地进行学习。
- Flexbox是为了解决floats和positioning布局解决不了的问题而产生的。
- Flexbox在以下几种情况下功力十分威猛
- 在父元素内垂直居中一个block
- 在不管有多少width/height可以分配的情况下,让容器的所有子元素都可以占据等份的width/height。
- 让包含子内容个数不同的多列,占据相同的height,这是因为默认了多列中最高的height赋值给了flex item。
- 设置display属性为flex时,是要设置给flex container,可以通俗地理解为应用flex布局的item的parent元素。
display:inline-flex属性怎么用?
display: inline-flex does not make flex items display inline. It makes the flex container display inline. Difference between display:inline-flex and display:flex
基于demo:https://mdn.github.io/learning-area/css/css-layout/flexbox/flexbox0.html 添加一段html和一段css即可:
<section>
<article>...</article>
<article>...</article>
<article>...</article>
</section>
section {
display: inline-flex; // or flex
width: 50%;
}
display:inline-flex
如下图:
display:flex
如下图:
由此我们可以得出结论: display:inline-flex将应用了flexbox系统布局的parent flex container element(通常为block),也就是子元素,设置为inline level element。
评论: 这个属性,目前只想到左右布局情况下,左右的flex container的flex items数目不同,但是 在宽度shrink到一定程度的情况下,内容重叠。 因此这个属性不是很完美,需要其他属性打配合。
弹性盒模型图
- main axis(flex item作为row横穿过page,或者作为column竖插过page 的方向),main start,main end
- cross axis 是垂直方向的flex item布局参考的轴,cross start,cross end。
- flex container指的就是设置了display:flex或者display:inline-flex的父元素。
- flex items指的就是在flex container中的flexible boxes。
- main size和cross size指的是flex item的main axis方向和cross axis方向的宽度和高度。
如何控制flex container内的flex item的排列方向?
这个方向其实就是main axis,默认是row。
flex-direction: column;
还可以是row-reverse,column-reverse这两个反过来的排列。
flex container 宽度限定,怎么解决flex items会overflow出去的问题?
很简单。
为flex container设置flex-wrap: wrap;
,再为flex items设置flex:200px
。
如何理解flex:200px?
flex:200px
意思是每个flex item,宽度必须>=200px,最后一行的flex item可以200 px到占满整个flex container。
有没有整合了flex-direction和flex-wrap的缩写属性?
flex-direction: row;
flex-wrap: wrap;
=》flex-flow: row wrap;
如何调整flex item的占比?
flex:1;
flex:2;
flex:3;
flex:200px
和flex:2
冲突吗?
不冲突,200px代表最小宽度,2代表proportion。
可以写在一起:flex: 2 200px
;,每个flex item先占据200px空间,然后再分配剩余空间。
flex是一个缩写属性,从前往后是flex-grow,flex-shrink,flex-basis。
- flex-grow: flex container下的每个flex item生长占比。
- flex-shrink: flex container下的每个flex item缩放占比。
- flex-basis:flex container下的每个flex item的content box的大小。
如何让flex items水平垂直居中?
为flex container设置以下属性。
-
display: flex;
-
align-items: center;
flex item会参照cross axis方向对齐,可以用align-self修改覆盖当前值。 -
justify-content: space-around;
flex item在main axis方向上分配空间,此处大多数情况space-around比center更合适,因为可以直接分开flex item,并且距离main start和main end都是flex item间隔的一半,非常优雅,不要将其与justify-items和justify-self混淆了。
align-items和justify-content左右布局如何赋值?
align-items:start和end;
justify-content:flex-start和flex-end;
flex items的顺序
可以通过order:1
,order:2
这样的属性,再结合:first-child,:nth-child(n)这样的css选择器,为flex item排序,默认情况下order的值为0。
可以将flex item设置成flex container吗?
可以。demo: https://mdn.github.io/learning-area/css/css-layout/flexbox/complex-flexbox.html
article:nth-of-type(3) {
flex: 3 200px;
display: flex;
flex-flow: column;
}
article:nth-of-type(3) div:first-child {
flex:1 100px;
display: flex;
flex-flow: row wrap;
align-items: center;
justify-content: space-around;
}
button {
flex: 1 auto;
margin: 5px;
font-size: 18px;
line-height: 1.5;
}
flex的浏览器兼容性怎么样?
Firefox, Chrome, Opera, Microsoft Edge and IE 11, newer versions of Android/iOS 都适用。
css-tricks的flex指南
细读css-tricks flex文章: A Complete Guide to Flexbox
- 建议直接设置flex,智能设置参数。
- flex-grow占比 flex-shrink压缩 flex-basis基础大小。
- flex-grow flex-grow:0->普通行内布局。因此flex-grow是为了自动分配容器空间。
- flex-shrink flex-grow:0->超出容器。因此flex-shrink是为了保证flex item在容器 内。
- flex item的默认值为1 0 auto,设置为1时变为1 1 0%。(重要)
参考资料: https://developer.mozilla.org/en-US/docs/Learn/CSS/CSS_layout https://css-tricks.com/snippets/css/a-guide-to-flexbox/#flexbox-examples