FrankKai.github.io icon indicating copy to clipboard operation
FrankKai.github.io copied to clipboard

简单理解CSS layout和Flex布局?

Open FrankKai opened this issue 6 years ago • 5 comments

  • CSS layout存在的意义是什么?
  • CSS layout包含哪些东西?
  • display
  • Normal Flow
  • Flexbox
  • css-tricks的flex指南

FrankKai avatar Dec 14 '18 07:12 FrankKai

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

FrankKai avatar Dec 14 '18 07:12 FrankKai

display

  • change default display behaviour.
  • 可以改变任何元素的display,保证html semantic化。
  • 有些display属性值,需要调用其他属性进行配合,例如display:flex和display:grid。

FrankKai avatar Dec 14 '18 08:12 FrankKai

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>

image

  • horizontal为inline flow direction
  • tb为block flow direction

既然是行内元素,标签可以写在一行吗?

不行。 否则当子inline元素太多,超出父block元素的宽度时,inline不能执行writing-mode制定的horizontal-tb规则,将超出的子inline元素按照top-bottom的方式排列。

一张理解Normal Flow的图

image

FrankKai avatar Dec 14 '18 08:12 FrankKai

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如下图: image display:flex如下图: image

由此我们可以得出结论: display:inline-flex将应用了flexbox系统布局的parent flex container element(通常为block),也就是子元素,设置为inline level element。

评论: 这个属性,目前只想到左右布局情况下,左右的flex container的flex items数目不同,但是 在宽度shrink到一定程度的情况下,内容重叠。 因此这个属性不是很完美,需要其他属性打配合。

弹性盒模型图

image

  • 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:200pxflex: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 都适用。

FrankKai avatar Dec 14 '18 11:12 FrankKai

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%。(重要)

image

参考资料: https://developer.mozilla.org/en-US/docs/Learn/CSS/CSS_layout https://css-tricks.com/snippets/css/a-guide-to-flexbox/#flexbox-examples

FrankKai avatar Jun 20 '20 03:06 FrankKai