HTML5+CSS3前端入门教程---从0开始通过一个商城实例手把手教你学习PC端和移动端页面开发第8章FlexBox布局(下)

简介: HTML5+CSS3前端入门教程---从0开始通过一个商城实例手把手教你学习PC端和移动端页面开发第8章FlexBox布局(下)

flex-basis


flex-basis属性可以指定Flex项目的初始大小。也就是flex-growflex-shrink属性调整它的大小以适应Flex容器之前。

flex-basis默认的值是autoflex-basis可以取任何用于width属性的任何值。比如 % || em || rem || px等。

注意:如果flex-basis属性的值是0时,也需要使用单位。即flex-basis: 0px不能写成flex-basis:0

这里同样使用只有一个列表项的列表做为示例。

/* 声明父元素为flex容器 */
    ul {
    display:flex;
    border: 1px solid red;
    padding: 0;
    list-style: none;
}
li {
    background-color: #8cacea;
    height: 100px;
    margin: 8px;
    padding: 10px;
}
<ul>
    <li>I am a simple list</li>
</ul>


默认情况,Flex项目的初始宽度由flex-basis的默认值决定,即:flex-basis: auto。Flex项目宽度的计算是基于内容的多少来自动计算(很明显,加上了padding值)。

image.png


image

这意味着,如果你增加Flex项目中的内容,它可以自动调整大小。

<ul>
    <li>I am a simple list AND I am a simple list</li>
</ul>


image.png

image

然而,如果你想将Flex项目设置一个固定的宽度,你也可以这样做:

li {
    flex-basis: 150px;
}

现在Flex项目的宽度受到了限制,它的宽度是150px

image.png


image


flex速记


flexflex-growflex-shrinkflex-basis三个属性的速记(简写)。

在适当的时候,我建议你使用flex,这样比使用三个属性方便。

li {
    flex: 0 1 auto;
}

上面的代码相当于:

li {
    flex-grow: 0;
    flex-shrink: 1;
    flex-basis: auto;
}

注意它们之间的顺序。flex-grow第一,然后是flex-shrink,最后是flex-basis。缩写成GSB,可以帮助你更好的记忆。

如果flex属性值中少一个值,会发生什么呢?

如果你只设置了flex-growflex-shrink值,flex-basis可能是默认值0。这就是所谓的绝对flex项目。只有当你设置了flex-basis,你会得到一个相对flex项目。

/* 这是一个绝对的Flex项目 */
li {
    flex: 1 1; /*flex-basis 默认值为 0*/
}
/* 这是一个相对的Flex项目 */
li {
  flex-basis: 200px; /* 只设置了flex-basis的值 */
}


你肯定想知道相对和绝对的Flex项目是什么?将在后面回答这个问题。

让我们看看一些非常有用的flex值。


flex: 0 1 auto

li {
    flex: 0 1 auto;
}

这相当于写了flex默认属性值以及所有的Flex项目都是默认行为。


image.png

image

很容易理解这一点,首先看看flex-basis属性。flex-basis设置为auto,这意味着Flex项目的初始宽度计算是基于内容的大小。

把注意力放到下一个属性,flex-grow设置为0。这意味着flex-grow不会改变Flex项目的初始宽度。也就是说,flex-grow的开关是关闭的。

flex-grow控制Flex项目的增长,如果其值设置为0,Flex项目不会放大以适应屏幕(Flex容器大小)。

最后,flex-shrink的值是1。也就是说,Flex项目在必要时会缩小。

应用到Flex项目效果就是这样子:

image.png

image

注意:Flex项目没有增长(宽度)。如果有必要,如果调整浏览器(调小浏览器宽度),Flex项目会自动计算宽度。


flex: 0 0 auto

li {
    flex: 0 0 auto;
}


这个相当于flex: none

还是老规矩:宽度是被自动计算,不过弹性项目不会伸展或者收缩(因为二者都被设置为零)。伸展和收缩开关都被关掉了。

它基本上是一个固定宽度的元素,其初始宽度是基于弹性项目中内容大小。

看看这个 flex 简写是如何影响两个弹性项目的。一个弹性项目会比另一个容纳更多内容。


image.png

image

应该注意到的第一件事情是,这两个弹性项目的宽度是不同的。因为宽度是基于内容宽度而自动计算的,所以这是预料得到的。

试着缩放一下浏览器,你会注意到弹性项目不会收缩其宽度。它们从父元素中突出来了,要看到所有内容,必须横向滚动浏览器。

image.png

image

在缩放浏览器时,弹性项目不会收缩,而是从弹性容器中突出来了。


flex: 1 1 auto


这与 flex: auto 项目相同。

还是按我前面立的规矩。即,自动计算初始化宽度,但是如果有必要,会伸展或者收缩以适应整个可用宽度

伸展和收缩开关打开了,宽度自动被计算。

image.png


image

此时,项目会填满可用空间,在缩放浏览器时也会随之收缩。剩余宽度被2个item平均分配,一人一半。


flex: "positive number"


一般应用于有多个弹性项目的情形。

这里正数可以代表任何正数(没有引号)。这与 flex: “正数” 1 0 相同。

flex: 2 1 0 与写为 flex: 2 是一样的,2 表示任何正数。

li {
    flex: 2 1 0; / *与 flex: 2相同 */
}

与前面我立的规矩一样,即,将弹性项目的初始宽度设置为零(嗯?没有宽度?),伸展项目以填满可用空间,并且最后只要有可能就收缩项目


弹性项目没有宽度,那么宽度该如何计算呢?

这个时候 flex-grow 值就起作用了,它决定弹性项目变宽的程度。由它来负责没有宽度的问题。

当有多个弹性项目,并且其初始宽度 flex-basis 被设置为基于零的任何值时,比如 0px,使用这种 flex 简写更实用。

实际发生的是,弹性项目的宽度被根据 flex-grow 值的比例来计算。

考虑如下两个列表项标记及 CSS:

<ul>
    <li>I am One</li>
    <li>I am Two</li>
</ul>
  <style>
    /* 声明父元素为flex容器 */
    ul {
    display:flex;
    border: 1px solid red;
    padding: 0;
    list-style: none;
}
li {
    background-color: #8cacea;
    height: 100px;
    margin: 8px;
    padding: 10px;
    /* flex-basis: 150px; */
}
/* 第一个弹性项目 */
li:nth-child(1) {
    flex: 2 1 0; /* 与写成 flex: 2 相同*/
}
/* 第二个弹性项目 */
li:nth-child(2){
    flex: 1 1 0;
    background-color: #8cacea;
}
  </style>

记住设置 flex-grow : 1,会让弹性项目填满可用空间。伸展开关打开了。

这里有两个弹性项目。一个的 flex-grow 属性值是 1,另一个是 2,那么会出现啥情况呢?

两个项目上的伸展开关都打开了。不过,伸展度是不同的,12

二者都会填满可用空间,不过是按比例的。

它是这样工作的:前一个占 1/3 的可用空间,后一个占 2/3 的可用空间。


image.png

image

即使两个弹性项目内容一样大(近似),它们所占空间还是不同。宽度不是基于内容的大小,而是伸展值。一个是另一个的约两倍。


绝对和相对Flex项目


前面了解了一些基本概念,但重要的是要澄清一些重要的概念。那绝对和相对Flex项目之间到底有啥区别呢?二者之间主要的区别在于间距及如何计算间距。

一个相对Flex项目内的间距是根据它的内容大小来计算的。而在绝对Flex项目中,只根据 flex 属性来计算,而不是内容。

考虑如下的标记:

<ul>
    <li>
        This is just some random text  to buttress the point being explained.
    Some more random text to buttress the point being explained.
    </li>
    <li>This is just a shorter random text.</li>
</ul>

两个列表项元素,一个比另一个的文本多得多。

加点样式:

ul {
    display: flex; /*触发弹性盒*/
}
li {
    flex: auto; /*记住这与 flex: 1 1 auto; 相同*/
    border: 2px solid red;
    margin: 2em;
}

如下是结果:

image.png


image

如果你已经忘了的话,flex: 1 1 auto 是与 flex-grow: 1flex-shrink: 1flex-basis: auto 相同的。

Flex项目的初始宽度是被自动计算的(flex-basis: auto),然后会伸展以适应可用空间(flex-grow: 1)。

当Flex项目因为被设置为 flex-basis: auto,而导致宽度被自动计算时,是基于Flex项目内包含的内容的大小而计算。

上面示例中Flex项目的内容大小不相同。因此,Flex项目的大小就会不相等。

既然各个宽度开始就不是相等的(它是基于内容的),那么当项目伸展时,宽度也保持不相等。

可以试试让两个li的内容相同再试试。

image.png

image

上面示例中的Flex项目是相对Flex项目。

下面我们把Flex项目变成绝对的, 就是说这次它们的宽度是基于 flex 属性,而不是内容的大小。一行代码就可以出奇迹。

li {
    flex: 1 ; /*与 flex: 1 1 0 相同*/
}

效果如下:


image.png

image

这次看到两个Flex项目的宽度相同了吗?

Flex项目的初始宽度是零(flex-basis: 0),并且它们会伸展以适应可用空间。当有两到多个Flex项目的 flex-basis 取值为0时,它们会基于 flex-grow值共享可用空间。

现在宽度不会基于内容大小而计算,而是基于指定的 flex 属性值来计算。

绝对Flex项目的宽度只基于 flex 属性,而相对Flex项目的宽度基于初始内容大小


Auto-margin 对齐


当心Flex项目上的 margin: auto 对齐。当在Flex项目上使用 margin: auto 时,事情看起来就很怪异了。

你需要理解会发生什么。它会导致不可预料的结果,不过我打算解释解释。

当在Flex项目上使用 margin: auto 时,值为 auto 的方向(左、右或者二者都是)会占据所有剩余空间。

这玩意有点难理解。下面我来说明一下。

考虑如下的导航栏标记以及 CSS 样式:

<ul>
    <li>Branding</li>
    <li>Home</li>
    <li>Services</li>
    <li>About</li>
    <li>Contact</li>
</ul>
  <style>
    /* 声明父元素为flex容器 */
    ul {
    display:flex;
    border: 1px solid red;
    padding: 0;
    list-style: none;
}
li {
    background-color: #8cacea;
    margin: 8px;
    padding: 10px;
    flex: 0 0 auto;
    border: 2px solid red;
}
  </style>

你可以看到如下的效果:


image.png

image

这里有几件事情要注意:

  • flex-grow 值为设置为0。这就解释了为什么列表项不会伸展。
  • Flex项目向Main-Axis的开头对齐(这是默认行为)。
  • 由于项目被对齐到Main-Axis开头,右边就有一些多余的空间。看到了吧?

image.png

image


现在在第一个列表项(branding)上使用 margin: auto,看看会出啥情况。

li:nth-child(1) {
    margin-right: auto; /*只应用到右外边距*/
}

image.png

image

刚刚发生了什么?之前的剩余空间现在已经被分配到第一个Flex项目的右边了。

image.png

image

还记得我前面说的话吧?当在Flex项目上使用 margin: auto 时,值为 auto 的方向(左、右或者二者都是)会占据所有剩余空间

如果想让一个Flex项目的两边都用自动外边距对齐,该怎么办呢?

/* 如果愿意的话,也可以用 margin 简写来设置两个边 */
li:nth-child(1) {
    margin-left: auto;
    margin-right: auto
}

image.png

image

现在空白被分配到Flex项目的两边了。

那么,这是不是对很酷的自动外边距对齐的一种折衷方案呢?看起来是。如果没注意的话,它也可能是受挫之源。当在一个Flex项目上使用自动外边距(margin: auto)时,justify-content 属性就不起作用了。

例如,在上面的Flex容器上通过 justify-content 属性,设置不同的对齐选项时,对布局没有影响。

ul {
    justify-content: flex-end;
}


image.png

Flexbox实战


导航系统是每个网站或者应用程序的重要组成部分。这个世界上的每个网站都会有某种导航系统。

下面我们看看这些热门网站,以及它们是如何实现其导航系统的。你看到Flexbox是如何帮助你更高效地创建这些布局吗?

也仔细看看哪里会用得上自动外边距特性。


Bootstrap导航


image.png

image

AirBnB PC端导航

image.png

image

Twitter PC端导航

image.png

image

建议你自己写代码。试着自己实现这些导航系统


切换flex-direction会发生什么?

还记得我说过默认的Main-Axis方向是从左到右,Cross-Axis方向是从上到下吧?


image.png

image

好吧,现在你也可以改变这个方向。

正如在较早的小节中所描述的那样,用 flex-direction: column 时,确实是这样。

当用 flex-direction: column 时,Main-Axis和Cross-Axis会向如下所看到的那样改变:


image.png

image

如果曾用英语写过文字,那么你就知道英语是从左到右,从上到下来写的。

Flexbox的默认Main-Axis和Cross-Axis也是采用同样的方向。

不过,如果将 flex-direction 切换为 column,它就不再遵循英语的范式,而是日语的范式!

是的,日语。

如果你用日语写过文字,那么应该很熟悉了。(郑重声明,我从没用过日语写过文字)。

日文通常是从上到下写的!没那么怪,对吧?

这就解释了为嘛这对英语写作者可能有点恼火。


image.png

image

看看下面这个例子。标准无序列表(ul),带有 3 个列表项(li)。不过这次我要改变一下flex-direction

<ul>
    <li></li>
    <li></li>
    <li></li>
</ul>
 <style>
    /* 声明父元素为flex容器 */
    ul {
    display:flex;
    border: 1px solid red;
    padding: 0;
    list-style: none;
    flex-direction: column;
}
li {
    background-color: #8cacea;
    margin: 8px;
    padding: 10px;
    flex: 0 0 auto;
    border: 2px solid red;
}
  </style>

如下是方向变化之前的样子:

image.png


image

如下是方向变化之后的样子:

image.png

image

现在文字是以日语风格写的:沿Main-Axis从上到下

你会看到项目的宽度填满了空间,对吧?

如果在之前要变成这样子,得处理 flex-basis 以及 flex-grow 属性。

下面来看看这些会如何影响新的布局。

li {
    flex-basis: 100px;
}

下面是你会得到的。


image.png

image

什么?高度是被影响了,但是宽度没有啊?我之前说过,flex-basis 属性定义每个Flex项目的初始宽度。

在切换 flex-direction 时,请注意,影响Main-Axis的每一个属性现在会影响新Main-Axis。像 flex-basis 这种会影响Main-Axis上Flex项目宽度的属性,现在会影响项目的高度,而不是宽度。

方向已经被切换了!

所以,即使你使用 flex-grow 属性,它也是影响高度。本质上,每个作用于横向轴(即Main-Axis)上的 flex 属性,现在都会作用于纵向上的新Main-Axis。它只是在方向上的一个切换。

这里再来一个例子。我发誓在这个例子之后你会有更好的理解。减少之前看到过的Flex项目的宽度,它们就不再填满整个空间了:

li {
    width: 200px;
}


image.png

image

如果想把列表项移到屏幕中间该怎么办呢?

在英语中,这是你到目前为止处理弹性容器的方式。就是说, 把Flex项目移到Main-Axis的中间 。

所以,你会用 justify-content: center。但是这样做不起作用。因为方向变了,中心是沿着Cross-Axis,而不是Main-Axis。

再来看看:


image.png

image

所以请用日语文字来思考。Main-Axis是从上到下,你不需要这样。Cross-Axis是从左到右。貌似是你所要的

你需要 把Flex项目移到Cross-Axis的中间 。这里想起哪个Flex容器属性了么?

是的,align-items 属性。align-items 属性处理Cross-Axis上的对齐。

所以要把这些项目移到中间,得这样做:

li {
    align-items: center;
}

瞧瞧!Flex项目已经居中了吧。

image.png

image

参考:

https://medium.freecodecamp.com/understanding-flexbox-everything-you-need-to-know-b4013d4dc9af#.pr6cltk9j

目录
相关文章
|
4天前
|
前端开发 UED 容器
在 CSS 中使用 Flex 布局实现页面自适应时需要注意什么?
【10月更文挑战第22天】在使用 Flex 布局实现页面自适应时,需要对其基本原理和特性有深入的理解,同时结合具体的布局需求和场景,进行细致的调整和优化。通过合理的设置和注意事项的把握,才能实现理想的自适应效果,提升用户体验。还可以根据实际情况进行更深入的探索和实践,以不断提升 Flex 布局的应用能力。
|
14天前
|
机器学习/深度学习 弹性计算 自然语言处理
前端大模型应用笔记(二):最新llama3.2小参数版本1B的古董机测试 - 支持128K上下文,表现优异,和移动端更配
llama3.1支持128K上下文,6万字+输入,适用于多种场景。模型能力超出预期,但处理中文时需加中英翻译。测试显示,其英文支持较好,中文则需改进。llama3.2 1B参数量小,适合移动端和资源受限环境,可在阿里云2vCPU和4G ECS上运行。
|
22天前
|
编解码 前端开发 UED
前端:移动端视口配置
移动端视口配置是指针对移动设备浏览器设置视口的宽度、高度和缩放等属性,以确保网页能根据不同的屏幕尺寸和分辨率进行适配,提供更好的用户体验。合理的视口配置是移动优先设计的关键环节。
|
25天前
|
前端开发 容器
使用 CSS Grid 布局实现响应式设计
【10月更文挑战第1天】使用 CSS Grid 布局实现响应式设计
36 4
|
25天前
|
前端开发 容器
前端技术分享:利用CSS Grid布局实现响应式设计
【10月更文挑战第1天】前端技术分享:利用CSS Grid布局实现响应式设计
|
2月前
|
前端开发 容器
css布局-弹性布局学习笔记
这篇文章是关于CSS弹性布局的学习笔记,详细介绍了flex容器和元素的相关属性,包括flex-direction、flex-wrap、flex-flow、justify-content、align-items、align-content以及order、flex-grow、flex-shrink、flex-basis、flex和align-self等,解释了这些属性在弹性盒子布局中的作用和用法。
|
2月前
|
JavaScript 前端开发
网页前端课程设计-【模仿】香港中文大学官网,轮播图及div+css布局,js的dom操作
这篇文章介绍了如何模仿香港中文大学官网进行网页前端课程设计,包括使用div+css布局、js的DOM操作以及实现轮播图等技术细节。
|
3月前
|
前端开发 安全 容器
CSS如何优雅实现卡片多行排列布局?
【8月更文挑战第24天】CSS如何优雅实现卡片多行排列布局?
86 3
|
3月前
|
前端开发 开发者 容器
探索现代Web开发中的CSS Grid布局技术
【8月更文挑战第29天】在数字时代的浪潮中,网页设计不断进化以适应日新月异的用户需求。CSS Grid布局技术作为一项革新性的前端工具,为设计师和开发者提供了前所未有的布局能力。本文旨在通过深入浅出的方式介绍CSS Grid的核心概念、基本用法以及在实际项目中的应用,帮助读者快速掌握这一强大的网页布局工具。
52 3
|
3月前
|
前端开发 容器
【CSS Flexbox 探秘】弹性盒模型:揭秘网页布局的终极神器!
【8月更文挑战第25天】Flexbox 是 CSS3 中的关键特性,为网页设计提供了强大的布局能力。本文通过问答形式全面解析 Flexbox 的核心概念与属性,包括容器与项目属性,并通过示例演示如何使用 Flexbox 实现水平与垂直居中、等间距布局及响应式设计。相较于传统布局方法,Flexbox 更加灵活且简化了样式设置,同时在现代浏览器中拥有良好的支持度。掌握 Flexbox 对于提升网页布局效率至关重要。
56 1