用于创建 CSS 网格布局的 CLI 工具
更新
快速介绍
第一级——基准测试
第 2 级 - 获得升级
第 3 级——我们需要更深入
CSS Grid 非常适合创建各种 HTML 布局,无需依赖任何外部库。根据Caniuse的测试,它支持 95.49% 的主流浏览器(如果您需要支持 IE,我深表歉意)。
目录
- 更新!
- 快速介绍
- 基准测试| 动态创建列和行
- 升级| 硬编码常见布局预设
- 我们需要更深入地了解|我最想让你看到的是……动态生成 CSS 网格
更新
6月1日更新:
根据此博文以及Github issue的建议和评论,get-grid@next 正在开发中。为了兼容 HTML 标签、Web 组件和 ID,查询格式进行了许多重要修复。
请阅读此处的系列第二篇文章以了解新格式。
这些变化主要影响本文最后一部分解释的查询格式。
快速介绍
使用 CSS 网格创建布局非常简单,但编写较少的重复代码总是好的(我听到大家一致同意)。
我开始寻找快速生成 CSS 网格的方法。我在网上
找到了一些生成器。SitePoint 上的这个列表涵盖了其中很多。我还找到了一些文章,提供了一些常见布局(例如 Holy Grail)的代码,你可以复制粘贴。
拖放式网格生成器很棒,但我还在寻找更动态的东西。
如果能用 CLI 创建 CSS 网格布局会怎么样?它非常易读——简单到你可以用它来动态生成布局,并在运行时注入它们。
想想这个应用就很有趣。
- 您可以使用命令行中预先编写的 90% 代码创建一个基本网格
- 编写媒体查询将变得轻而易举
- (如果我们只是在做白日梦的话)……你可以编写一个自然语言处理器,将其插入到底层代码中。这样,有人就可以说:“创建一个横跨整个宽度的标题。现在,在其下方添加一个侧边栏,将其宽度设为四分之一。用内容填充剩余的行……”,这些文字就会被转换成生成代码的命令。
但我在这里有点太超前了。
让我们从简单的开始,了解一下 CLI 的工作原理。为了创建 CLI,我使用了commander.js。
如果你想参与编程,你可以使用 npm 安装该软件包
npm i -g get-grid
您可以尝试的最基本命令是:
get-grid
该工具将网格复制到剪贴板,但如果这不起作用,只需使用--output标志。
get-grid --output
你可以这样做
get-grid --help
寻求快速帮助
第一级——基准测试
我从简单开始:
用户应该能够指定他们想要的行数和列数,以及父容器类。
因此,要创建 2 列、2 行的布局,只需执行以下操作:
get-grid -c2 -r2 --class grid-holder
瞧!生成器输出了以下代码:
<div class="grid-holder">
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
</div>
.grid-holder{
display: grid;
grid-template-columns: repeat(2, 1fr);
grid-template-rows: repeat(2, 1fr);
grid-gap: 1em;
}
您会注意到,有些属性是默认设置的。
这些设置非常基础,非常简陋。不过,它仍然比手动输入要快,也比拖放操作要快。
是时候更上一层楼了。
到了下一个阶段,我希望能够用最简单的方式输入我想要的布局。
第 2 级 - 获得升级
快速创建常用布局非常方便。我硬编码了一些常用布局,并将它们插入到 switch case 中。这虽然不是什么创新或出色的功能,但它确实生成了常用布局。
所以你可以这样做:
get-grid --template holy-grail
您将获得以下代码:
<div class="grid-container">
<header>
Header
</header>
<aside class="sidebar-left">
Left Sidebar
</aside>
<article>
Article
</article>
<aside class="sidebar-right">
Right Sidebar
</aside>
<footer>
Footer
</footer>
</div>
.grid-container {
display: grid;
grid-template-columns: 150px auto 150px;
grid-template-rows: repeat(3, 100px);
grid-gap: 1em;
}
header,
aside,
article,
footer {
background: #eaeaea;
padding: 1em;
}
header, footer {
grid-column: 1 / 4;
}
这个布局是我直接从Codepen上截取的。
我之前没有创建过很多预定义布局,但我正在考虑一些有趣的方法,比如创建预设并命名,以便以后使用。
正如屏幕截图所示,该工具应该被称为“grid-this”,但我更喜欢“get-grid”。
这仍然不是我想要的“动态性”。我希望能够指定布局的样子(通过 CLI),然后代码会动态生成。
第 3 级——我们需要更深入
更新:
查询格式略有更改,以处理 ID、语义 HTML 以及 Web 组件。您可以查看本系列的第二篇文章,了解此处的更改。
对于这一步,我必须设计一种查询符号;一种简洁的符号;不需要花费很多时间去思考,并且可以快速教授的符号。
以下是我的想法:
header/sidebar-content-content-content/footer
“/”表示换行,“-”表示换列。如果整行都被同一个区域占据,则无需再次指定。
那么,我们能从中得到什么呢?
get-grid --query header/sidebar-content-content/footer
输出的代码:
<div class="grid-container">
<div class="header">header</div>
<div class="sidebar">sidebar</div>
<div class="content">content</div>
<div class="footer">footer</div>
</div>
.grid-container{
display: grid;
grid-template-rows: 1fr 1fr 1fr ;
grid-template-columns: repeat(3, 1fr);
grid-gap: 8px;
}
.header{
padding: 1rem;
grid-column: 1 / 4;
grid-row: 1 / 1;
border: 1px solid #444;
background: #eee;
}
.sidebar{
padding: 1rem;
grid-column: 1 / 2;
grid-row: 2 / 2;
border: 1px solid #444;
background: #eee;
}
.content{
padding: 1rem;
grid-column: 2 / 4;
grid-row: 2 / 2;
border: 1px solid #444;
background: #eee;
}
.footer{
padding: 1rem;
grid-column: 1 / 4;
grid-row: 3 / 3;
border: 1px solid #444;
background: #eee;
}
这确实是动态生成布局的。代码会解析你的查询(两次),并生成 grid-column 和 grid-row 属性。查询读起来就像自然语言一样,所以理论上应该可以动态创建简单的布局。
因此使用这个查询:
get-grid --query
header/sidebar1-content-content-content-sidebar2/
footer1-footer1-footer2-footer2-footer3-footer3
它有效,简单,而且动态!太棒了!
不过,我们先别急着上手。这只是一个原型,是我花了几个小时才完成的(写这篇文章的时候我还在修复bug)。它还有很多不足之处(有些我可能都没注意到)。
对于如何改进某些方面,我有一些想法。我将尝试以问答的形式进行解释:
1) 如何指定行的自定义高度?
为了指定高度,查询可以包含“:”运算符。假设它可能是这样的:
header:60px/sidebar-content-content-content:auto/footer:200px
2) 如果只有特定的行或列重复怎么办?如果一个类跨越多行(而不是多列)怎么办?
为了处理重复,我们可以使用“-”的变体以及“*”和“#”运算符。
- 我们可以使用 header/sidebar-content-3/footer 来重复整行三次,将行高增加到 3fr(“-3”不被检测为类,因为 CSS 类不能以数字开头)。
- 并且 header/sidebar-content*3/footer 仅重复“内容”列三次(保持行高 1fr)
- 或者 header/widgeta#2-content#3/widgetb/footer 将 Widgeta 高度保持在 2fr,但将内容高度增加到 3fr。“widgetb”将填满 1fr 空间。
- 我们还可以通过设置标志来改变 grid-auto-flow 属性。
3) 如果某个区域为空,会发生什么情况?
如果我们想在 Widgetb 所在的位置留出空白区域,可以使用“.”运算符,例如:header/widgeta#2-content#3/./footer
4) 如果要在类中使用“-”会发生什么?
我尝试过使用“-”以外的运算符来分隔列,但这会大大降低可读性,阅读起来也不太直观。为了解决这个问题,我们可以使用转义字符(例如“\”)来指定不属于查询本身的“-”。
我还没有考虑到所有可能的情况,以上想法也只是假设。我会随着时间的推移逐步完善这些想法。与此同时,你可以查看GitHub 仓库。如果这个工具对你有帮助,请给我点个星 :)
期待评论、想法、建议和批评!
文章来源:https://dev.to/saunved/a-cli-tool-for-creating-css-grid-layouts-2aj4