简体   繁体   中英

Should I be using an id or a class to "signal" the purpose of an HTML element in Tailwind.css?

The context :

I have a complex html structure on a header of a website built with Alpine.js and Tailwind.css on the frontend.

"Complex structure", as in:

<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 -->

There are several groups of links in the navigation, sub-navs if you'd like. And the navigation itself is different on mobile and on desktop, implemented as two wrapping divs. One wrapping div wraps the mobile, the other wraps the desktop, but there are also other elements wrapping both divs, then some other content above the navigation, then additional info in the same header where the navigation "lives".

TL;DR: It's a complex HTML structure with multiple layouts on different viewports and with multiple levels of nesting (all together, the resulting HTML is 1500 lines of code).

The question :

Initially, a co-worker used a CSS class to signal the "meaning" of the specific section, for example:

<nav class="MAIN-MENU grid grid-cols-3 2xl:grid-cols-4 items-center px-5 justify-between">

I've put the "offending" code in ALL-CAPS, so that it's easier to spot in this question.

I'm trying to make the intent of the nested elements more obvious by "signalling" the functionality of the elements.

The explanation of user AndyJamesM on how/when to use id's and classes and the comparison of HTML4 and HTML5 standards is useful but doesn't really apply in this case.

Thus, I've taken a different approach, since it's a single unique element, so I've moved it to the id attribute, like this:

<nav
  id="main-menu"
  class="grid grid-cols-3 2xl:grid-cols-4 items-center px-5 justify-between"
>

Both the id="main-menu" and the class="main-menu don't have any styling, they're just there for "naming purposes" and for readability, so that when people glance over the code, they immediately know what's happening.

Logically, I would say that it's better to use the id="main-menu" because:

  1. It's a single element on the page, so I'm signalling uniqueness
  2. It's extracted from the class attribute, because the class attribute already has too much noise from other Tailwind classes.
  3. It's setting up the stage for possibly hooking up with some JS (Alpine.js) functionality down the road.

As far as keeping an empty class name to signal the purpose, I cannot see the benefit of that approach. I've listed the 3 arguments against it, in the bullet points above.

I can't find counter arguments where I would favor the use of class names as signals for intent.

Is there any clearly defined best practice to follow when making this decision?

I have a co-worker advocating for use of classes as the answer. I don't find it logical, but he's adamant about his viewpoint based on seniority in the company, and a hunch. The argument that I get is that id's should be avioded, but why?

Edit: One possible viable reason to not use id for naming: We're "signalling" the use of JS - when in fact there is none. This can be "cleaned up" by appending js- in front of every id value that is actually using JS, but this also means additional time wasted on updating the code, while not being sure if this is the best approach.

Is there a different approach than the two given options?

One possible alternative is HTML comments. This might be the best choice it seems.

The aria-labelledby approach also seems like a step in the right direction.

Another thing that comes to mind is using custom data attributes. Since they don't have to have a value, it could be as simple as this:

<nav data-nested-desktop-sub-nav>

But still, the question remains: what would be "the best" approach?

In HTML 4 ID's were used to add semantics (meaning / naming) to elements. In html5 new tags were introduced to provide better semantics "out of the box"

I'm trying to make the intent of the nested elements more obvious by "signalling" the functionality of the elements.

The nav element already does this by giving the element meaning and states that the links inside it are MAIN navigation links and screen readers know the role of this element is for navigation.

So using a <nav> element which provides meaning/semantics already as its intended to be used with the main navigation elements as per html5 specs and perhaps this is inside a <header> too. Structurally this markup provides solid meaning as it is a main navigation inside a site header. In this case I do not see any value in adding an ID purely for identification.

"It's not necessary for all links to be contained in a <nav> element. <nav> is intended only for major block of navigation links; typically the <footer> element often has a list of links that don't need to be in a <nav> element."

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

Furthermore to promote accessibility if that's the concern use "aria-labelledby"

"A document may have several <nav> elements, for example, one for site navigation and one for intra-page navigation. aria-labelledby can be used in such case to promote accessibility, see example."

Using <header> and <nav> provide far more value than any ID ever could. They help define the document outline by creating content sections and add value to screen readers for accessibility.

A nav in a header creates an outline hierarchy as follows:

- Header
    - Main Nav

Using ID on the nav adds little value like it used to unless you are using it for hooking up to JS. A class hanging out there just for naming adds nothing else and is arguably completely pointless.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM