整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:

HTML布局和框架

页布局对改善网站的外观非常重要。

请慎重设计您的网页布局。

实例

使用 <div> 元素的网页布局

[demo]

<!DOCTYPE html>

<html>

<head>

<meta charset="UTF-8">

<style type="text/css">

div#container{width:500px}

div#header {background-color:#99bbbb;}

div#menu {background-color:#ffff99;height:200px;width:150px;float:left;}

div#content {background-color:#EEEEEE;height:200px;width:350px;float:left;}

div#footer {background-color:#99bbbb;clear:both;text-align:center;}

h1 {margin-bottom:0;}

h2 {margin-bottom:0;font-size:18px;}

ul {margin:0;}

li {list-style:none;}

</style>

</head>

<body>

<div id="container">

<div id="header">

<h1>Main Title of Web Page</h1>

</div>

<div id="menu">

<h2>Menu</h2>

<ul>

<li>HTML</li>

<li>CSS</li>

<li>JavaScript</li>

</ul>

</div>

<div id="content">Content goes here</div>

<div id="footer">Copyright W3School.com.cn</div>

</div>

</body>

</html>

[/demo]

如何使用 <div> 元素添加布局。

使用 <table> 元素的网页布局

[demo]

<!DOCTYPE html>

<html>

<head>

<meta charset="UTF-8">

</head>

<body>

<table width="500" border="0">

<tr>

<td colspan="2" style="background-color:#99bbbb;">

<h1>Main Title of Web Page</h1>

</td>

</tr>

<tr valign="top">

<td style="background-color:#ffff99;width:100px;text-align:top;">

<b>Menu</b><br />

HTML<br />

CSS<br />

JavaScript

</td>

<td style="background-color:#EEEEEE;height:200px;width:400px;text-align:top;">

Content goes here</td>

</tr>

<tr>

<td colspan="2" style="background-color:#99bbbb;text-align:center;">

Copyright W3School.com.cn</td>

</tr>

</table>

</body>

</html>

[/demo]

如何使用 <table> 元素添加布局。

网站布局

大多数网站会把内容安排到多个列中(就像杂志或报纸那样)。

可以使用 <div> 或者 <table> 元素来创建多列。CSS 用于对元素进行定位,或者为页面创建背景以及色彩丰富的外观。

提示:即使可以使用 HTML 表格来创建漂亮的布局,但设计表格的目的是呈现表格化数据 - 表格不是布局工具!

HTML 布局 - 使用 <div> 元素

div 元素是用于分组 HTML 元素的块级元素。

下面的例子使用五个 div 元素来创建多列布局:

实例

[demo]

<!DOCTYPE html>

<html>

<head>

<meta charset="UTF-8">

<style type="text/css">

div#container{width:500px}

div#header {background-color:#99bbbb;}

div#menu {background-color:#ffff99; height:200px; width:100px; float:left;}

div#content {background-color:#EEEEEE; height:200px; width:400px; float:left;}

div#footer {background-color:#99bbbb; clear:both; text-align:center;}

h1 {margin-bottom:0;}

h2 {margin-bottom:0; font-size:14px;}

ul {margin:0;}

li {list-style:none;}

</style>

</head>

<body>

<div id="container">

<div id="header">

<h1>Main Title of Web Page</h1>

</div>

<div id="menu">

<h2>Menu</h2>

<ul>

<li>HTML</li>

<li>CSS</li>

<li>JavaScript</li>

</ul>

</div>

<div id="content">Content goes here</div>

<div id="footer">Copyright W3School.com.cn</div>

</div>

</body>

</html>

[/demo]

上面的 HTML 代码会产生如下结果:

使用 div 和 CSS 进行布局

HTML 布局 - 使用表格

使用 HTML <table> 标签是创建布局的一种简单的方式。

可以使用 <div> 或者 <table> 元素来创建多列。CSS 用于对元素进行定位,或者为页面创建背景以及色彩丰富的外观。

提示:即使可以使用 HTML 表格来创建漂亮的布局,但设计表格的目的是呈现表格化数据 - 表格不是布局工具!

下面的例子使用三行两列的表格 - 第一和最后一行使用 colspan 属性来横跨两列:

实例

[demo]

<!DOCTYPE html>

<html>

<head>

<meta charset="UTF-8">

</head>

<body>

<table width="500" border="0">

<tr>

<td colspan="2" style="background-color:#99bbbb;">

<h1>Main Title of Web Page</h1>

</td>

</tr>

<tr valign="top">

<td style="background-color:#ffff99;width:100px;text-align:top;">

<b>Menu</b><br />

HTML<br />

CSS<br />

JavaScript

</td>

<td style="background-color:#EEEEEE;height:200px;width:400px;text-align:top;">

Content goes here</td>

</tr>

<tr>

<td colspan="2" style="background-color:#99bbbb;text-align:center;">

Copyright W3School.com.cn</td>

</tr>

</table>

</body>

</html>

[/demo]

上面的 HTML 代码会产生以下结果:

使用表格进行布局

HTML 布局 - 有用的提示

提示:使用 CSS 最大的好处是,如果把 CSS 代码存放到外部样式表中,那么站点会更易于维护。通过编辑单一的文件,就可以改变所有页面的布局。如需学习更多有关 CSS 的知识,请访问我们的 CSS 教程。

提示:由于创建高级的布局非常耗时,使用模板是一个快速的选项。通过搜索引擎可以找到很多免费的网站模板(您可以使用这些预先构建好的网站布局,并优化它们)。

HTML 布局标签

标签 描述

<div> 定义文档中的分区或节(division/section)。

<span> 定义 span,用来组合文档中的行内元素。

通过使用框架,你可以在同一个浏览器窗口中显示不止一个页面。

实例

垂直框架

[demo]

<html>

<frameset cols="25%,50%,25%">

<frame src="/example/html/frame_a.html">

<frame src="/example/html/frame_b.html">

<frame src="/example/html/frame_c.html">

</frameset>

</html>

[/demo]

本例演示:如何使用三份不同的文档制作一个垂直框架。

水平框架

[demo]

<html>

<frameset rows="25%,50%,25%">

<frame src="/example/html/frame_a.html">

<frame src="/example/html/frame_b.html">

<frame src="/example/html/frame_c.html">

</frameset>

</html>

[/demo]

本例演示:如何使用三份不同的文档制作一个水平框架。

框架

通过使用框架,你可以在同一个浏览器窗口中显示不止一个页面。每份HTML文档称为一个框架,并且每个框架都独立于其他的框架。

使用框架的坏处:

开发人员必须同时跟踪更多的HTML文档

很难打印整张页面

框架结构标签(<frameset>)

框架结构标签(<frameset>)定义如何将窗口分割为框架

每个 frameset 定义了一系列行或列

rows/columns 的值规定了每行或每列占据屏幕的面积

编者注:frameset 标签也被某些文章和书籍译为框架集。

框架标签(Frame)

Frame 标签定义了放置在每个框架中的 HTML 文档。

在下面的这个例子中,我们设置了一个两列的框架集。第一列被设置为占据浏览器窗口的 25%。第二列被设置为占据浏览器窗口的 75%。HTML 文档 "frame_a.htm" 被置于第一个列中,而 HTML 文档 "frame_b.htm" 被置于第二个列中:

<frameset cols="25%,75%">

<frame src="frame_a.htm">

<frame src="frame_b.htm">

</frameset>

基本的注意事项 - 有用的提示:

假如一个框架有可见边框,用户可以拖动边框来改变它的大小。为了避免这种情况发生,可以在 <frame> 标签中加入:noresize="noresize"。

为不支持框架的浏览器添加 <noframes> 标签。

重要提示:不能将 <body></body> 标签与 <frameset></frameset> 标签同时使用!不过,假如你添加包含一段文本的 <noframes> 标签,就必须将这段文字嵌套于 <body></body> 标签内。(在下面的第一个实例中,可以查看它是如何实现的。)

更多实例

如何使用 <noframes> 标签

[demo]

<html>

<frameset cols="25%,50%,25%">

<frame src="/example/html/frame_a.html">

<frame src="/example/html/frame_b.html">

<frame src="/example/html/frame_c.html">

<noframes>

<body>您的浏览器无法处理框架!</body>

</noframes>

</frameset>

</html>

[/demo]

本例演示:如何使用 <noframes> 标签。

混合框架结构

[demo]

<html>

<frameset rows="50%,50%">

<frame src="/example/html/frame_a.html">

<frameset cols="25%,75%">

<frame src="/example/html/frame_b.html">

<frame src="/example/html/frame_c.html">

</frameset>

</frameset>

</html>

[/demo]

本例演示如何制作含有三份文档的框架结构,同时将他们混合置于行和列之中。

含有 noresize="noresize" 属性的框架结构

[demo]

<html>

<frameset cols="50%,*,25%">

<frame src="/example/html/frame_a.html" noresize="noresize" />

<frame src="/example/html/frame_b.html" />

<frame src="/example/html/frame_c.html" />

</frameset>

</html>

[/demo]

本例演示 noresize 属性。在本例中,框架是不可调整尺寸的。在框架间的边框上拖动鼠标,你会发现边框是无法移动的。

导航框架

[demo]

<html>

<frameset cols="120,*">

<frame src="/example/html/html_contents.html">

<frame src="/example/html/frame_a.html" name="showframe">

</frameset>

</html>

[/demo]

本例演示如何制作导航框架。导航框架包含一个将第二个框架作为目标的链接列表。名为 "contents.htm" 的文件包含三个链接。

内联框架

[demo]

<html>

<head>

<meta charset="UTF-8">

</head>

<body>

<iframe src="./imagecopy1234567890/test.jpg"></iframe>

<p>一些老的浏览器不支持 iframe。</p>

<p>如果得不到支持,iframe 是不可见的。</p>

</body>

</html>

[/demo]

本例演示如何创建内联框架(HTML 页中的框架)。

跳转至框架内的一个指定的节

[demo]

<html>

<frameset cols="20%,80%">

<frame src="/example/html/frame_a.html">

<frame src="/example/html/link.html#C10">

</frameset>

</html>

[/demo]

本例演示两个框架。其中的一个框架设置了指向另一个文件内指定的节的链接。这个"link.htm"文件内指定的节使用 <a name="C10"> 进行标识。

使用框架导航跳转至指定的节

[demo]

<html>

<frameset cols="180,*">

<frame src="/example/html/content.html">

<frame src="/example/html/link.html" name="showframe">

</frameset>

</html>

[/demo]

本例演示两个框架。左侧的导航框架包含了一个链接列表,这些链接将第二个框架作为目标。第二个框架显示被链接的文档。导航框架其中的链接指向目标文件中指定的节。

lt;marquee>...</marquee>普通卷动

<marquee behavior=slide>...</marquee>滑动

<marquee behavior=scroll>...</marquee>预设卷动

<marquee behavior=alternate>...</marquee>来回卷动

<marquee direction=down>...</marquee>向下卷动

<marquee direction=up>...</marquee>向上卷动

<marquee direction=right></marquee>向右卷动

<marquee direction=left></marquee>向左卷动

<marquee loop=2>...</marquee>卷动次数

<marquee width=180>...</marquee>设定宽度

<marquee height=30>...</marquee>设定高度

<marquee bgcolor=FF0000>...</marquee>设定背景颜色

<marquee scrollamount=30>...</marquee>设定卷动距离

<marquee scrolldelay=300>...</marquee>设定卷动时间

<!>字体效果

<h1>...</h1>标题字(最大)

<h6>...</h6>标题字(最小)

<b>...</b>粗体字

<strong>...</strong>粗体字(强调)

<i>...</i>斜体字

<em>...</em>斜体字(强调)

<dfn>...</dfn>斜体字(表示定义)

<u>...</u>底线

<ins>...</ins>底线(表示插入文字)

<strike>...</strike>横线

<s>...</s>删除线

<del>...</del>删除线(表示删除)

<kbd>...</kbd>键盘文字

<tt>...</tt> 打字体

<xmp>...</xmp>固定宽度字体(在文件中空白、换行、定位功能有效)

<plaintext>...</plaintext>固定宽度字体(不执行标记符号)

<listing>...</listing> 固定宽度小字体

<font color=00ff00>...</font>字体颜色

<font size=1>...</font>最小字体

<font style =font-size:100 px>...</font>无限增大

<!>区断标记

<hr>水平线

<hr size=9>水平线(设定大小)

<hr width=80%>水平线(设定宽度)

<hr color=ff0000>水平线(设定颜色)

<br>(换行)

<nobr>...</nobr>水域(不换行)

<p>...</p>水域(段落)

<center>...</center>置中

<!>连结格式

<base href=位址>(预设好连结路径)

<a href=位址></a>外部连结

<a href=位址 target=_blank></a>外部连结(另开新视窗)

<a href=位址 target=_top></a>外部连结(全视窗连结)

<a href=位址 target=页框名></a>外部连结(在指定页框连结)

<!>贴图/音乐

<img src=图片位址>贴图

<img src=图片位址 width=180>设定图片宽度

<img src=图片位址 height=30>设定图片高度

<img src=图片位址 alt=提示文字>设定图片提示文字

<img src=图片位址 border=1>设定图片边框

<bgsound src=MID音乐档位址>背景音乐设定

<!>表格语法

<table aling=left>...</table>表格位置,置左

<table aling=center>...</table>表格位置,置中

<table background=图片路径>...</table>背景图片的URL=就是路径网址

<table border=边框大小>...</table>设定表格边框大小(使用数字)

<table bgcolor=颜色码>...</table>设定表格的背景颜色

<table borderclor=颜色码>...</table>设定表格边框的颜色

<table borderclor=颜色码>...</table>设定表格边框的颜色

<table borderclordark=颜色码>...</table>设定表格暗边框的颜色

<table borderclorlight=颜色码>...</table>设定表格亮边框的颜色

<table cellpadding=参数>...</table>指定内容与格线之间的间距(使用数字)

<table cellspacing=参数>...</table>指定格线与格线之间的距离(使用数字)

<table cols=参数>...</table>指定表格的栏数

<table frame=参数>...</table>设定表格外框线的显示方式

<table width=宽度>...</table>指定表格的宽度大小(使用数字)

<table height=高度>...</table>指定表格的高度大小(使用数字)

<td colspan=参数>...</td>指定储存格合并栏的栏数(使用数字)

<td rowspan=参数>...</td>指定储存格合并列的列数(使用数字)

<!>分割视窗

<frameset cols="20%,*">左右分割,将左边框架分割大小为20%右边框架的大小浏览器会自动调整

<frameset rows="20%,*">上下分割,将上面框架分割大小为20%下面框架的大小浏览器会自动调整

<frameset cols="20%,*">分割左右两个框架

<frameset cols="20%,*,20%">分割左中右三个框架

<分割上下两个框架

<frameset rows="20%,*,20%">分割上中下三个框架


<! - - ... - -> 注解

<a href target> 指定超连结的分割视窗

<a href=#锚的名称> 指定锚名称的超连结

<a href> 指定超连结

<a name=锚的名称> 被连结点的名称

<address>....</address> 用来显示电子邮箱地址

<b> 粗体字

<base target> 指定超连结的分割视窗

<basefont size> 更改预设字形大小

<bgsound src> 加入背景音乐

<big> 显示大字体

<blink> 闪烁的文字

<body text link vlink> 设定文字颜色

<body> 显示本文

<br> 换行

<caption align> 设定表格标题位置

<caption>...</caption> 为表格加上标题

<center> 向中对齐

<cite>...<cite> 用於引经据典的文字

<code>...</code> 用於列出一段程式码

<comment>...</comment> 加上注解

<dd> 设定定义列表的项目解说

<dfn>...</dfn> 显示"定义"文字

<dir>...</dir> 列表文字标签

<dl>...</dl> 设定定义列表的标签

<dt> 设定定义列表的项目

<em> 强调之用

<font face> 任意指定所用的字形

<font face> 任意指定所用的字形

<font size> 设定字体大小

<form action> 设定户动式表单的处理方式

<form method> 设定户动式表单之资料传送方式

<frame marginheight> 设定视窗的上下边界

<frame marginwidth> 设定视窗的左右边界

<frame name> 为分割视窗命名

<frame noresize> 锁住分割视窗的大小

<frame scrolling> 设定分割视窗的卷轴

<frame src> 将html档加入视窗

<frameset cols> 将视窗分割成左右的子视窗

<frameset rows> 将视窗分割成上下的子视窗

<frameset>...</frameset> 划分分割视窗

<h1>~<h6> 设定文字大小

<head> 标示文件资讯

<hr> 加上分格线

<html> 文件的开始与结束

<i> 斜体字

<img align> 调整图形影像的位置

<img alt> 为你的图形影像加注

<img dynsrc loop> 加入影片

<img height width> 插入图片并预设图形大小

<img hspace> 插入图片并预设图形的左右边界

<img lowsrc> 预载图片功能

<img src border> 设定图片边界

<img src> 插入图片

<img vspace> 插入图片并预设图形的上下边界

<input type name value> 在表单中加入输入栏位

<isindex> 定义查询用表单

<kbd>...</kbd> 表示使用者输入文字

<li type>...</li> 列表的项目 ( 可指定符号 )

<marquee> 跑马灯效果

<menu>...</menu> 条列文字标签

<meta name="refresh" content url> 自动更新文件内容

<multiple> 可同时选择多项的列表栏

<noframe> 定义不出现分割视窗的文字

<ol>...</ol> 有序号的列表

<option> 定义表单中列表栏的项目

<p align> 设定对齐方向

<p> 分段

<person>...</person> 显示人名

<pre> 使用原有排列

<samp>...</samp> 用於引用字

<select>...</select> 在表单中定义列表栏

<small> 显示小字体

<strike> 文字加横线

<strong> 用於加强语气

<sub> 下标字

<sup> 上标字

<table border=n> 调整表格的宽线高度

<table cellpadding> 调整资料栏位之边界

<table cellspacing> 调整表格线的宽度

<table height> 调整表格的高度

<table width> 调整表格的宽度

<table>...</table> 产生表格的标签

<td align> 调整表格栏位之左右对齐

<td bgcolor> 设定表格栏位之背景颜色

<td colspan rowspan> 表格栏位的合并

<td nowrap> 设定表格栏位不换行

<td valign> 调整表格栏位之上下对齐

<td width> 调整表格栏位宽度

<td>...</td> 定义表格的资料栏位

<textarea name rows cols> 表单中加入多少列的文字输入栏

<textarea wrap> 决定文字输入栏是自动否换行

<th>...</th> 定义表格的标头栏位

<title> 文件标题

<tr>...</tr> 定义表格美一行

<tt> 打字机字体

<u> 文字加底线

<ul type>...</ul> 无序号的列表 ( 可指定符号 )

<var>...</var> 用於显示变数

家好,我是皮汤。最近业务调整,组内开启了前端工程化方面的基建,我主要负责 CSS 技术选型这一块,针对目前业界主流的几套方案进行了比较完善的调研与比较,分享给大家。

目前整个 CSS 工具链、工程化领域的主要方案如下:

而我们技术选型的标准如下:

- 开发速度快

- 开发体验友好

- 调试体验友好

- 可维护性友好

- 扩展性友好

- 可协作性友好

- 体积小

- 有最佳实践指导

目前主要需要对比的三套方案:

- Less/Sass + PostCSS 的纯 CSS c侧方案

- styled-components / emotion 的纯 CSS-in-JS 侧方案

- TailwindCSS 的以写辅助类为主的 HTML 侧方案

## 纯 CSS 侧方案

### 介绍与优点

> 维护状态:一般

> Star 数:16.7K

> 支持框架:无框架限制

> 项目地址:https://github.com/less/less.js

Less/Sass + PostCSS 这种方案在目前主流的组件库和企业级项目中使用很广,如 ant-design 等

它们的主要作用如下:

- 为 CSS 添加了类似 JS 的特性,你也可以使用变量、mixin,写判断等

- 引入了模块化的概念,可以在一个 less 文件中导入另外一个 less 文件进行使用

- 兼容标准,可以快速使用 CSS 新特性,兼容浏览器 CSS 差异等

这类工具能够与主流的工程化工具一起使用,如 Webpack,提供对应的 loader 如 sass-loader,然后就可以在 React/Vue 项目中建 `.scss` 文件,写 sass 语法,并导入到 React 组件中生效。

比如我写一个组件在响应式各个断点下的展示情况的 sass 代码:

```

.component {

width: 300px;

@media (min-width: 768px) {

width: 600px;

@media (min-resolution: 192dpi) {

background-image: url(/img/retina2x.png);

}

}

@media (min-width: 1280px) {

width: 800px;

}

}

```

或导入一些用于标准化浏览器差异的代码:

```

@import "normalize.css";

// component 相关的其他代码

```

### 不足

这类方案的一个主要问题就是,只是对 CSS 本身进行了增强,但是在帮助开发者如何写更好的 CSS、更高效、可维护的 CSS 方面并没有提供任何建议。

- 你依然需要自己定义 CSS 类、id,并且思考如何去用这些类、id 进行组合去描述 HTML 的样式

- 你依然可能会写很多冗余的 Less/Sass 代码,然后造成项目的负担,在可维护性方面也有巨大问题

### 优化

- 可以引入 CSS 设计规范:BEM 规范,来辅助用户在整个网页的 HTML 骨架以及对应的类上进行设计

- 可以引入 CSS Modules,将 CSS 文件进行 “作用域” 限制,确保在之后维护时,修改一个内容不会引起全局中其他样式的效果

#### BEM 规范

B (Block)、E(Element)、M(Modifier),具体就是通过块、元素、行为来定义所有的可视化功能。

拿设计一个 Button 为例:

```

/* Block */

.btn {}

/* 依赖于 Block 的 Element */

.btn__price {}

/* 修改 Block 风格的 Modifier */

.btn--orange {}

.btn--big {}

```

遵循上述规范的一个真实的 Button:

```

<a class="btn btn--big btn--orange" href="#">

<span class="btn__price"></span>

<span class="btn__text">BIG BUTTON</span>

</a>

```

可以获得如下的效果:

#### CSS Modules

CSS Modules 主要为 CSS 添加局部作用域和模块依赖,使得 CSS 也能具有组件化。

一个例子如下:

```

import React from 'react';

import style from './App.css';

export default () => {

return (

<h1 className={style.title}>

Hello World

</h1>

);

};

```

```

.title {

composes: className;

color: red;

}

```

上述经过编译会变成如下 hash 字符串:

```

<h1 class="_3zyde4l1yATCOkgn-DBWEL">

Hello World

</h1>

```

```

._3zyde4l1yATCOkgn-DBWEL {

color: red;

}

```

CSS Modules 可以与普通 CSS、Less、Sass 等结合使用。

## 纯 JS 侧方案

### 介绍与优点

> 维护状态:一般

> Star 数:35.2K

> 支持框架:React ,通过社区支持 Vue 等框架

> 项目地址:https://github.com/styled-components/styled-components

使用 JS 的模板字符串函数,在 JS 里面写 CSS 代码,这带来了两个认知的改变:

- 不是在根据 HTML,然后去写 CSS,而是站在组件设计的角度,为组件写 CSS,然后应用组件的组合思想搭建大应用

- 自动提供类似 CSS Modules 的体验,不用担心样式的全局污染问题

同时带来了很多 JS 侧才有的各种功能特性,可以让开发者用开发 JS 的方式开发 CSS,如编辑器自动补全、Lint、编译压缩等。

比如我写一个按钮:

```

const Button = styled.button`

/* Adapt the colors based on primary prop */

background: ${props => props.primary ? "palevioletred" : "white"};

color: ${props => props.primary ? "white" : "palevioletred"};

font-size: 1em;

margin: 1em;

padding: 0.25em 1em;

border: 2px solid palevioletred;

border-radius: 3px;

`;

render(

<div>

<Button>Normal</Button>

<Button primary>Primary</Button>

</div>

);

```

可以获得如下效果:

还可以扩展样式:

```

// The Button from the last section without the interpolations

const Button = styled.button`

color: palevioletred;

font-size: 1em;

margin: 1em;

padding: 0.25em 1em;

border: 2px solid palevioletred;

border-radius: 3px;

`;

// A new component based on Button, but with some override styles

const TomatoButton = styled(Button)`

color: tomato;

border-color: tomato;

`;

render(

<div>

<Button>Normal Button</Button>

<TomatoButton>Tomato Button</TomatoButton>

</div>

);

```

可以获得如下效果:

### 不足

虽然这类方案提供了在 JS 中写 CSS,充分利用 JS 的插值、组合等特性,然后应用 React 组件等组合思想,将组件与 CSS 进行细粒度绑定,让 CSS 跟随着组件一同进行组件化开发,同时提供和组件类似的模块化特性,相比 Less/Sass 这一套,可以复用 JS 社区的最佳实践等。

但是它仍然有一些不足:

- 仍然是是对 CSS 增强,提供非常大的灵活性,开发者仍然需要考虑如何去组织自己的 CSS

- 没有给出一套 “有观点” 的最佳实践做法

- 在上层也缺乏基于 styled-components 进行复用的物料库可进行参考设计和使用,导致在初始化使用时开发速度较低

- 在 JS 中写 CSS,势必带来一些本属于 JS 的限制,如 TS 下,需要对 Styled 的组件进行类型注释

- 官方维护的内容只兼容 React 框架,Vue 和其他框架都由社区提供支持

整体来说不太符合团队协作使用,需要人为总结最佳实践和规范等。

### 优化

- 寻求一套写 CSS 的最佳实践和团队协作规范

- 能够拥有大量的物料库或辅助类等,提高开发效率,快速完成应用开发

## 偏向 HTML 侧方案

### 介绍与优点

> 维护状态:积极

> Star 数:48.9K

> 支持框架:React、Vue、Svelte 等主流框架

> 项目地址:https://github.com/tailwindlabs/tailwindcss

典型的是 TailwindCSS,一个辅助类优先的 CSS 框架,提供如 `flex` 、`pt-4` 、`text-center` 、`rotate-90` 这样实用的类名,然后基于这些底层的辅助类向上组合构建任何网站,而且只需要专注于为 HTML 设置类名即可。

一个比较形象的例子可以参考如下代码:

```

<button class="btn btn--secondary">Decline</button>

<button class="btn btn--primary">Accept</button>

```

上述代码应用 BEM 风格的类名设计,然后设计两个按钮,而这两个类名类似主流组件库里面的 Button 的不同状态的设计,而这两个类又是由更加基础的 TailwindCSS 辅助类组成:

```

.btn {

@apply text-base font-medium rounded-lg p-3;

}

.btn--primary {

@apply bg-rose-500 text-white;

}

.btn--secondary {

@apply bg-gray-100 text-black;

}

```

上面的辅助类包含以下几类:

- 设置文本相关: `text-base` 、`font-medium` 、`text-white` 、`text-black`

- 设置背景相关的:`bg-rose-500` 、`bg-gray-100`

- 设置间距相关的:`p-3`

- 设置边角相关的:`rounded-lg`

通过 Tailwind 提供的 `@apply` 方法来对这些辅助类进行组合构建更上层的样式类。

上述的最终效果展示如下:

可以看到 TailwindCSS 将我们开发网站的过程抽象成为使用 Figma 等设计软件设计界面的过程,同时提供了一套用于设计的规范,相当于内置最佳实践,如颜色、阴影、字体相关的内容,一个很形象的图片可以说明这一点:

TailwindCSS 为我们规划了一个元素可以设置的属性,并且为每个属性给定了一组可以设置的值,这些属性+属性值组合成一个有机的设计系统,非常便于团队协作与共识,让我们开发网站就像做设计一样简单、快速,但是整体风格又能保持一致。

TailwindCSS 同时也能与主流组件库如 React、Vue、Svelte 结合,融入基于组件的 CSS 设计思想,但又只需要修改 HTML 上的类名,如我们设计一个食谱组件:

```

// Recipes.js

import Nav from './Nav.js'

import NavItem from './NavItem.js'

import List from './List.js'

import ListItem from './ListItem.js'

export default function Recipes({ recipes }) {

return (

<div className="divide-y divide-gray-100">

<Nav>

<NavItem href="/featured" isActive>Featured</NavItem>

<NavItem href="/popular">Popular</NavItem>

<NavItem href="/recent">Recent</NavItem>

</Nav>

<List>

{recipes.map((recipe) => (

<ListItem key={recipe.id} recipe={recipe} />

))}

</List>

</div>

)

}

// Nav.js

export default function Nav({ children }) {

return (

<nav className="p-4">

<ul className="flex space-x-2">

{children}

</ul>

</nav>

)

}

// NavItem.js

export default function NavItem({ href, isActive, children }) {

return (

<li>

<a

href={href}

className={`block px-4 py-2 rounded-md ${isActive ? 'bg-amber-100 text-amber-700' : ''}`}

>

{children}

</a>

</li>

)

}

// List.js

export default function List({ children }) {

return (

<ul className="divide-y divide-gray-100">

{children}

</ul>

)

}

//ListItem.js

export default function ListItem({ recipe }) {

return (

<article className="p-4 flex space-x-4">

<img src={recipe.image} alt="" className="flex-none w-18 h-18 rounded-lg object-cover bg-gray-100" width="144" height="144" />

<div className="min-w-0 relative flex-auto sm:pr-20 lg:pr-0 xl:pr-20">

<h2 className="text-lg font-semibold text-black mb-0.5">

{recipe.title}

</h2>

<dl className="flex flex-wrap text-sm font-medium whitespace-pre">

<div>

<dt className="sr-only">Time</dt>

<dd>

<abbr title={`${recipe.time} minutes`}>{recipe.time}m</abbr>

</dd>

</div>

<div>

<dt className="sr-only">Difficulty</dt>

<dd> · {recipe.difficulty}</dd>

</div>

<div>

<dt className="sr-only">Servings</dt>

<dd> · {recipe.servings} servings</dd>

</div>

<div className="flex-none w-full mt-0.5 font-normal">

<dt className="inline">By</dt>{' '}

<dd className="inline text-black">{recipe.author}</dd>

</div>

<div class="absolute top-0 right-0 rounded-full bg-amber-50 text-amber-900 px-2 py-0.5 hidden sm:flex lg:hidden xl:flex items-center space-x-1">

<dt className="text-amber-500">

<span className="sr-only">Rating</span>

<svg width="16" height="20" fill="currentColor">

<path d="M7.05 3.691c.3-.921 1.603-.921 1.902 0l1.07 3.292a1 1 0 00.95.69h3.462c.969 0 1.372 1.24.588 1.81l-2.8 2.034a1 1 0 00-.364 1.118l1.07 3.292c.3.921-.755 1.688-1.539 1.118l-2.8-2.034a1 1 0 00-1.176 0l-2.8 2.034c-.783.57-1.838-.197-1.539-1.118l1.07-3.292a1 1 0 00-.363-1.118L.98 9.483c-.784-.57-.381-1.81.587-1.81H5.03a1 1 0 00.95-.69L7.05 3.69z" />

</svg>

</dt>

<dd>{recipe.rating}</dd>

</div>

</dl>

</div>

</article>

)

}

```

上述食谱的效果如下:

可以看到我们无需写一行 CSS,而是在 HTML 里面应用各种辅助类,结合 React 的组件化设计,既可以轻松完成一个非常现代化且好看的食谱组件。

除了上面的特性,TailwindCSS 在响应式、新特性支持、Dark Mode、自定义配置、自定义新的辅助类、IDE 方面也提供非常优秀的支持,除此之外还有基于 TailwindCSS 构建的物料库 Tailwind UI ,提供各种各样成熟、好看、可用于生产的物料库:

![](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/1cb983da6f71470b91ac764d14907998~tplv-k3u1fbpfcp-zoom-1.image)

因为需要自定的 CSS 不多,而需要自定义的 CSS 可以定义为可复用的辅助类,所以在可维护性方面也是极好的。

### 不足

- 因为要引入一个额外的运行时,TailwindCSS 辅助类到 CSS 的编译过程,而随着组件越来越多,需要编译的工作量也会变大,所以速度会有影响

- 过于底层,相当于给了用于设计的最基础的指标,但是如果我们想要快速设计网站,那么可能还需要一致的、更加上层的组件库

- 相当于引入了一套框架,具有一定的学习成本和使用成本

### 优化

- Tailwind 2.0 支持 [JIT](https://blog.tailwindcss.com/tailwindcss-2-1 "JIT"),可以大大提升编译速度,可以考虑引入

- 基于 TailwindCSS,设计一套符合自身风格的上层组件库、物料库,便于更加快速开发

- 提前探索、学习和总结一套教程与开发最佳实践

- 探索 styled-components 等结合 TailwindCSS 的开发方式

## 参考链接

- [CSS 工程化发展历程](https://bytedance.feishu.cn/docs/doccnTRF0OZtJMgKuo3y0hIDMbc# "CSS 工程化发展历程")


/ 感谢支持/

以上便是本次分享的全部内容,希望对你有所帮助^_^

喜欢的话别忘了 分享、点赞、收藏 三连哦~

欢迎关注公众号 程序员巴士,来自字节、虾皮、招银的三端兄弟,分享编程经验、技术干货与职业规划,助你少走弯路进大厂。