我应该使用 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 元素已经通过赋予元素含义来做到这一点,并声明其中的链接是主要的导航链接,屏幕阅读器知道该元素的作用是导航。

所以使用 &lt;nav&gt; 元素,它已经提供了意义/语义,因为它打算根据 html5 规范与主要导航元素一起使用,也许这也在 &lt;header&gt; 内。在结构上,这个标记提供了坚实的意义,因为它是网站标题内的主要导航。在这种情况下,我认为添加一个纯粹用于识别的 ID 没有任何价值。

“不需要所有链接都包含在&lt;nav&gt; 元素中。 &lt;nav&gt; 仅用于主要的导航链接块;通常 &lt;footer&gt; 元素通常有一个不需要的链接列表 在 &lt;nav&gt; 元素中。”

见:https://developer.mozilla.org/en-US/docs/Web/HTML/Element/nav#usage_notes

如果担心的话,还可以使用“aria-labelledby”来促进可访问性

"一个文档可能有多个&lt;nav&gt;元素,例如,一个用于站点 导航和一个用于页面内导航。 aria-labelledby 可以是 在这种情况下用于促进可访问性,请参阅示例。”

使用&lt;header&gt;&lt;nav&gt; 提供的价值远远超过任何ID。它们通过创建内容部分来帮助定义文档大纲,并为屏幕阅读器增加可访问性的价值。

标题中的导航创建大纲层次结构,如下所示:

- Header
    - Main Nav

在导航上使用 ID 并没有像以前那样增加任何价值,除非您使用它来连接 JS。一个只是为了命名而挂在那里的类不会增加任何其他内容,并且可以说是完全没有意义的。

【讨论】:

谢谢@AndyJamesN,但我已经知道了。我认为向该页面的某些访问者说明它仍然很有用。但是,我的问题是如何处理深度嵌套的导航结构。文件被分成多个部分的事实加剧了这个问题。我已更新问题以更好地反映这一点。 此外,我在结构中也有 erb 调用,这让事情变得更糟。

以上是关于我应该使用 id 还是类来“表明”Tailwind.css 中 HTML 元素的用途?的主要内容,如果未能解决你的问题,请参考以下文章

图像应该占据剩余位置(Vue/Tailwind/Flex)

你能把 Tailwind 和 vanilla CSS 混合起来吗?

我应该使用 IntentService 还是 Service 进行 UI 更新?

带有 flexbox 的 Tailwind 页面大于屏幕高度/宽度

带有可滚动内容的容器完全静止高度(Tailwind)

Tailwind css - “list-disc”没有正确设置 <li> 项目符号(双项目符号)