Provides elm-review rules to sort and organize Tailwind CSS classes in Elm files for improved readability.
-
Tailwind.SortAndGroupClasses- Reports unsorted Tailwind classes and provides automatic fixes to organize them into logical groups.
module ReviewConfig exposing (config)
import Tailwind.SortAndGroupClasses
import Review.Rule exposing (Rule)
config : List Rule
config =
[ Tailwind.SortAndGroupClasses.rule
]This rule organizes Tailwind CSS classes in Attr.class declarations by:
- Sorting classes into logical groups (layout, positioning, spacing, typography, colors, etc.)
-
Splitting long class strings into multiple
Attr.classdeclarations by category -
Merging scattered
Attr.classcalls: when an attribute list has two or moreAttr.classcalls, they're combined, regrouped, and moved ahead of any other attributes (which keep their original relative order) -
Handling responsive/state variants (sm:, md:, hover:, dark:, etc.) correctly, including stacked variants (
dark:hover:bg-gray-700) and the important modifier (!mt-4/mt-4!)
Html.div
[ Attr.class "text-gray-700 mt-4 flex p-2 bg-white rounded-lg hover:bg-gray-50 items-center justify-between w-full shadow-sm border border-gray-200"
]
[]Html.div
[ Attr.class "flex"
, Attr.class "w-full"
, Attr.class "items-center justify-between"
, Attr.class "p-2"
, Attr.class "mt-4"
, Attr.class "text-gray-700"
, Attr.class "bg-white hover:bg-gray-50"
, Attr.class "border border-gray-200 rounded-lg"
, Attr.class "shadow-sm"
]
[]The rendered HTML produces the exact same classes - multiple Attr.class declarations concatenate into a single class attribute.
Classes are sorted into these groups (in order):
- Layout & Display (
block,flex,grid,hidden,table,list-item, etc.) - Positioning (
absolute,relative,top-*,z-*, etc.) - Box Sizing (
box-border,box-content) - Container & Sizing (
w-*,h-*,max-w-*, etc.) - Overflow & Visibility (
overflow-*,visible,invisible) - Flexbox (
flex-*,grow-*,shrink-*,basis-*,order-*) - Grid (
grid-cols-*,col-span-*, etc.) - Alignment (
justify-*,items-*,content-*,self-*,place-*) - Gap & Spacing (
gap-*,space-*) - Padding (
p-*,px-*,py-*, etc.) - Margin (
m-*,mx-*,my-*, etc.) - Typography (
text-*size/alignment,font-*,leading-*,align-*, etc.) - Text Color (
text-red-*,text-gray-*, etc.) - Background (
bg-*) - Border (
border-*,rounded-*,divide-*) - Ring & Outline (
ring-*,outline-*) - Shadow (
shadow-*) - Opacity & Effects (
opacity-*) - Filters (
blur-*,brightness-*,filter,filter-none, etc.) - Transforms (
scale-*,rotate-*,translate-*) - Transitions & Animation (
transition-*,duration-*,animate-*) - Interactivity (
cursor-*,select-*,pointer-events-*,accent-*,appearance-*, etc.) - SVG (
fill-*,stroke-*) - Screen Readers (
sr-only,not-sr-only)
Note that Alignment (8, flex/grid alignment) is a distinct group from Flexbox (6) and Grid (7) — flex items-center justify-between becomes two separate Attr.class calls (flex in Layout & Display, items-center justify-between in Alignment), not one merged call. This keeps grouping fully mechanical: every class always lands in exactly one of the 24 categories above, with no case-by-case judgment calls about what "reads better" combined.
Within each group, classes are sorted alphabetically. Variant prefixes are handled by sorting based on the base class, with this prefix order: unprefixed first, then breakpoints (sm, md, lg, xl, 2xl), then states (hover, focus, active, disabled, or any other single-word variant), then dark mode. Stacked variants (e.g. dark:hover:bg-gray-700) are ranked by breakpoint, then dark, then state, regardless of the order the prefixes are written in. The important modifier (!mt-4 or mt-4!) doesn't affect grouping or ordering.
You can try the example configuration above out by running the following command:
elm-review --template cekrem/elm-review-tailwind/exampleSee AI_DISCLOSURE.md.