惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

C
Cyber Attacks, Cyber Crime and Cyber Security
Cisco Talos Blog
Cisco Talos Blog
Scott Helme
Scott Helme
The Last Watchdog
The Last Watchdog
G
GRAHAM CLULEY
T
Tenable Blog
PCI Perspectives
PCI Perspectives
Simon Willison's Weblog
Simon Willison's Weblog
N
News and Events Feed by Topic
Know Your Adversary
Know Your Adversary
S
Schneier on Security
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
P
Privacy International News Feed
C
CERT Recently Published Vulnerability Notes
NISL@THU
NISL@THU
SecWiki News
SecWiki News
S
Securelist
D
Docker
阮一峰的网络日志
阮一峰的网络日志
人人都是产品经理
人人都是产品经理
T
Tailwind CSS Blog
T
Troy Hunt's Blog
The Register - Security
The Register - Security
K
Kaspersky official blog
Blog — PlanetScale
Blog — PlanetScale
云风的 BLOG
云风的 BLOG
Hacker News: Ask HN
Hacker News: Ask HN
S
Secure Thoughts
Stack Overflow Blog
Stack Overflow Blog
T
Threat Research - Cisco Blogs
博客园 - 司徒正美
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
F
Fortinet All Blogs
T
Threatpost
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
小众软件
小众软件
WordPress大学
WordPress大学
Security Archives - TechRepublic
Security Archives - TechRepublic
博客园 - 聂微东
Attack and Defense Labs
Attack and Defense Labs
B
Blog RSS Feed
Project Zero
Project Zero
Y
Y Combinator Blog
T
The Blog of Author Tim Ferriss
博客园 - 【当耐特】
V
V2EX
Help Net Security
Help Net Security
P
Proofpoint News Feed
A
Arctic Wolf

Tailwind CSS Blog

Tailwind CSS v4.3: Scrollbars, new colors, and more Vanilla JavaScript support for Tailwind Plus Vanilla JavaScript support for Tailwind Plus Compass: A starter kit for online courses Tailwind CSS v4.1: Text shadows, masks, and tons more Tailwind UI is now Tailwind Plus Tailwind UI is now Tailwind Plus Tailwind CSS v4.0 Tailwind CSS v4.0 Tailwind CSS v4.0 Beta 1 Tailwind CSS v4.0 Beta 1 Radiant: A beautiful new marketing site template Headless UI v2.1: Simplified transition API and improved multi-dialog support Automatically clean up whitespace and duplicate class names Automatically clean up whitespace and duplicate class names Catalyst: Application layouts, navigation menus, description lists, and more Headless UI v2.0 for React Headless UI v2.0 for React We're hiring a Design Engineer + Staff Engineer We're hiring a Design Engineer + Staff Engineer Open-sourcing our progress on Tailwind CSS v4.0 Open-sourcing our progress on Tailwind CSS v4.0 Introducing Catalyst: A modern UI kit for React Tailwind CSS v3.4: Dynamic viewport units, :has() support, balanced headlines, subgrid, and more Heroicons Micro: What are these, icons for ants? Meet Studio: Our beautiful new agency site template Tailwind Connect 2023: Recap of our first in-person event New changelog template + the biggest Tailwind UI update ever New changelog template + the biggest Tailwind UI update ever Tailwind CSS v3.3: Extended color palette, ESM/TS support, logical properties, and more Protocol: A beautiful starting point for your next API documentation site Tailwind CSS v3.2: Dynamic breakpoints, multi-config, and container queries, oh my! We built you a new personal website + Heroicons v2.0, Headless UI v1.7, and more We built you a new personal website + Heroicons v2.0, Headless UI v1.7, and more New Tailwind CSS + Framer Motion template and Tailwind Jobs New Tailwind CSS + Framer Motion template and Tailwind Jobs Tailwind UI: Site templates and all-access Tailwind CSS v3.1: You wanna get nuts? Come on, let's get nuts! Headless UI v1.6, Tailwind UI team management, Tailwind Play improvements, and more Headless UI v1.6, Tailwind UI team management, Tailwind Play improvements, and more Headless UI v1.5: The One With Comboboxes Automatic Class Sorting with Prettier Automatic Class Sorting with Prettier Effortless Typography, Even in Dark Mode Effortless Typography, Even in Dark Mode Standalone CLI: Use Tailwind CSS without Node.js Tailwind CSS v3.0 Tailwind CSS v3.0 Introducing Tailwind UI Ecommerce Introducing Tailwind UI Ecommerce Headless UI v1.4: The One With Tabs Tailwind CSS v2.2 Tailwind CSS v2.2 Tailwind UI: Now with React + Vue support Headless UI v1.0 Headless UI v1.0 Tailwind CSS v2.1 Tailwind CSS v2.1 Heroicons v1.0 Heroicons v1.0 Just-In-Time: The Next Generation of Tailwind CSS Welcoming James McDonald to Tailwind Labs Welcoming James McDonald to Tailwind Labs "Tailwind CSS: From Zero to Production" on YouTube Welcoming David Luhr to Tailwind Labs Welcoming David Luhr to Tailwind Labs Multi-line truncation with @tailwindcss/line-clamp Multi-line truncation with @tailwindcss/line-clamp Tailwind CSS v2.0 Tailwind CSS v2.0 Tailwind CSS v1.9.0 Tailwind CSS v1.9.0 Introducing Tailwind Play Introducing Tailwind Play "What's new in Tailwind CSS?" on YouTube "What's new in Tailwind CSS?" on YouTube Tailwind CSS v1.8.0 Tailwind CSS v1.8.0 Utility-Friendly Transitions with @tailwindui/react Utility-Friendly Transitions with @tailwindui/react Introducing Heroicons.com Introducing Heroicons.com Tailwind CSS v1.7.0 Tailwind CSS v1.7.0 From Nine Hundred to One: How We Hired Robin Malfait Tailwind CSS v1.6.0 Tailwind CSS v1.6.0 Simon Vrachliotis Joins Tailwind Labs Simon Vrachliotis Joins Tailwind Labs Welcoming Brad Cornes to the Team Welcoming Brad Cornes to the Team Tailwind CSS v1.5.0 Tailwind CSS v1.5.0 Introducing Tailwind CSS Typography Introducing Tailwind CSS Typography Building the Tailwind Blog with Next.js Building the Tailwind Blog with Next.js Introducing linting for Tailwind CSS IntelliSense Introducing linting for Tailwind CSS IntelliSense
Headless UI: Unstyled, Accessible UI Components
2020-10-07 · via Tailwind CSS Blog

One of the biggest pain points when building modern web applications is building custom components like select menus, dropdowns, toggles, modals, tabs, radio groups — components that are pretty similar from project to project, but never quite the same.

You could use an off-the-shelf package, but they usually come tightly coupled with their own provided styles. It ends up being very hard to get them to match the look and feel of your own project, and almost always involves writing a bunch of CSS overrides, which feels like a big step backwards when working Tailwind CSS.

The other option is building your own components from scratch. At first it seems easy, but then you remember you need to add support for keyboard navigation, managing ARIA attributes, focus trapping, and all of a sudden you're spending 3-4 weeks trying to build a truly bullet-proof dropdown menu.

We think there's a better option, so we're building it.

Headless UI is a set of completely unstyled, fully accessible UI components for React and Vue (and soon Alpine.js) that make it easy to build these sorts of custom components without worrying about any of the complex implementation details yourself, and without sacrificing the ability to style them from scratch with simple utility classes.

Here's what it looks like to build a custom dropdown (one of many components the library includes) using @headlessui/react, with complete keyboard navigation support and ARIA attribute management, styled with simple Tailwind CSS utilities:

import { Menu } from "@headlessui/react";function MyDropdown() {  return (    <Menu as="div" className="relative">      <Menu.Button className="rounded bg-blue-600 px-4 py-2 text-white ...">Options</Menu.Button>      <Menu.Items className="absolute right-0 mt-1">        <Menu.Item>          {({ active }) => (            <a className={`${active && "bg-blue-500 text-white"} ...`} href="/account-settings">              Account settings            </a>          )}        </Menu.Item>        <Menu.Item>          {({ active }) => (            <a className={`${active && "bg-blue-500 text-white"} ...`} href="/documentation">              Documentation            </a>          )}        </Menu.Item>        <Menu.Item disabled>          <span className="opacity-75 ...">Invite a friend (coming soon!)</span>        </Menu.Item>      </Menu.Items>    </Menu>  );}

Here's what you're getting for free in that example, without having to write a single line of code related to it yourself:

  • The dropdown panel opens on click, spacebar, enter, or when using the arrow keys
  • The dropdown closes when you press escape, or click outside of it
  • You can navigate the items using the up and down arrow keys
  • You can jump the first item using the Home key, and the last item using the End key
  • Disabled items are automatically skipped when navigating with the keyboard
  • Hovering over an item with your mouse after navigating with the keyboard will switch to mouse position based focusing
  • Items are announced properly to screen readers while navigating them with the keyboard
  • The dropdown button is properly announced to screenreaders as controlling a menu
  • ...and probably tons more that I'm forgetting.

All without writing the letters aria anywhere in your own code, and without writing a single event listener. And you still have complete control over the design!

There are over 3000 lines of tests for this component. Pretty nice that you didn't have to do that yourself, right?

Here's a fully-styled live demo (taken from Tailwind UI) so you can see it in action:

Make sure to try it with the keyboard or a screen reader to really appreciate it!

We just tagged v0.2.0, which currently includes the following components:

To learn more and dive in, head over to the Headless UI website and read the documentation.


If you've followed my work online for the last few years, you might remember my fascination with renderless UI components — something I was really started getting into towards the end of 2017. I've wanted a library like this to exist for years, but until we started growing the team we just didn't have the resources to make it happen.

Earlier this year we hired Robin Malfait, and he's been working on Headless UI full-time ever since.

The biggest motivation for this project is that we'd really like to add production-ready JS examples to Tailwind UI, which is currently an HTML-only, bring-your-own-JavaScript sort of project. This is great for lots of our customers who want full control over how everything works, but for many others it's a point of friction.

We didn't want to add 200 lines of gnarly JS to every component example, so we started working on Headless UI as a way to extract all of that noise, without giving up any flexibility in the actual UI design.

Why reinvent the wheel?

We're not the first people to try and tackle this problem. Downshift was the first library I saw that got me excited about this idea back in 2017, Reach UI and Reakit started development in 2018, and React Aria was released most recently, just earlier this year.

We decided to try our own take on the problem for a few reasons:

  • Existing solutions are focused almost entirely on React, and we'd like to bring these ideas to other ecosystems like Vue, Alpine, and hopefully more in the future.
  • These libraries are going to be foundational for adding JS support to Tailwind UI, and since that's what keeps the business running it felt important to have complete decision-making power over how the libraries worked and what they supported.
  • We have our own ideas on what the APIs should look like for these components, and want to be able to explore those ideas freely.
  • We want to make sure it is always super easy to style these components with Tailwind, rather than having to write custom CSS.

We think what we've come up with so far hits a great balance between flexibility and developer experience, and we're grateful there are other people working on similar problems that we can learn from and share our ideas with.

What's next

We've got quite a few more components to develop for Headless UI, including:

  • Modal
  • Radio group
  • Tabs
  • Accordion
  • Combobox
  • Datepicker

...and likely many more. We're also about to start on Alpine.js support, and we're hoping to be able to tag a v1.0 for React, Vue, and Alpine near the end of the year.

After that we'll start exploring other frameworks, with the hope that we can eventually offer the same tools for ecosystems like Svelte, Angular, and Ember, either first-class or with community partners.

If you'd like to keep up with what we're doing, be sure to follow the project on GitHub.

Want to talk about this post? Discuss this on GitHub →