HTML

HTML comparisons

11 old vs modern HTML techniques, side by side.

Browser compatibility:
HTML
Beginner

Better mobile keyboards without JavaScript

Old // JS: detect mobile, swap type
if (/Mobi/.test(navigator.userAgent)) {
  input.type = 'tel';
}
Modern <input
  inputmode="numeric"
  enterkeyhint="search"
/>
see modern →
HTML
Beginner

Live form output without DOM writes

Old // JS: write to div on every input
input.addEventListener('input', () => {
  display.textContent = input.value;
});
Modern <input type="range" id="vol"/>
<output for="vol">50</output>
see modern →
HTML
Beginner

Lazy load images without JavaScript

Old // JS: IntersectionObserver
new IntersectionObserver(([entry]) => {
  img.src = img.dataset.src;
}).observe(img);
Modern <img
  src="photo.jpg"
  loading="lazy"
/>
see modern →
HTML
Beginner

Accordion disclosure without JavaScript

Old // JS: toggle class + aria on click
btn.addEventListener('click', () => {
  panel.classList.toggle('open');
});
Modern <details>
  <summary>What is CSS?</summary>
  <!-- content shown on expand -->
</details>
see modern →
HTML
Beginner

Native autocomplete without JavaScript

Old // Typeahead or Awesomplete
new Awesomplete('#input', {
  list: ['Chrome', 'Firefox']
});
Modern <input list="browsers" />
<datalist id="browsers">
  <option>Chrome</option>
</datalist>
see modern →
HTML
Beginner

Exclusive accordions without JavaScript

Old // JS: close all, open clicked
details.forEach(d => d.open = false);
this.open = true;
Modern <details name="faq">...</details>
<details name="faq">...</details>
/* browser closes others */
see modern →
HTML
Beginner

Modal controls without onclick handlers

Old <button onclick="
  document.querySelector('#dlg')
  .showModal()">Open</button>
Modern <button commandfor="dlg"
  command="show-modal">Open</button>
<dialog id="dlg">...</dialog>
see modern →
HTML
Beginner

Dialog light dismiss without click-outside listeners

Old // JS: listen for click on ::backdrop
dialog.addEventListener('click',
  (e) => { /* check bounds */ })
Modern <dialog closedby="any">
  Click outside to close
</dialog>
/* no JS listeners */
see modern →
HTML
Intermediate

Customizable selects without a JavaScript library

Old // Select2 or Choices.js
new Choices('#my-select');
/* rebuilds entire DOM */
Modern select,
select ::picker(select) {
  appearance: base-select;
}
see modern →
HTML
Beginner

Dropdown menus without JavaScript toggles

Old .menu { display: none; }
.menu.open { display: block; }
/* + JS: click, clickOutside, ESC, aria */
Modern button[popovertarget=menu] { }
#menu[popover] {
  position: absolute;
}
see modern →
HTML
Intermediate

Modal dialogs without a JavaScript library

Old .overlay { position: fixed; z-index: 999; }
/* + JS: open/close, ESC, focus trap */
Modern dialog {
  padding: 1rem;
}
dialog::backdrop { background: rgb(0 0 0 / .5); }
see modern →

Other categories

New CSS drops.

Join 600+ readers who've survived clearfix hacks.

ESC