Question

I have been busy making an interactive tab layout using only CSS and I've had someone tell me that this is not the intended semantic meaning of <input> tags. Now, I know that HTML5 focuses a lot more on semantics than previous versions of HTML did, so I was wondering, is something that does something like the following against the input semantics:

<label for="toggleTab" class="togglelabel">Toggle tab</label>
<input type="checkbox" id="toggleTab" class="toggleinput">
<div class="toggletab">Look at this thing hide and show</div>

CSS:

.toggletab, .togglelabel {border:1px solid #AAA;display:block;}
.toggleinput, .toggletab {display:none;}
.toggleinput:checked + .toggletab {display:block;}

(demo)

The standards[1][2] both say the same thing:

The input element represents a typed data field, usually with a form control to allow the user to edit the data.

So to me this seems like this is indeed against what the input tag should be used for (since this has nothing to do with data, but just with displaying certain things to the user or not).

And then of course my followup question would be, if this is indeed not what input tags should be used for according to the standard, is it bad to go against the semantics standards?

Was it helpful?

Solution

Well structurally this will be quite difficult. Inputs need go inside form elements, and if you are going to be using these all over the page, most of your page will be wrapped as one giant form, potentially will nested forms, for search bars, user input and the like.

As your quote says:

The input element represents a typed data field, usually with a form control to allow the user to edit the data.

The control you are suggesting isn't for editing data its for adding graphical user functionality. If you were to bing the input to a form, either by placing the input inline into a form, or using the @form attribute as your comment suggests, what exactly is the semantic of that form? If would have no action, it would have no site to post to, and if an accessibile browser were to try and render the elements of that form in a different way it would have no semantic content.

For the kind of hide/show toggle functionality, I'd recommend instead using an a link and hanging some javascript off that. As stated:

If the a element has an href attribute, then it represents a hyperlink (a hypertext anchor) labeled by its contents.

In this context Hyperlink does not preclude the use of javascript as the acting force on the page, if it did most pages would be non-compliant to the spec. This is backed up by the first type of link suggested in the definition of hyperlink suggests that the link can be "used to augment the current document".

As a side note, in accessible browsers, inputs like these maye be rendered or presented in ways different to what you expect. Each form might be pulled out into a list of possible data editing options, and this would not fit the semantics of what a user might expect.

OTHER TIPS

Semantics & custom behaviour

If the question is about which element has the least implied semantics, I reckon your best bet is the <button type="button"> element: the HTML5 spec describes it as « a button with no additional semantics» which, without scripting, « does nothing » — unlike the <a> element, which has implicit behaviour as a hypertext link and anchor.

The HTML4 forms spec refers to these as 'push buttons', which « have no default behavior. Each push button may have client-side scripts associated with the element's event attributes ».

Furthermore, the HTML4 spec cites buttons repeatedly in its description of scripts: they are the only element referenced specifically in the introduction to scripts, although inputs also feature in the examples of DOM-event triggered scripts — however, as buttons are non-self-closing, they can contain other DOM nodes, which may make them more flexible depending on your needs.

Non-<input> solution

Using the push button, custom behaviour can be inferred by using data-* attributes for CSS selectors:

.toggleinput[ data-checked ] + .toggletab {
  display:block;
}

…and scripted as follows:

// Use Array's forEach to loop through selection
Array.prototype.forEach.call(
  // …of all `.toggleinput` elements
  document.querySelectorAll( '.toggleinput' ),
  function bind( input ){
    input.addEventListener( 'click', function toggleCheckedState(){
      // `dataset` is an object representation of data-* attributes
      if( this.dataset.checked ){
        // Remove the attribute if it exists
        delete this.dataset.checked;
      }
      else {
        // Declare it if it doesn't
        this.dataset.checked = true;
      }
    }, false );
  }
);

Forked code demo

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top