freeCodeCamp 旅途4 - 响应式设计和布局

弹性盒子

网页的用户界面(User Interface 缩写 UI)包括两个部分:

  • 第一部分是视觉要素,如色彩、字体和图片等。
  • 第二部分是这些元素的排列和定位。
    CSS3 引入了 Flexible Box,简称 flexbox(弹性盒子),它特别适合用来创建弹性的页面布局。弹性布局以一种可预见的方式排列元素,使其适用于不同尺寸的设备。虽然这是个新东西,但所有现代浏览器都已经支持 flexbox。

使用 display: flex 定位两个盒子

只要在一个元素的 CSS 中添加display: flex;,就可以使用其他 flex 属性来构建响应式页面了。

#box-container {    height: 500px;    display: flex;  }
#box-1 {    background-color: dodgerblue;    width: 50%;    height: 50%;      }
#box-2 {    background-color: orangered;    width: 50%;    height: 50%;      }

使用 flex-direction 属性

添加了display: flex的元素会成为 flex 容器。只要把flex-direction属性添加到父元素,并设置其为 rowcolumn 即可轻易横或竖排列它的子元素。设为 row 可以让子元素水平排列,column 可以让子元素垂直排列。默认值为 row。
flex-direction: row-reverse; // 一行逆序排列

使用 flex-direction 创建多行,使用flex-direction属性可以把子元素排列成一行。这个属性告诉 CSS 需要将这个元素的子元素水平排列。

使用 flex-direction 属性创建一列,#box-container { display: flex; height: 500px; flex-direction: column; }

使用 flex-direction 创建多列, header .profile-name { display: flex; flex-direction: column; margin-left: 10px; }

使用 justify-content 属性对齐元素

flex 容器里的 flex 子元素有时不能充满整个容器,所以我们需要告诉 CSS 如何以特定方案排列和调整 flex 子元素。justify-content属性就是处理这个问题。

元素横着排列

把 flex 容器设为一个行,它的子元素会从左到右逐个排列,把 flex 容器设为一个列,它的子元素会从上到下逐个排列。子元素排列的方向被称为 main axis(主轴)。对于行,主轴水平贯穿每一个项目;对于列,主轴垂直贯穿每一个项目。

关于 flex 子元素在主轴排列方式,可以选择以下值:其中一个很常用的是justify-content: center;,可以让 flex 子元素排列在 flex 容器中间。其他可选值还有:

  • flex-start:从 flex 容器的前端开始排列项目。对行来说是把项目都靠左放,对于列是把项目都靠顶部放。
  • flex-end:从 flex 容器的后端开始排列项目。对行来说是把项目都靠右放,对于列是把项目都靠底部放。
  • space-between:项目间保留一定间距地在主轴排列。第一个和最后一个项目会被挤到容器边沿。例如,在行中第一个项目会紧贴着容器左侧,最后一个项目会紧贴着容器右侧,然后其他项目均匀排布。
  • space-around:与space-between相似,但头尾两个项目不会紧贴容器边缘,空间会均匀分布在所有项目两边

使用 align-items 属性对齐元素

align-items属性与justify-content类似。justify-content属性使 flex 子元素沿主轴排列。行的主轴是水平线,列的主轴是垂直线。

Flex 容器中,与主轴垂直的叫做 cross axis(交叉轴)。行的交叉轴是垂直的,列的交叉轴是水平的。CSS 提供了align-items属性,可以用于在交叉轴调整 flex 子元素。对于行,它规定了项目在容器中应该靠上还是靠下,而对于列,就是靠左或靠右。
align-items的可选值包括:

  • flex-start:从 flex 容器的前端开始排列项目。对行来说是把项目都靠顶部放,对于列是把项目都靠左放。
  • flex-end:从 flex 容器的后端开始排列项目。对行来说是把项目都靠底部放,对于列是把项目都靠右放。
  • center:把项目的位置调整到中间。对于行,垂直居中(项目上下方空间相等)。对于列,水平居中(项目左右方空间相等)。
  • stretch:拉伸项目,填满 flex 容器。例如,排成行的项目从容器顶部拉伸到底部。
  • baseline:基线对齐地排列。基线是字体相关的概念,可以认为字体坐落在基线上。

使用 flex-wrap 属性包裹一行或一列

CSS flexbox 有一个把 flex 子元素拆分为多行(或多列)的特性。默认情况下,flex 容器会调整项目大小,把它们都塞到一起。如果是行的话,所有项目都会在一条直线上。
使用flex-wrap属性可以使项目换行。这意味着多出来的项目会被移到新的行或列。换行发生的断点由项目和容器的大小决定。
换行方向的可选值有这些:

  • nowrap:默认值,不换行。
  • wrap:行从上到下排,列从左到又排。
  • wrap-reverse:行从下到上排,列从右到左排。

使用 flex-shrink 属性收缩项目

flex-shrink属性使用之后,如果 flex 容器太小,该项目会自动缩小。当容器的宽度小于里面所有项目的宽度,项目就会自动压缩。
flex-shrink属性接受 number 类型的值。数值越大,与其他项目相比会被压缩得更厉害。例如,如果一个项目的flex-shrink为 1 ,另一个项目flex-shrink为 3,那么 3 的那个与另一个相比会受到 3 倍压缩。

使用 flex-grow 属性扩展项目

flex-shrink相对的是flex-growflex-shrink会在容器太小时对元素作出调整。相应地,flex-grow会在容器太大时对元素作出调整。
如果一个项目flex-grow属性的值为 1,另一个flex-grow为 3,那么 3 的会比 1 的扩大三倍。

使用 flex-basic 属性设置项目的初始大小

flex-basis属性指定了项目在 CSS 进行flex-shrinkflex-grow调整前的初始大小。
flex-basis属性的单位与其他 size 属性一致(pxem%等)。如果值为auto,项目的大小依赖于自身内容。

使用 flex 短方法属性

flex 属性有一个简写方式。flex-growflex-shrinkflex-basis属性可以在flex中一同设置。
例如,flex: 1 0 10px;会把项目属性设为flex-grow: 1;flex-shrink: 0;以及flex-basis: 10px;。属性的默认设置是flex: 0 1 auto;

  #box-1 {    background-color: dodgerblue;     height: 200px;    
    flex: 2 2 150px;    
  }
  #box-2 {    background-color: orangered;    height: 200px;
    flex: 1 1 150px;
  }
/* 在容器大于 300px 时,会让#box-1填充倍率为#box-2的两倍;
在容器小于 300px 时,缩小倍率为#box-2的两倍。
300px 是两个盒子的flex-basis的值之和。 */

使用 order 属性重新排列项目

order属性告诉 CSS flex 容器里项目的顺序。默认情况下,项目排列顺序与源 HTML 文件中顺序相同。这个属性接受数字作为参数,可以使用负数。

使用 align-self 属性

flex 子元素的最后一个属性是align-self。这个属性允许你调整每个项目自己的对齐方式,而不是一次性设置全部项目。因为floatclearvertical-align等调整使用的属性都不能应用在 flex 子元素,所以这个属性显得十分有用。
align-self的允许值与align-items一样,并且它会覆盖align-items的值。

CSS 网格

CSS Grid 帮助你轻松实现复杂的 Web 设计。它通过把 HTML 元素转换为具有行和列的网格容器,以便将子元素放置在所需要的位置。

创建

通过将属性display的值设为grid,使 HTML 元素变为网格容器。通过前面的操作,你可以对该容器使用与 CSS 网格(CSS Grid)相关的属性。display:grid;

在 CSS 网格中,父元素称为容器(container),它的子元素称为项(items)。

使用 grid-template-columns 添加多列, grid-template-rows 添加多行

在一个网格容器中使用grid-template-columns属性可以添加一些列,示例如下:
.container { display: grid; grid-template-columns: 50px 50px; }可以在网格容器中添加两列,宽度均为 50px。

grid-template-columns属性值的个数表示网格的列数,而每个值表示对应列的宽度。

使用 grid-template-rows 添加多行,用法和 grid-template-columns一样,grid-template-columns

使用 CSS 网格单位来更改列和行的大小

在 CSS 网格中,可以使用绝对定位和相对定位单位如pxem来确定行或列的大小。下面的单位也可以使用:

  • fr:设置列或行占剩余空间的一个比例
  • auto:设置列宽或行高自动等于它的内容的宽度或高度
  • %:将列或行调整为它的容器宽度或高度的百分比,

生成三列的网格,每列宽度分别为:1fr,100px,和 2fr。grid-template-columns: 1fr 100px 2fr;

使用 grid-column-gap 创建多列之间的间距

如果需要在列与列之间添加一些间隙,我们可以使用grid-column-gapgrid-column-gap: 10px;

使用 grid-row-gap 创建多行之间的间距,grid-row-gap: 5px;

使用 grid-gap 更快地添加间距

grid-gapgrid-row-gapgrid-column-gap的简写,它更方便使用。如果grid-gap有一个值,行与行之间和列与列之间将添加等于该值的间隙。但是,如果有两个值,第一个值将作为行间隙的高度值,第二个值是列间隙的宽度值。
grid-gap: 10px 20px;在行之间添加10px的间隙,在列之间添加20px的间隙。

使用 grid-column 来控制剩余部分

网格的假想水平线和垂直线被称为线(lines)。这些线在网格的左上角从 1 开始编号,垂直线向右、水平线向下累加计数。


3x3 网格的线条

你可以用grid-column属性定义网格项开始和结束的位置,进而控制每个网格项占用的列数。
grid-column: 1 / 3;网格项从左侧第一条线开始到第三条线结束,占用两列。
grid-column: 2 / 4 ;网格项占用网格的第 2 列和第 3 列。

使用 grid-row 来控制剩余部分,来确定行开始和结束的水平线。
grid-row: 2 / 4;网格项占用网格的第 2 行和第 3 行。

使用 justify-self 水平对齐项目

在 CSS 网格中,每个网格项的内容分别位于被称为单元格(cell)的框内。你可以使用网格项的justify-self属性,设置其内容的位置在单元格内沿行轴对齐的方式。默认情况下,这个属性的值是stretch,这将使内容占满整个单元格的宽度。该 CSS 网格属性也可以使用其他的值:

  • start:使内容在单元格左侧对齐,
  • center:使内容在单元格居中对齐,
  • end:使内容在单元格右侧对齐,

使用 align-self 垂直对齐项目
对网格项使用align-self属性,设置网格项沿列轴对齐方式。对于该属性,能使用可用于justify-self属性的任一个值。

使用 justify-items 水平对齐所有项目

对于这个属性你能使用justify-selfalign-self中的所有值,与之不同的是,它将使网格中所有的网格项按所设置的方式对齐。

使用 align-items 垂直对齐所有项目
对网格容器使用align-items属性可以给网格中所有的网格项设置沿列轴对齐的方式。

将网格划分为区域模板

你可以将网格中的一些网格单元格组合成一个区域(area),并为该区域指定一个自定义名称。你可以通过给容器加上grid-template-areas来实现:

grid-template-areas: "header header header" "advert content content" "footer footer footer";
将顶部三个单元格合并成一个名为header的区域,将底部三个单元格合并为一个名为footer的区域,并在中间行生成两个区域————advertcontent
注意:在代码中,每个单词代表一个网格单元格,每对引号代表一行。除了自定义标签,你还能使用句点(.)来表示一个空单元格。

使用 grid-area 属性将项目放置在网格区域中

在为网格容添加区域模板后,你可以通过添加你定义的名称将网格项放入自定义区域。为此,你需要对网格项使用grid-area

.item1 { grid-area: header; }
类名为item1的网格项就被放到了header区域里。这种情况下,网格项将使用整个顶行,因为这一行被名为 header 区域。

使用 grid-area 创建区域模板

如果网格中没有定义区域模板,你也可以像这样为它添加一个模板:
item1 { grid-area: 1/1/2/4; }网格项将占用第 1 条和第 2 条水平线之间的行及第 1 条和第 4 条垂直线之间的列。

grid-area: 起始水平线 / 起始垂直线 / 末尾水平线 / 终止垂直线 ;网格项将占用第 1 条和第 2 条水平线之间的行及第 1 条和第 4 条垂直线之间的列。

使用 repeat 函数减少重复

当使用grid-template-columnsgrid-template-rows定义网格结构时,你需要为添加的每一行和每一列都输入一个值。

使用repeat方法指定行或列的重复次数,后面加上逗号以及需要重复的值。添加 100 行网格的例子,使每行高度均为 50px:grid-template-rows: repeat(100, 50px);

你还可以用 repeat 方法重复多个值,并在定义网格结构时与其他值一起使用。
grid-template-columns: repeat(2, 1fr 50px) 20px;
相当于:grid-template-columns: 1fr 50px 1fr 50px 20px;

使用 minmax 函数限制项目大小

内置函数minmax也可以可用于设置grid-template-columnsgrid-template-rows的值。它的作用是在网格容器改变大小时限制网格项的大小。为此,你需要指定网格项允许的尺寸范围。

grid-template-columns: 100px minmax(50px, 200px);添加两列,第一列 100px 宽,第二列宽度最小值是 50px,最大值是 200px。

使用 auto-fill 创建弹性布局

重复方法带有一个名为自动填充(auto-fill)的功能。它的功能是根据容器的大小,尽可能多地放入指定大小的行或列。你可以通过结合auto-fill和minmax来更灵活地布局。

repeat(auto-fill, minmax(60px, 1fr));列的宽度会随容器大小改变,在可以插入一个 60px 宽的列之前,当前行的所有列会一直拉伸。
注意:如果容器无法使所有网格项放在同一行,余下的网格项将移至新的一行。

使用 auto-fit 创建弹性布局

auto-fit效果几乎和auto-fill一样。不同点仅在于,当容器的大小大于各网格项之和时,auto-fill将会持续地在一端放入空行或空列,这样就会使所有网格项挤到另一边;而auto-fit则不会在一端放入空行或空列,而是会将所有网格项拉伸至合适的大小。
注意:如果容器无法使所有网格项放在同一行,余下的网格项将移至新的一行。

使用媒体查询创建响应式布局

通过使用媒体查询重新排列网格区域,更改网格尺寸以及重新排列网格项位置,CSS 网格能轻松地使网站更具响应性。

@media (min-width: 400px){
    .container{
      grid-template-columns: 50% 50%;    //  分成两列,每列占50%
      grid-template-rows: auto auto auto;  // 分成三行,每行占 33.33%
      grid-template-areas:
        "header header"
        "advert content"
        "footer footer";
    }

在网格中创建网格

将元素转换为网格只会影响其子代元素。因此,在把某个子代元素设置为网格后,就会得到一个嵌套的网格。

例如,设置类为item3的元素的displaygrid-template-columns属性,就会得到一个嵌套的网格。.item3 { display: grid; grid-template-columns: auto 1fr; }

项目实战

Build a Tribute Page

a Tribute Page

Tim.jpg

Build a Survey Form

a Survey Form

Build a Product Landing Page

a Product Landing Page

just-we

Build a Technical Documentation Page

a Technical Documentation Page

Build a Personal Portfolio Webpage

a Personal Portfolio Webpage

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

推荐阅读更多精彩内容