# Tailwind CSS best practices
## Utility classes ##
1. When writing a string of multiple utility classes, always do so in an order with meaning. The "Concentric CSS" approach works well with utility classes (i.e,. 1. positioning/visibility 2. box model 3. borders 4. backgrounds 5. typography 6. other visual adjustments). Once you establish a familiar pattern of ordering, parsing through long strings of utility classes will become much, much faster so a little more effort up front goes a long way!
2. Always use fewer utility classes when possible. For example, use `mx-2` instead of `ml-2 mr-2` and don't be afraid to use the simpler `p-4 lg:pt-8` instead of the longer, more complicated `pt-4 lg:pt-8 pr-4 pb-4 pl-4`.
3. Prefix all utility classes that will only apply at a certain breakpoint with that breakpoint's prefix. For example, use `block lg:flex lg:flex-col lg:justify-center` instead of `block lg:flex flex-col justify-center` to make it very clear that the flexbox utilities are only applicable at the `lg:` breakpoint and larger.
4. Keep in mind that, by default, all responsive utilities are set to apply at `min-width`. That is, the `sm:` prefix does not apply only to small viewports; it applies to small breakpoints _and larger_. So for example instead of using the longform `block sm:block md:flex lg:flex xl:flex` for a `
` element you can just write `md:flex`. They both have the same behavior.
5. Also note that, by default, the `sm:` breakpoint does not start at `min-width: 0` as you might expect. It starts at `min-width: 640px`. So if you want something to apply only to the smallest of viewports (those smaller than `640px`), you must first set it to apply to _all_ breakpoints and then override it for larger breakpoints. For example, use `block sm:inline` if you want something to appear as `block` for only the smallest of screens.
6. Use a consistent pattern of margin classes to make it easier to reason about positioning. For example, consistently use only `mt-*` and `ml-*` utilities, which will position the current element, or consistently use only `mb-*` and `mr-*` utilities, which will position adjacent elements. In general it is easier to reason about positioning when using the former pattern because it is effectively scoped to the styled element, but keep in mind that you may need to make exceptions to your selected pattern for elements which only appear under certain conditions, as you wouldn't want to have to also add conditional margins to elements that are adjacent to the conditional element.
7. Remember that you can often add a wrapper `
` with padding instead of using margins, which may help avoid potential issues with margin collapsing. By using utility-first CSS, you don't need to invent "semantic" class names for single purpose `
`s so there is no reason to avoid using them when they are helpful.
## Component classes
1. Do not prematurely use `@apply` to abstract component classes where a proper framework/template-based component is more appropriate. However, if the string of utility classes within that component is also used in other components, then there is true duplication. In this case, the creation of a new shared CSS component class with `@apply` may be warranted.
2. Do not `@apply` component classes in other components. For example, maintain seperate `.btn` and `.btn-blue` classes rather than using `.btn-blue { @apply btn; }`
## Dynamic classes ##
1. When CSS classes are selected or generated dynamically, do not use string concatination to combine fragments of the full class. Instead switch between the complete strings. For example, use this `{% set width = maxPerRow == 2 ? 'sm:w-1/2' : 'sm:w-1/3' %}` instead of this `{% set width = 'sm:w-1/' ~ maxPerRow %}`. You always want the complete string of each utility class present in the markup to make it easier to reason about and to ensure that it survives the PurgeCSS process, if it is a part of your build tools.