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

推荐订阅源

cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
GbyAI
GbyAI
F
Fortinet All Blogs
Y
Y Combinator Blog
I
InfoQ
Microsoft Azure Blog
Microsoft Azure Blog
C
Cyber Attacks, Cyber Crime and Cyber Security
Vercel News
Vercel News
T
The Blog of Author Tim Ferriss
P
Proofpoint News Feed
S
Schneier on Security
NISL@THU
NISL@THU
The Hacker News
The Hacker News
Simon Willison's Weblog
Simon Willison's Weblog
The GitHub Blog
The GitHub Blog
MyScale Blog
MyScale Blog
Cisco Talos Blog
Cisco Talos Blog
F
Full Disclosure
P
Palo Alto Networks Blog
T
The Exploit Database - CXSecurity.com
Know Your Adversary
Know Your Adversary
A
About on SuperTechFans
The Cloudflare Blog
T
Threat Research - Cisco Blogs
M
MIT News - Artificial intelligence
宝玉的分享
宝玉的分享
雷峰网
雷峰网
Hugging Face - Blog
Hugging Face - Blog
博客园 - 三生石上(FineUI控件)
D
DataBreaches.Net
Martin Fowler
Martin Fowler
H
Help Net Security
B
Blog RSS Feed
B
Blog
爱范儿
爱范儿
V
V2EX
I
Intezer
L
LangChain Blog
WordPress大学
WordPress大学
小众软件
小众软件
美团技术团队
Latest news
Latest news
H
Hackread – Cybersecurity News, Data Breaches, AI and More
T
Tor Project blog
L
Lohrmann on Cybersecurity
Cyberwarzone
Cyberwarzone
Last Week in AI
Last Week in AI
Project Zero
Project Zero
C
Cybersecurity and Infrastructure Security Agency CISA
V
Visual Studio Blog

Tailwind CSS Blog

Tailwind CSS v4.3: Scrollbars, new colors, and more 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 CSS v4.0 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 Catalyst: Application layouts, navigation menus, description lists, and more Headless UI v2.0 for React We're hiring a Design Engineer + Staff Engineer 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 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 New Tailwind CSS + Framer Motion template and Tailwind Jobs Tailwind UI: Site templates and all-access 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 Effortless Typography, Even in Dark Mode Standalone CLI: Use Tailwind CSS without Node.js Tailwind CSS v3.0 Introducing Tailwind UI Ecommerce Headless UI v1.4: The One With Tabs Tailwind CSS v2.2 Tailwind UI: Now with React + Vue support Headless UI v1.0 Tailwind CSS v2.1 Heroicons v1.0 Just-In-Time: The Next Generation of Tailwind CSS Welcoming James McDonald to Tailwind Labs "Tailwind CSS: From Zero to Production" on YouTube Welcoming David Luhr to Tailwind Labs Multi-line truncation with @tailwindcss/line-clamp Tailwind CSS v2.0 Tailwind CSS v1.9.0 Introducing Tailwind Play Headless UI: Unstyled, Accessible UI Components "What's new in Tailwind CSS?" on YouTube Tailwind CSS v1.8.0 Utility-Friendly Transitions with @tailwindui/react Introducing Heroicons.com Tailwind CSS v1.7.0 From Nine Hundred to One: How We Hired Robin Malfait Tailwind CSS v1.6.0 Simon Vrachliotis Joins Tailwind Labs Welcoming Brad Cornes to the Team Tailwind CSS v1.5.0 Introducing Tailwind CSS Typography Building the Tailwind Blog with Next.js Introducing linting for Tailwind CSS IntelliSense
Tailwind CSS v3.1: You wanna get nuts? Come on, let's get nuts!
2022-06-07 · via Tailwind CSS Blog

It's been about six months since we released Tailwind CSS v3.0, and even though we've been collecting a lot of little improvements in the codebase since then, we just didn't have that-one-feature yet that makes you say "okay, it's release-cuttin' time".

Then on a random Saturday night a couple of weeks ago, I was talking to Robin in our Discord about coming up with a way to target the html element using :has and a class deeper in the document, and explained how I thought it would look if we added support for arbitrary variants — something I've wanted to tackle for over a year:

Twenty minutes later Robin had a working proof of concept (in six lines of code!), and after another hour or so of Jordan performing regex miracles in our class detection engine, arbitrary variants were born and we had our release-worthy feature.

So here it is — Tailwind CSS v3.1! For a complete list of every fix and improvement check out the release notes, but here's the highlights:

  • First-party TypeScript types
  • Built-in support for CSS imports in the CLI
  • Change color opacity when using the theme function
  • Easier CSS variable color configuration
  • Border spacing utilities
  • Enabled and optional variants
  • Prefers-contrast variants
  • Style native dialog backdrops
  • Arbitrary values but for variants

Upgrade your projects by installing the latest version of tailwindcss from npm:

npm install tailwindcss@latest

Or spin up a Tailwind Play to play around with all of the new goodies right in the browser.


First-party TypeScript types

We're now shipping types for all of our JS APIs you work with when using Tailwind, most notably the tailwind.config.js file. This means you get all sorts of useful IDE support, and makes it a lot easier to make changes to your configuration without referencing the documentation quite as much.

To set it up, just add the type annotation above your config definition:

/** @type {import('tailwindcss').Config} */module.exports = {  content: [    // ...  ],  theme: {    extend: {},  },  plugins: [],};

If you're a big TypeScript nerd you might enjoy poking around the actual type definitions — lots of interesting stuff going on there to support such a potentially complex object.

Built-in support for CSS imports in the CLI

If you're using our CLI tool to compile your CSS, postcss-import is now baked right in so you can organize your custom CSS into multiple files without any additional configuration.

@import "tailwindcss/base";@import "./select2-theme.css";@import "tailwindcss/components";@import "tailwindcss/utilities";

If you're not using our CLI tool and instead using Tailwind as a PostCSS plugin, you'll still need to install and configure postcss-import yourself just like you do with autoprefixer, but if you are using our CLI tool this will totally just work now.

This is especially handy if you're using our standalone CLI and don't want to install any node dependencies at all.

Change color opacity when using the theme function

I don't think tons of people know about this, but Tailwind exposes a theme() function to your CSS files that lets you grab values from your config file — sort of turning them into variables that you can reuse.

.select2-dropdown {  border-radius: theme(borderRadius.lg);  background-color: theme(colors.gray.100);  color: theme(colors.gray.900);}/* ... */

One limitation though was that you couldn't adjust the alpha channel any colors you grabbed this way. So in v3.1 we've added support for using a slash syntax to adjust the opacity, like you can with the modern rgb and hsl CSS color functions:

.select2-dropdown {  border-radius: theme(borderRadius.lg);  background-color: theme(colors.gray.100 / 50%);  color: theme(colors.gray.900);}/* ... */

We've made this work with the theme function in your tailwind.config.js file, too:

module.exports = {  content: [    // ...  ],  theme: {    extend: {      colors: ({ theme }) => ({        primary: theme("colors.blue.500"),        "primary-fade": theme("colors.blue.500 / 75%"),      }),    },  },  plugins: [],};

You can even use this stuff in arbitrary values which is pretty wild — honestly surprisingly useful for weird custom gradients and stuff:

<div class="bg-[image:linear-gradient(to_right,theme(colors.red.500)_75%,theme(colors.red.500/25%))]">  <!-- ... --></div>

Anything to avoid editing a CSS file am I right?

Easier CSS variable color configuration

If you like to define and configure your colors as CSS variables, you probably have some horrible boilerplate like this in your tailwind.config.js file right now:

function withOpacityValue(variable) {  return ({ opacityValue }) => {    if (opacityValue === undefined) {      return `rgb(var(${variable}))`;    }    return `rgb(var(${variable}) / ${opacityValue})`;  };}module.exports = {  theme: {    colors: {      primary: withOpacityValue("--color-primary"),      secondary: withOpacityValue("--color-secondary"),      // ...    },  },};

We've made this way less awful in v3.1 by adding support for defining your colors with a format string instead of having to use a function:

module.exports = {  theme: {    colors: {      primary: "rgb(var(--color-primary) / <alpha-value>)",      secondary: "rgb(var(--color-secondary) / <alpha-value>)",      // ...    },  },};

Instead of writing a function that receives that opacityValue argument, you can just write a string with an <alpha-value> placeholder, and Tailwind will replace that placeholder with the correct alpha value based on the utility.

If you haven't seen any of this before, check out our updated Using CSS variables documentation for more details.

Border spacing utilities

We've added new set of utilities for the border-spacing property, so you can control the space between table borders when using separate borders:

StateCity
IndianaIndianapolis
OhioColumbus
MichiganDetroit
<table class="border-separate border-spacing-2 ...">  <thead>    <tr>      <th class="border border-slate-300 ...">State</th>      <th class="border border-slate-300 ...">City</th>    </tr>  </thead>  <tbody>    <tr>      <td class="border border-slate-300 ...">Indiana</td>      <td class="border border-slate-300 ...">Indianapolis</td>    </tr>    <!-- ... -->  </tbody></table>

I know what you're thinking — "I have never in my life wanted to build a table that looks like that..." — but listen for a second!

One situation where this is actually super useful is when building a table with a sticky header row and you want a persistent bottom border under the headings:

Scroll this table to see the sticky header row in action

NameEmailRole
Courtney Henrycourtney.henry@example.comAdmin
Tom Cooktom.cook@example.comMember
Whitney Franciswhitney.francis@example.comAdmin
Leonard Krasnerleonard.krasner@example.comOwner
Floyd Milesfloyd.miles@example.comMember
Emily Selmanemily.selman@example.comMember
Kristin Watsonkristin.watson@example.comAdmin
Emma Dorseyemma.dorsey@example.comMember
Alicia Bellalicia.bell@example.comAdmin
Jenny Wilsonjenny.wilson@example.comOwner
Anna Robertsanna.roberts@example.comMember
Benjamin Russelbenjamin.russel@example.comMember
Jeffrey Webbjeffrey.webb@example.comAdmin
Kathryn Murphykathryn.murphy@example.comMember
<table class="border-separate border-spacing-0">  <thead class="bg-gray-50">    <tr>      <th class="sticky top-0 z-10 border-b border-gray-300 ...">Name</th>      <th class="sticky top-0 z-10 border-b border-gray-300 ...">Email</th>      <th class="sticky top-0 z-10 border-b border-gray-300 ...">Role</th>    </tr>  </thead>  <tbody class="bg-white">    <tr>      <td class="border-b border-gray-200 ...">Courtney Henry</td>      <td class="border-b border-gray-200 ...">courtney.henry@example.com</td>      <td class="border-b border-gray-200 ...">Admin</td>    </tr>    <!-- ... -->  </tbody></table>

You might think you could just use border-collapse here since you actually don't want any space between the borders but you'd be mistaken. Without border-separate and border-spacing-0, the border will scroll away instead of sticking under the headings. CSS is fun isn't it?

Check out the border spacing documentation for some more details.

Enabled and optional variants

We've added new variants for the :enabled and :optional pseudo-classes, which target form elements when they are, well, enabled and optional.

"But Adam why would I ever need these, enabled and optional aren't even states, they are the defaults. Do you even make websites?"

Ouch, that hurts because it's true — I pretty much just write emails and answer the same questions over and over again on GitHub now.

But check out this disabled button example:

<button type="button" class="bg-indigo-500 hover:bg-indigo-400 disabled:opacity-75 ..." disabled>Processing...</button>

Notice how when you hover over the button, the background still changes color even though it's disabled? Before this release, you'd usually fix that like this:

<button  type="button"  class="bg-indigo-500 hover:bg-indigo-400 disabled:opacity-75 disabled:hover:bg-indigo-500 ..."  disabled>  Processing...</button>

But with the new enabled modifier, you can write it like this instead:

<button type="button" class="bg-indigo-500 hover:enabled:bg-indigo-400 disabled:opacity-75 ..." disabled>  Processing...</button>

Instead of overriding the hover color back to the default color when the button is disabled, we combine the hover and enabled variants to just not apply the hover styles when the button is disabled in the first place. I think that's better!

Here's an example combining the new optional modifier with our sibling state features to hide a little "Required" notice for fields that aren't required:

Email

Name

<form>  <div>    <label for="email" ...>Email</label>    <div>      <input required class="peer ..." id="email" />      <div class="peer-optional:hidden ...">Required</div>    </div>  </div>  <div>    <label for="name" ...>Name</label>    <div>      <input class="peer ..." id="name" />      <div class="peer-optional:hidden ...">Required</div>    </div>  </div>  <!-- ... --></form>

This lets you use the same markup for all of your form groups and letting CSS handle all of the conditional rendering for you instead of handling it yourself. Kinda neat!

Prefers-contrast variants

Did you know there's a prefers-contrast media query? Well there is, and now Tailwind supports it out of the box.

Use the new contrast-more and contrast-less variants to modify your design when the user has requested more or less contrast, usually through an operating system accessibility preference like "Increase contrast" on macOS.

Try emulating `prefers-contrast: more` in your developer tools to see the changes

Social Security Number

We need this to steal your identity.

<form>  <label class="block">    <span class="block text-sm font-medium text-slate-700">Social Security Number</span>    <input      class="border-slate-200 placeholder-slate-400 contrast-more:border-slate-400 contrast-more:placeholder-slate-500"    />    <p class="mt-2 text-sm text-slate-600 opacity-10 contrast-more:opacity-100">We need this to steal your identity.</p>  </label></form>

I wrote some documentation for this but honestly I wrote more here than I did there.

Style native dialog backdrops

There's a pretty new HTML <dialog> element with surprisingly decent browser support that is worth playing with if you like to live on the bleeding edge.

Dialogs have this new ::backdrop pseudo-element that's rendered while the dialog is open, and Tailwind CSS v3.1 adds a new backdrop modifier you can use to style this baby:

<dialog class="backdrop:bg-slate-900/50 ...">  <form method="dialog">    <!-- ... -->    <button value="cancel">Cancel</button>    <button>Submit</button>  </form></dialog>

I recommend reading the MDN Dialog documentation if you want to dig in to this thing more — it's exciting stuff but there's a lot to know.

Arbitrary values but for variants

Okay so this one is the real highlight for me — you know how we give you the addVariant API for creating your own custom variants?

const plugin = require("tailwindcss/plugin");module.exports = {  // ...  plugins: [    plugin(function ({ addVariant }) {      addVariant("third", "&:nth-child(3)");    }),  ],};

...and you know how we have arbitrary values for using any value you want with a utility directly in your HTML?

<!--] --><div class="top-[117px]">  <!-- ... --></div>

Well Tailwind CSS v3.1 introduces arbitrary variants, letting you create your own ad hoc variants directly in your HTML:

<div class="[&:nth-child(3)]:py-0">  <!-- ... --></div>

This is super useful for variants that sort of feel like they need to be parameterized, for example adding a style if the browser supports a specific CSS feature using a @supports query:

<div  class="bg-white [@supports(backdrop-filter:blur(0))]:bg-white/50 [@supports(backdrop-filter:blur(0))]:backdrop-blur">  <!-- ... --></div>

You can even use this feature to target child elements with arbitrary variants like [&>*]:

You can even style the first p inside the div in the second child li but only on hover:

Now should you do this? Probably not very often, but honestly it can be a pretty useful escape hatch when trying to style HTML you can't directly change. It's a sharp knife, but the best chefs aren't preparing food with safety scissors.

Play with them a bit and I'll bet you find they are a great tool when the situation calls for it. We're using them in a couple of tricky spots in these new website templates we're working on and the experience is much nicer than creating a custom class.


So that's Tailwind CSS v3.1! It's only a minor version change, so there are no breaking changes and you should be able to update your project by just installing the latest version:

npm install tailwindcss@latest

For the complete list of changes including bug fixes and a few minor improvements I didn't talk about here, dig in to the release notes on GitHub.

I've already got a bunch of ideas for Tailwind CSS v3.2 (maybe even text shadows finally?!), but right now we're working hard to push these new website templates over the finish line. Look for another update on that topic in the next week or two!