Tails (tails v0.1.11)

Tailwind class utilities like class merging.

In most cases, only classes that we know all of the values for are merged. In some cases, we merge anything starting with a given prefix. Eventually, we will have tools to read your tailwind config to determine additional classes to merge, or have explicit configuration on additional merge logic.

The preferred way to use tails classes the classes/1 function. This gives you:

  1. conditional classes
  2. list merging (from left to right)
  3. arbitrary nesting

For example:

classes(["mt-1 mx-2", ["pt-2": var1, "pb-4", var2], "mt-12": var3])

Will merge all classes from left to right, flattening the lists and conditionally including the classes where the associated value is true.

what-classes-are-currently-merged

What classes are currently merged?

directional-classes

Directional classes

These classes support x/y/l/r suffix merging.

  • Padding - p
  • Margin - m

only-explicitly-known-values

Only explicitly known values

Only explicitly known values will be merged, all others will be retained.

  • Sr Only - sr-only, not-sr-only
  • Transition Timing Function - ease-linear, ease-in, ease-out, ease-in-out
  • Text Overflows - truncate, text-ellipses, text-clip
  • Text Transform - uppercase, lowercase, capitalize, normal-case
  • Text Decoration - underline, overline, line-through, no-underline
  • Isolation - isolate, isolation-auto
  • Position - static, fixed, absolute, relative, sticky
  • Font Smoothing - antialiased, subpixel-antialiased
  • Font Style - italic, non-italic
  • Display - block, inline-block, inline, flex, inline-flex, table, inline-table, table-caption, table-cell, table-column, table-column-group, table-footer-group, table-header-group, table-row-group, table-row, flow-root, grid, inline-grid, contents, list-item, hidden
  • Visibility - visible, invisible, collapse
  • Text Overflow - truncate, text-ellipsis, text-clip
  • Will Change - will-change-auto, will-change-scroll, will-change-contents, will-change-transform
  • User Select - select-none, select-text, select-all, select-auto
  • Touch Action - touch-auto, touch-none, touch-pan-x, touch-pan-left, touch-pan-right, touch-pan-y, touch-pan-up, touch-pan-down, touch-pinch-zoom, touch-manipulation
  • Snap Type - snap-none, snap-x, snap-y, snap-both
  • Snap Strictness - snap-mandatory, snap-proximity
  • Snap Align - snap-start, snap-end, snap-center, snap-align-none
  • Snap Stop - snap-normal, snap-always
  • Scroll Behaviour - scroll-auto, scroll-smooth
  • Resize - resize-none, resize-y, resize-x
  • Pointer Events - pointer-events-auto, pointer-events-none
  • Cursor - cursor-auto, cursor-default, cursor-pointer, cursor-wait, cursor-text, cursor-move, cursor-help, cursor-not-allowed, cursor-none, cursor-context-menu, cursor-progress, cursor-cell, cursor-crosshair, cursor-vertical-text, cursor-alias, cursor-copy, cursor-no-drop, cursor-grab, cursor-grabbing, cursor-all-scroll, cursor-col-resize, cursor-row-resize, cursor-n-resize, cursor-e-resize, cursor-s-resize, cursor-w-resize, cursor-ne-resize, cursor-nw-resize, cursor-se-resize, cursor-sw-resize, cursor-ew-resize, cursor-ns-resize, cursor-nesw-resize, cursor-nwse-resize, cursor-zoom-in, cursor-zoom-out
  • Transform - transform-gpu, transform-none
  • Animate - animate-none, animate-spin, animate-ping, animate-pulse, animate-bounce
  • Transition Property - transition-none, transition-all, transition-colors, transition-opacity, transition-shadow, transition-transform
  • Table Layout - table-auto, table-fixed
  • Border Collapse Mode - border-collapse, border-separate
  • Mix Blend Mode - mix-blend-normal, mix-blend-multiply, mix-blend-screen, mix-blend-overlay, mix-blend-darken, mix-blend-lighten, mix-blend-color-dodge, mix-blend-color-burn, mix-blend-hard-light, mix-blend-soft-light, mix-blend-difference, mix-blend-exclusion, mix-blend-hue, mix-blend-saturation, mix-blend-color, mix-blend-luminosity, mix-blend-plus-lighter
  • Background Blend Mode - bg-blend-normal, bg-blend-multiply, bg-blend-screen, bg-blend-overlay, bg-blend-darken, bg-blend-lighten, bg-blend-color-dodge, bg-blend-color-burn, bg-blend-hard-light, bg-blend-soft-light, bg-blend-difference, bg-blend-exclusion, bg-blend-hue, bg-blend-saturation, bg-blend-color, bg-blend-luminosity
  • Outline Styles - outline-none, outline-dashed, outline-dotted, outline-double
  • Divide Styles - divide-solid, divide-dashed, divide-dotted, divide-double, divide-none
  • Border Style - border-solid, border-dashed, border-dotted, border-double, border-hidden, border-none
  • Word Breaks - break-normal, break-words, break-all, break-keep
  • Whitespace - whitespace-normal, whitespace-nowrap, whitespace-pre, whitespace-pre-line, whitespace-pre-wrap
  • Text Align - text-left, text-center, text-right, text-justify, text-start, text-end
  • Vertical Align - align-baseline, align-top, align-middle, align-bottom, align-text-top, align-text-bottom, align-sub, align-super
  • Text Decoration Style - decoration-solid, decoration-double, decoration-dotted, decoration-dashed, decoration-wavy
  • List Style Type - list-none, list-disc, list-decimal
  • List Style Position - list-inside, list-outside
  • Tracking - tracking-tighter, tracking-tight, tracking-normal, tracking-wide, tracking-wider, tracking-widest
  • Place Content - place-content-center, place-content-start, place-content-end, place-content-between, place-content-around, place-content-evenly, place-content-baseline, place-content-stretch
  • Place Items - place-items-start, place-items-end, place-items-center, place-items-baseline, place-items-stretch
  • Place Selfs - place-selfs-auto, place-selfs-start, place-selfs-end, place-selfs-center, place-selfs-stretch
  • Align Content - content-center, content-start, content-end, content-between, content-around, content-evenly, content-baseline
  • Align Items - items-start, items-end, items-center, items-baseline, items-stretch
  • Align Selfs - selfs-auto, selfs-start, selfs-end, selfs-center, selfs-stretch, selfs-baseline
  • Auto Cols - auto-cols-auto, auto-cols-min, auto-cols-max, auto-cols-fr
  • Auto Rows - auto-rows-auto, auto-rows-min, auto-rows-max, auto-rows-fr
  • Grid Flow - grid-flow-row, grid-flow-col, grid-flow-dense, grid-flow-row-dense, grid-flow-col-dense
  • Justify Contents - justify-start, justify-end, justify-center, justify-between, justify-around, justify-evenly
  • Justify Items - justify-items-start, justify-items-end, justify-items-center, justify-items-stretch
  • Justify Selfs - justify-selfs-auto, justify-selfs-start, justify-selfs-end, justify-selfs-center, justify-selfs-stretch
  • Flex Grow Shrink - flex-1, flex-auto, flex-initial, flex-none
  • Flex Direction - flex-row, flex-row-reverse, flex-col, flex-col-reverse
  • Shrink - shrink-0
  • Grow - grow-0
  • Flex Wrap - flex-wrap, flex-wrap-reverse, flex-nowrap
  • Overflow - overflow-auto, overflow-hidden, overflow-clip, overflow-visible, overflow-scroll
  • Overflow X - overflow-x-auto, overflow-x-hidden, overflow-x-clip, overflow-x-visible, overflow-x-scroll
  • Overflow Y - overflow-y-auto, overflow-y-hidden, overflow-y-clip, overflow-y-visible, overflow-y-scroll
  • Overscroll - overscroll-auto, overscroll-contain, overscroll-none
  • Overscroll X - overscroll-x-auto, overscroll-x-contain, overscroll-x-none
  • Overscroll Y - overscroll-y-auto, overscroll-y-contain, overscroll-y-none
  • Object Fit - object-contain, object-cover, object-fill, object-none, object-scale-down
  • Object Position - object-bottom, object-center, object-left, object-left-bottom, object-left-top, object-right, object-right-bottom, object-right-top, object-top
  • Float - float-left, float-right, float-none
  • Clear - clear-left, clear-right, clear-both, clear-none
  • Break After - break-after-auto, break-after-avoid, break-after-all, break-after-avoid-page, break-after-page, break-after-left, break-after-right, break-after-column
  • Break Before - break-before-auto, break-before-avoid, break-before-all, break-before-avoid-page, break-before-page, break-before-left, break-before-right, break-before-column
  • Break Inside - break-inside-auto, break-inside-avoid, break-inside-avoid-page, break-inside-avoid-column
  • Box Decoration - box-decoration-clone, box-decoration-slice
  • Box Size - box-border, box-content
  • Font Family - font-sans, font-serif, font-mono
  • Font Weight - font-thin, font-extralight, font-light, font-normal, font-medium, font-semibold, font-bold, font-extrabold, font-black
  • Aspect Ratio - aspect-auto, aspect-square, aspect-video
  • Outline Style - outline-none, outline-dashed, outline-dotted, outline-double
  • Background Size - bg-auto, bg-cover, bg-contain
  • Background Repeat - bg-repeat, bg-no-repeat, bg-repeat-x, bg-repeat-y, bg-repeat-round, bg-repeat-space
  • Background Positions - bg-bottom, bg-center, bg-left, bg-left-bottom, bg-left-top, bg-right, bg-right-bottom, bg-right-top, bg-top
  • Background Blend - bg-blend-normal, bg-blend-multiply, bg-blend-screen, bg-blend-overlay, bg-blend-darken, bg-blend-lighten, bg-blend-color-dodge, bg-blend-color-burn, bg-blend-hard-light, bg-blend-soft-light, bg-blend-difference, bg-blend-exclusion, bg-blend-hue, bg-blend-saturation, bg-blend-color, bg-blend-luminosity
  • Background Origin - bg-origin-border, bg-origin-padding, bg-origin-content
  • Background Clip - bg-clip-border, bg-clip-padding, bg-clip-content, bg-clip-text
  • Background Image - bg-none, bg-gradient-to-t, bg-gradient-to-tr, bg-gradient-to-r, bg-gradient-to-br, bg-gradient-to-b, bg-gradient-to-bl, bg-gradient-to-l, bg-gradient-to-tl
  • Background Attachment - bg-fixed, bg-local, bg-scroll
  • Col - col-auto
  • Fill Color - prefix fill-: colors
  • Outline Color - prefix outline-: colors
  • Caret Color - prefix caret-: colors
  • Accent Color - prefix accent-: colors
  • Ring Color - prefix ring-: colors
  • Shadow Color - prefix shadow-: colors
  • Ring Offset Color - prefix ring-offset-: colors
  • Divide Color - prefix divide-: colors
  • Border Color - prefix border-: colors
  • Border Color Y - prefix border-y-: colors
  • Border Color X - prefix border-x-: colors
  • Border Color T - prefix border-t-: colors
  • Border Color R - prefix border-r-: colors
  • Border Color B - prefix border-b-: colors
  • Border Color L - prefix border-l-: colors
  • Text Decoration Color - prefix decoration-: colors
  • Background - prefix bg-: colors
  • Text Color - prefix text-: colors

any-values-matching-prefix

Any values matching prefix

Any values matching the following prefixes will be merged with each other respectively

  • Stroke Width - stroke
  • Rotate - rotate
  • Translate - translate
  • Translate X - translate-x
  • Translate Y - translate-y
  • Scale X - scale-x
  • Scale Y - scale-y
  • Scale - scale
  • Skew X - skew-x
  • Skew Y - skew-y
  • Duration - duration
  • Delay - delay
  • Blur - blur
  • Brightness - brightness
  • Contrast - contrast
  • Sepia - sepia
  • Hue Rotate - hue-rotate
  • Grayscale - grayscale
  • Saturate - saturate
  • Invert - invert
  • Drop Shadow - drop-shadow
  • Shadow - shadow
  • Backdrop Blur - backdrop-blur
  • Backdrop Brightness - backdrop-brightness
  • Backdrop Contrast - backdrop-contrast
  • Backdrop Sepia - backdrop-sepia
  • Backdrop Hue Rotate - backdrop-hue-rotate
  • Backdrop Grayscale - backdrop-grayscale
  • Backdrop Saturate - backdrop-saturate
  • Backdrop Invert - backdrop-invert
  • Backdrop Opacity - backdrop-opacity
  • Border Opacity - border-opacity
  • Ring Width - ring
  • Underline Offset - underline-offset
  • Text Decoration Thickness - decoration
  • Text Indent - indent
  • Leading - leading
  • Gap - gap
  • Gap X - gap-x
  • Gap Y - gap-y
  • Order - order
  • Basis - basis
  • Space X - space-x
  • Space Y - space-y
  • Z - z
  • Left - left
  • Right - right
  • Top - top
  • Bottom - bottom
  • Inset - inset
  • Inset Y - inset-y
  • Inset X - inset-x
  • Columns - columns
  • Col Span - col-span
  • Col Start - col-start
  • Col End - col-end
  • Row Span - row-span
  • Row Start - row-start
  • Row End - row-end
  • Font Size - text
  • Outline Width - outline
  • Outline Offset - outline-offset
  • Grid Cols - grid-cols
  • Grid Rows - grid-rows
  • Width - w
  • Min Width - min-w
  • Max Width - max-w
  • Height - h
  • Min Height - min-h
  • Max Height - max-h

singletons

Singletons

The following classes are tracked as special classes, but don't have any special merge behavior because they either compose with other similar classes or have no conflicts

  • container
  • content-none
  • space-y-reverse
  • space-x-reverse
  • divide-y-reverse
  • divide-x-reverse
  • ring-inset
  • filter-none
  • backdrop-filter-none
  • col-auto
  • row-auto
  • normal-nums
  • ordinal
  • slashed-zero
  • lining-nums
  • oldstyle-nums
  • proportional-nums
  • tabular-nums
  • diagonal-fractions
  • stacked-fractions

Link to this section Summary

Functions

Builds a class string out of a mixed list of inputs or a string. You can use the ~t sigil as a shortcut.

Trims nil values and returns a map

Merges a list of class strings. See merge/2 for more

Semantically merges two lists of tailwind classes, treating the first as a base and the second as overrides

Removes the given class from the class list.

Builds a class string out of a mixed list of inputs or a string.

Link to this section Types

@type t() :: %Tails{
  accent_color: term(),
  align_content: term(),
  align_items: term(),
  align_selfs: term(),
  animate: term(),
  aspect_ratio: term(),
  auto_cols: term(),
  auto_rows: term(),
  "backdrop-filter-none": term(),
  backdrop_blur: term(),
  backdrop_brightness: term(),
  backdrop_contrast: term(),
  backdrop_grayscale: term(),
  backdrop_hue_rotate: term(),
  backdrop_invert: term(),
  backdrop_opacity: term(),
  backdrop_saturate: term(),
  backdrop_sepia: term(),
  basis: term(),
  bg: term(),
  bg_attachment: term(),
  bg_blend: term(),
  bg_blend_mode: term(),
  bg_clip: term(),
  bg_image: term(),
  bg_origin: term(),
  bg_positions: term(),
  bg_repeat: term(),
  bg_size: term(),
  blur: term(),
  border_collapse_mode: term(),
  border_color: term(),
  border_color_b: term(),
  border_color_l: term(),
  border_color_r: term(),
  border_color_t: term(),
  border_color_x: term(),
  border_color_y: term(),
  border_opacity: term(),
  border_spacing: term(),
  border_style: term(),
  border_width: term(),
  bottom: term(),
  box_decoration: term(),
  box_size: term(),
  break_after: term(),
  break_before: term(),
  break_inside: term(),
  brightness: term(),
  caret_color: term(),
  classes: term(),
  clear: term(),
  col: term(),
  "col-auto": term(),
  col_end: term(),
  col_span: term(),
  col_start: term(),
  columns: term(),
  container: term(),
  "content-none": term(),
  contrast: term(),
  cursor: term(),
  delay: term(),
  "diagonal-fractions": term(),
  display: term(),
  divide: term(),
  "divide-x-reverse": term(),
  "divide-y-reverse": term(),
  divide_color: term(),
  divide_styles: term(),
  drop_shadow: term(),
  duration: term(),
  fallback: term(),
  fill_color: term(),
  "filter-none": term(),
  flex_direction: term(),
  flex_grow_shrink: term(),
  flex_wrap: term(),
  float: term(),
  font_family: term(),
  font_size: term(),
  font_smoothing: term(),
  font_style: term(),
  font_weight: term(),
  gap: term(),
  gap_x: term(),
  gap_y: term(),
  grayscale: term(),
  grid_cols: term(),
  grid_flow: term(),
  grid_rows: term(),
  grow: term(),
  height: term(),
  hue_rotate: term(),
  inset: term(),
  inset_x: term(),
  inset_y: term(),
  invert: term(),
  isolation: term(),
  justify_contents: term(),
  justify_items: term(),
  justify_selfs: term(),
  leading: term(),
  left: term(),
  "lining-nums": term(),
  list_style_position: term(),
  list_style_type: term(),
  m: term(),
  max_height: term(),
  max_width: term(),
  min_height: term(),
  min_width: term(),
  mix_blend_mode: term(),
  "normal-nums": term(),
  object_fit: term(),
  object_position: term(),
  "oldstyle-nums": term(),
  order: term(),
  ordinal: term(),
  outline_color: term(),
  outline_offset: term(),
  outline_style: term(),
  outline_styles: term(),
  outline_width: term(),
  overflow: term(),
  overflow_x: term(),
  overflow_y: term(),
  overscroll: term(),
  overscroll_x: term(),
  overscroll_y: term(),
  p: term(),
  place_content: term(),
  place_items: term(),
  place_selfs: term(),
  pointer_events: term(),
  position: term(),
  "proportional-nums": term(),
  resize: term(),
  right: term(),
  "ring-inset": term(),
  ring_color: term(),
  ring_offset_color: term(),
  ring_width: term(),
  rotate: term(),
  rounded: term(),
  "row-auto": term(),
  row_end: term(),
  row_span: term(),
  row_start: term(),
  saturate: term(),
  scale: term(),
  scale_x: term(),
  scale_y: term(),
  scroll_behaviour: term(),
  scroll_m: term(),
  scroll_p: term(),
  sepia: term(),
  shadow: term(),
  shadow_color: term(),
  shrink: term(),
  skew_x: term(),
  skew_y: term(),
  "slashed-zero": term(),
  snap_align: term(),
  snap_stop: term(),
  snap_strictness: term(),
  snap_type: term(),
  "space-x-reverse": term(),
  "space-y-reverse": term(),
  space_x: term(),
  space_y: term(),
  sr_only: term(),
  "stacked-fractions": term(),
  stroke_width: term(),
  table_layout: term(),
  "tabular-nums": term(),
  text_align: term(),
  text_color: term(),
  text_decoration: term(),
  text_decoration_color: term(),
  text_decoration_style: term(),
  text_decoration_thickness: term(),
  text_indent: term(),
  text_overflow: term(),
  text_overflows: term(),
  text_transform: term(),
  theme: term(),
  top: term(),
  touch_action: term(),
  tracking: term(),
  transform: term(),
  transition_property: term(),
  transition_timing_function: term(),
  translate: term(),
  translate_x: term(),
  translate_y: term(),
  underline_offset: term(),
  user_select: term(),
  variant: term(),
  variants: term(),
  vertical_align: term(),
  visibility: term(),
  whitespace: term(),
  width: term(),
  will_change: term(),
  word_breaks: term(),
  z: term()
}

Link to this section Functions

Link to this function

classes(classes)

Builds a class string out of a mixed list of inputs or a string. You can use the ~t sigil as a shortcut.

If the value is a string, we make a new Tails with it (essentially deduplicating it).

If the value is a list, then for each item in the list:

  • If the value is a list, we call classes/1 on it.
  • If it is a tuple, we discard it unless the second element is truthy.
  • Otherwise, we to_string it

And then we merge the whole list up into one class string.

This allows for conditional class rendering, arbitrarily nested.

examples

Examples

iex> classes(["a", "b"])
"a b"

iex> classes([a: false, b: true])
"b"

iex> classes([[a: true, b: false], [c: false, d: true]])
"a d"

Trims nil values and returns a map

Merges a list of class strings. See merge/2 for more

Link to this function

merge(tailwind, classes)

Semantically merges two lists of tailwind classes, treating the first as a base and the second as overrides

Generally, instead of calling merge/2 you will call classes/1 with a list of classes.

See the module documentation for what classes will be merged/retained.

Examples

iex> merge("p-4", "p-2") |> to_string()
"p-2"
iex> merge("p-2", "p-4") |> to_string()
"p-4"
iex> merge("p-4", "px-2") |> to_string()
"p-4 px-2"
iex> merge("font-bold", "font-thin") |> to_string()
"font-thin"
iex> merge("block absolute", "fixed hidden") |> to_string()
"fixed hidden"
iex> merge("bg-blue-500", "bg-auto") |> to_string()
"bg-blue-500 bg-auto"
iex> merge("bg-auto", "bg-repeat-x") |> to_string()
"bg-auto bg-repeat-x"
iex> merge("bg-blue-500", "bg-red-400") |> to_string()
"bg-red-400"
iex> merge("grid grid-cols-2 lg:grid-cols-3", "grid-cols-3 lg:grid-cols-4") |> to_string()
"grid grid-cols-3 lg:grid-cols-4"
iex> merge("min-h-2", "min-h-[1rem]") |> to_string()
"min-h-[1rem]"
iex> merge("min-w-2", "min-h-[1rem]") |> to_string()
"min-w-2 min-h-[1rem]"
iex> merge("border-2", "border-gray-500") |> to_string()
"border-2 border-gray-500"
iex> merge("rounded-lg", "rounded") |> to_string()
"rounded"
iex> merge("rounded", "rounded-lg") |> to_string()
"rounded-lg"
iex> merge("rounded", "px-2") |> to_string()
"px-2 rounded"
iex> merge("border-separate", "border-spacing-1") |> to_string()
"border-spacing-1 border-separate"
iex> merge("shadow", "shadow-md") |> to_string()
"shadow-md"
iex> merge("shadow-none", "shadow-inner") |> to_string()
"shadow-inner"
iex> merge("shadow-lg", "shadow") |> to_string()
"shadow"
iex> merge("text-xl", "text-[16px]") |> to_string()
"text-[16px]"
iex> merge("text-white", "text-[#000]") |> to_string()
"text-[#000]"
iex> merge("text-center text-xl text-white", "text-[16px] text-[#000]") |> to_string()
"text-[#000] text-center text-[16px]"
iex> merge("border-b-4 border-opacity-20") |> to_string()
"border-b-4 border-opacity-20"
iex> merge("border-black border-b-4 border-opacity-20") |> to_string()
"border-b-4 border-black border-opacity-20"
iex> merge("border-2 border-px") |> to_string()
"border-px"

Classes can be removed

iex> merge("font-normal text-black", "remove:font-normal grid") |> to_string()
"grid text-black"

All preceding classes can be removed

iex> merge("font-normal text-black", "remove:* grid") |> to_string()
"grid"

Classes can be explicitly kept

iex> merge("font-normal text-black", "remove:font-normal grid") |> to_string()
"grid text-black"
Link to this function

remove(tailwind, class)

Removes the given class from the class list.

Link to this macro

sigil_t(contents, flags)

(macro)

Builds a class string out of a mixed list of inputs or a string.

See classes/1 for more information.

iex> ~t([[a: true, b: false], [c: false, d: true]])
"a d"