flex 弹性盒子

1. 弹性盒基础

弹性盒子是一种简单而强大的布局方式,我们可以通过弹性盒子指明空间的分布方式内容的对齐方式元素的视觉顺序。内容可以轻易地横向排列或者纵向排列,也可以沿着某一条轴布局。

弹性盒子最突出的一个特点,能让元素在不同屏幕尺寸下或者不同显示设备做好适应准备,因为内容可以根据空间的大小增减尺寸。

弹性盒子依赖的是父子关系。在父元素上面声明 display: flex 来创建一个弹性容器,它主要负责内部子元素的布置,控制子元素的布局。在弹性容器中的这些子元素,一般都叫弹性元素

display: flex;

2. 弹性容器

首先要完全理解的概念是弹性容器display: flex 声明的目标元素会成为弹性容器,容器内部的元素,不管是DOM节点还是文本还是生成的内容,都称为弹性元素。弹性容器中,绝对定位的元素也叫弹性元素,不过确定其尺寸和位置时,需要将这个弹性元素视为弹性容器中唯一一个弹性元素。

2.1 flex-direction

首先从布局的大体来看,首先要决定元素的布局排列方式:从上到下、从左到右,还是其他的排列方式。这时,可以通过 flex-direction 来改变布局顺序。

flex-direction: row | row-reverse | column | column-reverse;

该属性置顶在弹性容器中如何摆放弹性元素,即定义弹性容器的主轴,弹性元素默认会按这条主轴方向进行排列。

2.2 flex-wrap

在flex布局中,当弹性元素个数过多时,并且超过了弹性容器的宽度,这时默认情况下会将子元素进行挤压,然后放在同一行主轴上进行排列。默认情况下,弹性元素不会进行换行,并且允许元素缩减尺寸。

同样的,我们可以通过 flex-wrap 来让元素进行换行处理。

flex-wrap: nowrap | wrap | wrap-reverse;
  • nowrap:默认值,元素不换行;
  • wrap:元素允许换行;
  • wrap-reverse:只是决定多出的行显示在第一行之后。

3. 布置弹性元素

为什么所有元素都按主轴起边一侧紧挨在一起?

3.1 元素在主轴上的分布方式

justify-content: flex-start | flex-end | center | space-around | space-between | space-evenly;
  • flex-start:默认值,弹性元素紧靠主轴的起始边;
  • flex-end:弹性元素紧靠主轴的终边进行排列,与 flex-direction: row-reverse 不同,这个仅仅是将元素贴着终边排列,没有改变元素视觉上的布局顺序;
  • center:把弹性元素作为一个整体,居中显示在主轴尺寸的中点
  • space-around:把余下的空间拆分开,然后平均地分配给每一个弹性元素,看起来就像每个元素四周都有等量的外边距;这里要注意普通元素的外边距是第一个元素或最后一个元素与弹性容器间距离的两倍;
  • space-between:把每一行里的第一个弹性元素放在主轴的起始边,最后一个元素放在主轴的终边,然后剩下的每一对相邻的弹性元素之间放置等量的空白(外边距);
  • space-evenly:把余下的空间平均拆分分配到每个元素上。
3.1.1 flex-start 和 flex-end

flex-start 是默认行为,即所有弹性元素都向主轴的起边靠拢,每一行里的第一个弹性元素都紧靠主轴起始边的一侧;

flex-end 则是在一行里的最后一个弹性元素向主轴的终边靠拢,前面各弹性元素紧挨后一个弹性元素;

3.1.2 center

当设置为center时,所有弹性元素会挤在一起,然后统一居中显示在主轴中点处,而不再向主轴起边或者终边靠拢。如果空间放不下躲雨的弹性元素,并且不允许换行,则会进行挤压容纳。

3.1.3 space-between

这个属性,一行里的第一个弹性元素向主轴起始边靠拢,一行里的最后一个元素在主轴终边靠拢。当主轴元素上只存在一个弹性元素时,它不会居中,而是会将它放在主轴的起始边。

3.1.4 space-around

一行中额外的空白将均匀分布在弹性元素的周围。当一行中只有一个元素,这个元素将会居中显示。

3.2 元素在侧轴上的分布方式

justify-content 定义弹性元素在弹性容器主轴方向上的对齐方式,而 align-items 属性定义的是弹性元素在侧轴上的对齐方式。

align-items: flex-start | flex-end | center | baseline;
3.2.1 起边对齐、终边对齐、居中对齐

这三个值是最常见,效果也相对简单的属性值。

flex-start 将各弹性元素在侧轴起始边处开始进行排列,这也是默认的显示方式;

flex-end 将各元素在侧轴的终边开始进行排列;

center 将弹性元素的中点与所在行的侧轴中点进行对齐,这也是我们常用的居中对齐的方法。

3.2.2 align-self

如果想改变某个或某些弹性元素的对齐方式,而不是修改全部弹性元素,那就可以用到 align-self 这个属性,这个属性的取值和 align-items 一样,只不过这个属性只会作用在当前弹性元素上。

将奇数弹性元素进行侧轴上的居中对齐

li:nth-child(odd) {
  align-self: center;
}

4. 对齐内容

align-content: flex-start | flex-end | center | space-between | space-around | space-evenly;

该属性定义弹性容器有额外空间时,在侧轴方向上如何对齐各弹性元素行

与之前的属性 align-items 比较,align-content 属性指定的是容器中侧轴方向上额外空间如何分配到弹性元素行之间和周围,而 align-items 则是指定每一行弹性元素的分布位置,虽然在效果上会有相似的地方,但是实际上的作用是完全不同的。

align-content 它的默认值并不是 flex-start ,而是一个叫 stretch 的属性值。这个属性值,将额外的空间平均分配到每个弹性元素中,增加行的侧轴尺寸,直到边与边重合。这也是导致我们弹性元素换行时,没有紧跟上一行元素的罪魁祸首。

5. flex 属性

flex: <flex-grow> <flex-shrink> <flex-basis> | none;

弹性布局最突出的一点,就是把弹性元素变得具有弹性,在主轴方向上调整弹性元素的宽度或者高度,可以占满可用的空间。弹性容器会根据弹性增长因子分配额外的空间或者根据弹性缩减因子按比例缩小元素,以防溢出。

5.1 flex-grow

弹性增长因子。该属性定义有多余空间时,是否允许弹性元素增大,以及允许增大且有多余空间时,相对其他同辈的元素以多大的比例去增大。简单来说,如果弹性容器有多余的空间,这空间将会按照弹性增长因子的比例去分配给各个弹性元素。

flex-grow: <number>;
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            list-style: none;
            text-decoration: none;
        }

        .father {
            width: 750px;
            height: 400px;
            background-color: pink;
            display: flex;
        }

        .son {
            width: 100px;
            height: 100px;
            background-color: skyblue;
            line-height: 100px;
            box-sizing: border-box;
            border: 1px solid #000;
            font-size: 30px;
        }

        .sonC{
            flex-grow: 1;
        }
    </style>
</head>

<body>
    <div class="father">
        <div class="son sonA"></div>
        <div class="son sonB"></div>
        <div class="son sonC"></div>
    </div>
</body>

</html>

当设置 .sonC 的增长因子为1时,多余的空间将会按照 0:0:1 的比例分配到每个元素上,0就代表不分配,这样就会把剩余的空间全都添加到 .sonC 元素上。

flex-grow 虽然可以设置很大的数值,但是实际上看的是每个元素之间的比例大小。1:1:2 和 20:20:40 带来的效果是一样的。

5.2 flex-shrink

该属性指的是弹性缩减因子,当弹性容器定义的空间不足以容纳所有的弹性元素,且不允许换行的情况下,每个弹性元素都会以缩减因子这个比例去缩小宽高。

/* 这个值和 flex-grow 一样,可以取数字,可以小数但不能负数。默认值为 1; */
flex-shrink: <number>;
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            list-style: none;
            text-decoration: none;
        }

        .father {
            width: 750px;
            height: 400px;
            background-color: pink;
            display: flex;
        }

        .son {
            width: 300px;
            height: 300px;
            background-color: skyblue;
            line-height: 100px;
            box-sizing: border-box;
            border: 1px solid #000;
            font-size: 30px;
            flex-shrink: 0;
        }

        .sonA {
            /* flex-grow: 20; */
            flex-shrink: 1;
        }

        .sonB {
            /* flex-grow: 20; */
        }

        .sonC {
            /* flex-grow: 40; */
        }
    </style>
</head>

<body>
    <div class="father">
        <div class="son sonA"></div>
        <div class="son sonB"></div>
        <div class="son sonC"></div>
    </div>
</body>

</html>

按照例子的情况,子元素需要一共缩减150px,才能让sonC容纳进来。通过上面的设置,150px 将会以 1:0:0 的比例在每个弹性元素上进行缩减。所以 sonA 这个元素将会缩减150px。

对于缩减因子,需要注意一个地方:如果某个弹性元素的内部存在无法缩小的元素(例如图片、视频、文字)或者定义了宽高,那么这个弹性元素在达到这个内部元素的宽度时,将会等同于 flex-shrink: 0 时的效果,缩小这个操作将会交给其他弹性元素了。

5.3 flex-basis

我们知道,弹性元素的尺寸受到内容及模型属性的影响,而且可以通过 flex 的几个属性来重置。其中 flex-basis 就定义了弹性元素的初始或者默认尺寸,即根据增长因子和缩小因子分配或减小空间前,弹性元素的大小。

flex-basis: auto | content | <length> | <percentage>;

在效果上,flex-basis 虽然和 width 的效果大体是一样的,但实际上,在 Flex 布局中,弹性元素设置的 width 其实没有任何效果。这里其实并不是 width 直接生效,而是 flex-basis 带来的作用。

回到 flex-basis: auto 这个属性值上,它具体的含义是弹性元素的基本尺寸是根据自身的尺寸来决定的,而自身的尺寸和下面几个因素有关:

  • 盒模型,默认作用在 content-box 上;
  • width 还有 min-widthmax-width 等 CSS 属性;
  • content 内容;

例子一

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            list-style: none;
            text-decoration: none;
        }

        .father {
            width: 750px;
            height: 400px;
            background-color: pink;
            display: flex;
        }

        .son {
            /* width: 200px; */
            flex-basis: 200px;
            height: 300px;
            background-color: skyblue;
            line-height: 100px;
            box-sizing: border-box;
            border: 1px solid #000;
            font-size: 30px;
            flex-shrink: 1;
        }

        .sonA {
            /* flex-grow: 20; */
        }

        .sonB {
            /* flex-grow: 20; */
            flex-shrink: 1;
        }

        .sonC {
            /* flex-grow: 40; */
        }

        /* img {
            width: 250px;
            height: 200px;
        } */

        .test {
            width: 250px;
            height: 200px;
            background-color: yellow;
        }
    </style>
</head>

<body>
    <div class="father">
        <div class="son sonA"></div>
        <div class="son sonB"></div>
        <div class="son sonC">aaaaaaaaaaaaaaaaaaaaaaaaaaa</div>
    </div>
</body>

</html>

因为此时的 content 内容最小宽度超过了 200px,于是 flex-basis: 200px 不会按照宽度来显示,而是按照最小内容宽度显示了。但是通过 width: 200px 来设置的尺寸,则会把弹性元素限制得死死的,字符直接溢出到外面。

5.4 简写属性 flex

按照上面的知识点,我们知道每个子属性的默认值 flex-grow: 0 flex-shrink: 1 flex-basis: auto,在简写属性中,可以这样表达:

flex: 0 1 auto;

在一般开发时,我们都不太需要控制后面两个属性,因为会进行元素的换行处理。所以一般只需要考虑它的增长因子。

flex: 1;

当 flex 属性只有一个值时且是正数时,这个值将会用作增长因子

6. order 属性

在默认情况下,弹性元素的显示和排列顺序在源码中的顺序是一致的。在某些情况下,需要单独改变某个元素的排列位置,比如1,2,3的排列方式改为,1,3,2 的顺序。这时就可以通过 order 来控制。

order改变的只是视觉上的顺序,源码的顺序不会发生改变。比如 Tab 键索引的顺序,不会受到 order 的影响

order: <integer>;

默认值为0,意思是所有元素的顺序都是0,则代表在同一排序组中,元素是按照源码中的顺序沿主轴方向进行排列。order 的值,越小越靠前。

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            list-style: none;
            text-decoration: none;
        }

        .father {
            /* width: 750px; */
            height: 900px;
            background-color: pink;
            display: flex;
            flex-wrap: wrap;
        }

        .son {
            width: 100px;
            height: 100px;
            line-height: 300px;
            background-color: skyblue;
            line-height: 100px;
            box-sizing: border-box;
            border: 1px solid #000;
            font-size: 30px;
            text-align: center;
        }

        .sonE {
            order: -1;
        }

        .sonD {
            order: 1;
        }
    </style>
</head>

<body>
    <div class="father">
        <div class="son sonA">1</div>
        <div class="son sonB">2</div>
        <div class="son sonC">3</div>
        <div class="son sonD">4</div>
        <div class="son sonE">5</div>
        <div class="son sonF">6</div>
    </div>
</body>

</html>
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,402评论 6 499
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,377评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,483评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,165评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,176评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,146评论 1 297
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,032评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,896评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,311评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,536评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,696评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,413评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,008评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,659评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,815评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,698评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,592评论 2 353

推荐阅读更多精彩内容

  • 2009年,W3C 提出了一种新的方案----Flex 布局,可以简便、完整、响应式地实现各种页面布局。目前,它已...
    丫3阅读 563评论 0 0
  • 父元素属性 1.display:flex(定义了一个flex容器) 2. flex-direction(决定主轴的...
    柚子硕阅读 256评论 0 1
  • 一、什么是弹性盒子 1.弹性盒子的定义和作用 弹性盒子是 CSS3 的一种新的布局模式。Flex是Flexble ...
    笑该动人d阅读 753评论 0 0
  • 这篇文章主要是分享了Flex弹性盒模型的基本概念, 简要介绍了Flex弹性盒模型的发展历程,最后重点介绍了Flex...
    前白阅读 407评论 0 1
  • 弹性盒子是 CSS3 的一种新的布局模式Flex是Flexible Box的缩写,意为”弹性布局”,用来为盒状模型...
    hi武林高手阅读 934评论 0 4