- Created by Anonymous, last modified on Dec 10, 2020
Tailwind CSS is a utility-based styling library. In order to streamline and standardize things like colors and spacing within our application, an Electron theme has been created to extend Tailwind's functionality, thus making it easy for us to access some standard Duke colors, fonts, etc. As a result, you will get most of the magic of Tailwind, but with most of the colors, text, and sizing options overwritten to reflect Duke's design aesthetic.
We won't talk too much about the decisions behind why we are using this implementation here, but Chris Greufe has already done an incredible job documenting the ins-and-outs of it . If you want to know more of the granular aspects and philosophy to our approach, you are encouraged to give it a read.
Instead, this doc will mostly focus on how the dev team actually uses this implementation and a bit about our approach, as well as a proposed style guide.
Philosophy and Approach
Tailwind CSS is our primary way of styling within the DXT-JSS-Public React/Nuxt App. A lot of effort and resources have been put into making Tailwind and Electron do as much of the heavy lifting for us as possible, so for maintainability's sake, every effort should be made to find a solution to style your work with Tailwind. If you're hitting a wall trying to figure out an approach that works within Tailwind, don't hesitate to reach out to a teammate. If you find yourself in the rare situation where you encounter something that simply cannot be resolved using Tailwind, we use as our fallback. If you find that you are creating a styled component often to deal with an edge case, it's probably worth documenting .
Tooling
There's not a lot of tooling required for Tailwind but the can be pretty helpful. Once installed, it gives suggestions for Tailwind classes as well as Electron-specific ones. It also shows a preview of the CSS rules that the utility class utilizes.
Enabling Tailwind Properties
Although Tailwind provides the flexibility to apply a wide range of modifiers to a variety of CSS rules, you may occasionally find that a Tailwind class is not behaving the way you expect in a responsive context, or upon hover. This may mean that you will need edit the Tailwind config. Please be careful to , rather than simply adding them to the variant object, which will overwrite all the defaults.
Key Differences
The main difference you'll find between Tailwind's approach and Electron's is that Duke doesn't need an extensive color library. As a result, you'll find that something like text-blue-800 or bg-yellow-200 does not behave as you'd expect. Most likely you will be looking for something like text-blue-dark or bg-yellow. So the color palette will be limited, and rather than a number to modify the color, there will either be no modifier, or a modifier of -light, -lighter, -dark, or -darker.
Style Guide
Because almost all of our styles exist within utility classes, there is often no need for traditional CSS classes to style a block. It's fairly unusual to need to add a class like wrapper or large BEM classes. Occasionally, you may need to add a class to make it easier for unit tests to search for a selector. In such a case, we suggest that you use a js- prefix, and that you place it at the beginning of your utility classes.
example:
|
1
|
<``div class``=``"js-form text-blue-dark ..."``>
|
Often, the amount of classes you need to style a complex element can be rather long. In this case, it is suggested that you group your classes conceptually. Since Tailwind is a mobile-first framework, it makes sense to start with "base" styles that will be present across all sizes of the component. Of the base styles, start with sizing (height, width, padding, margin) and other fiddly rules so that they are easily accessible to you and anyone who may need to maintain your code in the future. Utility classes that represent rules that are easily identifiable at a glance, such as text color or background color, should come secondary.
🚫 Bad
|
<div className=``"text-blue mt-12 bg-black w-20 md:flex px-24" />
|
✅ Good
|
<div className=``"w-20 mt-12 px-24 text-blue bg-black md:flex ..." />
|
From there, group your classNames into responsive clusters in order from smallest to largest.
🚫 Bad
|
<div className=``"lg:flex md:block xl:bg-gray-lighter lg:text-center md:text-white" />
|
✅ Good
|
<div className=``"md:block md:text-white lg:flex lg:text-center xl:bg-gray-lighter" />
|
And lastly, add your non-responsive variants, such as hover states, and transitions. So ultimately, your styles should look something like this:
|
<div className=``"js-form w-20 mt-12 px-24 text-blue bg-black md:block md:text-white lg:flex lg:text-center xl:bg-gray-lighter hover:bg-blue transition-all duration-500" />
|
Resources
- some random guy made a really handy cheatsheet for Tailwind CSS. Obviously, our rules won't be on it, but it's a nice quick reference for a lot of the classes.
- their official docs are better than most
Tailwind CSS Cheat Sheet
Excerpt
Cheat sheet that provides a quick, interactive reference for all utility classes and CSS properties provided by Tailwind CSS, a utility-first CSS framework.
Layout
{% embed url="https: //tailwindcomponents.com/cheatsheet" %}
Breakpoints (screen sizes) that wrap utility classes.
Sets rendering of an element's fragments when broken across multiple lines, columns, or pages.
Sets max-width to match min-width of the current breakpoint.
Sets how the total width and height of an element is calculated.
Sets the display box type of an element.
Sets an element's placement to a side of its container and allows content to wrap around it.
Sets whether an element is moved below preceding floated elements.
Sets whether an element creates a stacking context.
Sets how the content of a replaced element (img or video tag) should be resized.
Sets the alignment of the selected replaced element.
Sets how to handle content that's too big for its container.
Sets browser behavior upon reaching the boundary of a scrolling area.
Sets an element's position.
Sets the placement of a positioned element.
Show or hide without affecting the layout of the document.
Sets the z-order ("stack order") of a positioned element.
Spacing
Controls padding in 0.25rem increments.
Controls margin (and negative margin) in 0.25rem increments.
Sets left or top (x or y) margin between child elements, but skips the first element.
Backgrounds
Sets behavior of background images when scrolling.
Sets where a background extends.
Sets background opacity when used with bg-[color].
Sets the background origin position.
Sets position of a background image.
Sets repetition of a background image.
Sets background size of a background image.
Sets the background color gradients and where to stop.
Tables
Collapse or separate table borders.
Defines the algorithm used to lay out table cells, rows, and columns.
Transforms
Scales an element that has transform applied.
Rotates an element that has transform applied.
Translates an element that has transform applied.
Skews an element that has transform applied.
Sets the origin of an element's transforms. Think of the origin as pushing a thumbtack into the element at the specified position.
Sets the transform of an element.
Effects
Sets the shadow around an element.
Sets the transparency of an element.
Sets how an element blends with the background.
Sets how an element's background images blend with its background color.
Flexbox
Sets element to be a flex container.
Sets direction of flex items.
Creates how flex items wrap.
Controls how flex items grow and shrink.
Controls how flex items grow.
Controls how flex items shrink.
Controls how flex items are ordered.
Sizing
Sets the width of an element.
Sets the minimum width of an element.
Sets the maxiumum width of an element.
Sets the height of an element.
Sets the minimum height of an element.
Sets the maxiumum height of an element.
Borders
Sets border width in increments of 1px.
Sets border opacity when used with border-[color].
Sets left or top (x or y) border width between child elements, but skips the first element.
Sets border color between child elements when using divide width.
Sets border opacity between elements when used with divide-[color].
Sets border style between elements when using divide width.
Sets the width of outline rings using box shadows.
Sets the color of the outline ring.
Sets the opacity of the outline ring.
Sets an offset for outline rings.
Sets the color of the outline ring offset.
Transitions and Animation
Sets the CSS properties affected by transition animations.
Sets the length of time for a transition animations to complete.
transition-timing-function
Sets the easing function of transition animations.
Sets the delay for transitions.
Interactivity
Disables native styling based on the operating system's theme.
Changes the cursor when hovering over an element.
Sets the outline of the element.
Specifies whether an element is the target of mouse events.
Sets whether an element is resizable, along with direction.
Controls whether the user can select text.
Controls whether an element is visually hidden but still accessible to screen readers.
SVG
Sets the color to paint an SVG.
Sets the outline color of an SVG.
Sets the outline width of an SVG.
Grid
Defines columns for grid layout.
Sets a grid item size and location within the grid column.
Defines rows for grid layout.
Sets a grid item size and location within the grid row.
Controls the auto placement of grid elements.
Controls the size of auto-generated (implicit) grid columns.
Controls the size of auto-generated (implicit) grid rows.
Sets the gaps (gutters) between rows and columns.
Box Alignment
Controls how flex items are positioned along container's main axis.
.justify-end
justify-content: flex-end;
.justify-center
Controls default alignment for items on the inline axis for grids.
Controls element alignment on the inline axis for a grid item.
Controls how lines are positioned in multi-line flex containers.
Sets flex items position along a contrainer's cross axis.
Controls how an individual flex item is positioned along container's cross axis.
Controls alignment in both directions at once for grid or flexbox.
Controls alignment of items in both directions at once for grid or flexbox.
Controls alignment of individual element in both directions at once for grid or flexbox.
Typography
.text-current
color: currentColor;
.text-black
--tw-text-opacity: 1; color: rgba(0, 0, 0, var(--tw-text-opacity));
.text-white
--tw-text-opacity: 1; color: rgba(255, 255, 255, var(--tw-text-opacity));
.text-gray-50
Sets text opacity when used with text-[color].
Sets the antialiasing of the font.
Sets the style of the font.
Sets the font number variant.
Sets the spacing between letters.
Sets the bullet style of a list.
Sets the position of a list's bullets.
Sets the placeholder color using the ::placeholder pseudo element.
Sets the placeholder opacity when used with placeholder-[color].
Sets the alignment of text.
Sets the text-decoration of an element.
Sets the capitalization of text.
Sets the overflow of text.
Sets the vertical alignment of an inline or table-cell box.
Sets the whitespace of an element.
Sets the word breaks of an element.
Filter
Sets blur filter on elements (use with filter utility).
Sets brightness filter on elements (use with filter utility).
Sets contrast filter on elements (use with filter utility).
Sets drop-shadow filter on elements (use with filter utility).
Sets grayscale filter on elements (use with filter utility).
Sets hue-rotate filter on elements (use with filter utility).
Sets invert filter on elements (use with filter utility).
Sets saturate filter on elements (use with filter utility).
Sets sepia filter on elements (use with filter utility).
Sets backdrop filter filter on elements (use with filter utility).
Sets backdrop blur filter on elements (use with filter utility).
Sets backdrop brightness filter on elements (use with filter utility).
Sets backdrop contrast filter on elements (use with filter utility).
Sets backdrop grayscale filter on elements (use with filter utility).
Sets backdrop hue-rotate filter on elements (use with filter utility).
Sets backdrop invert filter on elements (use with filter utility).
Sets backdrop opacity filter on elements (use with filter utility).
Sets backdrop saturate filter on elements (use with filter utility).
Sets backdrop sepia filter on elements (use with filter utility).
Url: https: //nerdcave.com/tailwind-cheat-sheet


.content-between
align-content: space-between;
.content-around
align-content: space-around;
.content-evenly
align-content: space-evenly;
.place-content-between
place-content: space-between;
.place-content-around
place-content: space-around;
.place-content-evenly
place-content: space-evenly;
.place-content-stretch
place-content: stretch;
.text-opacity-20
--tw-text-opacity: 0.2;
.text-opacity-25
--tw-text-opacity: 0.25;
.text-opacity-30
--tw-text-opacity: 0.3;
.text-opacity-40
--tw-text-opacity: 0.4;
.text-opacity-50
--tw-text-opacity: 0.5;
.text-opacity-60
--tw-text-opacity: 0.6;
.text-opacity-70
--tw-text-opacity: 0.7;
.text-opacity-75
--tw-text-opacity: 0.75;
.text-opacity-80
--tw-text-opacity: 0.8;
.text-opacity-90
--tw-text-opacity: 0.9;
.text-opacity-95
--tw-text-opacity: 0.95;
.text-opacity-100
--tw-text-opacity: 1;
.text-justify
text-align: justify;
.normal-case
text-transform: none;
justify-content: center;
.justify-between
justify-content: space-between;
.justify-around
justify-content: space-around;
.justify-evenly
justify-content: space-evenly;
.content-center
align-content: center;
.content-end
align-content: flex-end;
.place-content-start
place-content: start;
.place-content-end
place-content: end;
--tw-text-opacity: 1; color: rgba(249, 250, 251, var(--tw-text-opacity));
.text-gray-100
--tw-text-opacity: 1; color: rgba(243, 244, 246, var(--tw-text-opacity));
.text-gray-200
--tw-text-opacity: 1; color: rgba(229, 231, 235, var(--tw-text-opacity));
.text-gray-300
--tw-text-opacity: 1; color: rgba(209, 213, 219, var(--tw-text-opacity));
.text-gray-400
--tw-text-opacity: 1; color: rgba(156, 163, 175, var(--tw-text-opacity));
.text-gray-500
--tw-text-opacity: 1; color: rgba(107, 114, 128, var(--tw-text-opacity));
.text-gray-600
--tw-text-opacity: 1; color: rgba(75, 85, 99, var(--tw-text-opacity));
.text-gray-700
--tw-text-opacity: 1; color: rgba(55, 65, 81, var(--tw-text-opacity));
.text-gray-800
--tw-text-opacity: 1; color: rgba(31, 41, 55, var(--tw-text-opacity));
.text-gray-900
--tw-text-opacity: 1; color: rgba(17, 24, 39, var(--tw-text-opacity));
.text-red-50
--tw-text-opacity: 1; color: rgba(254, 242, 242, var(--tw-text-opacity));
.text-red-100
--tw-text-opacity: 1; color: rgba(254, 226, 226, var(--tw-text-opacity));
.text-red-200
--tw-text-opacity: 1; color: rgba(254, 202, 202, var(--tw-text-opacity));
.text-red-300
--tw-text-opacity: 1; color: rgba(252, 165, 165, var(--tw-text-opacity));
.text-red-400
--tw-text-opacity: 1; color: rgba(248, 113, 113, var(--tw-text-opacity));
.text-red-500
--tw-text-opacity: 1; color: rgba(239, 68, 68, var(--tw-text-opacity));
.text-red-600
--tw-text-opacity: 1; color: rgba(220, 38, 38, var(--tw-text-opacity));
.text-red-700
--tw-text-opacity: 1; color: rgba(185, 28, 28, var(--tw-text-opacity));
.text-red-800
--tw-text-opacity: 1; color: rgba(153, 27, 27, var(--tw-text-opacity));
.text-red-900
--tw-text-opacity: 1; color: rgba(127, 29, 29, var(--tw-text-opacity));
.text-yellow-50
--tw-text-opacity: 1; color: rgba(255, 251, 235, var(--tw-text-opacity));
.text-yellow-100
--tw-text-opacity: 1; color: rgba(254, 243, 199, var(--tw-text-opacity));
.text-yellow-200
--tw-text-opacity: 1; color: rgba(253, 230, 138, var(--tw-text-opacity));
.text-yellow-300
--tw-text-opacity: 1; color: rgba(252, 211, 77, var(--tw-text-opacity));
.text-yellow-400
--tw-text-opacity: 1; color: rgba(251, 191, 36, var(--tw-text-opacity));
.text-yellow-500
--tw-text-opacity: 1; color: rgba(245, 158, 11, var(--tw-text-opacity));
.text-yellow-600
--tw-text-opacity: 1; color: rgba(217, 119, 6, var(--tw-text-opacity));
.text-yellow-700
--tw-text-opacity: 1; color: rgba(180, 83, 9, var(--tw-text-opacity));
.text-yellow-800
--tw-text-opacity: 1; color: rgba(146, 64, 14, var(--tw-text-opacity));
.text-yellow-900
--tw-text-opacity: 1; color: rgba(120, 53, 15, var(--tw-text-opacity));
.text-green-50
--tw-text-opacity: 1; color: rgba(236, 253, 245, var(--tw-text-opacity));
.text-green-100
--tw-text-opacity: 1; color: rgba(209, 250, 229, var(--tw-text-opacity));
.text-green-200
--tw-text-opacity: 1; color: rgba(167, 243, 208, var(--tw-text-opacity));
.text-green-300
--tw-text-opacity: 1; color: rgba(110, 231, 183, var(--tw-text-opacity));
.text-green-400
--tw-text-opacity: 1; color: rgba(52, 211, 153, var(--tw-text-opacity));
.text-green-500
--tw-text-opacity: 1; color: rgba(16, 185, 129, var(--tw-text-opacity));
.text-green-600
--tw-text-opacity: 1; color: rgba(5, 150, 105, var(--tw-text-opacity));
.text-green-700
--tw-text-opacity: 1; color: rgba(4, 120, 87, var(--tw-text-opacity));
.text-green-800
--tw-text-opacity: 1; color: rgba(6, 95, 70, var(--tw-text-opacity));
.text-green-900
--tw-text-opacity: 1; color: rgba(6, 78, 59, var(--tw-text-opacity));
.text-blue-50
--tw-text-opacity: 1; color: rgba(239, 246, 255, var(--tw-text-opacity));
.text-blue-100
--tw-text-opacity: 1; color: rgba(219, 234, 254, var(--tw-text-opacity));
.text-blue-200
--tw-text-opacity: 1; color: rgba(191, 219, 254, var(--tw-text-opacity));
.text-blue-300
--tw-text-opacity: 1; color: rgba(147, 197, 253, var(--tw-text-opacity));
.text-blue-400
--tw-text-opacity: 1; color: rgba(96, 165, 250, var(--tw-text-opacity));
.text-blue-500
--tw-text-opacity: 1; color: rgba(59, 130, 246, var(--tw-text-opacity));
.text-blue-600
--tw-text-opacity: 1; color: rgba(37, 99, 235, var(--tw-text-opacity));
.text-blue-700
--tw-text-opacity: 1; color: rgba(29, 78, 216, var(--tw-text-opacity));
.text-blue-800
--tw-text-opacity: 1; color: rgba(30, 64, 175, var(--tw-text-opacity));
.text-blue-900
--tw-text-opacity: 1; color: rgba(30, 58, 138, var(--tw-text-opacity));
.text-indigo-50
--tw-text-opacity: 1; color: rgba(238, 242, 255, var(--tw-text-opacity));
.text-indigo-100
--tw-text-opacity: 1; color: rgba(224, 231, 255, var(--tw-text-opacity));
.text-indigo-200
--tw-text-opacity: 1; color: rgba(199, 210, 254, var(--tw-text-opacity));
.text-indigo-300
--tw-text-opacity: 1; color: rgba(165, 180, 252, var(--tw-text-opacity));
.text-indigo-400
--tw-text-opacity: 1; color: rgba(129, 140, 248, var(--tw-text-opacity));
.text-indigo-500
--tw-text-opacity: 1; color: rgba(99, 102, 241, var(--tw-text-opacity));
.text-indigo-600
--tw-text-opacity: 1; color: rgba(79, 70, 229, var(--tw-text-opacity));
.text-indigo-700
--tw-text-opacity: 1; color: rgba(67, 56, 202, var(--tw-text-opacity));
.text-indigo-800
--tw-text-opacity: 1; color: rgba(55, 48, 163, var(--tw-text-opacity));
.text-indigo-900
--tw-text-opacity: 1; color: rgba(49, 46, 129, var(--tw-text-opacity));
.text-purple-50
--tw-text-opacity: 1; color: rgba(245, 243, 255, var(--tw-text-opacity));
.text-purple-100
--tw-text-opacity: 1; color: rgba(237, 233, 254, var(--tw-text-opacity));
.text-purple-200
--tw-text-opacity: 1; color: rgba(221, 214, 254, var(--tw-text-opacity));
.text-purple-300
--tw-text-opacity: 1; color: rgba(196, 181, 253, var(--tw-text-opacity));
.text-purple-400
--tw-text-opacity: 1; color: rgba(167, 139, 250, var(--tw-text-opacity));
.text-purple-500
--tw-text-opacity: 1; color: rgba(139, 92, 246, var(--tw-text-opacity));
.text-purple-600
--tw-text-opacity: 1; color: rgba(124, 58, 237, var(--tw-text-opacity));
.text-purple-700
--tw-text-opacity: 1; color: rgba(109, 40, 217, var(--tw-text-opacity));
.text-purple-800
--tw-text-opacity: 1; color: rgba(91, 33, 182, var(--tw-text-opacity));
.text-purple-900
--tw-text-opacity: 1; color: rgba(76, 29, 149, var(--tw-text-opacity));
.text-pink-50
--tw-text-opacity: 1; color: rgba(253, 242, 248, var(--tw-text-opacity));
.text-pink-100
--tw-text-opacity: 1; color: rgba(252, 231, 243, var(--tw-text-opacity));
.text-pink-200
--tw-text-opacity: 1; color: rgba(251, 207, 232, var(--tw-text-opacity));
.text-pink-300
--tw-text-opacity: 1; color: rgba(249, 168, 212, var(--tw-text-opacity));
.text-pink-400
--tw-text-opacity: 1; color: rgba(244, 114, 182, var(--tw-text-opacity));
.text-pink-500
--tw-text-opacity: 1; color: rgba(236, 72, 153, var(--tw-text-opacity));
.text-pink-600
--tw-text-opacity: 1; color: rgba(219, 39, 119, var(--tw-text-opacity));
.text-pink-700
--tw-text-opacity: 1; color: rgba(190, 24, 93, var(--tw-text-opacity));
.text-pink-800
--tw-text-opacity: 1; color: rgba(157, 23, 77, var(--tw-text-opacity));
.text-pink-900
--tw-text-opacity: 1; color: rgba(131, 24, 67, var(--tw-text-opacity));
.text-opacity-5
--tw-text-opacity: 0.05;
.text-opacity-10
--tw-text-opacity: 0.1;
.text-center
text-align: center;
.text-right
text-align: right;
.line-through
text-decoration: line-through;
.no-underline
text-decoration: none;
.lowercase
text-transform: lowercase;
.capitalize
text-transform: capitalize;
.overflow-ellipsis
text-overflow: ellipsis;
.overflow-clip
text-overflow: clip;
Excerpt
Best practices for adding your own custom styles to Tailwind.
Often the biggest challenge when working with a framework is figuring out what you’re supposed to do when there’s something you need that the framework doesn’t handle for you.
Tailwind has been designed from the ground up to be extensible and customizable, so that no matter what you’re building you never feel like you’re fighting the framework.
This guide covers topics like customizing your design tokens, how to break out of those constraints when necessary, adding your own custom CSS, and extending the framework with plugins.
If you want to change things like your color palette, spacing scale, typography scale, or breakpoints, add your customizations to the theme section of your tailwind.config.js file:
Learn more about customizing your theme in the documentation.
While you can usually build the bulk of a well-crafted design using a constrained set of design tokens, once in a while you need to break out of those constraints to get things pixel-perfect.
When you find yourself really needing something like top: 117px to get a background image in just the right spot, use Tailwind’s square bracket notation to generate a class on the fly with any arbitrary value:
This is basically like inline styles, with the major benefit that you can combine it with interactive modifiers like hover and responsive modifiers like lg:
This works for everything in the framework, including things like background colors, font sizes, pseudo-element content, and more:
If you ever need to use a CSS property that Tailwind doesn’t include a utility for out of the box, you can also use square bracket notation to write completely arbitrary CSS:
This is really like inline styles, but again with the benefit that you can use modifiers:
This can be useful for things like CSS variables as well, especially when they need to change under different conditions:
When an arbitrary value needs to contain a space, use an underscore (_) instead and Tailwind will automatically convert it to a space at build-time:
In situations where underscores are common but spaces are invalid, Tailwind will preserve the underscore instead of converting it to a space, for example in URLs:
In the rare case that you actually need to use an underscore but it’s ambiguous because a space is valid as well, escape the underscore with a backslash and Tailwind won’t convert it to a space:
Many utilities in Tailwind share a common namespace but map to different CSS properties. For example text-lg and text-black both share the text- namespace, but one is for font-size and the other is for color.
When using arbitrary values, Tailwind can generally handle this ambiguity automatically based on the value you pass in:
Sometimes it really is ambiguous though, for example when using CSS variables:
In these situations, you can “hint” the underlying type to Tailwind by adding a before the value:
When you need to add truly custom CSS rules to a Tailwind project, the easiest approach is to just add the custom CSS to your stylesheet:
For more power, you can also use the @layer directive to add styles to Tailwind’s base, components, and utilities layers:
Why does Tailwind group styles into "layers"?
In CSS, the order of the rules in your stylesheet decides which declaration wins when two selectors have the same specificity:
Here, both buttons will be black since .bg-black comes after .btn in the CSS:
To manage this, Tailwind organizes the styles it generates into three different “layers” — a concept popularized by .
The base layer is for things like reset rules or default styles applied to plain HTML elements.
The components layer is for class-based styles that you want to be able to override with utilities.
The utilities
Being explicit about this makes it easier to understand how your styles will interact with each other, and using the @layer directive lets you control the final declaration order while still organizing your actual code in whatever way you like.
The @layer directive helps you control declaration order by automatically relocating your styles to the corresponding @tailwind directive, and also enables features like and for your own custom CSS.
If you just want to set some defaults for the page (like the text color, background color, or font family), the easiest option is just adding some classes to the html or body elements:
This keeps your base styling decisions in your markup alongside all of your other styles, instead of hiding them in a separate file.
If you want to add your own default base styles for specific HTML elements, use the @layer directive to add those styles to Tailwind’s base layer:
Use the function or directive when adding custom base styles if you want to refer to any of the values defined in your .
Use the components layer for any more complicated classes you want to add to your project that you’d still like to be able to override with utility classes.
Traditionally these would be classes like card, btn, badge — that kind of thing.
By defining component classes in the components layer, you can still use utility classes to override them when necessary:
Using Tailwind you probably don’t need these types of classes as often as you think. Read our guide on for our recommendations.
The components layer is also a good place to put custom styles for any third-party components you’re using:
Use the function or directive when adding custom component styles if you want to refer to any of the values defined in your .
Add any of your own custom utility classes to Tailwind’s utilities layer:
This can be useful when there’s a CSS feature you’d like to use in your project that Tailwind doesn’t include utilities for out of the box.
Any custom styles you add to Tailwind with @layer will automatically support Tailwind’s modifier syntax for handling things like hover states, responsive breakpoints, dark mode, and more.
Learn more about how these modifiers work in the documentation.
Any custom styles you add to the base, components, or utilities layers will only be included in your compiled CSS if those styles are actually used in your HTML.
If you want to add some custom CSS that should always be included, add it to your stylesheet without using the @layer directive:
Make sure to put your custom styles where they need to go to get the precedence behavior you want. In the example above, we’ve added the .card class before @tailwind utilities to make sure utilities can still override it.
If you are writing a lot of CSS and organizing it into multiple files, make sure those files are combined into a single stylesheet before processing them with Tailwind, or you’ll see errors about using @layer without the corresponding @tailwind directive.
The easiest way to do this is using the plugin:
Learn more in our documentation.
Component frameworks like Vue and Svelte support adding per-component styles within a <style> block that lives in each component file.
While you can use features like @apply and theme inside component styles like this, the @layer directive will not work and you’ll see an error about @layer being used without a matching @tailwind directive:
Don't use `@layer` in component styles
This is because under-the-hood, frameworks like Vue and Svelte are processing every single <style> block independently, and running your PostCSS plugin chain against each one in isolation.
That means if you have 10 components that each have a <style> block, Tailwind is being run 10 separate times, and each run has zero knowledge about the other runs. Because of this, Tailwind can’t take the styles you define in a @layer and move them to the corresponding @tailwind directive, because as far as Tailwind can tell there is no @tailwind directive to move it to.
One solution to this is to simply not use @layer inside your component styles:
Add your styles without using `@layer`
You lose the ability to control the precedence of your styles, but unfortunately that’s totally out of our control because of how these tools work.
Our recommendation is that you just don’t use component styles like this at all and instead use Tailwind the way it’s intended to be used — as a single global stylesheet where you use the classes directly in your HTML:
Use Tailwind's utilities instead of component styles
You can also add custom styles to your project using Tailwind’s plugin system instead of using a CSS file:
Learn more about writing your own plugins in the documentation.
<div class="top-[117px]">
<!-- ... -->
</div><div class="top-[117px] lg:top-[344px]">
<!-- ... -->
</div><div class="bg-[#bada55] text-[22px] before:content-['Festivus']">
<!-- ... -->
</div><div class="[mask-type:luminance]">
<!-- ... -->
</div><div class="[mask-type:luminance] hover:[mask-type:alpha]">
<!-- ... -->
</div><div class="[--scroll-offset:56px] lg:[--scroll-offset:44px]">
<!-- ... -->
</div><div class="grid grid-cols-[1fr_500px_2fr]">
<!-- ... -->
</div><div class="bg-[url('/what_a_rush.png')]">
<!-- ... -->
</div><div class="before:content-['hello\_world']">
<!-- ... -->
</div><!-- Will generate a font-size utility -->
<div class="text-[22px]">...</div>
<!-- Will generate a color utility -->
<div class="text-[#bada55]">...</div><div class="text-[var(--my-var)]">...</div><!-- Will generate a font-size utility -->
<div class="text-[length:var(--my-var)]">...</div>
<!-- Will generate a color utility -->
<div class="text-[color:var(--my-var)]">...</div>.btn {
background: blue;
/* ... */
}
.bg-black {
background: black;
}<button class="btn bg-black">...</button>
<button class="bg-black btn">...</button><!doctype html>
<html lang="en" class="text-gray-900 bg-gray-100 font-serif">
<!-- ... -->
</html><!-- Will look like a card, but with square corners -->
<div class="card rounded-none">
<!-- ... -->
</div>