skip to Main Content

I’m trying to make a settings page with HTML and CSS. The single settings have a label on the left side and an interactive element / multiple interactive elements on the right side.

I don’t know which HTML tag is best for the single settings with the label on the left and the interactive elements on the right.
I also don’t know how I can semantically correct group and label the interactive counter element (plus and minus button and span for current value).

I don’t want to use only divs for grouping elements, but I’m not sure what the correct HTML tags for this use case are.

Image how it looks like

My HTML written:

<section>
  <h1>Settings</h1>

  <div>
    <span>Automation</span>
    <button>Start automation</button>
  </div>
  <div>
    <span>Number of votes</span>
    <div>
      <button>-</button>
      <span>5</span>
      <button>+</button>
    </div>
  </div>
  <div>
    <span>Max votes on card</span>
    <div>
      <button>-</button>
      <span>3</span>
      <button>+</button>
    </div>
  </div>
</section>

I tried to write semantically correct HTML for my settings but I’m struggling to find the correct tags etc.

2

Answers


  1. There are multiple semantic improvements to raise accessibility.

    First of all, you should use a semantic list for settings or options: <menu>.
    Then wrap all "rows" into <li> list items which will create rows by default.

    If you have a <button> then you also should use a label connected to it so that screen readers know what the button is for. A <span> is not an appropriate replacement.

    If you have 2 buttons for incrementing and decrementing, then you should use the role="spinbutton which exists for exactly the case. The official documentation that I linked also states that an input type="number" could be used but does not specifically say that it should be favored. For further explanations about the other attributes such as aria-labelledby, tabindex, and aria-valuenow you should read the same documentation. Note that the documentation also specifically states that the aria-valuenow needs to be updated with JS.

    The reason why input type="number" does not specifically raise accessibility even though being a semantic tag is the usage of screen readers and how those users use those inputs. The advantage of input type="number" is that they have a default incremation and decremation button. However users that abuse assistive technology do not use mcies but the keyboard to navigate. They do not increment or decrement by clicking those buttons but by updating the value with a keyboard input such as typing the number in it directly. Also note, that you need the aria-valuemin and aria-valuemax to set limits to that "input" element.

    menu {
      padding-left: 0;
      max-width: 20em;
    }
    menu li {
      list-style: none;
      display: flex;
      border-bottom: 1px solid black;
      padding: 0.5em 0;
      gap: 0.5em;
    }
    
    menu li :first-child {
      margin-right: auto;
    }
    <section>
      <h1>Settings</h1>
    
      <menu>
        <li>
          <label for="btn-automationStart">Automation</label>
          <button id="btn-automationStart">Start automation</button>
        </li>
        <li>
          <span id="label-numberOfVotes">Number of votes</span>
          <button tabindex="-1" aria-label="decrease by one">-</button>
          <span role="spinbutton" tabindex="0" aria-valuenow="5" aria-valuemin="0" aria-valuemax="10" aria-labeldby="label-numberOfVotes">5</span>
          <button tabindex="-1" aria-label="increase by one">+</button>
        </li>
        <li>
          <span id="label-maxVotesOnCard">Max votes on card</span>
          <button tabindex="-1" aria-label="decrease by one">-</button>
          <span role="spinbutton" tabindex="0" aria-valuenow="3" aria-valuemin="0" aria-valuemax="5" aria-labeldby="label-maxVotesOnCard">3</span>
          <button tabindex="-1" aria-label="increase by one">+</button>
        </li>
      </menu>
    </section>
    Login or Signup to reply.
  2. Consider using <fieldset> and <legend> elements to group input elements and provide those groups with captions. Note that fieldset elements need to belong to a <form>, so you’ll need to include that as well, along with an appropriate method attribute (which I’ve omitted).

    Without knowing more context, I’d recommend replacing the plus/minus buttons and numbers with a native <input type="number> element. It will make it easier for users to input a number directly (rather than having to increment or decrement repetitively to it), can be displayed in different ways by user agents to better suit the user’s input method, has built-in logic for controlling min and max values, and will likely be more quickly understood by users of assistive tech.

    Your markup could look something like the below. CSS can be added to make it look more like the screenshot you shared, if desired.

    <main>
      <h1>Settings</h1>
      <form>
        <fieldset>
          <legend>Automation</legend>
          <button>Start automation</button>
        </fieldset>
        <fieldset>
          <legend>Votes</legend>
          <div><label>Number of votes <input type="number" min="0" value="3"></label></div>
          <div><label>Max votes on card <input type="number" min="0" value="5"></label></div>
        </fieldset>
      </form>
    </main>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search