4

CSS布局秘籍(2)-6脉神剑 - 安木夕

 1 year ago
source link: https://www.cnblogs.com/anding/p/16852345.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client
image.png

HTML系列:

CSS系列:

00、布局的6脉神剑

特性/优点 缺点 兼容性 使用方式
Flex 一维横向/纵向排列,灵活 不明显 IE11 display: flex;
Gid 二维网格,非常灵活、强大 不明显 IE10 display:grid
column-count 列式布局,适应性强 注意内容跨列折断 IE10 column-count: 2;
float 文字环绕效果,勉强算优点吧 脱离文档流,重叠、坍塌,坑多😂 良好 float:left
position 适合特殊位置定位需求 适用特定场景,还行 良好 position: absolute;
表格布局 工整的表格布局 不支持合并,不太好用 IE8 display: table;

01、Flex弹性盒子(display:flex)

Flexbox(IE11)是 CSS 弹性盒子布局模块(Flexible Box Layout Module)的缩写,用于实现横向纵向的单向布局,在父元素(flex容器)上应用display: flex ,所有子元素(flex项)都将会按照 flex 进行布局。Flex是新一代的CSS排版布局系统,使用简单,不用担心float浮动布局的各种坑,推荐食用。

flex 布局需了解他的两根轴:

  • 主轴flex-direction 定义的方向,就是flex项排列的方向,默认横向排列,从左到右。
  • 交叉轴:垂直与主轴的方向。
image.png
父元素属性 描述 值/备注
display: flex; IE11 父元素启用flex布局 display: flex;
flex-flow(父元素) flex-direction 和 flex-wrap 的简写属性 flex-flow: row nowrap;
flex-direction(父) 弹性盒子(子元素)的排列方式 row:横向排列(默认值);column:纵向排列
● row-reverse(反序)、column-reverse
flex-wrap(父) 设置换行,默认nowrap不换行。(wrap /ræp/换行) nowrap:摆放到到一行,超出会导致溢出
wrap:换行;wrap-reverse:换行+反序
align-items(父) 垂直对齐:元素在交叉轴方向对齐方式 center 居中、flex-start、flex-end
● stretch: /stretʃ/ 拉伸
justify-content(父) 水平对齐:设置主轴方向上对齐,主轴方向是通过 flex-direction 设置的方向。
(justify /ˈdʒʌstɪfaɪ/ 对齐)
center、stretch、flex-start、flex-end
● space-around:均匀排列,居中排列
● space-between:均匀排列,两端对齐
flex项(子元素)属性 描述 值/备注
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 尺寸值 px/%content:根据内容的自动尺寸
order(flex项) flex项的序号,设置排序,默认值0排第一 排序索引,数字
<style> .flex { display: flex; flex-flow: row wrap; align-items: stretch; justify-content: stretch; } /*注意这里,一般用子代选择器*/ .flex>div { flex: 1 200px; background-color: #9be6bd; padding: 10px; } .flex>div:nth-child(even){ background-color: #eeb2cb; }</style><div class="flex"> <div><b> div1:</b> <p>Flexbox 是 CSS 弹性盒子布局模块(Flexible Box Layout Module)的缩写</p> </div> <div>div2:</div> <div>div3:</div> <div>div4:</div> <div>div5:</div></div>
image.png

下面代码为基于flex的栅格布局(12格),可以自动等比例划分网格,比float浮动的栅格方便多了。

.row { display: flex;} .col { margin-left: 2.08333333%; margin-bottom: 1em; width: 6.25%; flex: 1 1 auto; background: rgb(255,150,150);}

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

grid布局是一个二维布局系统,通过设置定义一个网格,然后子元素按照顺序排列网格,或者设置其行列网格坐标。一个gird网格通常具有许多的行(row)与 列(column),以及行与行、列与列之间的间隙,这个间隙一般被称为沟槽(gutter /ˈɡʌtər/水沟)。

属性 描述 值/补充
display: grid; 父元素启用grid布局 还可以设置为inline-grid,行内网格
grid-template-rows
grid-template-columns IE10
定义行/列的二维网格,一个参数为一行/列,多行/列定义多个值,空格隔开
grid-template-columns: 200px max-content 100px auto auto; /* 5列 */
auto:自动排列;max-content:最大内容区域
尺寸值:px、em、%
● 比例单位fr2fr 1fr 1fr; 比例系数
minmax()函数:minmax(100px,auto),区间值
repeat()函数:repeat(2, 2fr 1fr),重复创建行列
grid-template-areas IE🚫 区域网格命名:按照区域命名的网格布局,先定义区域,在给子元素设置区域名称 ● 字符串命名,空格隔开,.标识空的格子
● 每个命名为一个单元格,同名合并格子
 grid-area(子元素) 给子元素设置区域名 grid-area: left
grid-template IE🚫 定义行列,上面rows / columns、areas的简写 grid-template: 50px 1fr / 150px 1fr;
grid-gapgap IE🚫 定义行、列的间隙,等同于gap grid-gap: 10px 20px; gap /ɡæp/ 缝隙
 row-gap 行间间隙 row-gap: 5px;
 column-gap 列间间隙 column-gap: 10px;
grid-auto-rowsIE10 自动设定隐式网格的大小-行网格-高度 grid-auto-rows:50px;
grid-auto-columns 自动设定隐式网格的大小-列网格-宽度 grid-auto-columns: 1fr;
grid-column(子元素)、
grid-row(子元素) IE🚫
设置子元素网格线序号坐标(行/列),注意这里的坐标是网格的行列分割线,不是单元格 auto、auto-fill:自动排列
行列坐标序号 grid-column: 2;
跨行列坐标,起
/
始坐标位置grid-column: 1 / 3;
/span跨行列数量:[开始坐标 /span [跨单元格数量]
其他:单位/函数 描述 值/补充
flex:fr (IE🚫) 网格(grid)可变长度单位 grid-template-columns: 200px 1fr 1fr;
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 { display: grid; grid-template-columns: 200px max-content 100px auto 10%; grid-template-rows: 100px auto; /* 两行布局:行定义/列定义 */ grid-template: minmax(100px,auto) 40px/ 200px 1fr 1fr; /* 两行三列命名布局,子元素需指定名称 grid-area */ grid-template-areas: "head head right" "nav main right"; grid-auto-rows: 50px; /* 网格间隙距离 */ row-gap: 5px; column-gap: 10px; grid-gap: 5px 10px;}.grid div:first-child{ /* 跨2个格子,两种方式 */ grid-column: 1/3; grid-column: 1 /span 2; /* 命名布局,指定命名格子 */ grid-area: right;}

🔸隐式网格

通过grid-template-columns grid-template-rowsgrid-template等显示申明创建的网格为显示网格,当子元素超出时会自动换行进行网格排列,这部分称为隐式网格,隐式网格的大小默认是auto(根据内容自适应),可以通过grid-auto-rowsgrid-auto-columns来设置隐式行列网格的尺寸大小。

🔸网格分割线

网格线是从头开始的,一般来说n行有n + 1根水平网格线,m列有m + 1根垂直网格线。设置子元素的网格坐标grid-row / grid-column时,用的坐标是基于网格线的,而不是格子。

image
<style> .from { display: grid; grid-gap: 8px 5px; /* 设置行列网格 */ grid-template-columns: repeat(2, 80px minmax(120px, 1fr)); grid-template-rows: repeat(3, minmax(40px, auto)); grid-auto-rows: minmax(40px, auto); /* 合并的写法 */ grid-template: repeat(2, minmax(36px, auto)) / repeat(2, 80px minmax(180px, 1fr)); } .from * { box-sizing: border-box; padding: 3px; margin: 0px; background-color: lightyellow; } .from label { display: flex; padding: 0 3px; align-items: center; justify-content: right; } .from>.form-cell { display: flex; padding: 0 10px; align-items: center; } .from>textarea { grid-column: 2/5; grid-column: 2/span 3; resize: none; }</style><div class="from"> <label for="">姓名:</label><input type="text"> <label for="">籍贯:</label><input type="text"> <label for="">性别:</label> <div class="form-cell"> <input type="radio"><label for="">男</label>   <input type="radio"><label for="">女</label> </div> <label for="">生日:</label><input type="date"> <label for="">简介:</label><textarea name="" id="" cols="100" rows="5">1111</textarea></div>
image.png

🔸区域网格命名

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

  • 区域字符命名,行内空格分割列,行间引号分割。两行三列:grid-template-areas: "head head right" "nav main right";
  • 相同命名的格子自动合并单元格,且必须为一个相邻的矩形。
  • 所有名字只能出现在一个连续的区域,不能在不同的位置出现。
  • 使用.符号,让一个格子留空,就是空着,啥也不干。
<style> .page{ display: grid; /*定义2列、3行*/ grid-template-areas: "header header" "left right" "footer footer"; /*图1布局*/ grid-template-areas: "left header" "left right" "footer right"; /*图2布局*/ grid-template-rows: 40px 1fr 40px; grid-template-columns: minmax(100px,200px) auto; height: 300px; margin: 10px; } .page>.header{grid-area: header;} .page>.left{grid-area: left;background-color: lemonchiffon; } .page>.right{grid-area: right;background-color: rgb(170, 236, 238); } .page>.footer{grid-area: footer;} .page>div{background-color: aquamarine;padding: 10px; }</style><div class="page"> <div class="header">header</div> <div class="left">left</div> <div class="right">right</div> <div class="footer">footer</div></div>

» 调整命名即可实现不同的布局:

image.png
image.png

03、float浮动布局

float 属性让素左右浮动起来,元素从正常布局流 (normal flow) 中移除,会浮动到父容器的左侧或右侧。会改变元素本身和跟随他后面的(不管层级、类型)其他正常流布局元素的行为,它后面的正常布局的元素围绕该浮动元素,并填满其右侧(或左侧)的空间。因为float脱离了文档流,正常流的元素就会和他重叠,但元素的content内容不重叠,就会产生环绕效果。

属性 描述
float 设置元素浮动布局 ● left:将元素浮动到左侧。
● right:将元素浮动到右侧。
clear 适用于浮动和非浮动元素,清除浮动效果 ● none:元素不会被向下移动以清除浮动。
● left:元素被向下移动以清除左浮动
● right:元素被向下移动以清除右浮动
● both:元素被向下移动以清除左右浮动
<div> <img src="/res/qq-128.png" width="80" style="float:left"> <img src="/res/vedio.png" width="80" style="float:right"> <p style="background-color:#0001;">所有元素都是一个盒子Box,盒子Box是页面布局的基本单位,盒子的不同类型决定了他的布局方式。一个页面由各种盒子的组合、嵌套形成。</p></div>
image.png

flexgrid网格布局问世之前,float是实现页面布局的重要手段,他也存在一些惨无人道的问题,可以参考上一章节BFC部分内容。

  • 使用float布局必须精心计算他们的宽度,还要考虑他们的padding、border、margin,推荐启用代替IE盒模型,避免不受控的溢出。
  • 而且他本质上还是一维的,不支持跨行。
  • 浮动使用的越复杂,清除也会越复杂,应尽早清除,避免给后面的元素造成麻烦。推荐在浮动布局后添加一个空的清除浮动div。

下面的示例代码就是典型的传统基于float浮动实现的栅格布局,把列等分为12份,并穷举创建横跨2-12列的样式类,代码量多,点都不优雅。

body { width: 90%; max-width: 980px; margin: 0 auto;}*{box-sizing: border-box;}/* row用来清除row之间的浮动影响 */.row { clear: both;}.col { float: left; margin-left: 2.08333333%; width: 6.25%;}.col.span2 { width: calc((6.25%*2) + 2.08333333%); }.col.span3 { width: calc((6.25%*3) + (2.08333333%*2)); }.col.span4 { width: calc((6.25%*4) + (2.08333333%*3)); }/*...*/.col.span12 { width: calc((6.25%*12) + (2.08333333%*11)); }/* 用来作为空列的偏移*/.offset-by-one { margin-left: calc(6.25% + (2.08333333%*2));}

» float表单:

<style> .form-float *{ box-sizing: border-box; } .form-float>.row{ clear: both; padding: 5px 0; } .form-float>.row>.col{ float: left; background-color: antiquewhite; padding: 5px; } .form-float>.row>.col.lab{ width: 15%; text-align: right; } .form-float>.row>.col.span1{ width: 35%; } .form-float>.row>.col.span2{ width: 85%; } .clear{ clear: both; } </style><form class="form-float"> <div class="row" id="r1"> <label for="" class="col lab" id="l1">姓名:</label> <input type="text" class="col span1" value="杜牧"> <label for="" class="col lab">籍贯:</label><input type="text" class="col span1" value="唐"> </div> <div class="row"> <label for="" class="col lab">性别:</label> <div class="col span1"> <input type="radio"><label for="">男</label>   <input type="radio"><label for="">女</label> </div> <label for="" class="col lab">生日:</label><input type="date" class="col span1"> </div> <div class="row"> <label for="" class="col lab">简介:</label> <textarea name="" id="" cols="100" rows="5" class="col span2">停车坐爱枫林晚,霜叶红于二月花</textarea> </div></form><div class="clear"></div>
image.png

🔸清除浮动

脱离正常的文档流,并不会占据正常文档流的位置,如果一个父元素下面都是浮动元素,或正常元素高度低,则会导致父元素的高度坍塌。从而使得后面的正常元素布局出现不希望的情况,常见三种清除方法:

方法 说明
❶ 触发父元素为BFC 🔸 overflow: hidden; 比较常用的方式,缺点是文档超过区域大小后,内容会被隐藏。
🔸 display: flow-root;,新特性,创建无副作用的BFC。
❷ 设置父元素高宽 明确设置父元素的高度、宽度,缺点是不能自适应。
❸ 父级添加伪元素::after,并清空clear ::after中添加一个空的块级盒子,并清除其浮动。clear: both;使左右两边都不允许浮动元素,让后面的非浮动元素的边界移动到所有浮动元素的外边界下方,就强行撑开了高度。
📢注意,这里并没有产生BFC,详情参考 MDN-clear
/* 恢复父元素上的BFC */.parent { overflow: hidden;} /* 在父元素上使用清除clearfix:clear + 伪元素::after实现,附加一个空的块元素并清除 */.clearfix::after { content: ""; display: block; clear: both;}

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


04、position定位

position 可精准设置盒子的位置,正常布局流中,元素的position默认值为 static。使用其它值可实现元素不同的定位,结合偏移top, bottom, left, right使用,如果不设置偏移,则元素还是原来的位置。

❗定位并不是一种常规的布局方式,主要用于一些特殊位置的实现。

属性/值 描述 值/示例
position 设置元素定位方式
 static 静态定位,就是正常文档流位置,所有元素的默认值,此时设置偏移无效 position: static;
relative 相对定位 (relative /ˈrelətɪv/),在文档流的基础上,相对于自己位置的偏移定位,位置保留。不影响其他元素,可能会和其他元素重叠。 position: relative;
absolute 绝对定位 (/ˈæbsəluːt/),脱离文档流,就像单独一个图层中,不干扰其他元素布局。相对于最近一个非**static**定位的父元素(直到根元素),常用于弹出层(消息、菜单) position: absolute;
 fixed 固定定位,和absolute基本一样,脱离文档流,定位的对象是浏览器视口,可实现不滚动的固定内容。 position: fixed;
 sticky 粘性定位 (sticky /ˈstɪki/ 黏性的)IE🚫,_静态定位+固定定位 _fixed的结合体,先静态定位,当元素满足预定条件时(达到相对于视口的定位),进入固定定位fixed模式。
注意:sticky 元素会“固定”在离它最近的一个拥有“滚动机制”的父元素上
position: sticky;
top 顶部偏移:元素的上外边距边界与其包含块上边界之间的偏移,只用于定位 top: -50px;
bottom 底部偏移,只用于定位。若与top同时设置,都会生效,如有固定heighttop优先生效 bottom: 10px;
left 左侧偏移,只用于定位
right 右侧偏移,只用于定位
z-index z轴坐标,用于元素上下层叠顺序控制,默认auto=0,值越大层级越高。 z-index:-1;
<style> .btn-top{ display: block; font-size: 30px; font-weight: bold; width: 50px; height: 50px; line-height: 50px; border-radius: 50%; opacity: 0.5; text-align: center; text-decoration: none; background-color: #eeb2cb; /* 定位 */ position: fixed; bottom: 10px; right: 10px; } .btn-top:hover{ opacity: 1; background-color: coral; }</style><a href="#" class="btn-top" title="回到顶部">🔝</a>

image.png

» 回到顶部字符:🔝


05、表格布局(display:table)

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

属性值 描述
display: table 表格布局
display: table-row 类似表格的<tr>
display:table-row-group 类似表格的<tbody>
display: table-cell 类似表格的单元格<td>
vertical-align 单元格内容垂直对齐,可应用于垂直居中

» 表格布局-表单

<style> .form-table { display: table; width: 100%; border: 1px solid lightgray; } .form-table .trow { display: table-row; background-color: linen; } .form-table .trow>label{ display: table-cell; width: 100px; line-height: 40px; text-align: right; } .form-table .trow>input,.form-table textarea{ display: table-cell; width: 90%; }</style><div class="form-table"> <div class="trow"> <label for="" id="l1">姓名:</label><input type="text" value="杜牧"> <label for="">籍贯:</label><input type="text" value="唐"> </div> <div class="trow"> <label for="">性别:</label> <div> <input type="radio"><label for="">男</label>   <input type="radio"><label for="">女</label> </div> <label for="">生日:</label><input type="date"> </div </div><div class="trow"> <label for="">简介:</label> <textarea name="" id="" rows="4" colspan="3">不知道怎么实现跨行</textarea></div></div>
image.png

06、column-count多列布局

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

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

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

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

» 没有加break-inside的效果,文章块被折断

image.png
image.png

©️版权申明:版权所有@安木夕,本文内容仅供学习,欢迎指正、交流,转载请注明出处!原文编辑地址-语雀
HTML元素大全(2)-表单


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK