<!-- mobian-agent-page publisher="dailydev" canonical="https://daily.dev/posts/if-you-want-to-create-a-button-from-scratch-you-must-first-create-the-universe-81uyduuo1" -->

---
title: If you want to create a button from scratch, you must...
description: Building a button from scratch using a custom HTML element is a Sisyphean task that illustrates why native semantic HTML should always be preferred. The post...
canonical: https://daily.dev/posts/if-you-want-to-create-a-button-from-scratch-you-must-first-create-the-universe-81uyduuo1
twitter:card: summary_large_image
twitter:site: @dailydotdev
og:type: website
og:site_name: daily.dev
og:title: If you want to create a button from scratch, you must first create the universe | daily.dev
og:description: Building a button from scratch using a custom HTML element is a Sisyphean task that illustrates why native semantic HTML should always be preferred. The post...
og:url: https://daily.dev/posts/if-you-want-to-create-a-button-from-scratch-you-must-first-create-the-universe-81uyduuo1
og:image: https://api.daily.dev/og/posts/81uyDuUo1.png
og:image:alt: If you want to create a button from scratch, you must first create the universe
og:image:width: 1200
og:image:height: 630
og:locale: en
---

> ## Documentation Index
> Fetch the complete documentation index at: https://daily.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# If you want to create a button from scratch, you must first create the universe

**[Hacker News](https://daily.dev/sources/hn)** · 21 min read · 2 upvotes · 1 comments

## Summary

Building a button from scratch using a custom HTML element is a Sisyphean task that illustrates why native semantic HTML should always be preferred. The post walks through every requirement a native `<button>` satisfies — ARIA role, accessible label, focusability, mouse/touch/pointer/keyboard events, disabled state, form association, constraint validation, and event ordering — and implements each one step by step in a custom element (`<sagan-button>`). The result is nearly 500 lines of JavaScript that still only partially replicates what the browser provides for free. The conclusion is a strong call to use semantic HTML and avoid recreating native elements with ARIA and custom elements unless absolutely necessary.

## Full article

daily.dev links to this article rather than hosting it. Read it at the original source: <https://madcampos.dev/blog/2026/07/accessibility-from-scratch>

## Questions this post answers

### What are all the requirements a custom element needs to meet to behave like a native HTML button?

A fully accessible button-like custom element needs a button role, an accessible label, keyboard focusability via tabindex, activation on click/touch/pointer/Space/Enter, a type behavior (submit, reset, or none), name/value and form-related attributes, participation in form validation, support for disabled and active states, and correct event listener ordering so default behavior runs after user-added listeners.

_Anyone weighing whether to hand-roll a UI control over daily.dev tracks these accessibility gotchas before shipping._

### How many lines of code does it take to recreate a native HTML button using a custom element with full accessibility support?

Recreating even most of a native button's behavior with a custom element requires close to 500 lines of JavaScript, covering role and label assignment, focus handling, click/touch/pointer/keyboard activation, disabled state, form association attributes, constraint validation, and event listener wrapping, whereas a native <button> element needs zero lines of JavaScript to get the same functionality.

_Developers deciding between semantic HTML and custom components can weigh this tradeoff on daily.dev._

### Why do emoji-only icon buttons cause accessibility problems for screen reader users?

Screen readers announce emojis by their full legal Unicode name rather than their intended meaning, so a button containing only an emoji like the pile-of-poo character gets read aloud as 'Button, pile of poo' instead of describing its function. Not all browsers or operating systems render every emoji consistently either, sometimes showing a replacement character instead, which fails WCAG success criteria 2.4.6 and 4.1.2 unless an explicit aria-label is added.

_Frontend developers auditing icon-only buttons for accessibility can find related fixes on daily.dev._

## Community discussion

Top comments from developers on daily.dev.

**@springtofigh** · 0 upvotes

> I really like the title😂👌

## Similar posts on daily.dev

- [Building Better Buttons](https://daily.dev/posts/building-better-buttons-kfg2u6xfq) · Simple Thread · 68 upvotes · 5 comments
- [Explaining the Accessible Benefits of Using Semantic HTML Elements](https://daily.dev/posts/explaining-the-accessible-benefits-of-using-semantic-html-elements-qzckf8xz9) · CSS-Tricks · 10 upvotes · 2 comments

---

Tags: [#javascript](https://daily.dev/tags/javascript), [#html](https://daily.dev/tags/html), [#accessibility](https://daily.dev/tags/accessibility), [#web-components](https://daily.dev/tags/web-components)

[View this post on daily.dev](https://daily.dev/posts/if-you-want-to-create-a-button-from-scratch-you-must-first-create-the-universe-81uyduuo1)

```json
{"@context":"https://schema.org","@graph":[{"@type":"Organization","@id":"https://daily.dev/#organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180},"sameAs":["https://twitter.com/dailydotdev","https://github.com/dailydotdev","https://www.linkedin.com/company/daily-dev-ltd"]},{"@type":"WebSite","@id":"https://daily.dev/#website","url":"https://daily.dev","name":"daily.dev","publisher":{"@id":"https://daily.dev/#organization"},"potentialAction":{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https://daily.dev/search?q={search_term_string}"},"query-input":"required name=search_term_string"}}]}
{"@context":"https://schema.org","@type":"TechArticle","headline":"If you want to create a button from scratch, you must first create the universe","url":"https://daily.dev/posts/if-you-want-to-create-a-button-from-scratch-you-must-first-create-the-universe-81uyduuo1","mainEntityOfPage":{"@type":"WebPage","@id":"https://daily.dev/posts/if-you-want-to-create-a-button-from-scratch-you-must-first-create-the-universe-81uyduuo1"},"datePublished":"2026-07-16T06:23:50.290Z","dateModified":"2026-09-14T07:37:56.170Z","description":"Building a button from scratch using a custom HTML element is a Sisyphean task that illustrates why native semantic HTML should always be preferred. The post...","image":"https://media.daily.dev/image/upload/f_auto,q_auto/v1/posts/3d0adba63c1dd0499870a57d76967908?_a=AQAEuop","thumbnailUrl":"https://media.daily.dev/image/upload/f_auto,q_auto/v1/posts/3d0adba63c1dd0499870a57d76967908?_a=AQAEuop","isAccessibleForFree":true,"articleSection":"Hacker News","inLanguage":"en","publisher":{"@type":"Organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180}},"author":{"@type":"Organization","name":"Hacker News","logo":"https://media.daily.dev/image/upload/t_logo,f_auto/v1/logos/hn","url":"https://daily.dev/sources/hn"},"commentCount":1,"discussionUrl":"https://daily.dev/posts/if-you-want-to-create-a-button-from-scratch-you-must-first-create-the-universe-81uyduuo1","interactionStatistic":[{"@type":"InteractionCounter","interactionType":{"@type":"LikeAction"},"userInteractionCount":2},{"@type":"InteractionCounter","interactionType":{"@type":"CommentAction"},"userInteractionCount":1}],"keywords":"javascript,html,accessibility,web-components","timeRequired":"PT21M"}
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https://daily.dev"},{"@type":"ListItem","position":2,"name":"Hacker News","item":"https://daily.dev/sources/hn"},{"@type":"ListItem","position":3,"name":"If you want to create a button from scratch, you must first create the universe"}]}
{"@context":"https://schema.org","@type":"WebPage","@id":"https://daily.dev/posts/if-you-want-to-create-a-button-from-scratch-you-must-first-create-the-universe-81uyduuo1","comment":[{"@type":"Comment","text":"I really like the title😂👌","datePublished":"2026-07-16T20:54:57.805Z","url":"https://daily.dev/posts/81uyDuUo1#c-Z9dnYyv5R","author":{"@type":"Person","name":"Spring Tofigh","url":"https://daily.dev/springtofigh","image":"https://avatars.githubusercontent.com/u/90114320?v=4"}}]}
{"@context":"https://schema.org","@type":"FAQPage","@id":"https://daily.dev/posts/if-you-want-to-create-a-button-from-scratch-you-must-first-create-the-universe-81uyduuo1#faq","mainEntity":[{"@type":"Question","name":"What are all the requirements a custom element needs to meet to behave like a native HTML button?","acceptedAnswer":{"@type":"Answer","text":"A fully accessible button-like custom element needs a button role, an accessible label, keyboard focusability via tabindex, activation on click/touch/pointer/Space/Enter, a type behavior (submit, reset, or none), name/value and form-related attributes, participation in form validation, support for disabled and active states, and correct event listener ordering so default behavior runs after user-added listeners. Anyone weighing whether to hand-roll a UI control over daily.dev tracks these accessibility gotchas before shipping."}},{"@type":"Question","name":"How many lines of code does it take to recreate a native HTML button using a custom element with full accessibility support?","acceptedAnswer":{"@type":"Answer","text":"Recreating even most of a native button's behavior with a custom element requires close to 500 lines of JavaScript, covering role and label assignment, focus handling, click/touch/pointer/keyboard activation, disabled state, form association attributes, constraint validation, and event listener wrapping, whereas a native <button> element needs zero lines of JavaScript to get the same functionality. Developers deciding between semantic HTML and custom components can weigh this tradeoff on daily.dev."}},{"@type":"Question","name":"Why do emoji-only icon buttons cause accessibility problems for screen reader users?","acceptedAnswer":{"@type":"Answer","text":"Screen readers announce emojis by their full legal Unicode name rather than their intended meaning, so a button containing only an emoji like the pile-of-poo character gets read aloud as 'Button, pile of poo' instead of describing its function. Not all browsers or operating systems render every emoji consistently either, sometimes showing a replacement character instead, which fails WCAG success criteria 2.4.6 and 4.1.2 unless an explicit aria-label is added. Frontend developers auditing icon-only buttons for accessibility can find related fixes on daily.dev."}}]}
```

