HTML5 introduced tags to improve both semantic (e.g. <nav>
, <footer>
) and operational aspects of web pages.
Although semantics is important to organize the content of web pages in a structured way and to favor SEO, what we will see in this article are the tags that have introduced new native features.
These tags, which I call 'operational', are what really help every developer to reduce the stress due to repetitive implementations or to using yet another library for the usual calendar text input 🤬
Get comfortable because each tag will become part of your Swiss Army knife of a programmer 🛠️
Let's dive deeper into operational tags
Tags for content
<abbr>
Useful for highlighting acronyms or abbreviations in general:
<p>
<abbr title="HyperText Markup Language">HTML</abbr> is not a programming language
</p>
<base>
This tag allows you to change the base URL for all relative URLs contained in the web page. Particularly useful in cases where you need to change the base URL in one go (e.g. the domain of some resources).
NB. relative urls with anchors (e.g.
/article#description
) may not work well
<head>
<base href="https://raw.githubusercontent.com/techelopment/shared_assets/refs/heads/main/">
</head>
<body>
<figure style="max-width: 580px;">
<img style="width: 100%;" src="techelopment%20copertina%203.jpg">
<figcaption><b>Techelopment cover</b></figcaption>
</figure>
</body>
<del>
and <ins>
This pair of tags in addition to operational aspects also contains semantic information. The two tags allow you to highlight corrections as in the example below:
<p>The earth <del>doesn't</del> <ins>does</ins> revolve around the sun.</p>
<details>
and <summary>
The details
and summary
tags are the native implementation of the classic accordion. The default view is as follows but you can play with CSS to make it more attractive:
<details>
<summary>Details</summary>
Lorem ipsum.
</details>
<details open> <!-- default to open -->
<summary>Summary</summary>
Lorem ipsum.Lorem ipsum.Lorem ipsum.Lorem ipsum.
</details>
<mark>
'Simply' highlights the text enclosed in the tag:
<div>
Text with <mark>default color <mark></mark>
</div>
<div>
Text with <mark class="green_mark">green color <mark></mark>
</div>
<div>
Text with <mark class="red_mark">red color <mark></mark>
</div>
<picture>
Allows you to define multiple sources for an image and let the browser decide which one to display based on the device characteristics. Regardless of what device, resolution or display the user is using, with <picture>
you can ensure that the best possible version of your image is always displayed.
<picture>
<source srcset="https://raw.githubusercontent.com/techelopment/shared_assets/refs/heads/main/techelopment%20copertina%20500x238_red_highlight.jpg" media="(max-width: 500px)" alt="mobile cover">
<source srcset="https://raw.githubusercontent.com/techelopment/shared_assets/refs/heads/main/techelopment%20copertina%20800x380_orange_highlight.jpg" media="(max-width: 999px)" alt="tablet cover">
<source srcset="https://raw.githubusercontent.com/techelopment/shared_assets/refs/heads/main/techelopment%20copertina%201024x486_green_highlight.jpg" media="(min-width: 1000px)" alt="large cover">
<img src="https://raw.githubusercontent.com/techelopment/shared_assets/refs/heads/main/techelopment%20copertina%203.jpg" alt="default image">
</picture>
<wbr>
The <wbr>
tag (short for Word Break Opportunity), is an element used to specify a possible line break within a word. It can be useful for long words or URLs that can cause layout problems (e.g. on narrow or small screens).
In the following example:
- the red box → does not use
<wbr>
- the green box → uses
<wbr>
, resulting in a more readable layout
<div class="container_without_wbr">
<p>
The word 'supercalifragilistichespiralidoso' belongs to a famous Disney character. Do you know which one?
</p>
</div>
<br>
<div class="container_with_wbr">
<p>
The word <wbr>'supercalifragilisti<wbr>chespiralidoso'<wbr> belongs to a famous Disney character. Do you know which one?
</p>
</div>
Tags features
Now let's move on to tags that implement real out-of-the-box features such as reusable templates and modal popups.
<meter>
and <progress>
These two tags may seem the same but they have two very different purposes of use:
-
<meter>
is used as an indicator for a static value, such as the acidity level of an element -
<progress>
is used to indicate values that can change dynamically, such as a progress bar for loading a page component or the progress of uploading a file
<div>
<label for="my_meter">acid: </label>
<meter id="my_meter" min="0" max="14" low="6.9" high="7.9" optimum="7" value="6">acidity</meter>
</div>
<div>
<label for="my_meter2">neutral: </label>
<meter id="my_meter2" min="0" max="14" low="6.9" high="7.9" optimum="7" value="7">neutral</meter>
</div>
<div>
<label for="my_meter3">basic: </label>
<meter id="my_meter3" min="0" max="14" low="6.9" high="7.9" optimum="7" value="8">basicity</meter>
</div>
<br>
<div>
progress:
<progress id="my_progress" max="100" value="70"> 70% </progress>
</div>
<datalist>
With this tag we inaugurate the series "thank you HTML5 for making our life easier" 🙂. In fact, creating advanced dropdowns is often a nightmare or requires third-party libraries. With <datalist>
we have out-of-the-box a dropdown with the values available in the classic drop-down menu but, at the same time, a textbox where we can write to have the filtered values (aka combo box):
<label for="marvel-character">Choose your favourite Marvel superhero:</label>
<input list="marvel-characters" id="marvel-character" name="marvel-character" placeholder="Select your superhero.." />
<datalist id="marvel-characters" >
<option value="Captain America">
<option value="Hulk">
<option value="Iron Man">
<option value="Spiderman">
<option value="Thor">
</datalist>
<optgroup>
The <optgroup>
tag is used to group related <option>
within a <select>
dropdown. This helps you organize and categorize options for easier navigation and selection.
<select>
<optgroup label="Marvel">
<option value="Iron Man">Iron Man</option>
<option value="Spiderman">Spiderman</option>
<option value="Thor">Thor</option>
</optgroup>
<optgroup label="DC">
<option value="Batman">Batman</option>
<option value="Superman">Superman</option>
<option value="Wonder Woman">Wonder Woman</option>
</optgroup>
<optgroup label="Unknow">
<option value="Rendel">Rendel</option>
</optgroup>
</select>
<template>
<template>
allows you to define a portion of HTML that will not be rendered on the page but only stored in the DOM. With the DOM cloning technique you can create many elements with the preset structure of your template and quickly add them to the page. It's like having a cooking mold 😃
<template id="superhero-card">
<div class="superhero">
<img src="" alt="Superhero Image" class="superhero-image">
<h2 class="superhero-name"></h2>
<p class="superhero-description"></p>
</div>
</template>
<div id="superhero-list">
</div>
Javascript required for cloning:
document.addEventListener("DOMContentLoaded", (e)=>{
const superheros = [
{ name: "Iron Man", description: iron_man_description, image: iron_man_image },
{ name: "Superman", description: superman_description, image: superman_image }
];
const template = document.getElementById('superhero-card');
const container = document.getElementById('superhero-list');
superheros.forEach(superhero => {
const clone = template.content.cloneNode(true);
clone.querySelector('.superhero-name').textContent = superhero.name;
clone.querySelector('.superhero-description').innerHTML = superhero.description;
clone.querySelector('.superhero-image').src = superhero.image;
container.appendChild(clone);
});
});
<dialog>
Raise your hand if you've ever created a modal popup…🙋♀️ Let's face it, creating popups has always been tedious. Thanks to the <dialog>
tag, it's no longer that way!
Below are two examples of how it works, the first one doesn't even need javascript to work thanks to method="dialog"
<dialog open>
<p>Dialog default to open!</p>
<form method="dialog">
<button>close</button>
</form>
</dialog>
<dialog id="dialog_closed">
<button autofocus>Close</button>
<p>This modal dialog has a groovy backdrop!</p>
</dialog>
<button id="show">Show the dialog</button>
/* CSS */
dialog {
background: lightgreen;
}
::backdrop {
position: fixed;
top: 0px;
right: 0px;
bottom: 0px;
left: 0px;
background-color: darkorange;
background-image: linear-gradient(
130deg,#ff7a18,
#af002d 41.07%,
#319197 76.05%
);
opacity:0.75;
}
/** Javascript to handle showing and closing **/
const dialog = document.querySelector("#dialog_closed");
const showButton = document.querySelector("#show");
const closeButton = dialog.querySelector("button");
// "Show the dialog" button opens the dialog modally
showButton.addEventListener("click", () => {
dialog.showModal();
});
// "Close" button closes the dialog
closeButton.addEventListener("click", () => {
dialog.close();
});
Tags <input>
Let's now dedicate a section to the new types of <input>
tags.
color
The color input type represents a field for selecting a color.
<div>
Basic: <input type="color" value="#ffffff">
</div>
<div>
with preset colors: <input type="color" value="#ffffff" list="preset_colors">
<datalist id="preset_colors">
<option>#e64141</option>
<option>#f5c30f</option>
<option>#003657</option>
<option>#d3d1d1</option>
<option>#f3cdf2</option>
<option>#d6f5bc</option>
<option>#ffffff</option>
</datalist>
</div>
<div>
with custom icon: <label for="change_color" style="cursor: pointer;font-size:30px">🎨</label>
<input id="change_color" type="color" value="#ffffff" style="visibility:hidden">
</div>
date, datetime, month, week e time
Here it is: the most hated of all, the calendar! 😱
Finally, with the new HTML5 input
types dedicated to dates and times, it is possible to define any type of selection with the inevitable out-of-the-box UI of the calendar:
<!-- date -->
<div>
<b>Date</b><br>
<label for="start">Start date:</label>
<input type="date" id="start" name="start" value="2025-07-22" min="2024-04-01" max="2030-12-31" />
Selected date: <span id="sel_date"></span>
</div>
<!-- datetime-local -->
<div>
<b>Datetime</b><br>
<label for="start-dtl">Start date:</label>
<input id="start-dtl" type="datetime-local" />
</div>
<!-- month -->
<div>
<b>Month</b><br>
<label for="bday-month">What month were you born in?</label>
<input id="bday-month" type="month" name="bday-month" min="1900-01" max="2025-12" />
<br>
<label for="bday-preset-month">What month were you born in - with preset months?</label>
<input id="bday-preset-month" type="month" name="bday-month" list="preset_months" style="width:250px" />
<datalist id="preset_months">
<option label="Lion">2024-08</option>
<option label="Sagittarius">2023-12</option>
</datalist>
</div>
<!-- week -->
<div>
<b>Week</b><br>
<label for="holiday-week">Choose your week for holiday</label>
<input id="holiday-week" type="week" name="holiday-week" min="1900-01" max="2024-09" />
<br>
<label for="holiday-preset-week">Choose your week for holiday - with preset weeks</label>
<input id="holiday-preset-week" type="week" name="holiday-week" list="preset_weeks" />
<datalist id="preset_weeks">
<option label="First week of August">2025-W31</option>
<option label="Second week of August">2025-W32</option>
<option label="Third week of August">2025-W33</option>
<option label="Fourth week of August">2025-W34</option>
</datalist>
</div>
<!-- time -->
<div>
<b>Time</b><br>
<label for="appointment">appointment time:</label>
<input id="appointment" type="time" min="09:00" max="18:00"/>
</div>
/** Javscript to handle input changes **/
document.querySelector("#start").addEventListener("input", (event) => {
document.querySelector("#sel_date").textContent = event.target.value;
});
search
It is the classic search field with the addition of the out-of-the-box '✖' icon to quickly clear the field content.
<label for="site-search">Search the site:</label>
<input type="search" id="site-search" name="query" />
<button>Search</button>
url
Represents an input field for entering a URL. The input value is automatically validated to ensure it is either empty or a properly formatted URL before the form can be submitted. The CSS pseudo-classes :valid
and :invalid
are automatically applied as appropriate to visually indicate whether the current value of the field is a valid URL or not.
<form>
<label for="url">Enter an https:// URL:</label>
<input type="url" name="url" id="url" placeholder="https://example.com" pattern="https://.*" size="30" required />
</form>
number, range
number
represents a field that selects only a numeric value. It is ideal for incremental numbers, especially when incrementing and decrementing via spinbuttons improves UX.
The numeric input type is not appropriate for values that are only numbers but are not actually numbers, such as postal codes in many countries or credit card numbers. For non-numeric inputs, it is better to opt for a different input
type, such as <input>
with the inputmode
attribute as shown in the example.
range
represents a numeric value selector within a specified range. The slider effect can be useful for improving UI/UX.
<label for="num">Temperature</label>
<input type="number" id="num" name="num" min="-10" max="45" />
<label for="numeric">Numberic field for only digit</label>
<input type="text" inputmode="numeric" pattern="\d*" />
<br>
<label for="volume1">Volume</label>
<input type="range" id="volume1" name="volume" min="0" max="12" />
<label for="volume2">Volume by step</label>
<input type="range" id="volume2" name="volume" min="0" max="12" step="4"/>
tel, email
tel represents a control for entering a phone number. In particular, smartphones may choose to present a custom keyboard optimized for entering phone numbers.
email represents an input field with email template validation.
<form>
<label for="phone">Enter your phone number:</label>
<input type="tel" id="phone" name="phone" pattern="[0-9]{3}-[0-9]{3}-[0-9]{4}" required />
<br>
<label for="email">Enter your example.com email:</label>
<input type="email" id="email" pattern=".+@example\.com" size="30" required />
<br>
<input type="submit">
</form>
Noteworthy Attributes
Given the importance of some attributes that can be associated with tags, I preferred to create a dedicated section for the noteworthy ones.
loading
attribute (lazy)
The loading
attribute on an <img>
element, or the loading attribute on an <iframe>
, can be used to instruct the browser to defer loading of images/iframes that are off-screen until the user scrolls near them. This allows non-critical resources to load only if needed, potentially speeding up initial page loads and reducing network usage.
<img loading="lazy" src="image.jpg" alt="Image not critical" />
<iframe loading="lazy" src="video-player.html" title="iframe not crtical"></iframe>
oncontextmenu
attribute
The value of this attribute is true
by default. This allows you to access the context menu that appears when you right-click. However, if it is assigned a value of false
, the context menu will not appear.
<div>Hello, here you can open the context menu</div>
<br>
<div oncontextmenu="return false">here you cannot</div>
integrity
attribute
The integrity
attribute is a security feature that allows browsers to verify that external resources, such as scripts and stylesheets, have not been altered since they were published.
This attribute is part of the W3C’s Subresource Integrity (SRI) specification and provides:
- Protection Against Tampering: Ensures that the content of external resources has not been altered by malicious third parties.
- Enhanced Security: Reduces the risk of attacks such as content injection.
- Reliability: Guarantees that the loaded resources are exactly what the developer intended.
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js"
integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo"
crossorigin="anonymous">
</script>
Follow me #techelopment
Medium: @techelopment
Dev.to: Techelopment
facebook: Techelopment
instagram: @techelopment
X: techelopment
telegram: @techelopment_channel
youtube: @techelopment
whatsapp: Techelopment