【CSS in Depth 2 精译_025】4.3 弹性布局的方向

当前内容所在位置(可进入专栏查看其他译好的章节内容)

  • 第一章 层叠、优先级与继承(已完结)
    • 1.1 层叠
    • 1.2 继承
    • 1.3 特殊值
    • 1.4 简写属性
    • 1.5 CSS 渐进式增强技术
    • 1.6 本章小结
  • 第二章 相对单位(已完结)
    • 2.1 相对单位的威力
    • 2.2 em 与 rem
    • 2.3 告别像素思维
    • 2.4 视口的相对单位
    • 2.5 无单位的数值与行高
    • 2.6 自定义属性
    • 2.7 本章小结
  • 第三章 文档流与盒模型(已完结)
    • 3.1 常规文档流
    • 3.2 盒模型
    • 3.3 元素的高度
    • 3.4 负的外边距
    • 3.5 外边距折叠
    • 3.6 容器内的元素间距问题
    • 3.7 本章小结
  • 第四章 Flexbox 布局
    • 4.1 Flexbox 布局原理(已完结)
      • 4.1.1 创建一个基础的 Flexbox 菜单
      • 4.1.2 添加内边距与间隔
    • 4.2 弹性子元素的大小(已完结)
      • 4.2.1 使用 flex-basis 属性
      • 4.2.2 使用 flex-grow 属性
      • 4.2.3 使用 flex-shrink 属性
      • 4.2.4 实际应用
    • 4.3 弹性布局的方向 ✔️
      • 4.3.1 变更弹性布局的方向 ✔️
      • 4.3.2 登录表单的样式设计 ✔️
    • 4.4 对齐、间距等细节处理(精译中 ⏳)

4.3 弹性布局的方向

Flexbox 的另一重要功能是切换主轴与副轴的方向,通过弹性容器上的 flex-direction 属性进行控制。该属性的初始值(row)规定子元素从左至右排列,一如前面演示的案例效果。若改为 flex-direction: column,则沿垂直方向从上到下排列。此外,属性值还支持 row-reverse 从右到左排列,以及 column-reverse 从下到上排列(如图 4.14 所示)。

图 4.14 改变 flex-direction 就改变了主轴的方向,与之垂直的副轴方向也会随之改变

图 4.14 改变 flex-direction 就改变了主轴的方向,与之垂直的副轴方向也会随之改变

本节将在示例页靠右的侧边栏演示该属性的用法,让两个子板块产生纵向堆叠效果。这貌似有些画蛇添足,毕竟它们已经竖直排列好了,块级元素也理应如此。但这样的页面布局存在一个极为隐蔽的漏洞,仅在左边的正文板块包含更多内容时才会显现,如图 4.15 所示。

只要给正文区 column-main 列添加一些标题及段落内容,就会发现主板块的高度超过了右边的侧边栏。按理来说 Flexbox 是可以让两列高度相等的,这里怎么不生效了呢?

图 4.15 主板块延伸到了右侧板块总高度外围(虚线标出了 column-sidebar 的大小)

图 4.15 主板块延伸到了右侧板块总高度外围(虚线标出了 column-sidebar 的大小)

如图 4.15(注意标注的虚线框)所示,左右两个弹性子元素确实是等高的。问题在于右侧子元素中的两个子板块没能填满整个侧边栏区域。

理想的布局效果应如图 4.16 所示。即使左侧内容区更长,右侧的两个子板块也会自动延展开来,填满整个侧边栏。在 Flexbox 出现以前,纯靠 CSS 几乎是无法实现的(需要略微借助 JavaScript 才行)

图 4.16 目标布局效果:右边栏的板块与左边的大板块对齐

图 4.16 目标布局效果:右边栏的板块与左边的大板块对齐。

4.3.1 变更弹性布局的方向

要让两个子板块延展到填满整个容器的高,就得把右边栏(column-sidebar)改为弹性容器,并设置 flex-direction: column;再给其中的两个子板块的 flex-grow 都赋上一个非零的属性值。如代码清单 4.9 所示,将以下样式更新到本地样式表。

代码清单 4.9 在右侧创建一个弹性布局列

.column-sidebar { 
  /* 对外部弹性盒而言是弹性子元素,对内部元素而言则是弹性容器 */
  flex: 1;
  display: flex;          
  flex-direction: column; 
  gap: var(--gap-size);   
}

.column-sidebar > .tile {
  /* 给侧边栏内部的弹性子元素一个非零的 flex-grow 值 */
  flex: 1;
}

至此就创建了一个嵌套的弹性盒子。元素 <div class="column-sidebar"> 既是外层弹性盒子的弹性子元素,又是内部两个子板块的弹性容器。其整体结构如下所示(简洁起见,文本内容已省略):

<main class="flex">
  <div class="column-main tile">
    ...
  </div>
  <div class="column-sidebar">
    <div class="tile">...</div>
    <div class="tile">...</div>
  </div>
</div>

这个内部的弹性盒子,其弹性布局的方向为 column,主轴方向由此转为从上到下(副轴方向则变为从左到右)。也就是说,此时 flex-basisflex-grow 以及 flex-shrink 属性仅对其弹性子元素的高度生效,而非宽度。由于子元素设置了 flex: 1, 它们的高度在必要时会延展到填满整个容器。无论左右两栏的高矮,此时主板块的底边都会和右边第二个小板块的底边始终对齐。

水平弹性盒子的大部分概念对于垂直方向(columncolumn-reverse)同样适用,但有个 关键区别 务必牢记:在 CSS 中高度的处理方式与宽度存在本质上的不同。弹性容器会 100% 填满可用宽度,而高度则始终由自身的内容决定。即便改变主轴方向,也不会改变这个本质特征。

弹性容器的高度则由弹性子元素决定,它们会正好填满容器。在纵向 Flexbox 布局中,子元素的 flex-growflex-shrink 属性不会起作用,除非有其他因素强行改变弹性容器的高度。本例中的“其他因素”就是外层弹性容器衍生过来的高度。

4.3.2 登录表单的样式设计

页面的整体布局告一段落,剩下的工作是给右侧两个子板块中更小的内容元素设计样式,即登录表单和注册链接部分。登录表单就不用弹性盒布局了,但为了演示的完整性再简要过一遍。最终设计好的表单效果如图 4.17 所示。

图 4.17 登录表单的最终效果

图 4.17 登录表单的最终效果

<form> 的样式类 login-form 为 CSS 选择器,分别对登录表单中的标题、输入框及按钮三个部分进行样式设计,并根据代码清单 4.10 更新到示例页面。

代码清单 4.10 登录表单的样式设计

/* 标题设为加粗、右对齐、全大写 */
.login-form h3 {
  margin: 0;
  font-size: 0.9em;
  font-weight: bold;
  text-align: end;
  text-transform: uppercase;
}

/* 仅为文本类型的输入框(不包含复选框与单选按钮)设置样式 */
.login-form input:not([type=checkbox]):not([type=radio]) {
  display: block;
  inline-size: 100%;
}

/* 按钮的样式 */
.login-form button {
  margin-block-start: 1em;
  border: 1px solid #cc6b5a;
  background-color: white;
  padding: 0.5em 1em;
  cursor: pointer;
}

先来看标题,用的都是熟悉的字体属性。text-align 用于文字右对齐,text-transform 则用于设置文字大写。注意观察,示例 HTML 里的内容并没有写成大写形式。当字母大写仅仅视为一种样式时,正常的做法是在 HTML 中按照标准的语法规则书写,再用 CSS 转成大写。这样今后无需重新输入 HTML 中的文字就能控制大小写。

第二组规则集处理的是输入框。这里的选择器比较特殊,主要是因为 <input> 元素很特殊。<input> 元素既可以输入文本和密码,也可以输入很多类似的 HTML5 数据,如数字、电子邮箱及日期;此外还能记录看上去截然不同的表单项数据,比如单选按钮和复选框的选中结果。

示例中 :not() 伪类选择器与属性选择器 [type=checkbox][type=radio] 组合起来的写法(详见附录 A),可以选中除复选框和单选按钮以外的所有 <input> 元素。这是一个黑名单方式:把不想选中的元素剔除掉。也可以采用白名单方式:将想要选中的所有 <input> 元素类型通过属性选择器一一罗列,但这样写起来就会显得十分冗长。

注意

尽管示例表单只出现了文本和密码输入框,但演示的重点在于,该 CSS 样式可能影响到后续其他的 HTML 标记,需要尽量予以兼顾。

在这组规则集中,输入框加上了 display: block 的样式,令其独占一行,同时将宽度设为 100%。通常情况下,块级元素会自动填满可用宽度,但 <input> 比较特殊,其宽度由 size 属性决定。该属性表示输入框在不出现滚动条的情况下大致能够容纳的字符数。若不指定 size 的值,则会赋一个默认值。也可以用 CSS 的 widthinline-size 属性强制设置一个宽度。

第三组规则集处理的是登录按钮。这些样式大多很简单,只有 cursor 属性可能相对陌生。它控制的是鼠标指针悬停在元素上方时的外观效果。其值为 pointer 时,鼠标指针会变成一个具有指示效果的手型,鼠标悬停到链接元素时的默认效果就是这个形状。它告诉用户该元素是可以点击的,这一细节处理可以让按钮样式更加完美。

  • 9
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

安冬的码畜日常

您的鼓励是我持续优质内容的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值