Bootstrap与移动应用开发
上QQ阅读APP看书,第一时间看更新

任务1 认识Flex弹性盒布局

1.1.1 为什么要使用弹性布局

网站设计使用固定宽度(如960像素)是期望给所有终端用户带来较为一致的浏览体验,但这种固定宽度设计在笔记本上显示刚刚好,而在部分高分辨率显示器上却会在两边出现空白,如图1.1所示。这样的网页对使用高分辨率显示器的用户的体验是极差的。同理,如果设置1263px的固定宽度,在低分辨率的显示器上去浏览,那么就会出现横向的滚动条,需要用户滑动滚动条才能看清楚网页右边的内容,用户体验也是很不好的,如图1.2所示。

图1.1 固定宽度网页在高分辨率下显示效果

图1.2 固定宽度网页在低分辨率下显示效果

那么如何解决上述问题呢?使得无论在何种分辨率下都能让用户很好地浏览网页。下面就来学习弹性布局。

1.1.2 实现弹性布局的方法

读者如果已经掌握了盒子模型和浮动相关的知识,那么接下来就先从一个固定的布局开始入手分析。具体代码如示例1所示。

示例1

<!--省略部分代码--> 
<div class="box clear"> 
    <aside> 
        <h2>热点新闻</h2> 
        <ul> 
            <li><a href="#">后院篮球9月3日于麓山</a></li> 
            <li><a href="#">好久不见,恒大外援阿兰代表预备队出战</a></li> 
            <!--省略部分代码--> 
        </ul> 
    </aside> 
    <article> 
        <p>首页>正文</p> 
 
        <h2>穆帅:我不会被解雇 你们知道曼联要赔我多少钱吗?</h2> 
 
        <p class="time">2018-09-04 07:57:41 来源: 网易体育</p> 
 
        <div> 
            <p> 

英超第4轮,曼联客场击败伯恩利,穆里尼奥拿到了救命的三分。赛后,压力得到释放的穆帅很是开心,他与球迷进行了积极的互动,并将手里的夹克送给球迷。而在接受媒体采访的时候,穆帅表示自己一点都不担心被解雇,他还略带玩笑地说道:“你们知道曼联解雇我得赔多少钱吗?”

            </p> 
<!--省略部分代码--> 

关键的CSS代码如下所示。

.box { 
            width: 960px; 
            border: 1px solid #000000; 
            padding: 10px; 
} 
aside { 
            width: 280px; 
            float: left; 
            background: red; 
            padding: 10px; 
} 
article { 
            margin-left: 10px; 
            width: 650px; 
            float: left; 
            background: yellow; 
 
} 

上述代码在宽屏浏览器中的显示效果如图1.3所示。可以发现,在网页右边出现了一块空白。这是因为网页内容的总宽度是960px,而浏览器的宽度是1424px,所以网页元素右边就会出现多余的空白。

图1.3 宽屏下的显示效果

如果浏览器的宽度很小,又会是什么显示效果呢?具体如图1.4所示。

图1.4 窄屏下的显示效果

从图1.4中可以看出,网页内容有一部分被遮挡住了,需要用户手动滑动横向滚动条才能看到完整的网页。这样的浏览效果对于用户来说体验是非常不好的,接下来介绍两种方法,来解决上述问题。

1. “浮动+百分比”布局

首先来思考一下,为什么示例1中的页面会在不同浏览器尺寸下显示差别那么大?其实是因为结构元素设置了固定宽度。从这个角度出发,如果网页的宽度不是一个固定值,是否就可以具有“弹性”呢?

给网页元素设置宽度一直都习惯使用像素(px)作为单位,其实还有一种单位——百分比。接下来就把示例1的代码用百分比单位稍加修改,具体如下所示。

.box { 
    width: 100%; 
    border: 1px solid #000000;  
    padding: 10px;  
} 
aside { 
    width: 30%; 
    float: left;  
    background: red;  
    padding: 10px;  
} 
article {   
    width: 65%;  
    margin-left: 10px;  
    float: left;  
    background: yellow;  
} 

使用浮动和百分比修改页面后的显示效果如图1.5和图1.6所示。这时候网页的内容就不会再受浏览器宽度的影响了,它会随着浏览器的伸展而伸展、收缩而收缩。

图1.5 “浮动+百分比”布局在宽屏下的显示效果

图1.6 “浮动+百分比”布局在窄屏下的显示效果

仔细观察图1.5和图1.6会发现,如果左边栏内容没有右边栏内容多,下边会空出来。如果这两栏的下面还有其他网页内容,就会排在它们下方,网页上会在中间空出来一块,很难看。况且网页元素收缩也不是无限收缩,当收缩到它的最小宽度时,第二栏就会排到第二行上。

所以这种布局方式也不是在所有场合都可以使用。除此之外,还有Flex布局方式。下面就来看看Flex布局方式能否更完美地解决示例1中的问题。

2. Flex布局

Flex(Flexible Box)布局是在CSS3中引入的,又称“弹性盒模型”。该模型决定一个盒子在其他盒子中的分布方式以及如何处理可用的空间。

Flex布局对于设计比较复杂的页面非常有用,可以在屏幕和浏览器窗口大小发生变化时,保持元素的相对位置和大小不变,同时减少了在实现元素位置的定义以及重置元素的大小时对浮动布局的依赖。

Flex布局在定义伸缩项目大小时,伸缩容器会预留一些可用空间,以调节伸缩项目的相对大小和位置。例如,可以确保伸缩容器中的多余空间平均分配给多个伸缩项目。当然,如果伸缩容器没有足够大的空间来放置伸缩项目,浏览器会根据一定的比例减少伸缩项目的大小,使其不溢出伸缩容器。

综上所述,Flex布局主要具有以下几点功能。

➢ 在屏幕和浏览器窗口大小发生改变时,可以灵活地调整布局。

➢ 控制元素在页面上的布局方向。

➢ 按照不同于文档对象模型(DOM)所指定的排序方式对屏幕上的元素重新排序。

如何在网页中使用弹性盒模型呢?要开启弹性盒模型,只需要设置拥有盒子的display属性值为flex即可。

语法

display : flex; 

接下来就用弹性盒模型的方式对示例1的代码进行修改,具体如示例2所示。

示例2

<!--省略部分代码--> 
<div class="box clear"> 
    <aside> 
        <h2>热点新闻</h2> 
        <ul> 
            <li><a href="#">后院篮球9月3日于麓山</a></li> 
            <li><a href="#">好久不见,恒大外援阿兰代表预备队出战</a></li> 
            <!--省略部分代码--> 
        </ul> 
    </aside> 
    <article> 
        <p>首页>正文</p> 
 
        <h2>穆帅:我不会被解雇 你们知道曼联要赔我多少钱吗?</h2> 
 
        <p class="time">2018-09-04 07:57:41 来源: 网易体育</p> 
 
        <div> 
            <p> 
                英超第 4 轮,曼联客场击败伯恩利,穆里尼奥拿到了救命的三分。赛后,压力得
到释放的穆帅很是开心,他与球迷进行了积极的互动,并将手里的夹克送给球迷。而在接受媒体采访的时
候,穆帅表示自己一点都不担心被解雇,他还略带玩笑地说道:“你们知道曼联解雇我得赔多少钱吗?” 
 
            </p> 
<!--省略部分代码--> 

关键的CSS代码如下所示。

.box {  
    display: flex; 
    border: 1px solid #000000;  
    padding: 10px;  
} 
aside { 
    background: red;  
    padding: 10px;  
} 
article {  
    margin-left: 10px;  
    background: yellow;  
} 

在宽屏浏览器下的显示效果如图1.7所示,在窄屏浏览器下的显示效果如图1.8所示。

图1.7 Flex布局在宽屏下的显示效果

图1.8 Flex布局在窄屏下的显示效果

如图1.7和图1.8所示,网页中的内容可以实现自动伸缩。从代码中可以发现,在父级盒子中定义了display为flex就能把类名为box的整个大盒子设置为弹性的盒子。相比“浮动+百分比”布局来说,没有对aside和article两个盒子设置浮动和宽度。但结果是这两个盒子排到了一行,并且这两个盒子的高度是一样的,也避免了左边盒子下面出现一大片空白。

总结弹性盒模型的好处如下。

➢ 可以让盒子里面的元素排在一行。

➢ 盒子里面的元素高度相同。

虽然弹性盒模型可以解决网页内容适应浏览器窗口大小自动伸缩的问题,可是依然会发现aside和article两栏是以最小宽度显示的。那么在弹性盒模型中如何设置每个元素的宽度呢?除此之外还能设置元素的什么属性呢?下面就来学习一下弹性盒模型的其他属性。

(1)伸缩性(flex)

伸缩布局的特性是让伸缩项目可伸缩,也就是让伸缩项目的宽度或高度自动填充伸缩容器额外的空间,这可以用flex属性来完成。

下面就通过示例2来分析flex属性的用法。修改CSS代码如下所示。

.box { 
    display: flex;
    border: 1px solid #000000;   
    padding: 10px;   
} 
aside { 
    flex:1;
    background: red;   
    padding: 10px;   
} 
article {   
    flex:1; 
    margin-left: 10px;   
    background: yellow;   
} 

注意

为了保证CSS3部分属性在不同浏览器下的兼容性,需要给元素加前缀。例如:flex:1,要让IE浏览器支持,就需要写为-ms-flex:1,其他浏览器同理。

在宽屏浏览器下的显示效果如图1.9所示,在窄屏浏览器下的显示效果如图1.10所示。

图1.9 flex属性值为1时宽屏下的显示效果

图1.10 flex属性值为1时窄屏下的显示效果

如果把article的flex修改为2,具体代码如下所示。

article {   
    flex:2;  
    margin-left: 10px;  
    background: yellow;  
} 

在宽屏浏览器下的显示效果如图1.11所示,在窄屏浏览器下的显示效果如图1.12所示。

图1.11 article的flex属性值为2时宽屏下的显示效果

图1.12 article的flex属性值为2时窄屏下的显示效果

从上面的图中可以发现,flex属性的具体数值并不代表具体的宽度值,而是一个比例值。即在父容器的剩余空间里按比例去分配自己的宽度。aside和article的flex如果都是1,表示宽度比例为1:1,所以无论浏览器宽度如何都能保持内容宽度以1:1显示。article的flex属性值变为2后,比例值变为1:2,也就是说article的宽度是aside的两倍,且不受浏览器宽度的影响。

(2)伸缩流方向(flex-direction)

flex-direction属性决定主轴的方向(即项目的排列方向),可以很简单地将多个元素的排列方向从水平方向修改为垂直方向,或者从垂直方向修改为水平方向。

注意

采用Flex布局的元素,称为Flex容器(flex container),简称“容器”。它的所有子元素自动成为容器成员,称为Flex项目(flex item),简称“项目”。容器默认存在两根轴:水平的主轴(main axis)和垂直的交叉轴(cross axis),又叫侧轴。主轴的开始位置(与边框的交叉点)叫作main start,结束位置叫作main end;交叉轴的开始位置叫作cross start,结束位置叫作cross end。

项目默认沿主轴排列。单个项目占据的主轴空间叫作main size,占据的交叉轴空间叫作cross size。具体如图1.13所示。

图1.13 flex容器的主轴和交叉轴

语法

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

➢ row:主轴为水平方向,起点在左端。即网页元素排版方式为从左到右排列(默认值)。

➢ row-reverse:主轴为水平方向,起点在右端。与row相反,元素从右到左排列。

➢ column:主轴为垂直方向,起点在上端。类似于row,不过是从上到下排列。

➢ column-reverse:主轴为垂直方向,起点在下端。类似于row-reverse,不过是从下到上排列。

其中,row是默认的排列方式,前面示例显示的都是row的排列方式,这里就不再演示了。如果将示例2的代码改为row-reverse的方式,具体代码如下。

.box { 
    display: flex;  
    flex-direction: row-reverse;    / *与row排列相反。元素从右到左排列* / 
    border: 1px solid #000000;  
    padding: 10px;  
} 

在浏览器中的显示效果如图1.14所示。

图1.14 flex-direction属性值为row-reverse的显示效果

从图1.14中可以发现,设置flex-direction属性为row-reverse之后,aside和article两列的排列顺序完全颠倒了。

如果把flex-direction的属性设置为column,具体代码如下所示。

.box { 
    display: flex; 
    flex-direction: column;    / *类似于row,不过是从上到下排列* / 
    border: 1px solid #000000;  
    padding: 10px;  
} 

在浏览器中的显示效果如图1.15所示。box盒子里的两栏元素由水平方向显示变为垂直方向显示。

图1.15 flex-direction属性值为column的显示效果

flex-direction属性设置为column-reverse,就是把aside和article两列的排列顺序在垂直方向上完全颠倒,这里就不再演示了。

(3)伸缩换行(flex-wrap)

flex-wrap属性适用于伸缩容器,也就是伸缩项目的父元素,主要用来定义伸缩容器里是单行显示还是多行显示。侧轴的方向决定了新行堆放的方向。

语法

flex-wrap:nowrap | wrap | wrap-reverse 

具体有三个取值:

➢ nowrap:默认值。伸缩容器单行显示,伸缩项目不会换行。

➢ wrap:伸缩容器多行显示,伸缩项目会换行。

➢ wrap-reverse:伸缩容器多行显示,伸缩项目会换行,并且颠倒行顺序。

前面两个属性都很好理解,而第三个属性wrap-reverse会换行且颠倒行顺序,显示效果如图1.16所示。

图1.16 flex-wrap属性值为wrap-reverse的显示效果

(4)主轴对齐(justify-content)

justify-content属性适用于伸缩容器,也就是伸缩项目的父元素,主要用来定义伸缩项目在主轴上的对齐方式。

语法

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

属性值:

➢ flex-start:伸缩项目向一行的起始位置靠齐。

➢ flex-end:伸缩项目向一行的结束位置靠齐。

➢ center:伸缩项目向一行的中间位置靠齐。

➢ space-between:伸缩项目会平均分布在行里。第一个伸缩项目在一行中的最开始位置,最后一个伸缩项目在一行中的最终点位置。

➢ space-around:伸缩项目会平均分布在行里,两端保留一半的空间。

上述几种属性值的实际演示效果如图1.17所示。

图1.17 justify-content各属性值对伸缩项目的效果

(5)侧轴对齐(align-items)

align-items属性定义伸缩项目在侧轴上的对齐方式。align-items与justify-content相呼应,可以把它想象成侧轴(垂直于主轴)的justify-content。

语法

align-items: flex-start | flex-end | center | baseline | stretch; 

➢ flex-start:伸缩项目在侧轴起点边的外边距紧靠该行侧轴起点边。

➢ flex-end:伸缩项目在侧轴终点边的外边距紧靠该行侧轴终点边。

➢ center:伸缩项目的外边距盒在该行的侧轴上居中放置。

➢ baseline:伸缩项目根据伸缩项目的第一行文字的基线对齐。

➢ stretch:默认值。伸缩项目拉伸填满整个伸缩容器。

上述几种属性值的实际演示效果如图1.18所示。

图1.18 align-items各属性值对伸缩项目的效果

相比浮动等布局技术,Flex布局在处理对齐和间距等问题上具有更强大的能力。

如果使用Flex布局模型,只需要将一个容器的display属性设置成伸缩容器,接下来就可以使用一系列的新属性来控制伸缩容器内的子元素的排列布局方式。

1.1.3 上机训练

上机练习1——制作爱V猫友情链接页面

制作图1.19和图1.20所示的爱V猫友情链接页面,要求如下。

图1.19 爱V猫友情链接页面在宽屏下的显示效果

图1.20 爱V猫友情链接页面在窄屏下的显示效果

(1)使用HTML5结构元素布局页面结构。

(2)使用弹性盒模型布局网页头部的内容,主轴的对齐方式为space-between,侧轴的对齐方式为center。

(3)使用弹性盒模型布局网页主体部分的内容,主轴的对齐方式为center。左边“公司介绍”模块的伸缩性(flex)为1,并且它自身也是一个伸缩容器,伸缩流方向(flex-direction)为column;右边模块的伸缩性(flex)为4。

(4)主体部分的右侧图片整体模块是一个弹性盒,伸缩换行(flex-wrap)为wrap,主轴的对齐方式为flex-start。

(5)使用弹性盒模型布局网页的尾部内容,伸缩流方向(flex-direction)为column,主轴的对齐方式和侧轴的对齐方式都是center。