flex 布局
一、定义
Flex 是 Flexible Box 的缩写,意为"弹性布局",用来为盒状模型提供最大的灵活性。
任何一个容器都可以指定为 Flex 布局
.box{
display: flex;
display: -webkit-flex; /* Safari */ // Webkit 内核的浏览器,必须加上-webkit前缀
}
// 若box为行内元素 display: inline-flex;
注:设为 Flex 布局后,子元素的float
、clear
和vertical-align
属性将失效
二、容器的属性(父级 盒子box)
1、justify-content 定义了项目在主轴(horizontal-align(水平方向))上的对齐方式
.box {
justify-content: flex-start | flex-end | center | space-between | space-around;
}
flex-start
(默认值):左对齐flex-end
:右对齐center
: 居中space-between
:两端对齐,项目之间的间隔都相等。space-around
:每个项目两侧的间隔相等。所以,项目之间的间隔比项目与边框的间隔大一倍
2、align-items
定义项目在交叉轴(vertical-align(垂直方向))上对齐方式
.box {
align-items: flex-start | flex-end | center | baseline | stretch;
}
flex-start
:交叉轴的起点对齐。flex-end
:交叉轴的终点对齐。center
:交叉轴的中点对齐。baseline
: 项目的第一行文字的基线对齐。stretch
(默认值):如果项目未设置高度或设为auto,将占满整个容器的高度
3、align-content
定义了多根轴线的对齐方式。如果项目只有一根轴线,该属性不起作用
.box {
align-content: flex-start | flex-end | center | space-between | space-around | stretch;
}
flex-start
:与交叉轴的起点对齐。flex-end
:与交叉轴的终点对齐。center
:与交叉轴的中点对齐。space-between
:与交叉轴两端对齐,轴线之间的间隔平均分布。space-around
:每根轴线两侧的间隔都相等。所以,轴线之间的间隔比轴线与边框的间隔大一倍。stretch
(默认值):轴线占满整个交叉轴
4、flex-direction
决定主轴的方向(即项目的排列方向)
.box {
flex-direction: row | row-reverse | column | column-reverse;
}
row
(默认值):主轴为水平方向,起点在左端。row-reverse
:主轴为水平方向,起点在右端。column
:主轴为垂直方向,起点在上沿。column-reverse
:主轴为垂直方向,起点在下沿。
5、flex-wrap
定义一条轴线排不下,换行方式;默认情况下,项目都排在一条线(又称"轴线")上
.box{
flex-wrap: nowrap | wrap | wrap-reverse;
}
nowrap
(默认):不换行。wrap
:换行,第一行在上方 顺序。wrap-reverse
:换行,第一行在下方 反序。
6、flex-flow
flex-direction
属性和flex-wrap
属性的简写形式,默认值为row nowrap
.box {
flex-flow: <flex-direction> || <flex-wrap>;
}
三、项目属性(子级 盒子中的个体item内容)
1、order
定义项目的排列顺序。数值越小,排列越靠前,默认为0
.item {
order: <integer>;
}
2、flex-grow
定义项目的放大比例,默认为0
,即如果存在剩余空间,也不放大
.item {
flex-grow: <number>; /* default 0 */
}
注:如果所有项目的flex-grow
属性都为1,则它们将等分剩余空间(如果有的话)。如果一个项目的flex-grow
属性为2,其他项目都为1,则前者占据的剩余空间将比其他项多一倍
3、flex-shrink
定义了项目的缩小比例,默认为1,即如果空间不足,该项目将缩小
.item {
flex-shrink: <number>; /* default 1 */
}
注:如果所有项目的flex-shrink
属性都为1,当空间不足时,都将等比例缩小。如果一个项目的flex-shrink
属性为0,其他项目都为1,则空间不足时,前者不缩小。负值对该属性无效。
4、flex-basis
定义了在分配多余空间之前,项目占据的主轴空间(main size)。浏览器根据这个属性,计算主轴是否有多余空间。它的默认值为auto
,即项目的本来大小
.item {
flex-basis: <length> | auto; /* default auto */
}
注:它可以设为跟width
或height
属性一样的值,则项目将占据固定空间
5、flex
是flex-grow
, flex-shrink
和 flex-basis
的简写,默认值为0 1 auto
。后两个属性可选
.item {
flex: none | [ <'flex-grow'> <'flex-shrink'>? || <'flex-basis'> ]
}
注:该属性有两个简写值:auto
(1 1 auto
) 和 none (0 0 auto
)
box的width * ( 1 - items的flex-basis) = flex-grow的空间
itemX所占空间比例=flex-grow的空间/(item1+ite2+item3)的flex-grow * itemXd的的flex-grow
***********
flex
的默认值是 「0 1 auto」 简写 「flex: 0 auto」或者「flex: initial」
flex:
none
,则计算值为 「0 0 auto」
flex:
auto
,则计算值为 「1 1 auto」
flex:
一个非负数字m, 则计算值为 「m 1 0%」
flex:
一个长度或百分比m,则计算值为 「1 1 m」
flex:
两个非负数字m,n,则计算值为 「m n 0%」
flex:
一个非负数字m和一个长度或百分比n,则计算值为 「m 1 n」
***********
计算公式:
flex-grow 是扩展比率
flex-shrink 是收缩比率
flex-basis 伸缩基准值
1、flex-basis总和 与 父级宽度 比较
计算剩余值/溢出值 (取绝对值)
剩余值/溢出值 = 父级宽度 - flex-basis总和
1.flex-basis总和 > 父级宽度
flex-basis总和加起来为1000px; 那么 1000px > 800px (父级的宽度);子元素势必要压缩;溢出了200px;
1.1 计算加权值
son1 = (flex-shrink) * flex-basis;
son2 = (flex-shrink) * flex-basis;
…..
sonN = (flex-shrink) * flex-basis;
加权值 = son1 + son2 + …. + sonN;
1.2 计算被压缩值
压缩值 _w = (子元素flex-basis值 * (子元素flex-shrink值) / 加权值) * 溢出值
1.3 计算最后的实际宽度
压缩后的宽度 w = 子元素flex-basis值 - _w
2.flex-basis总和 < 父级宽度
2.1 计算扩展值
扩展值 _w = (子元素flew-grow值 / flew-grow总和) * 剩余值
2.2 计算最后实际宽度
扩展后的宽度 w = 子元素flex-basis值 + _w
flex-basis
规定的是子元素的基准值,所以是否溢出的计算与此属性息息相关
flex-basis
规定的范围取决于 box-sizing
。这里主要讨论以下 flex-basis
的取值情况:
-
auto
:首先检索该子元素的主尺寸,如果主尺寸不为auto
,则使用值采取主尺寸之值;如果也是auto
,则使用值为content
。 -
content
:指根据该子元素的内容自动布局。有的用户代理没有实现取content
值,等效的替代方案是flex-basis
和主尺寸都取auto
。 -
百分比:根据其包含块(即伸缩父容器)的主尺寸计算。如果包含块的主尺寸未定义(即父容器的主尺寸取决于子元素),则计算结果和设为
auto
一样。
6、align-self
允许单个项目有与其他项目不一样的对齐方式,可覆盖align-items
属性。默认值为auto
,表示继承父元素的align-items
属性,如果没有父元素,则等同于stretch
.item {
align-self: auto | flex-start | flex-end | center | baseline | stretch;
}
注:该属性可能取6个值,除了auto,其他都与align-items属性完全一致
四、总结:
1、图解
https://img.mukewang.com/58b27b7c00012f3c12430476.jpg
2、实例 demo
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>flex-demo</title> 6 <style> 7 /*骰子的布局*/ 8 .box { 9 display: flex; 10 width: 50px; 11 height: 50px; 12 border: 1px solid #ccc; 13 border-radius: 2px; 14 } 15 .box .item{ 16 display: inline-block; 17 width: 10px; 18 height: 10px; 19 margin:3px; 20 border-radius: 50%; 21 background: #000; 22 } 23 /*中上(1,0)*/ 24 .c2{ 25 justify-content: center; 26 } 27 /*右上(2,0)*/ 28 .c3{ 29 justify-content: flex-end; 30 } 31 /*左间(0,1)*/ 32 .c4{ 33 align-items: center; 34 } 35 /*左下(0,2)*/ 36 .c5{ 37 align-items: flex-end; 38 } 39 /*中间(1,1)*/ 40 .c6{ 41 justify-content: center; 42 align-items: center; 43 } 44 /*右间(2,1)*/ 45 .c7{ 46 justify-content: flex-end; 47 align-items: center; 48 } 49 50 /*中下(1,2)*/ 51 .c8{ 52 justify-content: center; 53 align-items: flex-end; 54 } 55 /*右下(2,2)*/ 56 .c9{ 57 justify-content: flex-end; 58 align-items: flex-end; 59 } 60 /*两个*/ 61 /*space-between*/ 62 .c21{ 63 justify-content: space-between; 64 } 65 /*两个flex-direction+column*/ 66 .c22{ 67 justify-content: space-between; 68 flex-direction: column; 69 } 70 /*2.3两个space-between+flex-direction+ align-items*/ 71 .c23{ 72 justify-content: space-between; 73 flex-direction: column; 74 align-items: center; 75 } 76 /*2.4两个space-between+flex-direction+ align-items*/ 77 .c24{ 78 justify-content: space-between; 79 flex-direction: column; 80 align-items: flex-end; 81 } 82 /*2.5两个space-between+flex-direction+ align-items*/ 83 84 .c25 .item:nth-child(2) { 85 align-self: center; 86 } 87 /*2.6两个space-between+flex-direction+ align-items*/ 88 .c26{ 89 justify-content: space-between; 90 } 91 .c26 .item:nth-child(2) { 92 align-self: flex-end; 93 } 94 95 /*3.1三个align-self:center+flex-end*/ 96 97 .c31 .item:nth-child(2) { 98 align-self: center; 99 } 100 .c31 .item:nth-child(3) { 101 align-self: flex-end; 102 } 103 /*4.1四个*/ 104 .c41 { 105 flex-wrap: wrap; 106 justify-content: flex-end; 107 align-content: space-between; 108 } 109 /*4.2四个*/ 110 .c42 { 111 flex-wrap: wrap; 112 align-content: space-between; 113 } 114 .column { 115 flex-basis: 100%; 116 display: flex; 117 justify-content: space-between; 118 } 119 /*6.1六个*/ 120 .c61{ 121 flex-wrap: wrap; 122 } 123 .row{ 124 flex-basis: 100%; 125 display:flex; 126 } 127 128 .row:nth-child(2){ 129 justify-content: center; 130 } 131 132 .row:nth-child(3){ 133 justify-content: space-between; 134 } 135 /*九个*/ 136 .c9{ 137 flex-wrap: wrap; 138 } 139 140 /*网格布局*/ 141 /*基本*/ 142 .Grid { 143 display: flex; 144 } 145 146 .Grid-cell { 147 flex: 1; 148 } 149 /*百分比布局*/ 150 .Grid-cell.u-full { 151 flex: 0 0 100%; 152 } 153 154 .Grid-cell.u-1of2 { 155 flex: 0 0 50%; 156 } 157 158 .Grid-cell.u-1of3 { 159 flex: 0 0 33.3333%; 160 } 161 162 .Grid-cell.u-1of4 { 163 flex: 0 0 25%; 164 } 165 166 /*圣杯布局圣杯布局(Holy Grail Layout)*/ 167 .fh { 168 display: flex; 169 min-height: 98vh; 170 flex-direction: column; 171 margin: 1rem; 172 } 173 174 .fh-header { 175 display: flex; 176 flex: 1.2; 177 border: 1px solid #ccc; 178 } 179 180 .fh>.fh-middle { 181 flex: 1; 182 border: 1px solid #ccc; 183 margin: 1rem 0; 184 } 185 186 .fh>.fh-footer { 187 flex: 2.5; 188 border: 1px solid #ccc; 189 } 190 191 .fh-content { 192 flex: 1; 193 border: 1px solid #ccc; 194 } 195 196 .fh-nav { 197 /* 边栏的宽度设为20rem */ 198 flex: 0 0 20rem; 199 border: 1px solid #ccc; 200 } 201 202 .fh-nav { 203 /* 导航放到最左边 */ 204 order: -1; 205 margin-right: 1rem; 206 } 207 /*输入框布局*/ 208 .InputAddOn { 209 display: flex; 210 } 211 212 .InputAddOn-field { 213 flex: 1; 214 } 215 /*悬挂式布局*/ 216 .Media { 217 display: flex; 218 align-items: flex-start; 219 } 220 221 .Media-figure { 222 margin-right: 1em; 223 } 224 /*固定低栏*/ 225 .Site { 226 display: flex; 227 min-height: 100vh; 228 flex-direction: column; 229 } 230 231 .Site-content { 232 flex: 1; 233 } 234 /*流式布局*/ 235 .parent { 236 width: 200px; 237 height: 150px; 238 background-color: black; 239 display: flex; 240 flex-flow: row wrap; 241 } 242 243 .child { 244 box-sizing: border-box; 245 background-color: white; 246 flex: 0 0 25%; 247 height: 50px; 248 border: 1px solid red; 249 } 250 </style> 251 </head> 252 <body> 253 <h4>一、骰子的布局(左0中1右2,上0间1下2)</h4> 254 <p>1.1一个左上(0,0):justify-content:flex-start(default);</p> 255 <div class="box c1"> 256 <span class="item"></span> 257 </div> 258 <p>1.2一个中上(1,0):justify-content:center;</p> 259 <div class="box c2"> 260 <span class="item"></span> 261 </div> 262 <p>1.3一个右上(2,0):justify-content:flex-end;</p> 263 <div class="box c3"> 264 <span class="item"></span> 265 </div> 266 <p>1.4一个左间(0,1) 267 :align-items: center;</p> 268 <div class="box c4"> 269 <span class="item"></span> 270 </div> 271 <p>1.5一个左下(0,2):align-items: flex-end;</p> 272 <div class="box c5"> 273 <span class="item"></span> 274 </div> 275 <p>1.6一个中间(1,1):justify-content: center;align-items:center;</p> 276 <div class="box c6"> 277 <span class="item"></span> 278 </div> 279 <p>1.7一个右间(2,1):justify-content:flex-end;align-items:center;</p> 280 <div class="box c7"> 281 <span class="item"></span> 282 </div> 283 <p>1.8一个中下(1,2) :justify-content:center;align-items:flex-end;</p> 284 <div class="box c8"> 285 <span class="item"></span> 286 </div> 287 <p>1.9一个右下(2,2) justify-content: flex-end; 288 align-items: flex-end;</p> 289 <div class="box c9"> 290 <span class="item"></span> 291 </div> 292 <p>2.1两个space-between</p> 293 <div class="box c21"> 294 <span class="item"></span> 295 <span class="item"></span> 296 </div> 297 <p>2.2两个space-between+flex-direction</p> 298 <div class="box c22"> 299 <span class="item"></span> 300 <span class="item"></span> 301 </div> 302 <p>2.3两个space-between+flex-direction+ align-items</p> 303 <div class="box c23"> 304 <span class="item"></span> 305 <span class="item"></span> 306 </div> 307 <p>2.4两个space-between+flex-direction+ align-items:flex-end</p> 308 <div class="box c24"> 309 <span class="item"></span> 310 <span class="item"></span> 311 </div> 312 <p>2.5两个align-self</p> 313 <div class="box c25"> 314 <span class="item"></span> 315 <span class="item"></span> 316 </div> 317 <p>2.6两个align-self</p> 318 <div class="box c26"> 319 <span class="item"></span> 320 <span class="item"></span> 321 </div> 322 323 <p>3.1三个align-self:center+flex-end</p> 324 <div class="box c31"> 325 <span class="item"></span> 326 <span class="item"></span> 327 <span class="item"></span> 328 </div> 329 <p>4.1四个</p> 330 <div class="box c41"> 331 <span class="item"></span> 332 <span class="item"></span> 333 <span class="item"></span> 334 <span class="item"></span> 335 </div> 336 <p>4.2四个</p> 337 <div class="box c42"> 338 <span class="column"> 339 <span class="item"></span> 340 <span class="item"></span> 341 </span> 342 <span class="column"> 343 <span class="item"></span> 344 <span class="item"></span> 345 </span> 346 </div> 347 <p>6.1六个</p> 348 <div class="box c61"> 349 <div class="row"> 350 <span class="item"></span> 351 <span class="item"></span> 352 <span class="item"></span> 353 </div> 354 <div class="row"> 355 <span class="item"></span> 356 </div> 357 <div class="row"> 358 <span class="item"></span> 359 <span class="item"></span> 360 </div> 361 </div> 362 <p>9九个</p> 363 <div class="box c9"> 364 <span class="item"></span> 365 <span class="item"></span> 366 <span class="item"></span> 367 <span class="item"></span> 368 <span class="item"></span> 369 <span class="item"></span> 370 <span class="item"></span> 371 <span class="item"></span> 372 <span class="item"></span> 373 </div> 374 <h2>二、网格布局</h2> 375 376 <p>2.1基本网格布局</p> 377 <div class="Grid"> 378 <div class="Grid-cell">Grid-cell</div> 379 <div class="Grid-cell">Grid-cell</div> 380 <div class="Grid-cell">Grid-cell</div> 381 </div> 382 <p>2.2百分比布局</p> 383 <div class="Grid"> 384 <div class="Grid-cell u-1of4">u-1of4</div> 385 <div class="Grid-cell">... 386 <!-- <div class="div wrap"> --> 387 <div style="float: left;">1</div> 388 <div style="float: left;">2</div> 389 <div style="float: left;">3</div> 390 <!-- </div> --> 391 </div> 392 <div class="Grid-cell u-1of3">u-1of3</div> 393 </div> 394 395 <h2>三、圣杯布局</h2> 396 <div class="fh"> 397 <header class="fh-header"> 398 <nav class="fh-nav">nav</nav> 399 <main class="fh-content">mian</main> 400 </header> 401 <div class="fh-middle">middle</div> 402 <footer class="fh-footer">footer</footer> 403 </div> 404 405 <h2>四、输入框的布局</h2> 406 <div class="InputAddOn"> 407 <span class="InputAddOn-item">icon</span> 408 <input class="InputAddOn-field"> 409 <button class="InputAddOn-item">btn</button> 410 </div> 411 412 <h2>五、悬挂式布局</h2> 413 <div class="Media"> 414 <img class="Media-figure" src="https://img.mukewang.com/58b27bb400017ac206010476.jpg" alt="aa"> 415 <p class="Media-body">哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈</br></br></br></br></br></br></br>哈哈哈哈哈哈哈...</br></br></br></br></br></br></br></br></br></br>哈哈哈哈哈哈哈...</br></br></br></br></br></br></br></br></br></br></br></br></br></br></br>哈哈哈哈哈哈哈...</p> 416 </div> 417 418 <h2>六、固定低栏</h2> 419 <div class="site"> 420 <header>header</header> 421 <main class="Site-content">main </main> 422 <footer>footer</footer> 423 </div> 424 425 <h2>七、流式布局</h2> 426 <div class="parent"> 427 <span class="child"></span> 428 <span class="child"></span> 429 <span class="child"></span> 430 <span class="child"></span> 431 <span class="child"></span> 432 <span class="child"></span> 433 <span class="child"></span> 434 <span class="child"></span> 435 <span class="child"></span> 436 </div> 437 </body> 438 </html>
参考:https://www.imooc.com/article/16494?block_id=tuijian_wz
http://www.ruanyifeng.com/blog/2015/07/flex-grammar.html
https://www.cnblogs.com/lvmylife/p/7670149.html
https://zhuanlan.zhihu.com/p/24372279 详解 flex-grow 与 flex-shrink - 知乎