我应该使用 id 还是类来“表明”Tailwind.css 中 HTML 元素的用途?
Posted
技术标签:
【中文标题】我应该使用 id 还是类来“表明”Tailwind.css 中 HTML 元素的用途?【英文标题】:Should I be using an id or a class to "signal" the purpose of an HTML element in Tailwind.css? 【发布时间】:2021-07-17 21:05:00 【问题描述】:上下文:
我在前端使用 Alpine.js 和 Tailwind.css 构建的网站的标题上有一个复杂的 html 结构。
“复杂结构”,如:
<header class="BODY-HEADER">
<div class="NOTIFICATION-WRAPPER grid md:grid-cols ... id-cols-3 t ... font-medium ... p-4">
<div class="TOP-MSG my-auto ... inline-block hidden md:block ... text-right">
<span class="EMAIL">
<svg>...</svg>
<span class="ml-1">
email @ example . com
</span>
</div>
<div class="CONTACT-INFO flex">
<span class="PHONE mr-4">
<svg>...</svg>
<a class="ml-1">...</a>
</span>
</div>
<div class="NOTIFICATION m-auto md:my-auto ... text-center ... lg:ml-0">
Subscribe to our newsletter.
</div>
</div>
<script>
function initializeHdr()
return
...
,
menu: initializeHdrNav()
function initializeCompareHdr()
return
...
</script>
<div
x-data="sticky header logic here"
@scroll.window="scroll sticky header trigger here"
>
<div
id="js-sticky-header"
:class=" 'lg:fixed': showStickyHdr == true "
class="header-sticky top-0 z-10 w-full"
>
<div
id="menu-wrapper"
x-data="initializeHdr()"
@keydown.window.escape="searchModalOpen = false;"
@private-content-loaded.window="getAllData(event.detail.data)"
class="z-10 w-full ... bg-container-dark"
>
<nav id="MAIN-MENU" class="grid grid ... justify-between items-center ... ">
<div class="LOGO-WRAPPER md:w-40 px-5 ... 0 mx-auto ... ">
<!-- the logo -->
<a href="url to local environment's home here" title="" aria-label="the logo label here">
<!-- etc... another 1400 lines are all part of the MAIN NAVIGATION structure -->
导航中有几组链接,如果您愿意,可以使用子导航。并且导航本身在移动设备和桌面上是不同的,实现为两个包装 div。一个包装 div 包装移动设备,另一个包装桌面,但还有其他元素包装这两个 div,然后是导航上方的一些其他内容,然后是导航“存在”的同一标题中的附加信息。
TL;DR:它是一个复杂的 HTML 结构,在不同的视口上有多种布局,并有多层嵌套(加在一起,生成的 HTML 是 1500 行代码)。
问题:
最初,一位同事使用 CSS 类来表示特定部分的“含义”,例如:
<nav class="MAIN-MENU grid grid-cols-3 2xl:grid-cols-4 items-center px-5 justify-between">
我已将“违规”代码全大写,以便在此问题中更容易发现。
我试图通过“指示”元素的功能来使嵌套元素的意图更加明显。
用户 AndyJamesM 关于如何/何时使用 id 和类的解释以及 HTML4 和 HTML5 标准的比较很有用,但在这种情况下并不真正适用。
因此,我采用了不同的方法,因为它是一个唯一的元素,所以我将其移至 id
属性,如下所示:
<nav
id="main-menu"
class="grid grid-cols-3 2xl:grid-cols-4 items-center px-5 justify-between"
>
id="main-menu"
和 class="main-menu
都没有任何样式,它们只是为了“命名目的”和可读性,所以当人们浏览代码时,他们会立即知道发生了什么。
从逻辑上讲,我会说最好使用id="main-menu"
,因为:
-
它是页面上的单个元素,所以我表示它的独特性
它是从
class
属性中提取的,因为class
属性已经有太多来自其他 Tailwind 类的噪音。
它正在为将来可能连接一些 JS (Alpine.js) 功能做准备。
就保留一个空的类名来表示目的而言,我看不出这种方法的好处。我在上面的要点中列出了反对它的 3 个论点。
我找不到我会赞成使用类名作为意图信号的反驳论点。
在做出此决定时是否有任何明确定义的最佳实践可以遵循?
我有一位同事主张使用课程作为答案。我觉得这不合逻辑,但他坚持自己基于公司资历和预感的观点。我得到的论点是应该避免使用 id,但是为什么呢?
编辑:不使用id
命名的一个可能的可行原因是:我们正在“暗示”使用 JS - 实际上没有。这可以通过在每个id
值前面附加js-
来“清理”,实际上 使用 JS,但这也意味着在更新代码上浪费了额外的时间,同时不确定是否这是最好的方法。
是否有与两个给定选项不同的方法?
一种可能的替代方法是 HTML cmets。这似乎是最好的选择。
aria-labelledby
方法似乎也是朝着正确方向迈出的一步。
想到的另一件事是使用自定义数据属性。因为他们不必必须有一个值,它可以像这样简单:
<nav data-nested-desktop-sub-nav>
但问题仍然存在:什么是“最好的”方法?
【问题讨论】:
这是个人意见..... 一个人会认为是一种方式,另一个人会认为是另一种方式,第三个人会说你们都错了。 显然,HTML cmets 是一种选择。我已经根据这个更新了问题。 【参考方案1】:在 HTML 4 中,ID 用于向元素添加语义(含义/命名)。在 html5 中引入了新标签以提供更好的“开箱即用”语义
我试图通过以下方式使嵌套元素的意图更加明显 “信号”元素的功能。
nav 元素已经通过赋予元素含义来做到这一点,并声明其中的链接是主要的导航链接,屏幕阅读器知道该元素的作用是导航。
所以使用 <nav>
元素,它已经提供了意义/语义,因为它打算根据 html5 规范与主要导航元素一起使用,也许这也在 <header>
内。在结构上,这个标记提供了坚实的意义,因为它是网站标题内的主要导航。在这种情况下,我认为添加一个纯粹用于识别的 ID 没有任何价值。
“不需要所有链接都包含在
<nav>
元素中。<nav>
仅用于主要的导航链接块;通常<footer>
元素通常有一个不需要的链接列表 在<nav>
元素中。”
见:https://developer.mozilla.org/en-US/docs/Web/HTML/Element/nav#usage_notes
如果担心的话,还可以使用“aria-labelledby”来促进可访问性
"一个文档可能有多个
<nav>
元素,例如,一个用于站点 导航和一个用于页面内导航。 aria-labelledby 可以是 在这种情况下用于促进可访问性,请参阅示例。”
使用<header>
和<nav>
提供的价值远远超过任何ID。它们通过创建内容部分来帮助定义文档大纲,并为屏幕阅读器增加可访问性的价值。
标题中的导航创建大纲层次结构,如下所示:
- Header
- Main Nav
在导航上使用 ID 并没有像以前那样增加任何价值,除非您使用它来连接 JS。一个只是为了命名而挂在那里的类不会增加任何其他内容,并且可以说是完全没有意义的。
【讨论】:
谢谢@AndyJamesN,但我已经知道了。我认为向该页面的某些访问者说明它仍然很有用。但是,我的问题是如何处理深度嵌套的导航结构。文件被分成多个部分的事实加剧了这个问题。我已更新问题以更好地反映这一点。 此外,我在结构中也有 erb 调用,这让事情变得更糟。以上是关于我应该使用 id 还是类来“表明”Tailwind.css 中 HTML 元素的用途?的主要内容,如果未能解决你的问题,请参考以下文章
你能把 Tailwind 和 vanilla CSS 混合起来吗?
我应该使用 IntentService 还是 Service 进行 UI 更新?