内容介绍
本专题假设你已经具备了基本的 HTML 5 、Javascript(ES6) 和 CSS 3 知识。本专题是为了补全 AXUM 全栈开发所需要的技术栈,而不是从零开始的前端课程,如果你还不具备以上知识,请通过其它途径学习完成之后,再来学习本专题。React: 简介与安装
本章将通过编程世界通用的“Hello World”程序,告诉你:创建 React 应用的几种方法、虚拟DOM、JSX以及将 React 挂载到真实 DOM 的步骤。- 支持试读
React:类式组件、函数式组件及state和props
本章将讨论 React 的类式组件、函数式组件以及 React 两个最重要的属性:`state` 和 `props`。 React: 组件的生命周期
本章将讨论 React 组件的常用生命周期。- 支持试读
React: 事件处理、表单处理及受控组件与非受控组件
本章讨论 React 的事件处理,以及表单处理时涉及两个策略:受控组件与非受控组件。 React: 流程控制与key
本章将讨论 React(JSX) 的条件判断和循环。React: 自定义组件及组件通讯
本章我们将正式开启 React 组件之路。虽然我们之前章节的都叫组件,但整个应用只有一个组件,略显单薄。同时,我们还将讨论组件之间如何进行通讯。React: 路由
本章将讨论 React 的路由:通过路由,你可以制作出“多页面”的系统。React: 状态共享
本章将通过一个非常典型的案例来讨论 React 的状态共享:只有登录用户才能看到某些内容。早期的 React 完全依靠其生态中的 redux 等第三方库来实现状态共享;现在 React 提供了官方的 `Context` 来实现这一目的。React: SEO挑战、服务端渲染及本地存储
经过紧张的学习,React 课程终于暂告一个段落了。本章将是一个相对轻松的内容,我们一起探讨一下 React 应用的 SEO 以及为什么需要服务端渲染,同时对 React 课程做个简单的小结。NextJS: 简介与安装
NextJS 是一个 React 框架,它提供了很多有用的功能把 React 的力量发挥地淋漓尽致。本章我们将开始 NextJS 之旅,首先自然是安装它,然后来一个「你好,NextJS」NextJS: 渲染模式和数据获取
趁你现在对我们刚刚讨论的有关 React 和 SEO 的问题还保持有较强的印象,我们先来讨论 NextJS 是如何利用多种渲染模式来应用 SEO 挑战的。NextJS: 内置组件及自动路由
NextJS 既然是 React 的框架,自然提供了一些内置组件来扩展 React。本章将介绍几个常用的 NextJS 内置组件,同时也将介绍 NextJS 的路由系统。NextJS: 开发博客系统
本章我们将使用 NextJS 开发一个小型的博客系统,你将学习到如何从远程服务器获取数据以及数据过滤、NextJS 常用组件的用法、NextJS 的自动路由等功能。Tailwind:简介与响应式设计的基本原则
TailwindCSS 是一款响应式的、移动设备优先的 CSS 工具类框架。本章对响应式布局、移动设备优先、断点等基本概念进行简要说明;并讨论几种安装 tailwind 的方式。Tailwind: 通过小示例体验它
本章通过两个小示例来体验一下 tailwind 的魔力。Tailwind: 默认配置
Tailwind 定义了一系列变量,比如颜色、大小、间距等。本章将介绍 tailwind 的一些默认设置。Tailwind: 撸一个按钮
本章将带你使用 tailwind 撸一个按钮Tailwind: 使用 flex 和 grid 进行响应式布局
本章我们将讨论使用 `flex` 和 `grid` 进行响应式布局,以及为什么不建议再使用 `float` 进行布局。- 支持试读
Tailwind: 撸一个带图标和动画效果的下拉框
本章将使用 tailwind 实现一个没有任何 Javscript 代码的纯 CSS 的下拉框,把应用到导航栏、菜单栏时,也被称为下拉菜单。同时我们将讨论如何在 tailwind 中使用图标,包括图标的进化史:从字体文件到SVG。 Tailwind: 撸一个报价卡片
本章我们将使用 tailwind 撸一个报价卡片。Tailwind: 撸一个响应式的纯CSS导航栏
本章将使用 tailwind 撸一个响应式的、纯 CSS 的导航栏。Tailwind: 集成到React/NextJS
本章将介绍如何将 Tailwind 集成到 React 或 NextJS 项目中。Tailwind: 复用
本章通过将之前撸的按钮改成 NextJS 版,进而讨论 Tailwind 的复用原则。Tailwind: 配置和插件
本章将讨论如何配置 tailwind,以及几个 tailwind 官方插件。Tailwind: 制作响应式博客
本章我们使用 tailwind 将之前课程中 NextJS 迷你博客改造为响应式的布局。
Tailwind: 使用 flex 和 grid 进行响应式布局
有关 float
布局
之所以一上来就“批判” float
,是因为用它来进行页面布局的历史太悠久了——我们要批判的不是 float
,而是到今天还在用 float
布局的人。
float
的本意是实现图文混排,就像报刊杂志那样,能让文字环绕在图片周围。在以前的 CSS 2 时代,不知道哪个小聪明(或许是谷某歌)使用float
再配合一些“黑魔法”,让 div
布局替换掉了更可恶的 table
布局。不得不说,这是具有划时代意义的,它让 HTML 语义化迈向了新篇章。
由于 float
本就不是为了布局而生,所以用它来布局需要做很多工作,而且还需要“黑魔法”来清除浮动。让我们来回(xi)顾(shu)一下它的弊端:
- 需要用“黑魔法”来清除浮动——比如鼎(chou)鼎(ming)有(zhao)名(zhu)的
clearfix
- 如果需要实现布局元素的对齐,又要使用“黑魔法”
- 需要手动精确计算参与布局的元素的尺寸
- 如果需要让参与布局的元素之间颜色间隙,又需要手动精确计算
- 如果要实现响应式布局,几何量级的噩梦
到了现在的 CSS 3 时代,让我们跟 float
布局说声再见,让 float
回归它的本职:图文混排。能这么有底气的说这句话,是因为 CSS 3 提供了专门用于布局的 flex
和 grid
。
flex
更适合一维布局,而 grid
更适合多维布局。当然这不是绝对的,通过嵌套 flex
也可以实现多维布局;同样地,grid
都能用来多维布局,一维布局更不在话下。我是想告诉读者,要学会在不同的场景选择最适合的技术。
Tailwind 官方文档中,专门将 flex
和 grid
放在同一个专题里进行描述,让我们一起来体验新时代的布局。
为了便于课程讲解,从本章开始的示例代码中,我会给每个元素加上
id
。它只是为了课程讲解,没有特别的作用。
为了便于课程讲解,从本章开始的示例代码中,我会给每个元素加上 id
。它只是为了课程讲解,没有特别的作用。
flex
布局
国人更喜欢将其称为弹性布局,确实挺符合它的气质的。在 tailwind 中,使用 flex
类开启 flex
布局:
<div class="flex"></div>
开始布局
<div class="flex" id="main">
<div class="bg-red-50" id="left">左</div>
<div class="bg-blue-50" id="right">右</div>
</div>
点击这里打开代码并预览效果。你会发现,只需要在父元素(#main
)中加上 flex
类,子元素自动进行了水平方向的布局,子元素根本不需要设置跟布局相关的样式。
#main
flex
:开启flex
布局
#left
bg-red-50
:为了便于查看效果,给它设置50号红色的背景
#right
bg-blue-50
:给它设置50号蓝色背景
flex
:开启flex
布局
bg-red-50
:为了便于查看效果,给它设置50号红色的背景
bg-blue-50
:给它设置50号蓝色背景
接下来,让我们继续优化这个布局
让布局元素更具意义
<div class="flex max-w-2xl mx-auto" id="main">
<div class="bg-red-50 w-1/3 h-52" id="left">左</div>
<div class="bg-blue-50 w-2/3 h-36" id="right">右</div>
</div>
点击这里打开代码并预览效果。你看到,两个子元素已经拥有了宽度和高度,它们水平排列在容器上。同时,虽然两个子元素的高度不一样,但它们在垂直方向上依然保持顶端对齐。
#main
max-w-2xl
:设置整个布局容器的最大宽度是2xl
mx-auto
:实现水平居中
#left
w-1/3
:设置它的宽度是父容器的三分之一- 很神奇的是,tailwind 的类里竟然能写分数形式。这不奇怪,它还提供了一些小数形式的类
- 此例中,我们想精确控制子元素的宽度,所以这里使用了
width
,但它和我们响应式布局的原则并不冲突:- 它是基于它的父容器的宽度设置的,而它的父容器的宽度是通过响应式的
max-w-2xl
指定 - 它使用的是三分之一这种相对值,而不是类似
33px
这样的绝对值
- 它是基于它的父容器的宽度设置的,而它的父容器的宽度是通过响应式的
- 由于我们的内容很少,在没有其它属性的帮助下,
flex
自动计算的宽度会非常小(比如上一步的例子)。我们可以通过很多方式来让这个子元素不那么窄,比如本例通过宽度来实现。
h-52
:设置它的高度是52
#right
w-2/3
:设置它的宽度是父容器的三分之二h-36
:设置它的高度是36
max-w-2xl
:设置整个布局容器的最大宽度是2xl
mx-auto
:实现水平居中
w-1/3
:设置它的宽度是父容器的三分之一- 很神奇的是,tailwind 的类里竟然能写分数形式。这不奇怪,它还提供了一些小数形式的类
- 此例中,我们想精确控制子元素的宽度,所以这里使用了
width
,但它和我们响应式布局的原则并不冲突:- 它是基于它的父容器的宽度设置的,而它的父容器的宽度是通过响应式的
max-w-2xl
指定 - 它使用的是三分之一这种相对值,而不是类似
33px
这样的绝对值
- 它是基于它的父容器的宽度设置的,而它的父容器的宽度是通过响应式的
- 由于我们的内容很少,在没有其它属性的帮助下,
flex
自动计算的宽度会非常小(比如上一步的例子)。我们可以通过很多方式来让这个子元素不那么窄,比如本例通过宽度来实现。
h-52
:设置它的高度是52
- 很神奇的是,tailwind 的类里竟然能写分数形式。这不奇怪,它还提供了一些小数形式的类
- 此例中,我们想精确控制子元素的宽度,所以这里使用了
width
,但它和我们响应式布局的原则并不冲突:- 它是基于它的父容器的宽度设置的,而它的父容器的宽度是通过响应式的
max-w-2xl
指定 - 它使用的是三分之一这种相对值,而不是类似
33px
这样的绝对值
- 它是基于它的父容器的宽度设置的,而它的父容器的宽度是通过响应式的
- 由于我们的内容很少,在没有其它属性的帮助下,
flex
自动计算的宽度会非常小(比如上一步的例子)。我们可以通过很多方式来让这个子元素不那么窄,比如本例通过宽度来实现。
- 它是基于它的父容器的宽度设置的,而它的父容器的宽度是通过响应式的
max-w-2xl
指定 - 它使用的是三分之一这种相对值,而不是类似
33px
这样的绝对值
w-2/3
:设置它的宽度是父容器的三分之二h-36
:设置它的高度是36
继续我们的示例,现在,我们想实现这样的效果:
- 两个子元素是从左往右分布的
- 两个子元素之间要有
2
个单位的间隙 - 两个子元素之间,垂直方向不再是顶端对齐,而是底部对齐
<div class="flex max-w-2xl mx-auto justify-start items-end space-x-2" id="main">
<div class="bg-red-50 w-1/3 h-52" id="left">左</div>
<div class="bg-blue-50 w-2/3 h-36" id="right">右</div>
</div>
点击这里查看效果。
#main
justify-start
:设置子元素从左往右(准确说是从头到尾,从开始到结束。对于水平方向来说是从左到右,对于垂直方向来说是从上到下)进行分布,这是默认值。它还有其它值可供设置,比如常用的:justify-end
:从结束到开始进行分布(水平:从右到左;垂直:从下到上)justify-between
:两端分布- 更多可选值请查看官方文档
items-end
:设置子元素的垂直底部对齐,它还有其它值可供设置:items-center
:垂直居中对齐items-start
:默认值。垂直顶部对齐- 更多可选值请查看官方文档
space-x-2
:设置子元素之间的水平间隙为2
。其中的x
代表水平方向,可以改成y
来表示垂直方向,比如space-y-2
。你可以点击这里查看官方文档- 原生 CSS 提供了
gap
,它也可以设置子元素的间隙,我们将在下文的grid
布局里使用到 - 通过查看生成的 CSS 可知,
space
是 tailwind 封装的一个工具类,并不像gap
那样,是原生CSS直接提供的。 space
是通过一系列计算,通过伪类给子元素设置margin
值实现
- 原生 CSS 提供了
justify-start
:设置子元素从左往右(准确说是从头到尾,从开始到结束。对于水平方向来说是从左到右,对于垂直方向来说是从上到下)进行分布,这是默认值。它还有其它值可供设置,比如常用的:justify-end
:从结束到开始进行分布(水平:从右到左;垂直:从下到上)justify-between
:两端分布- 更多可选值请查看官方文档
items-end
:设置子元素的垂直底部对齐,它还有其它值可供设置:items-center
:垂直居中对齐items-start
:默认值。垂直顶部对齐- 更多可选值请查看官方文档
space-x-2
:设置子元素之间的水平间隙为2
。其中的x
代表水平方向,可以改成y
来表示垂直方向,比如space-y-2
。你可以点击这里查看官方文档- 原生 CSS 提供了
gap
,它也可以设置子元素的间隙,我们将在下文的grid
布局里使用到 - 通过查看生成的 CSS 可知,
space
是 tailwind 封装的一个工具类,并不像gap
那样,是原生CSS直接提供的。 space
是通过一系列计算,通过伪类给子元素设置margin
值实现
- 原生 CSS 提供了
justify-end
:从结束到开始进行分布(水平:从右到左;垂直:从下到上)justify-between
:两端分布- 更多可选值请查看官方文档
items-center
:垂直居中对齐items-start
:默认值。垂直顶部对齐- 更多可选值请查看官方文档
- 原生 CSS 提供了
gap
,它也可以设置子元素的间隙,我们将在下文的grid
布局里使用到 - 通过查看生成的 CSS 可知,
space
是 tailwind 封装的一个工具类,并不像gap
那样,是原生CSS直接提供的。 space
是通过一系列计算,通过伪类给子元素设置margin
值实现
响应式布局
我们现在想实现这么一个效果:
#left
和#right
是垂直排列的,并且占满整个#main
的宽度- 它们之间的间隙是
3
#left
和#right
是水平排列的,分别占1/3
和2/3
的宽度- 它们之间的间隙是
2
首先,我们犯了一个重大错误,违背了「移动设备优先」原则——到目前为止,所有的样式都是为桌面设备设计的。这是因为我们是要讲述基础知识,情有可原。
接下来,我们将对已有代码进行改造,使其不但遵循移动设备优先原则,还能实现需要的响应式效果。
<div class="flex max-w-2xl mx-auto flex-col space-y-3 justify-start items-end md:flex-row md:space-y-0 md:space-x-2" id="main">
<div class="bg-red-50 w-full h-52 md:w-1/3" id="left">左</div>
<div class="bg-blue-50 w-full h-36 md:w-2/3" id="right">右</div>
</div>
你应该像我这样,通过加上
md:
断点来使用移动设备优先的原则实现响应式布局;而不应该通过sm:
断点来使用桌面设备优先来实现响应式布局——虽然在本案例中,通过sm:
会更少工作量
点击这里查看效果,你会发现随时你改变预览窗口的大小,整个布局会发生改变:在小屏幕上,两个子元素是垂直排列的;而在其它屏幕上,它们是水平排列的。
#main
flex-col
:设置按“列”进行布局,就是说设置为垂直布局。- 为什么之前的示例中没有
flex-col
,它会水平布局?因为 flex 默认就是水平布局,你也可以使用flex-row
显式的进行设置 - 你可以点击这里查看 flex 布局方向。
- 为什么之前的示例中没有
space-y-3
:垂直方向设置3
个单位的间隙md:flex-row
:md
断点,设置水平布局md:space-y-0
:md
断点,设置垂直方向的间隙为0md:space-x-2
:md
断点,设置水平方向的间隙为2
个单位
#left
w-full
:设置为占满整个父容器的宽度md:w-1/3
:md
断点,设置宽度为父容器的三分之一
#right
w-full
:设置为占满整个父容器的宽度md:w-2/3
:md
断点,设置宽度为父容器的三分之二
flex-col
:设置按“列”进行布局,就是说设置为垂直布局。- 为什么之前的示例中没有
flex-col
,它会水平布局?因为 flex 默认就是水平布局,你也可以使用flex-row
显式的进行设置 - 你可以点击这里查看 flex 布局方向。
- 为什么之前的示例中没有
space-y-3
:垂直方向设置3
个单位的间隙md:flex-row
:md
断点,设置水平布局md:space-y-0
:md
断点,设置垂直方向的间隙为0md:space-x-2
:md
断点,设置水平方向的间隙为2
个单位
- 为什么之前的示例中没有
flex-col
,它会水平布局?因为 flex 默认就是水平布局,你也可以使用flex-row
显式的进行设置 - 你可以点击这里查看 flex 布局方向。
w-full
:设置为占满整个父容器的宽度md:w-1/3
:md
断点,设置宽度为父容器的三分之一
w-full
:设置为占满整个父容器的宽度md:w-2/3
:md
断点,设置宽度为父容器的三分之二
grid
布局
在 tailwind 中,使用 grid
类开启 grid
布局:
<div class="grid"></div>
我们使用 grid
改写上例中的 flex
布局。
<div class="grid" id="main">
<div class="bg-red-50" id="left">左</div>
<div class="bg-blue-50" id="right">右</div>
</div>
通过这里,你会看到:和 flex
不同,grid
默认是垂直布局。——真正原因是,grid
默认使用每行1列来布局,而我们这里有两个子元素,它们就会分成两行。
#main
:grid
:开启grid
布局。
通过设置列数来实现水平布局
我们可以通过设置 grid
的列数来实现水平布局
<div class="grid grid-cols-2" id="main">
<div class="bg-red-50" id="left">左</div>
<div class="bg-blue-50" id="right">右</div>
</div>
点击这里你可以看到,两个子元素被均分地布局在水平方向上——我们并没有给子元素设置宽度。
#main
grid-cols-2
- 设置
grid
布局时,每行使用2
列来布局 - 在默认配置中,tailwind 提供了最多
12
列,即grid-cols-12
- 你可以点击这里查看官方文档
- 设置
grid-cols-2
- 设置
grid
布局时,每行使用2
列来布局 - 在默认配置中,tailwind 提供了最多
12
列,即grid-cols-12
- 你可以点击这里查看官方文档
- 设置
- 设置
grid
布局时,每行使用2
列来布局 - 在默认配置中,tailwind 提供了最多
12
列,即grid-cols-12
- 你可以点击这里查看官方文档
通过合并来限定子元素宽度
我们知道,设置了列数之后,grid
会均分地布局每个子元素——就是说,每个子元素的宽度是一样的。我们可以配置列数和合并列来实现限定子元素宽度
<div class="grid grid-cols-3" id="main">
<div class="bg-red-50" id="left">左</div>
<div class="bg-blue-50 col-span-2" id="right">右</div>
</div>
#main
grid-cols-3
:设置每行使用3列来布局
#right
col-span-2
:- 设置占用
2
列,即合并。 - 在没有设置这个之前,每个子元素占用
1
列,比如#left
元素,它并没有设置,但默认值就是col-span-1
- 官方文档
- 设置占用
grid-cols-3
:设置每行使用3列来布局
col-span-2
:- 设置占用
2
列,即合并。 - 在没有设置这个之前,每个子元素占用
1
列,比如#left
元素,它并没有设置,但默认值就是col-span-1
- 官方文档
- 设置占用
- 设置占用
2
列,即合并。 - 在没有设置这个之前,每个子元素占用
1
列,比如#left
元素,它并没有设置,但默认值就是col-span-1
- 官方文档
grid
不但能设置列、合并列;还能设置行、合并行。这就是grid
多维布局的表现,两者结合可以实现很灵活的布局。
grid
不但能设置列、合并列;还能设置行、合并行。这就是 grid
多维布局的表现,两者结合可以实现很灵活的布局。
设置对齐
<div class="grid grid-cols-3 items-end" id="main">
<div class="bg-red-50 h-56" id="left">左</div>
<div class="bg-blue-50 col-span-2 h-32" id="right">右</div>
</div>
查看效果会发现,grid
和 flex
一样,可以通过 items-*
来设置垂直对齐方式。
响应式布局
我们来实现和 flex 布局中,最终的响应式布局效果。
<div class="grid grid-cols-1 items-end gap-y-3 md:grid-cols-3 md:gap-y-0 md:gap-x-2" id="main">
<div class="bg-red-50 h-56" id="left">左</div>
<div class="bg-blue-50 col-span-1 h-32 md:col-span-2" id="right">右</div>
</div>
点击这里查看效果。
#main
grid-cols-1
:设置每行1列进行布局gap-y-3
:设置垂直方向间隙为3
【gap
的文档】md:grid-cols-3
:md
断点,设置每行3列进行布局md:gap-y-0
:md
断点,设置垂直方向间隙为0md:gap-x-2
:md
断点,设置水平方向间隙为2
#right
col-span-1
:设置占用1列md:col-span-2
:md
断点,设置占用2列
grid-cols-1
:设置每行1列进行布局gap-y-3
:设置垂直方向间隙为3
【gap
的文档】md:grid-cols-3
:md
断点,设置每行3列进行布局md:gap-y-0
:md
断点,设置垂直方向间隙为0md:gap-x-2
:md
断点,设置水平方向间隙为2
col-span-1
:设置占用1列md:col-span-2
:md
断点,设置占用2列