00、CSS布局

布局&响应式设计

0.1、正常布局流(Normal flow)

正常布局流就是不做任何布局控制,按照HTML的顺序(从左到右,从上而下)进行布局排列。正常布局流的几个关键点:

  • 单个内容的布局,把内容放入盒子,加上盒子三件套(padding、boder、margin。
  • 块级元素单独一行,按照顺序垂直组织,并按其margin分离。
  • 内联元素会在一行水平排列,高度、宽度都取决于内容,直到空间不足另起一行。
  • 相邻元素的margin会保留最大的那一个,就是盒子的外边距折叠。

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

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

    0.2、display布局属性

    正常流中的所有元素都有一个**display**的值,这个属性允许我们更改默认的显示方式。display可用来设置多种布局方式,可以让不同元素类型(行、块元素)转换。
属性/值 描述
display
none 元素隐藏不显示,也不加载,彻底隐藏
block 此元素将显示为块级元素
inline 内联,此元素会被显示为内联元素
inline-block 行内块元素(CSS2.1),介于内联和块之间的一个中间,除了不换行,高宽、盒子三件套都有效。
在导航中常用ul+inline-block+padding来实现导航
list-item 此元素会作为列表显示,元素的外部显示类型变为 block 盒,内部变为多个 list-item inline 盒。
table 表格布局,还有个inline-table
flex IE11 弹性盒子布局(横向布局),inline-flex
grid 非常灵活的网格布局,inline-grid,有些属性IE不支持
contents 充当遮罩的元素,不会产生任何盒子(不会被渲染),但不影响其子元素的布局和渲染
flow-rootIE🚫 建立一个无副作用的BFC

0.3、响应式设计

响应式网页设计(responsive /rɪˈspɒnsɪv/ web design,RWD),指的是允许 Web 页面适应不同屏幕宽度等因素,进行布局和外观的调整的一系列实践。它涵盖了很多 CSS 和 HTML 的功能和技术,现在基本上就是我们默认建设网站的方式。
CSS布局详细教程 - 图1
如上图,基于媒体查询和现代布局,响应式设计成为当下的主流。通过媒体查询测试,针对不同的尺寸适配不同的CSS样式、图片,如调整字体大小、段落填充、菜单按钮布局、以及增大触摸按钮的大小等,让网页能够自适应各种设备尺寸、设备类型。

  • 对于响应式图形,创建多种尺寸版本文件,基于媒体查询计算,选择合适尺寸的文件。或者改用新的 元素。

    1. <img srcset="elva-fairy-320w.jpg 320w,
    2. elva-fairy-480w.jpg 480w,
    3. elva-fairy-800w.jpg 800w"
    4. sizes="(max-width: 320px) 280px,
    5. (max-width: 480px) 440px,
    6. 800px"
    7. src="elva-fairy-800w.jpg" alt="Elva dressed as a fairy">
  • 响应式排版,传统方式可以结合vw单位(视口的1%)、固定尺寸rem、px单位,或者基于媒体查询设置字体尺寸。

    1. .p1 {
    2. font-size: calc(1rem + 2vw);
    3. }
    4. @media screen and (min-width:1440px) {
    5. .p2 {
    6. font-size: 150%;
    7. }
    8. }
  • 视口元标签,明确视口的宽度为设备的宽度,并初始化缩放比例为1,建议添加如下元素申明。

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

0.4、@媒体查询

媒体查询是指针对不同的设备、特定的设备特征或者参数进行定制化的修改网站的样式。媒体查询的标准语法: :::info media-type and (media-feature-rule) { / CSS规则 CSS rules go here / }
/ 注意关键字and后面的空格 / :::

  • 媒体类型media-type:媒体的类型,如print印刷品、screen屏幕。
  • 媒体表达式media-feature-rule):
  • CSS规则:通过媒体查询测试后的CSS样式。 | 属性 | 描述 | | | —- | —- | —- | | @media | 媒体查询申明 | | | media-type | 媒体类型 |
    - all:所有设备
    - print:打印,网页打印的时候
    - screen:屏幕
    - speech:语音合成器
    | | 逻辑操作符 | 连接多个媒体查询语句 |
    - and:查询条件都满足的时候才生效
    - not:查询条件取反
    - only:整个查询匹配的时候才生效,常用语兼容旧浏览器,使用时候必须指定媒体类型
    - 逗号或者 or:查询条件满足一项即可匹配;
    | | media-feature-rule | 媒体特征规则,探测视口宽度是比较普遍的做法。 |
    - min-width:>=最小宽度
    - max-width:<=最大宽度
    - 更多媒体查询特征,如orientation(屏幕方向)
    | | @import | 导入外部css样式,支持媒体查询 | |

image.png

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

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


01、BFC/IFC 格式化上下文

所有元素都是一个盒子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),使用还不广泛,不过现代浏览器基本都支持了。

实际上这些格式上下文也是相互嵌套的,各自负责各自区域进行渲染(布局)。
CSS布局详细教程 - 图3
上图为个人理解,不一定都对。

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

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

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

    🔸如何触发BFC?

  • **html**根元素

  • **float**浮动:left、right,脱离了文档流,自成一派。
  • **overflow**溢出属性值不为 visible,常用 overflow: hidden
  • **display**值:一个块级盒子
    • 行内块级盒子:inline-block
    • 表格类盒子:table、table-cell、table-caption、inline-table
    • 弹性盒子:flex 、inline-flex
    • 网格盒子:grid 、inline-grid
  • position定位,absolute、fixed、sticky,脱离了文档流,自成一派。 :::warning 📢注意:上面这些场景会触发创建块格式化上下文,而不是这些盒子本身。 :::

    🔸使用场景

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

    ❶ float导致的高度塌陷

    ❓ 问题:如果一个块级盒子如<div>中的元素都是float,他们都脱离了文档流,会导致盒子高度塌陷,就是高度没了。
    ✅ 解决方法:触发这个容器素的**BFC**,因为BFC在计算高度的时候会考虑浮动元素,浮动元素本身也是一个BFC。

    1. <div class="height-lose">
    2. <div>div1</div>
    3. <div>div2</div>
    4. <i>艰难的撑起了一点高度</i>
    5. </div>
    6. <style>
    7. .height-lose{
    8. border:2px solid;
    9. /* 建立BFC,防止高度塌陷 */
    10. overflow: hidden;
    11. /* display: table; */
    12. }
    13. .height-lose>div{
    14. float: left;
    15. height: 50px; width: 50px; margin: 5px;
    16. background-color: antiquewhite;
    17. }
    18. </style>

    image.png
    image.png

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

    ❓ 问题:如下示例,父容器<div>中,左侧子元素是浮动float布局,导致后面正常元素与他重叠了,看上去就是环绕效果。
    ✅ 解决方法:触发后面的的盒子为**BFC**,防止重叠。这种方法还可以用来实现左右两栏布局。

    1. <div class="left-right">
    2. <div>left:左浮动box左浮动box左浮动box</div>
    3. <div>right:我是右边,你挡着我了!我是右边。</div>
    4. </div>
    5. <style>
    6. .left-right div:first-of-type {
    7. float: left;
    8. width: 100px; background-color: #7F7;
    9. }
    10. .left-right div:last-of-type {
    11. width: 200px; background-color: #77FA;
    12. /* 右侧盒子触发BFC,防止被遮挡 */
    13. overflow: hidden;
    14. /* display: flex; */
    15. }
    16. </style>

    image.png
    image.png

    ❸ 清除float浮动

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

    ❹ 边距重叠

    ❓ 问题:如下示例,父容器<div>中,两个<p>元素的上下边距重叠了,有的时候这并不是项看到的。
    ✅ 解决方法:原本这两个元素是在同一个BFC里,解决方式就是把一个<p>元素放到另一个**BFC**里,拆散他们!

    1. <div class="margin-overlap">
    2. <p>p1:margin:30px 0</p>
    3. <div class="bfc">
    4. <p>p2:margin:30px 0</p>
    5. </div>
    6. </div>
    7. <style>
    8. .margin-overlap p {
    9. margin: 30px 0;
    10. padding: 0 10px;
    11. border: 2px solid skyblue;
    12. line-height: 30px;
    13. }
    14. .bfc {
    15. /* 建立BFC,就是要打破你们的水乳交融 */
    16. overflow: hidden;
    17. /* display: inline-block; */
    18. }
    19. </style>

image.png
image.png

1.2、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;来设置水平居中。
  • 垂直间距:会有用,但不会计算垂直的空间,不影响行高、不影响其他元素布局。
  • 默认有间隙:行内元素盒子之间有一个默认间隙。

image.png

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

image.png
image.png
⁉️上面的示例中有如下结论

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

02、Flex弹性盒子(display:flex)IE11

Flexbox (IE11)是 CSS 弹性盒子布局模块(Flexible Box Layout Module)的缩写,用于设计横向纵向的单向布局,父元素(flex容器)上应用display: flex ,所有直接子元素(flex项)都将会按照 flex 进行布局。
Flexbox布局需了解他的两根轴:

  • 主轴:flex-direction 定义的方向,就是flex项排列的方向。
  • 交叉轴:垂直与主轴的方向。

image.png

属性/标题 描述 值/备注
display: flex; IE11 父元素启用flex布局
flex-flow(父元素) flex-direction 和 flex-wrap 的简写属性 flex-flow: row wrap;
flex-direction(父元素) 弹性盒子(子元素)的排列方式
- row:横向排列(默认值),一行。
- column:纵向排列
- row-reverse:横向+反序排列
- column-reverse:纵向+反序排列
flex-wrap(父元素) 设置换行。wrap /ræp/换行
- nowrap:摆放到到一行,超出会导致溢出
- wrap:换行
- wrap-reverse:换行+(行)反序
flex (flex项)IE11 设置flex项的尺寸,下面三个的简写 flex: 1 1 100px;
flex-grow 设置 flex 项的尺寸规则,等比分配,值相等则等分 number
flex-shrink 设置收缩规则,超出容器大小会收缩,比例计算? number,(shrink /ʃrɪŋk/ 缩小)
flex-basis 初始大小(/ˈbeɪsɪs/),优先级高于width/height
- 尺寸值,200px,支持百分比
- content:根据内容的自动尺寸
align-items(flex项) 垂直对齐:元素在交叉轴方向对齐方式
- stretch: /stretʃ/ 拉伸
- flex-start、flex-end、center
justify-content(flex项) 水平对齐:设置主轴方向上对齐,主轴方向是通过 flex-direction 设置的方向。(justify /ˈdʒʌstɪfaɪ/ 对齐)

- stretch 拉伸
- flex-start、flex-end、center
- space-around:均匀排列,居中排列
- space-between:均匀排列,两端对齐
order(flex项) flex项的序号,设置排序,默认值0排第一 排序索引,数字
  1. <style>
  2. .flex {
  3. display: flex;
  4. flex-flow: row wrap;
  5. align-items: stretch;
  6. justify-content: stretch;
  7. }
  8. /*注意这里,一般用子代选择器*/
  9. .flex>div {
  10. flex: 1 200px;
  11. background-color: #9be6bd;
  12. padding: 10px;
  13. }
  14. .flex>div:nth-child(even){
  15. background-color: #eeb2cb;
  16. }
  17. </style>
  18. <div class="flex">
  19. <div><b> div1:</b>
  20. <p>Flexbox 是 CSS 弹性盒子布局模块(Flexible Box Layout Module)的缩写</p>
  21. </div>
  22. <div>div2:</div>
  23. <div>div3:</div>
  24. <div>div4:</div>
  25. <div>div5:</div>
  26. </div>

image.png
下面为基于flex布局的栅格布局,可以自动等比均分列网格,比float浮动更方便一些。

  1. .row {
  2. display: flex;
  3. }
  4. .col {
  5. margin-left: 2.08333333%;
  6. margin-bottom: 1em;
  7. width: 6.25%;
  8. flex: 1 1 auto;
  9. background: rgb(255,150,150);
  10. }

03、Grid网格布局(display:grid)

  1. [**grid **](https://developer.mozilla.org/zh-CN/docs/Learn/CSS/CSS_layout/Grids)布局是一个二维布局系统,通过行列设置定义一个网格,然后子元素按照顺序排列网格,或者设置其行列坐标。一个网格通常具有许多的列(**column**)与行(**row**),以及行与行、列与列之间的间隙,这个间隙一般被称为沟槽(**gutter** /ˈɡʌtər/水沟)。
属性 描述
**display: grid;** 父元素启用grid布局 还可以设置为inline-grid,行内网格
grid-template-rows
grid-template-columnsIE10
定义行/列
- auto、max-content:自动排列
- 尺寸px、em、%
- 比例单位**fr**2fr 1fr 1fr;
- minmax()函数:minmax(100px,auto),区间
- repeat()函数:repeat(2, 2fr 1fr),重复创建行列
grid-templateIE🚫 定义行列,rows、columns、areas的简写 grid-template: 100px 1fr / 50px 1fr;
grid-gapgap IE🚫 定义行、列的间隙,等同于gap grid-gap: 10px 20px; gap /ɡæp/ 缝隙
grid-row-gap 行间间隙
grid-column-gap 列间间隙
grid-auto-rowsIE10 自动设定隐式网格的大小-行网格-宽 grid-auto-rows:50px;
grid-auto-columns 自动设定隐式网格的大小-列网格-高
grid-column(子元素)、
grid-row(子元素)IE🚫
网格线序号坐标:设置子元素的行、列坐标,注意这里的坐标是行列分割线,不是单元格
- auto、auto-fill:自动排列
- 行列坐标序号 grid-column: 2;
- 跨行/列,反斜杠/起始位置grid-column: 1 / 3;
- span跨行/列:[开始位置] /span [合并的单元格数]
grid-template-areasIE🚫 区域网格命名:按照区域命名的网格布局,先定义区域,在给子元素设置区域
- 字符串命名,空格隔开
- 每个命名为一个单元格,同名合并,.为空格
grid-area(子元素) 给子元素这种区域名
其他:单位/函数
flex:fr IE🚫 网格(grid)可变长度单位
minmax(min,max) 定义长宽范围的闭区间函数,在网格布局中使用,用于gird布局。 参数为尺寸值、fr、auto、min-content、max-content
minmax(100px, auto)
repeat(重复次数,值..)IE🚫 网格列表尺寸的重复设置函数,用于gird布局。
- 第一个参数:重复次数、
- auto-fill:尽量最大网格数排列
- 后面参数:重复的网格尺寸

repeat(auto-fill,80px minmax(200px, auto)) ; |

🔸隐式网格

通过grid-template-columns 、 grid-template-rows创建的网格为显示网格,子元素较多时会自动换行进行网格排列,这部分称为隐式网格,隐式网格的大小默认是auto(根据内容自适应),可以通过grid-auto-rows、grid-auto-columns来设置其大小。

🔸网格分割线

网格线是从头开始的,一般来说n行有n + 1根水平网格线,m列有m + 1根垂直网格线。
CSS布局详细教程 - 图16

  1. <style>
  2. .from{
  3. display: grid; grid-gap: 5px;
  4. /* height: 300px; */
  5. /* 设置行列网格 */
  6. grid-template-columns: repeat(2,80px minmax(180px,1fr));
  7. grid-template-rows: repeat(3,minmax(40px,auto));
  8. grid-auto-rows: minmax(40px,auto);
  9. /* 合并的写法 */
  10. grid-template: repeat(3,minmax(40px,auto)) / repeat(2,80px minmax(180px,1fr));
  11. }
  12. .from label,.from input,from textarea{
  13. box-sizing: border-box;
  14. padding: 3px; margin: 0px;
  15. background-color: lightyellow;
  16. }
  17. .from label{
  18. display: flex; padding: 0 3px;
  19. align-items: center; justify-content: right;
  20. }
  21. .from>.form-cell{
  22. display: flex; padding: 0 10px;
  23. align-items: center; background-color: lightyellow;
  24. }
  25. .from>textarea{
  26. grid-column: 2/5; grid-column: 2/span 3;
  27. }
  28. </style>
  29. <div class="from">
  30. <label for="">姓名:</label><input type="text">
  31. <label for="">籍贯:</label><input type="text">
  32. <label for="">性别:</label>
  33. <div class="form-cell">
  34. <input type="radio"><label for=""></label>&nbsp;&nbsp;
  35. <input type="radio"><label for=""></label>
  36. </div>
  37. <label for="">生日:</label><input type="date">
  38. <label for="" >简介:</label><textarea name="" id="" cols="100" rows="5">1111</textarea>
  39. </div>

image.png

🔸区域网格命名

用“名字”来划分并指定区域,用法类似网格线序号,用来做页面布局很轻松。

  • 区域字符命名,行内空格分割,行间引号分割。
  • 相同命名的格子自动合并单元格,且必须为一个矩形。
  • 所有名字只能出现在一个连续的区域,不能在不同的位置出现。
  • 使用.符号,让一个格子留空。
    1. <style>
    2. .page{
    3. display: grid;
    4. /*定义2列、3行*/
    5. grid-template-areas: "header header" "left right" "footer footer";
    6. grid-template-rows: 40px 1fr 40px;
    7. grid-template-columns: minmax(100px,200px) auto;
    8. height: 300px; margin: 10px;
    9. }
    10. .page>.header{grid-area: header;}
    11. .page>.left{grid-area: left;background-color: lemonchiffon; }
    12. .page>.right{grid-area: right;background-color: rgb(170, 236, 238); }
    13. .page>.footer{grid-area: footer;}
    14. .page>div{background-color: aquamarine;padding: 10px; }
    15. </style>
    16. <div class="page">
    17. <div class="header">header</div>
    18. <div class="left">left</div>
    19. <div class="right">right</div>
    20. <div class="footer">footer</div>
    21. </div>
    image.pngimage.png

04、float浮动布局

float属性让素左右浮动起来,会改变元素本身和跟随他后面的(不管层级、类型)其他正常流布局元素的行为。元素从正常布局流 (normal flow) 中移除,会浮动到父容器的左侧或右侧,这时候他后面的正常布局的元素围绕该浮动元素,并填满其右侧(或左侧)的空间。

属性 描述
float 设置元素浮动布局
- left — 将元素浮动到左侧。
- right — 将元素浮动到右侧。
clear 适用于浮动和非浮动元素,清除浮动效果
- none:元素不会被向下移动以清除浮动。
- left:元素被向下移动以清除左浮动
- right:元素被向下移动以清除右浮动
- both:元素被向下移动以清除左右浮动

在grid网格布局支持之前,float是实现页面布局的重要手段,他也存在一广泛的问题。 :::warning

  • 使用float布局必须精心计算他们的宽度,还要考虑他们的padding、border、margin,推荐启用代替IE盒模型,避免不受控的溢出。
  • 而且他本质上还是一维的,不支持跨行。
  • 浮动使用的越复杂,清除也会越复杂,应尽早清除,避免给后面的元素造成麻烦。推荐在浮动布局后添加一个空的清除浮动div。 ::: 下面的示例代码就是典型的传统基于float浮动实现的栅格布局,把列等分为12份,并穷举创建横跨2-12列的样式类,
    1. body {
    2. width: 90%;
    3. max-width: 980px;
    4. margin: 0 auto;
    5. }
    6. *{box-sizing: border-box;}
    7. /* row用来清除row之间的浮动影响 */
    8. .row {
    9. clear: both;
    10. }
    11. .col {
    12. float: left;
    13. margin-left: 2.08333333%;
    14. width: 6.25%;
    15. }
    16. .col.span2 { width: calc((6.25%*2) + 2.08333333%); }
    17. .col.span3 { width: calc((6.25%*3) + (2.08333333%*2)); }
    18. .col.span4 { width: calc((6.25%*4) + (2.08333333%*3)); }
    19. /*...*/
    20. .col.span12 { width: calc((6.25%*12) + (2.08333333%*11)); }
    21. /* 用来作为空列的偏移*/
    22. .offset-by-one {
    23. margin-left: calc(6.25% + (2.08333333%*2));
    24. }
    1. <style>
    2. .form-float *{ box-sizing: border-box; }
    3. .form-float>.row{
    4. clear: both; padding: 5px 0;
    5. }
    6. .form-float>.row>.col{
    7. float: left;
    8. background-color: antiquewhite; padding: 5px;
    9. }
    10. .form-float>.row>.col.lab{
    11. width: 15%;
    12. text-align: right;
    13. }
    14. .form-float>.row>.col.span1{ width: 35%; }
    15. .form-float>.row>.col.span2{ width: 85%; }
    16. .clear{ clear: both; }
    17. </style>
    18. <form class="form-float">
    19. <div class="row" id="r1">
    20. <label for="" class="col lab" id="l1">姓名:</label> <input type="text" class="col span1" value="杜牧">
    21. <label for="" class="col lab">籍贯:</label><input type="text" class="col span1" value="唐">
    22. </div>
    23. <div class="row">
    24. <label for="" class="col lab">性别:</label>
    25. <div class="col span1">
    26. <input type="radio"><label for=""></label>&nbsp;&nbsp;
    27. <input type="radio"><label for=""></label>
    28. </div>
    29. <label for="" class="col lab">生日:</label><input type="date" class="col span1">
    30. </div>
    31. <div class="row">
    32. <label for="" class="col lab">简介:</label>
    33. <textarea name="" id="" cols="100" rows="5" class="col span2">停车坐爱枫林晚,霜叶红于二月花</textarea>
    34. </div>
    35. </form>
    36. <div class="clear"></div>
    image.png

    🔸清除浮动

    脱离正常的文档流,并不会占据文档流的位置,如果一个父元素下面都是浮动元素,则会导致父元素的高度坍塌(主要原因)。从而使得后面的正常元素布局出现不希望的情况,常见2中清除方法:
方法 说明
❶ 触发父元素为BFC
- overflow: hidden; 比较常用的方式,缺点是文档超过区域大小后,内容会被隐藏。
- display: flow-root;,新特性,创建无副作用的BFC。
❷ 设置父元素高宽 明确设置父元素的高度、宽度,缺点是不能自适应。
❸ 父级添加伪元素::after,并清空clear ::after中添加一个空的块级盒子,并清除其浮动。clear: both;使左右两边都不允许浮动元素,让后面的非浮动元素的边界移动到所有浮动元素的外边界下方,就强行撑开了高度。
📢注意,这里并没有产生BFC,详情参考 MDN-clear
  1. /* 恢复父元素上的BFC */
  2. .parent {
  3. overflow: hidden;
  4. }
  5. /* 在父元素上使用清除clearfix:clear + 伪元素::after实现,附加一个空的块元素并清除 */
  6. .clearfix::after {
  7. content: "";
  8. display: block;
  9. clear: both;
  10. }

:::success 不理解float为什么要这么设计???😂😂😂 :::


05、position定位

position 精准设置盒子中的盒子的位置,正常布局流中,默认为 static ,使用其它值会引起元素不同的布局方式。结合偏移top, bottom, left, right使用,如果不设置偏移,则元素还是原来的位置。 :::warning ❗定位并不是一种常规的布局方式,主要用于一些特殊位置的实现。 ::: | 属性/值 | 描述 | | | —- | —- | —- | | position | 设置元素定位方式 | | | static | 静态定位,就是正常文档流位置,所有元素的默认值。此时设置偏移无效 | position: static; | | relative | 相对定位 (relative /ˈrelətɪv/),在文档流的基础上,相对于自己位置的偏移定位,位置保留。不影响其他元素,可能会和其他元素重叠。 | position: relative; | | absolute | 绝对定位 (absolute /ˈæbsəluːt/),脱离文档流,就像单独一个图层中,完全不干扰其他元素布局。相对于最近一个非static定位的父元素(直到根元素),常用于弹出层(消息、菜单) | position: absolute; | | fixed | 固定定位,和absolute基本一样,脱离文档流,定位的对象是浏览器视口,可实现不滚动的固定内容。 | position: fixed; | | stickyIE🚫 | 粘性定位 (sticky /ˈstɪki/ 黏性的),静态定位+固定定位 fixed的结合体,先静态定位,当元素满足预定条件时(达到相对于视口的定位),进入固定定位fixed模式。
注意:sticky 元素会“固定”在离它最近的一个拥有“滚动机制”的父元素上 | position: sticky; | | top | 顶部偏移:元素的上外边距边界与其包含块上边界之间的偏移。只用于定位 | | | bottom | 底部偏移,只用于定位。若与top同时设置,都会生效,如有固定height则top生效 |
| | left | 左侧偏移,只用于定位 |
| | right | 右侧偏移,只用于定位 |
| | z-index | z轴坐标,用于元素上下层叠顺序控制,默认auto=0,值越大层级越高。 | z-index:-1; |

  1. <style>
  2. .btn-top{
  3. display: block;
  4. width: 3em; height: 3em; line-height: 3em;
  5. border-radius: 1.5em; opacity: 0.5;
  6. text-align: center; text-decoration: none;
  7. background-color: #eeb2cb;
  8. /* 定位 */
  9. position: fixed;
  10. bottom: 10px; right: 10px;
  11. }
  12. .btn-top:hover{
  13. opacity: 1; background-color: coral;
  14. }
  15. </style>
  16. <a href="#" class="btn-top" title="回到顶部">Top</a>

image.png


06、表格布局(display:table)

元素类似,实现一个行列工整的布局表格。表格的布局可以用在非表格内容上,使用display: table、table-row、table-cell和相关属性在非表元素上,常用于表单form的内容布局(好像并不好用-不能跨行?)。

属性值 描述
display: table 表格布局
display: table-row 类似表格的tr
display: table-cell; 类似表格的单元格td
vertical-align 单元格垂直对齐
  1. <style>
  2. .form-table {
  3. display: table;
  4. width: 100%; border: 1px solid lightgray;
  5. }
  6. .form-table .trow {
  7. display: table-row;
  8. background-color: linen;
  9. }
  10. .form-table .trow>label{
  11. display: table-cell;
  12. width: 100px; line-height: 40px;
  13. text-align: right;
  14. }
  15. .form-table .trow>input,.form-table textarea{
  16. display: table-cell;
  17. width: 90%;
  18. }
  19. </style>
  20. <div class="form-table">
  21. <div class="trow">
  22. <label for="" id="l1">姓名:</label><input type="text" value="杜牧">
  23. <label for="">籍贯:</label><input type="text" value="唐">
  24. </div>
  25. <div class="trow">
  26. <label for="">性别:</label>
  27. <div>
  28. <input type="radio"><label for=""></label>&nbsp;&nbsp;
  29. <input type="radio"><label for=""></label>
  30. </div>
  31. <label for="">生日:</label><input type="date">
  32. </div </div>
  33. <div class="trow">
  34. <label for="">简介:</label>
  35. <textarea name="" id="" rows="4" colspan="3">不知道怎么实现跨行</textarea>
  36. </div>
  37. </div>

image.png


07、column-count多列布局

多列布局是一种把内容按列排序的布局方式,通过column-count设置列的数量,使用column-width设置列宽,两者可都设置或值设置任意一个即可。跟flex布局有点像,不过他们的元素跨行(截断)分配方式不一样,column-count更合适文档排版(报纸的排版)。

属性 描述 值/示例
column-countIE10 父元素启用多列布局,指定列数量,如不指定,则会自动设置列数 auto、整数
column-width 列宽度,用于多列布局 尺寸px、em
column-gap 列间间隙 尺寸px、em、%
column-rule 列间隙列的样式,用法和border一样,包括线样式、粗细、颜色。
break-inside(子元素) 多列布局页面下的内容中断方式设置 break-inside: avoid;

column-count对容器里面内容的列拆分是自动进行的,容易造成一个元素被折断(跨列显示了),可以通过break-inside对特定内容进行换行方式设置。

  1. <style>
  2. .mulcol{
  3. column-count: 2;
  4. column-width: auto;
  5. column-gap: 15px;
  6. column-rule: 4px double red;
  7. background-color: antiquewhite;
  8. padding: 8px 10px;
  9. }
  10. .article{
  11. background-color: limegreen;
  12. break-inside: avoid;
  13. /* 设置旧属性page-break-inside 增强兼容性*/
  14. page-break-inside: avoid;
  15. }
  16. </style>
  17. <div class="mulcol">
  18. <div class="article">
  19. <h2>山行</h2>
  20. <p>远上寒山石径斜,白云深处有人家。停车左爱枫林晚,霜叶红于二月花。</p>
  21. </div>
  22. <div class="article">
  23. <h2>望庐山瀑布</h2>
  24. <img width="200px" src="http://n.sinaimg.cn/translate/166/w991h775/20181129/5biI-hpevhcm3526810.jpg" alt="">
  25. <p>日照香炉生紫烟,遥看瀑布挂前川。飞流直下三千尺,疑是银河落九天。</p>
  26. </div>
  27. </div>

image.png
image.png