01、CSS布局

1.1、正常布局流(Normal flow)

正常布局流 就是不做任何布局控制,按照HTML的顺序(从左到右,从上而下)进行布局排列。网页基于盒子模型进行正常的布局,主要特点:

  • 盒子布局:单个内容的布局,把内容放入盒子,加上盒子三件套(padding、boder、margin)。
  • 块盒子纵向布局:块级元素单独一行,按照顺序垂直排列,并按其margin分离。
  • 内联盒子水平布局:内联元素会在一行水平排列,高度、宽度都取决于内容,直到空间不足另起一行(换行)。高矮不齐,底部对齐。
  • 边距折叠:垂直相邻元素的垂直margin会保留最大的那一个,就是盒子的外边距折叠。
  • 空白折叠:无论多少个连续空格、换行、tab,都会折叠为一个空格。

块元素 行内元素
是否换行 独占一行,从新的一行开始,其后也另起一行 和其他行内元素在同一行
大小设置 元素的高、宽、行高、边距、对齐都可调整,宽度默认100% 元素高、宽、外边距不可设置,根据内容自适应
包含元素 一般可包含其他行内元素和块元素 一般可包含其他行内元素,不可包含块元素
常见元素 div,form、table,h1-h6,p,pre,ul/ol/li,dt/dl,hr,br span,font,input,textarea,label,img,a,button,select
盒子 块级盒子 (block box):应用完整的盒子模型 内联盒子 (inline box):部分盒子模型有效
  • 还有一种混合型“行内块元素”属于行内元素的一种,和其他元素在一行,但元素的高、宽、外边距都可以设置,如buttonimginput
  • 通过CSS样式的display属性可以更改元素的布局类型,如可设置<a>为一个块元素布局display: block;

标准布局总是这样从左到右、从上而下的顺序排列。但当我们要实现一些特殊的的布局效果时就没法了,这时的办法就是 —— 脱离文档流

脱离文档流,就是从正常文档流中移除,文档流布局就不考虑他了,也就不会占用空间。基本上可以这样理解,当然也不是绝对就没人管了,他的父容器还是管的,至于怎么管看《格式化上下文》。

常用的脱离文档流的方式:floatposition

  • float浮动,会使元素脱离文档流,移动到容器左/右边,后面元素会围绕浮动元素。
  • position定位,绝对定位(absolute)、固定定位(fixed),会使元素脱离文档流,空出来的位置被后续元素代替,所以会出现和其他元素重叠的问题。

1.2、display布局属性

正常流中的所有元素都有一个display的值,这个属性允许我们更改默认的显示方式。display用来设置多种布局方式,可让不同元素类型(行、块元素)转换。

属性/值 描述
display 设置元素显示类型,包括下面这些枚举值
 none 元素隐藏不显示,不占据空间、无交互,常用于隐藏元素
block 此元素将显示为块级元素
inline 内联,此元素会被显示为内联元素
inline-block 行内块元素(CSS2.1),介于内联和块之间,除了不换行,高宽、盒子三件套都有效。
常用<ul><li>+inline-block来实现导航
flex IE11 弹性盒子布局(横向布局),inline-flex 内联的弹性盒子
grid 非常灵活的网格布局,有些属性IE不支持。inline-grid 内联的网格布局
 list-item 此元素会作为列表,类似<ul>,父元素显示为 block 盒,内部变为多个 list-item inline
 table 表格布局,同家族还有个inline-table内联表格布局、table-row、table-cell
 contents 伪盒子,充当遮罩的元素,不会产生任何盒子(不会被渲染),但不影响其子元素的布局和渲染
 flow-root IE 建立一个无副作用的BFC
<span style="display:block">span元素2</span>  <!--转换为块元素,类似一个div-->
<div style="display:inline">div元素</div> <!--转换为行内元素,类似一个span-->

02、什么是响应式布局?

2.1、响应式设计

响应式网页设计(responsive /rɪˈspɒnsɪv/ web design,RWD)指的是允许 Web 页面适应不同屏幕宽度等因素,进行布局和外观的调整的一系列实践。它涵盖了很多 CSS 和 HTML 的功能和技术,现在也基本是我们默认建设网站的方式。

如上图,基于媒体查询和现代布局,响应式设计成为当下的主流。通过媒体查询测试,针对不同的尺寸适配不同的CSS样式、图片,如调整字体大小、段落填充、菜单按钮布局、以及增大触摸按钮的大小等,让网页能够自适应各种设备尺寸、设备类型。

  • 响应式图形,创建多种尺寸版本文件,基于srcsetsizes,适配合适尺寸的文件。或者改用新的 <picture>元素。
<img srcset="elva-fairy-320w.jpg 320w,
elva-fairy-480w.jpg 480w,
elva-fairy-800w.jpg 800w"
sizes="(max-width: 320px) 280px,
(max-width: 480px) 440px,
800px"
src="elva-fairy-800w.jpg" alt="Elva dressed as a fairy">
  • 响应式排版,传统方式可以结合vw单位(视口的1%)、固定尺寸rem、px单位,现在可以基于媒体查询设置不同样式规则。
.p1 {
font-size: calc(1rem + 2vw);
}
@media screen and (min-width:1440px) {
.p1 {
font-size: 150%;
}
}
  • 视口元标签,明确视口的宽度为设备的宽度,并初始化缩放比例为1,建议添加如下元素申明。

<meta name="viewport" content="width=device-width,initial-scale=1">

2.2、@媒体查询

媒体查询是指针对不同的设备、特定的设备特征或者参数进行定制化的修改网站的样式,媒体查询的标准语法:

@media media-type and (media-feature-rule) { /* CSS规则 CSS rules go here */ }   /* 注意关键字and后面的空格 */

属性 描述 值/备注
@media 媒体查询申明
 media-type 媒体类型 - all:所有设备
- screen:屏幕,常用
- speech:语音合成器;print:打印,网页打印的时候
 逻辑操作符(and) 连接多个媒体查询语句 - and:查询条件都满足的时候才生效
- not:查询条件取反
- only:整个查询匹配的时候才生效,常用语兼容旧浏览器,使用时候必须指定媒体类型
- 逗号或者 or:查询条件满足一项即可匹配;
 media-feature-rule 媒体特征规则,一些条件表达式,常用尺寸判断 - min-width:>=最小宽度;max-width:<=最大宽度
- 更多媒体查询特征,如orientation(屏幕方向)
@import 导入外部css样式,支持媒体查询 @import url(example.css) screen and (width:800px);

/* 媒体查询:在大尺寸模式启用flex布局,横向排列 */
@media screen and (min-width: 40em) {
.nav ul {
display: flex;
}
.nav li {
flex: 1;
}
}

响应式布局-代码示例(Codepen)


03、CSS的格式化上下文

所有元素都是一个盒子Box,盒子Box是页面布局的基本单位,盒子的不同类型决定了他的布局方式。一个页面由各种盒子的组合、嵌套形成。这些盒子各不相同,有些是横排,有些竖排,有些是弹性,有些是网格,那他们是如何布局的呢?这就必须要了解的一个概念——格式化上下文

格式化上下文(Formatting Contexts),就是把页面内容分为多个不同的格式化上下文(区域),每个格式化上下文都是一个独立的渲染(布局)区域,存放同类型的盒子。根据盒子的不同,格式化上下文分为多种(四种)类型,每种类型有自己的渲染规则,决定了其内部子元素的定位、排列方式。

格式化上下文 简述
BFC块级格式化上下文 Block fomatting context ,由块级盒子组成的上下文区域,纵向排列。需要重点了解的,浮动float布局的各种坑就靠他来填了。
IFC内联级格式上下文 Inline formatting context,内联格式上下文,就是横向布局的内联盒子,由内联盒子构成
FFC:弹性盒格式化上下文 Flexible Formatting Contex,就是flex布局的弹性盒子,申明flex(或inline-flex)布局就是创建了一个FFC弹性盒子格式上下文。
GFC:网格格式化上下文 Grids Formatting Context,就是grid(或inline-grid)布局的盒子,二维网格布局,使用很方便。
不过由于兼容性问题(很多属性不支持IE),使用还不广泛,不过现代浏览器基本都支持了。

实际上这些格式上下文也是相互嵌套的,各自负责各自区域进行渲染(布局)。

上图仅为个人理解。


04、BFC-块级格式化上下文

Block fomatting context (= block-level box + Formatting Context),块级格式化上下文,简称 BFC。是一个独立的渲染(布局)区域,用于给块级盒子布局,包含的都是块级盒子。

基本规则

  • 块级元素:首先BFC本身也是“块级盒子”(当然实际DOM中并没有这个盒子元素),其内部也都是块级元素盒子。
  • 独立主权:该区域的内部无论有什么东西、如何排列、在干什么,都不影响其外部,反之亦然。
  • 垂直排列:BFC内部的Box垂直排列,从上往下依次排列。
  • 垂直 margin 重叠:垂直方向间距由margin决定,同一BFC内相邻的Box的margin重叠,看谁的大就谁的。so,不是在同一个BFC则不会发生边距重叠。
  • 左边距,BFC中每个盒子,都是从其父容器Box的左边界开始,包括浮动元素也是这样。
  • 不会重叠:BFC区域不会与浮动盒子(float box)重叠,会向后找新的区域排列。注意,这是解决浮动盒子重叠的关键。
  • BFC高度:计算BFC高度时,会包含浮动元素(float box)。注意,这是解决高度坍塌、清除浮动的关键。

如何触发BFC?

  • html 根元素,最大的BFC。
  • float 浮动:left、right,脱离了文档流,自成一派。自成一个独立BFC,它的内部是正常流布局。
  • position 定位:absolute、fixed,脱离了文档流,自成一派,同float浮动一样。
  • overflow 溢出,属性值不为 visible,常用 overflow: hidden 触发容器为BFC。
  • display 值:一个块级盒子,为独立BFC区域:
    • 行内块级盒子:inline-block
    • 表格类盒子:table、table-cell、table-caption、inline-table
    • 弹性盒子:flex 、inline-flex
    • 网格盒子:grid 、inline-grid

注意:上面这些场景会触发创建块格式化上下文,而不是这些盒子本身。

使用场景

BFC主要还是浏览器用来渲染布局用的,在实际开发中可以利用他的这些规则做哪些事情呢?—— 处理浮动float布局的烂摊子!

① float导致的高度塌陷

问题:如果一个块级盒子如<div>中的元素都是float,他们都脱离了文档流,会导致盒子高度塌陷,就是高度没了。这时就会影响后面元素的布局了,造成不想看到的情景,float这个渣...

解决方法:触发这个容器的BFC,因为BFC在计算高度的时候会考虑内部的浮动元素,浮动元素本身也是一个独立BFC。

<div class="height-lose">
<div>div1</div>
<div>div2</div>
<i>艰难的撑起了一点高度</i>
</div>
<style>
.height-lose{
border:2px solid;
/* 建立BFC,防止高度塌陷 */
overflow: hidden;
/* display: table; */ /* 我也可以 */
}
.height-lose>div{
float: left;
height: 50px; width: 50px; margin: 5px;
background-color: antiquewhite;
}
</style>

» 父容器div的高度坍塌,因为没有计算浮动元素。触发父容器BFC即可解决

② float导致的盒子重叠/环绕

问题:如下示例,父容器<div>中,左侧子元素是浮动float布局,导致后面正常元素与他重叠了,区域重叠,内容会绕开,看上去就是环绕效果。

解决方法:触发后面的的盒子为BFC,防止重叠,因BFC不会和其他浮动元素重叠。这种方法还可以用来实现左右两栏布局。

<div class="left-right">
<div>left:左浮动box左浮动box</div>
<div>right:我是右边,你挡着我了!我是右边,不是左边,不要挡到我。</div>
</div>
<style>
.left-right div:first-of-type {
float: left;
width: 100px;
background-color: #7F7;
}
.left-right div:last-of-type {
width: 160px;
background-color: #77FA;
/* 右侧盒子触发BFC,防止被遮挡 */
overflow: hidden;
/* display: table; */ /* 我也可以 */
}
</style>

» 盒子重叠,内容环绕,触发BFC解决

③ 清除float浮动

由于浮动float会导致后续正常布局的元素布局“不正常”,主要原因就是浮动float盒子的父容器高度塌陷、元素重叠。因此解决方法也就是恢复其高度,触发其父元素的BFC即可,方法同上。

④ 边距重叠

问题:如下示例中,父容器<div>,两个子元素<p>的上下边距重叠了,有的时候这并不是希望看到的。

解决方法:原本这两个元素是在同一个BFC里,解决方式就是把一个<p>元素放到另一个BFC里,拆散他们!

<div class="margin-overlap">
<p>p1:margin:30px 0</p>
<div class="bfc">
<p>p2:margin:30px 0</p>
</div>
</div>
<style>
.margin-overlap p {
margin: 30px 0;
padding: 0 10px;
border: 2px solid skyblue;
line-height: 30px;
height: 30px;
}
.bfc {
/* 建立BFC,就是要打破你们的水乳交融 */
overflow: hidden;
/* display: table; */ /* 我也可以 */
}
</style>


05、IFC:内联级格式上下文

Inline formatting context ,内联级格式上下文,简称 IFC。包含行内元素盒子,从左到右横向排列成一行。形成条件比较简单,当块级元素中仅包含行内元素盒子时,就形成了一个IFC。很多时候都是浏览器自动用匿名块进行包装形成IFC,如当IFC中有块级元素插入时,会拆分产生两个IFC

基本规则

  • 水平排列:IFC内都是行内元素盒子,水平方向排列。
  • 垂直对齐vertical-align:底部、顶部对齐,或者文本基线,不同元素默认对齐方式不同。
  • 行框(line box):包含了一整行的行内盒子的矩形区域,被称为该行的行框(line box),宽度由内容决定,高度由CSS计算(最高的元素)。
  • 多行-多行框:当一个IFC的内容比较多,会自动换行,会切分为多个行框(line box)。
  • 水平间距:盒子之间水平margin、border、padding都有效,会推开其他盒子。
  • 水平对齐text-align:当内容宽度小于行框时,水平渲染规则由 text-align来决定。所以一般可以用text-align:center;来设置水平居中。
  • 垂直间距:会有用,但不会计算垂直的空间,不影响行高、不影响其他元素布局。
  • 默认有间隙:行内元素盒子之间有一个默认间隙。

<p>我只是路过而已!</p>
<div class="inline-box">
<span>span:padding:100px</span>
<img src="../res/qq.png" alt="图片" height="100px">
<p>p标签,inline-block</p>
</div>
<p>我是新的一个p盒子内容,我只是路过而已,别当到我了!</p>
<style>
.inline-box {
text-align: center; /*水平居中*/
background-color: aliceblue;
height: 130px;
/*line-height: 130px;*/ /* 基于line-height 垂直居中,子元素会继承*/
/* overflow: hidden; */ /* 隐藏溢出部分内容 */
}
.inline-box * {
background-color: #F666;
vertical-align: middle; /* 基于行框高度 垂直居中*/
}
.inline-box p {
display: inline-block;
margin: 0;
}
.inline-box span{
margin: 300px 0; /*margin没有卵用,如果为inline-block有用*/
padding: 100px 0; /*padding 会溢出,不影响其他元素布局,会重叠*/
border: 2px solid blue;
}
</style>

» 垂直的padding有效,超出了父容器边界

» 启用注释代码:

️上面的示例中可得出如下结论

  • 行框的高度由长得最高的元素撑起来的。
  • 垂直margin好像没什么用,paddingborder部分有效,不会计算垂直空间,不影响其他元素布局,但会影响渲染,有重叠。
  • text-align: center;,让行内元素水平居中布局显示。
  • vertical-align: middle;,可以让行内元素垂直居中显示(基于行框的高度,而不是父容器高度)。
  • line-height: 130px;,让行内元素基于line-height 垂直居中。

️版权申明:版权所有@安木夕,本文内容仅供学习,欢迎指正、交流,转载请注明出处!原文编辑地址-语雀

CSS布局秘籍(1)-任督二脉BFC/IFC的更多相关文章

  1. CSS布局秘籍(2)-6脉神剑

    HTML系列: 人人都懂的HTML基础知识-HTML教程(1) HTML元素大全(1) HTML元素大全(2)-表单 CSS系列: CSS基础知识筑基 常用CSS样式属性 CSS选择器大全48式 CS ...

  2. Appium+python自动化(十)- 元素定位秘籍助你打通任督二脉 - 上卷(超详解)

    简介 你有道灵光从天灵盖喷出来你知道吗,年纪轻轻就有一身横练的筋骨,简直百年一见的练武奇才啊,如果有一天让你打通任督二脉,那还不飞龙上天啊.正所谓我不入地狱谁入地狱,警恶惩奸维护世界和平这个任务就交个 ...

  3. 天河微信小程序入门《三》:打通任督二脉,前后台互通

    原文链接:http://www.wxapp-union.com/forum.php?mod=viewthread&tid=505&extra=page%3D1 天河君在申请到https ...

  4. 任督二脉之Shell中的正则表达式

    VBird说学习Linux,掌握了Shell和正则就相当于打通了任督二脉,此后能力的成长才会突飞猛进. Shell的基础学习之前已经总结了一篇博客:http://www.cnblogs.com/jyz ...

  5. Linux就这个范儿 第13章 打通任督二脉

    Linux就这个范儿 第13章 打通任督二脉 0111010110……你有没有想过,数据从看得见或看不见的线缆上飞来飞去,是怎么实现的呢?数据传输业务的未来又在哪里?在前面两章中我们学习了Linux网 ...

  6. English learning method ---学英语重中之重打通“任督二脉”

    漫漫十年艰辛路,英语学习之旅 曾经秉承“路漫漫其修远兮,吾将上下而求索”的信念,初一那年了解到原来(a b c d e f g) 不仅仅读作(啊,波,词,的,额,佛,哥),在英语的世界中它有另外的读法 ...

  7. 一个典型的后台软件系统的设计复盘——(三)打通任督二脉-context

    武侠小说练功讲究打通任督二脉.程序设计练到一定程度也讲究打通任督二脉.好奇心强的同学可以搜搜“打通任督二脉有什么感觉”. spring的任督二脉ApplicationContext 最经典的任督二脉莫 ...

  8. 深度讲解Linux内存管理和Linux进程调度-打通任督二脉

    我在多年的工程生涯中发现很多工程师碰到一个共性的问题:Linux工程师很多,甚至有很多有多年工作经验,但是对一些关键概念的理解非常模糊,比如不理解CPU.内存资源等的真正分布,具体的工作机制,这使得他 ...

  9. K2 BPM_当K2遇上医药,用流程打通企业的任督二脉_业务流程管理系统

    据调查,如今仍有60%的医药企业,存在合规经营和利润下降的困扰,在“研”.“产”.“供”.“销”的运营过程中,时时伴随着严苛的管理政策和法规.如何加强企业跨部门.跨组织.跨业务线的执行能力,始终是管理 ...

随机推荐

  1. 2步就可以压缩PPT大小,再也不怕C盘飘红了!

    在座哪位小朋友的C盘已经红了,举个手让我看看! 嗯......还真不少啊! 经常做PPT的同学已经开始抱怨了:领导给的图片一张就10M起,一个PPT里面百来张图,文件大小都快1个G了. 如果是文秘岗, ...

  2. iOS去广告最简单方案!+以图搜漫

    iOS去广告 ️推荐 | 通过下载.安装.启用(一般默认启用)描述文件,即可实现通过私人dns来达到全系统的广告拦截.隐私保护功能 ️注意: 限 iOS 14 及以上版本系统使用 复制链接需在 saf ...

  3. C#基础_C#计算样本标准差和总体标准差

    首先我们先了解样本标准差和总体标准差: 样本标准差=方差的算术平方根=s=sqrt(((x1-x)^2 +(x2-x)^2 +......(xn-x)^2)/(n-1)) 总体标准差=σ=sqrt(( ...

  4. ASP.NET Core 6框架揭秘实例演示[35]:利用Session保留语境

    客户端和服务器基于HTTP的消息交换就好比两个完全没有记忆能力的人在交流,每次单一的HTTP事务体现为一次"一问一答"的对话.单一的对话毫无意义,在在同一语境下针对某个主题进行的多 ...

  5. 在Yarn集群上跑spark wordcount任务

    准备的测试数据文件hello.txt hello scala hello world nihao hello i am scala this is spark demo gan jiu wan le ...

  6. MySQL8 Group By 新特性

    MySQL8 Group By 新特性 此生此夜不长好,明月明年何处看.   一.简介 MySQL8 新特性之 Group By 不再隐式排序.MySQL8对于group by 字段不再隐式排序,如需 ...

  7. Git Rebase-提交整洁之道

    git rebase git rebase是一个非常有用的命令,但知道和用的人非常少,今天介绍一下其作用 git rebase -i 作用:常用来合并多个相同目的的提交. 交互式有下面几个命令,常用命 ...

  8. getch()之隐藏输入密码

    getch() :读取字符且不会回显(不会显示):不从输入缓冲区读取:在getch中,把回车按键输入, 识别为回车符'\r':在getchar中,把回车按键输入,识别为回车符'\n'. getch() ...

  9. Python数据科学手册-机器学习: 主成分分析

    PCA principal component analysis 主成分分析是一个快速灵活的数据降维无监督方法, 可视化一个包含200个数据点的二维数据集 x 和 y有线性关系,无监督学习希望探索x值 ...

  10. windows系统下使用bat脚本文件设置 JDK 系统环境变量

    号开头的行不要写在bat文件中 # java_init.bat # 注意文件换行符是windows系统下的(CR LF),文件编码是ANSI # path变量追加这个可以拓展到tomcat,mysql ...