使用CSS网格建立会议时间表
巧妙运用新技术的成就感无与伦比!阅读各种入门指南,欣赏炫酷的演示固然不错,但只有在自己的项目中实际运用时,才能真正体会其精髓。
在为会议日程安排构建灵活布局的过程中,我对CSS Grid有了新的认识。该项目的各项需求与Grid的优势完美契合:二维(垂直和水平)布局,以及子元素的复杂定位。在构建概念验证的过程中,我发现了一些技巧,使代码高度可读,且使用起来非常有趣。
最终的演示包含了一些有趣的CSS Grid特性,并迫使我深入研究一些日常开发中不常遇到的Grid细节。
在开始之前,最好打开另一个标签页,参考CSS-Tricks的CSS Grid指南,以便随时查阅文中涉及的概念。
布局需求定义
我着手创建以下布局,灵感来自WordCamp——每年世界各地举办的数百场以WordPress为主题的会议。这些活动规模和形式各异,但都使用相同的日程安排布局工具。
我曾协助安排过几次WordCamp,并设计过WordCamp网站,因此我了解现有HTML表格布局的不足之处。如果日程安排不符合统一网格,那么……¯\_(ツ)_/¯
为了寻找更好的方法,我首先列出了布局需求:
-
可变长度的会议(限制在设定的时间增量内)
想象一下,三个房间里同时进行连续的一小时演讲,另一个房间里进行两小时的研讨会。 - 跨越一个或多个“赛道”的会议赛道通常与场地的特定房间相关联。就我所在西雅图的WordCamp而言,场地可以拆除一堵墙来合并两个房间!
-
日程安排可以包含空闲时间
最后一刻的取消或超短的会议会在日程安排中留下空隙。 -
设计易于使用CSS自定义
WordCamp网站仅允许通过CSS进行主题设置。 -
布局可以根据CMS内容自动生成
由于我们是在数千个网站上根据结构化的会议数据构建布局,因此我们不能依赖任何过于巧妙或定制的HTML或CSS。
开始:稳固的HTML
在编写任何CSS之前,我总是先从坚实的HTML开始。
顶级<div>将具有<code>.schedule
类,并作为网格父元素。每个唯一开始时间都有其自己的标题,后跟所有在该时间开始的会议。每个会议的标记并不重要,但请确保无需查看布局即可了解会议的时间和地点。(稍后您将明白原因。)
<h2 id="会议日程">会议日程</h2> <div class="schedule"> <h3 id="am">8:00am</h3> <div class="session session-1"> <h4 id="a-href-https-www-php-cn-link-ac-c-dd-dc-b-e-fe-c-e-b-会议主题-a"><a href="https://www.php.cn/link/93ac0c50dd620dc7b88e5fe05c70e15b">会议主题</a></h4> 8:00am - 9:00am 赛道 1 演讲者姓名 </div> <h3 id="am">9:00am</h3> <div class="session session-2"> <h4 id="a-href-https-www-php-cn-link-ac-c-dd-dc-b-e-fe-c-e-b-会议主题-a"><a href="https://www.php.cn/link/93ac0c50dd620dc7b88e5fe05c70e15b">会议主题</a></h4> 9:00am - 10:00am 赛道 1 演讲者姓名 </div> </div>
移动布局和网格回退完成!
添加一些您自己的CSS来美化页面,我们的移动布局和不支持CSS Grid浏览器的回退就已经完成了!
以下是使用我所用颜色的样子:
添加网格布局
现在是实际的CSS Grid部分!
我在构建这个过程中灵光一现的时刻来自于阅读Robin在CSS-Tricks上的文章,“使用CSS Grid制作条形图”。简而言之:一个网格行代表图表高度的1%,因此条形跨越的行数与其代表的百分比相同。
.chart { display: grid; grid-template-rows: repeat(100, 1fr); /* 1行=1%! */ } .fifty-percent-bar { grid-row: 51 / 101; /* 101 - 51 = 50 => 50% */ }
这让我意识到,网格非常适合任何与某种规则增量单位相关的布局。在日程安排的情况下,该单位是时间!在本演示中,我们将使用30分钟的增量,但您可以根据自己的需要进行调整。(只需注意Chrome的bug,它将Grid布局限制为1000行。)
我尝试的第一个版本使用了与Robin的条形图类似的语法和一些基本的数学运算来放置会议。我们使用八行,因为在上午8点到中午12点之间有八个30分钟的增量。请记住,隐式网格线编号从1开始(而不是0),因此网格行编号为1到9。
.schedule { display: grid; grid-template-rows: repeat(8, 1fr); } .session-1 { grid-row: 1 / 3; /* 上午8点-9点,3 - 1 = 2个30分钟增量 */ } .session-2 { grid-row: 3 / 6; /* 上午9点-10点30分,6-3 = 3个30分钟增量 */ }
这种技术的缺点是,在一个有很多行的网格上放置项目非常抽象和令人困惑。(这个问题也给Robin的条形图演示增加了大量的复杂性。)
这就是命名网格线发挥作用的地方!我们可以根据相应的时间,为每条线赋予一个可预测的名称,而不是依赖网格线编号。
.schedule { display: grid; grid-template-rows: [time-0800] 1fr [time-0830] 1fr [time-0900] 1fr [time-0930] 1fr; /* etc... 注意:使用24小时制的时间作为线名 */ } .session-1 { grid-row: time-0800 / time-0900; } .session-2 { grid-row: time-0900 / time-1030; }
这非常容易理解。无需复杂的数学计算来确定会议开始或结束前后的行数。更好的是,我们可以使用存储在WordPress中的信息生成网格线名称和会议布局样式。向网格添加开始和结束时间,就可以了!
由于日程安排有多个赛道,我们需要为每个赛道设置一列。赛道的工作方式与时间类似,为每个网格列线使用命名的赛道线。还有一列额外的第一列用于开始时间标题。
.schedule { /* continued */ grid-template-columns: [times] 4em [track-1-start] 1fr [track-1-end track-2-start] 1fr [track-2-end track-3-start] 1fr [track-3-end track-4-start] 1fr [track-4-end]; }
但是在这里,我们将命名网格线更进一步。每条线都获得两个名称:一个表示它开始的赛道,一个表示它结束的赛道。这并非严格必要,但它使代码更加清晰,尤其是在会议跨越多个列时。
定义了基于时间和赛道的网格线后,我们现在只需知道会议的时间和赛道即可放置任何会议!
.session-8 { grid-row: time-1030 / time-1100; grid-column: track-2-start / track-3-end; /* 跨越两个赛道! */ }
将所有这些放在一起,我们得到了一些冗长但极其可读的代码,使用起来非常令人愉快。
@media screen and (min-width: 700px) { .schedule { display: grid; grid-gap: 1em; grid-template-rows: [tracks] auto /* 预示! */ [time-0800] 1fr [time-0830] 1fr [time-0900] 1fr [time-0930] 1fr [time-1000] 1fr [time-1030] 1fr [time-1100] 1fr [time-1130] 1fr [time-1200] 1fr; grid-template-columns: [times] 4em [track-1-start] 1fr [track-1-end track-2-start] 1fr [track-2-end track-3-start] 1fr [track-3-end track-4-start] 1fr [track-4-end]; } .time-slot { grid-column: times; } }
<div style="grid-column: track-1; grid-row: time-0800 / time-0900;"> </div> <div style="grid-column: track-2; grid-row: time-0800 / time-0900"> </div>
最终代码使用内联样式进行会议放置,这对我来说感觉很对。如果您不喜欢这样做并且正在使用更现代的浏览器,您可以通过CSS变量将行名传递给CSS。
快速说明:使用fr单位与auto值进行行高设置
值得注意的一个细节是使用fr单位来定义行高。
当使用1fr确定行高时,所有行都具有相同的高度。该高度由日程安排中最高行的内容决定。(我不得不阅读W3C关于fr的规范才能弄清楚这一点!)这会产生一个高度与时间成比例的漂亮日程安排,但也可能导致非常高的布局。
例如,如果您的日程安排网格从上午7点到下午6点使用15分钟的增量,则共有48个网格行。在这种情况下,您可能希望使用auto作为您的行高,因为每个网格行的高度由其内容决定,因此日程安排更加紧凑。
关于辅助功能的一句话
某些CSS Grid技术确实存在辅助功能方面的担忧。具体来说,以与源顺序不匹配的方式视觉上更改信息顺序的能力会给使用键盘导航的人带来问题。
此布局使用此功能在网格上任意放置项目,因此需要谨慎。但是,由于标题和源顺序与开始时间的可视化对齐,因此在我看来,这似乎是一种安全的使用方式。
如果您受到启发去做类似的事情,请仔细考虑辅助功能。在这种情况下,按时间顺序排列信息是有意义的,但我可以想象一个合法的案例,即TAB顺序是向下而不是横向。(修改此演示以执行此操作应该不太难!)
无论您做什么,都要始终考虑辅助功能。
添加粘性赛道名称
最后,是时候添加看起来像表格标题的赛道名称到每一列的顶部了。由于会议的赛道已经可见,我选择使用aria-hidden="true"
来隐藏辅助技术中的“标题”。
赛道名称位于第一行网格中,方便地命名为“tracks”。只要您没有任何奇怪的溢出问题,position: sticky
就会让这些名称在滚动时保持可见。
赛道 1 赛道 2 赛道 3 赛道 4
.track-slot { display: none; /* 仅在使用Grid布局时可见 */ } @supports( display:grid ) { @media screen and (min-width:700px) { .track-slot { grid-row: tracks; display: block; position: sticky; top: 0; z-index: 1000; background-color: rgba(255,255,255,.9); } } }
这是最终演示的一个巧妙的收尾润色。✨
结果
以下是我们介绍的所有内容组合在一起后的样子!
我们才刚刚开始
这个日程安排绝对是我制作过的最令人满意的CSS Grid应用。我喜欢它的“数据驱动”和语义化的行命名方式,辅助功能和CMS需求也完美契合,没有任何不便。
对我来说,唯一剩下的问题是还有哪些其他类型的“数据驱动”网格可以构建?我看到了一些很棒的日历布局,还有一个大富翁棋盘布局。那么足球场、时间线、餐桌或剧院座位呢?还有什么?
以上是使用CSS网格建立会议时间表的详细内容。更多信息请关注PHP中文网其他相关文章!

热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

Video Face Swap
使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热门文章

热工具

记事本++7.3.1
好用且免费的代码编辑器

SublimeText3汉化版
中文版,非常好用

禅工作室 13.0.1
功能强大的PHP集成开发环境

Dreamweaver CS6
视觉化网页开发工具

SublimeText3 Mac版
神级代码编辑软件(SublimeText3)

关于Flex布局中紫色斜线区域的疑问在使用Flex布局时,你可能会遇到一些令人困惑的现象,比如在开发者工具(d...

在元素个数不固定的情况下如何通过CSS选择第一个指定类名的子元素在处理HTML结构时,常常会遇到元素个数不�...
