继续浏览精彩内容
慕课网APP
程序员的梦工厂
打开
继续
感谢您的支持,我会继续努力的
赞赏金额会直接到老师账户
将二维码发送给自己后长按识别
微信支付
支付宝支付

【Hello CSS】第六章-文档流与排版

陈大鱼头
关注TA
已关注
手记 49
粉丝 109
获赞 602

正常流

什么是“正常流”? 其实就是我们日常所说的“文档流”。

正常流的盒子属于格式化上下文(FC),在CSS2.2中可以是表格内联。 在CSS3中引入了flexgrid,当然以后会引入得更多。

块级盒子(block-level boxes) 与创建 块级格式化上下文(BFC) 有关;

行内级盒子(inline-level boxes) 与创建 行内级格式化上下文(IFC) 有关。

根据W3C上的解释:

浮动、绝对定位元素、块容器(例如inline-blocks、table-cells、and table-captions)都不是块盒子。除了overflow以外的visible(除非该值已经传播到了视口)为其内容建立新的BFC

表现是什么?

表现就是在包含块内一个盒子一个盒子不重叠地垂直排列,两个兄弟盒子直接的垂直距离由margin决定。浮动也是如此(虽然有可能两个盒子的距离会因为floats而变小),除非该盒子再创建一个新的BFC

简单来说,BFC就是一个独立不干扰外界也不受外界干扰的盒子啊(/ω\)

IFC

Mmmmm,BFC还是相对好理解,IFC比较复杂,W3C上所占的篇幅也比BFC多得多的。

简单来说,跟BFC表现不一样的盒子就是IFC了(*❦ω❦)。

BFC不一样,IFC内的盒子会从包含块的顶部一个接着一个地水平排列。这些盒子会考虑水平marginborderpadding。垂直对齐的方式也略有复杂。然后,包含形成一条线的框的矩形区域称为线盒(line box)

线盒(line box)的宽度:由浮动情况跟它所在的包含块决定。

线盒(line box)的高度:由line-height的计算结果决定。

基线(baseline)

线盒(line box) 的高度由line-height的计算结果决定。

line-height的定义就是线盒(line box)内两基线(baseline)(W3C原文)的间距。

vertical-align的默认值就是基线。

字母x

你们还记得读书时用的英语作业本吗?

http://img.mukewang.com/5de7cd0f0001b2dc04040220.jpg

如上图所示,我们看到小写字母x的位置,它的上下边缘就是我们的基线(baseline),但下边缘才是我们日常使用的属性值。顺便一提,CSS单位ex便是指的这个字母x的高度。

如何理解IFC

自从翻了CSS的发展史之后,了解了CSS的诞生背景之后,其实很多东西理解起来就轻松了。IFC之所以比BFC复杂,原因就在于很多非规律的成分,在西文了,我们可以简单粗暴的理解为英语作业本的表现,但是在writing-mode不同,文字表现不同的各个国家,IFC的表现也会有差异。

层叠上下文与层叠顺序

我们首先来看一张很著名的图

http://img4.mukewang.com/5de7cd0f0001154b04800193.jpg

上面便是在同样的上下文中,元素的层叠规则(CSS3以后的除外,那规则会比较复杂)。元素的 z-index 值只在父级层叠上下文中有意义。级层叠上下文被自动视为父级层叠上下文的一个独立单元。

文档中的层叠上下文由满足以下任意一个条件的元素形成:

  • 根元素 (HTML),

  • z-index 值不为 auto 的 绝对/相对定位,

  • 一个 z-index 值不为 auto 的 flex 项目 (flex item),即:父元素 display: flex|inline-flex

  • opacity 属性值小于 1 的元素,

  • transform 属性值不为 none 的元素,

  • mix-blend-mode 属性值不为 "normal"的元素,

  • filter值不为 none 的元素,

  • perspective值不为 none 的元素,

  • isolation 属性被设置为 isolate 的元素,

  • position: fixed

  • will-change 中指定了任意 CSS 属性,即便你没有直接指定这些属性的值

  • -webkit-overflow-scrolling 属性被设置 touch 的元素

新时代的布局

Flex

我想到如今,应该很少人会没写过或者没了解过 Flex (不知道的可以翻阅MDN)。

这个是 CSS 史上第一个以 start-end 来定义方向的属性,这是一个可伸缩的布局模型。

一个设有 display:flexdisplay:inline-flex 的元素是一个伸缩容器,伸缩容器的子元素被称为为伸缩项目,这些子元素使用伸缩布局模型来排版。

语法如下:

display: flex/inline-flex; flex: none | [ <'flex-grow'> <'flex-shrink'>? || <'flex-basis'> ];

flex 属性可以指定1个,2个或3个值。

单值语法: 值必须为以下其中之一:

  • 一个无单位 数(<number>) : 它会被当作<flex-grow>的值

  • 一个有效的 宽度(width) 值: 它会被当作 <flex-basis>的值

  • 关键字 noneauto, 或 initial

双值语法: 第一个值必须为一个无单位数,并且它会被当作 <flex-grow> 的值。第二个值必须为以下之一:

  • 一个无单位数:它会被当作 <flex-shrink> 的值。

  • 一个有效的宽度值: 它会被当作 <flex-basis> 的值。

三值语法:

  • 第一个值必须为一个无单位数,并且它会被当作 <flex-grow> 的值。

  • 第二个值必须为一个无单位数,并且它会被当作  <flex-shrink> 的值。

  • 第三个值必须为一个有效的宽度值, 并且它会被当作 <flex-basis> 的值。

Grid

我印象中第一次接触Grid布局的时候,开个Chrome的实验性功能也就只能能支持个repeat(4, 200px),但如今已经除了IE,其他浏览器差不多也是Full support了(如果你还不了解这个布局模型,可以翻阅MDN)。

在这里顺便提一下,Flex是一维布局,Grid是二维布局。意思就是Flex只能同时在一个方向进行作用,而Grid却可以在纵横两个方向同时工作。

语法如下:

display: grid/inline-grid; gird: <'grid-template'> | <'grid-template-rows'> / [ auto-flow && dense? ] <'grid-auto-columns'>? | [ auto-flow && dense? ] <'grid-auto-rows'>? / <'grid-template-columns'>

我们来看看 grid 所支持的一些 “奇怪” 的特性:

命名空间

我觉得 grid 布局中最有趣的功能就是命名空间了,我们可以看看以下示例:

首先是第一种 网格线命名

<style>     html,     body,     div {       margin: 0;       padding: 0;     }     .grid {       display: grid;       width: 420px;       background: #e4d6ba;       margin: 1em auto;     }     .g-namespace {       height: 400px;       grid-template-columns: [col1] 100px [col2] auto [col3] 100px;       grid-template-rows: [rows1] 25% [rows2] 100px [rows3] auto [rows4] 60px     }     .grid > div {       outline: 1px dotted;     } </style> <body>     <div class="grid g-namespace">         <div></div>         <div></div>         <div></div>         <div></div>         <div></div>         <div></div>         <div></div>         <div></div>         <div></div>         <div></div>         <div></div>         <div></div>     </div> </body>

效果如下:

http://img1.mukewang.com/5de7cd0f0001415104450422.jpg

第二种 真命名空间布局

<style>     html,     body,     div {         margin: 0;         padding: 0;     }     .grid {         display: grid;         width: 400px;         height: 400px;         margin: 1em auto;     }     .g-namespace {         grid-template-columns: 1fr 1fr 1fr;         grid-template-rows: 1fr 1fr 1fr;         grid-template-areas: "头部 头部 头部" "左边 中间 右边" "底部 底部 底部";     }     .头部 {         grid-area: 头部 / 头部 / 头部 / 头部;         background: #32CD32;     }     .底部 {         grid-area: 底部 / 底部 / 底部 / 底部;         background: #FFD700;     }     .左边 {         grid-area: 左边 / 左边 / 左边 / 左边;         background: #EE82EE;     }     .右边 {         grid-area: 右边 / 右边 / 右边 / 右边;         background: #FF7F50;     } </style> <body>     <div class="grid g-namespace">         <div class="头部"></div>         <div class="左边"></div>         <div class="右边"></div>         <div class="底部"></div>     </div> </body>

效果如下:

http://img2.mukewang.com/5de7cd0f0001e1b804220419.jpg

通过上面两个示例,我们可以发现Grid布局的二维性可以满足我们日常很多的布局要求,当然,第一眼看语法不免有点懵,但是熟悉之后,基本日常需求中的二维布局我们都能依赖它来完成。

一些常用的灵活尺寸

属性定义
fr可伸缩长度单位,网格容器中可用空间的一等份。
auto自由分配,由具体情况决定。
minmax()定义了一个长宽范围的闭区间。
fit-content()同等于min(maximum size, max(minimum size, argument))

以上属性对比结果如下:

http://img3.mukewang.com/5de7cd0f0001132708220412.jpg





打开App,阅读手记
0人推荐
发表评论
随时随地看视频慕课网APP