Transforms, layering, masking and lists

Use the power transforms for rotation, flipping and scaling, compose icons with layers and masks, and build icon lists that work in both directions.

Power transforms

<!-- Rotation and flipping: the simple transforms -->
<i class="fa-solid fa-arrow-right" aria-hidden="true"></i>
<i class="fa-solid fa-arrow-right fa-rotate-90" aria-hidden="true"></i>
<i class="fa-solid fa-arrow-right fa-rotate-180" aria-hidden="true"></i>
<i class="fa-solid fa-arrow-right fa-rotate-270" aria-hidden="true"></i>
<i class="fa-solid fa-arrow-right fa-flip-horizontal" aria-hidden="true"></i>
<i class="fa-solid fa-arrow-right fa-flip-vertical" aria-hidden="true"></i>
<i class="fa-solid fa-arrow-right fa-flip-both" aria-hidden="true"></i>

<!-- The power transform syntax: a space-separated list inside data-fa-transform
     (SVG route) or as utility classes (font route). -->
<i class="fa-solid fa-user" data-fa-transform="shrink-6 left-4 up-2" aria-hidden="true"></i>
<i class="fa-solid fa-user" data-fa-transform="grow-8 rotate-45" aria-hidden="true"></i>
<i class="fa-solid fa-user" data-fa-transform="shrink-4.5 down-1.25" aria-hidden="true"></i>

<!-- The equivalents as classes on the font route -->
<i class="fa-solid fa-user fa-shrink-6 fa-left-4 fa-up-2" aria-hidden="true"></i>
TransformEffectUnits
grow-NScale up by 6N%N is a number, fractions allowed
shrink-NScale down by 6N%Same
left-N / right-NTranslate horizontallyN/16 em
up-N / down-NTranslate verticallyN/16 em
rotate-NRotate by N degreesDegrees, can be fractional or negative
flip-h / flip-v / flip-bothMirror on an axisIn data-fa-transform
fa-rotate-byA CSS custom-property rotationSet --fa-rotate-angle
/* The rotation utility reads a custom property, so a dynamic angle needs no
   new class and no JavaScript. */
.icon-rotating {
  rotate: var(--fa-rotate-angle, 0deg);
  transition: rotate 300ms ease-out;
}
.icon-rotating.is-expanded { --fa-rotate-angle: 180deg; }

/* The SVG route exposes the same knobs through the component API:
     rotation={90} flip="horizontal" transform="shrink-6 left-2"
   Order matters: the transform string is applied as written, so
   "shrink-6 rotate-45" and "rotate-45 shrink-6" differ in the rotation's
   centre of mass. */
💡
Transforms are applied inside the icon's own box. A transform that moves an icon outside that box will be clipped by the SVG's viewBox on the SVG route and will overlap its neighbours on the font route. If you need an icon to overflow deliberately, increase the container rather than the transform.

Layers and masks

<!-- fa-layers composes icons into a single graphic. Sizing is set once on
     the parent; each child is positioned with fa-layers-*
     (fa-layers-1x through fa-layers-10x). -->
<span class="fa-layers fa-fw fa-3x" aria-hidden="true">
  <i class="fa-solid fa-circle" style="color: #6d28d9"></i>
  <i class="fa-solid fa-check" style="color: white" data-fa-transform="shrink-6"></i>
</span>

<!-- A counter badge: a common requirement, and this is the clean way -->
<span class="fa-layers fa-fw fa-2x">
  <i class="fa-solid fa-bell"></i>
  <span class="fa-layers-counter" style="background: #ef4444">12</span>
</span>

<!-- A text layer inside the stack -->
<span class="fa-layers fa-fw fa-2x">
  <i class="fa-solid fa-certificate"></i>
  <span class="fa-layers-text fa-inverse" data-fa-transform="shrink-8">NEW</span>
</span>

<!-- Masking: the icon takes the shape of the mask -->
<i class="fa-solid fa-pencil" data-fa-mask="fa-solid fa-circle" aria-hidden="true"></i>
<i class="fa-solid fa-user" data-fa-mask="fa-regular fa-heart" aria-hidden="true"></i>
/* The CSS equivalent for a badge, without the Font Awesome layering classes.
   Cheaper and easier to control with normal layout. */
.icon-with-badge {
  position: relative;
  display: inline-flex;
}

.icon-with-badge__count {
  position: absolute;
  top: -0.4em;
  right: -0.6em;
  min-width: 1.2em;
  padding: 0 0.3em;
  border-radius: 999px;
  background: #ef4444;
  color: white;
  font-size: 0.6em;
  font-weight: 600;
  line-height: 1.2em;
  text-align: center;
  /* logical offset so the badge flips in RTL */
  inset-inline-end: -0.6em;
  inset-inline-start: auto;
}
Goalfa-layersCSS equivalent
An icon on a circleYesA wrapper with position: relative
A count badgeYes, with fa-layers-counterAbsolute positioning plus a pseudo-element
Text inside an iconYes, with fa-layers-textAbsolute positioning
A custom mask shapeYes, with data-fa-maskA CSS mask-image
Accessible compositionNeeds care: layers are decorativeThe wrapper carries the label
Dynamic layout inside the stackConstrainedFull CSS
  • fa-layers sets a fixed square box and positions the children absolutely. That is why it needs fa-fw for consistent widths and why an icon that is wider than tall appears smaller than expected.
  • A layered composition is decorative by definition: put aria-hidden="true" on the wrapper and provide the accessible name on the surrounding control.
  • A CSS mask-image with an SVG data URI or a file reference achieves the same masking effect without loading Pro styles, and it works on plain elements rather than only icons.

Icon lists and logical properties

<!-- The fa-ul / fa-li pattern: a list whose markers are icons -->
<ul class="fa-ul">
  <li><span class="fa-li"><i class="fa-solid fa-check" aria-hidden="true"></i></span>Included in every plan</li>
  <li><span class="fa-li"><i class="fa-solid fa-check" aria-hidden="true"></i></span>Unlimited projects</li>
  <li><span class="fa-li"><i class="fa-solid fa-xmark" aria-hidden="true"></i></span>No on-premise hosting</li>
</ul>

<!-- fa-fw gives icons equal width, which is what keeps a vertical column
     of labels aligned. -->
<ul class="settings">
  <li><i class="fa-solid fa-user fa-fw" aria-hidden="true"></i> Profile</li>
  <li><i class="fa-solid fa-bell fa-fw" aria-hidden="true"></i> Notifications</li>
  <li><i class="fa-solid fa-lock fa-fw" aria-hidden="true"></i> Security</li>
</ul>
/* In v7, fixed width is on by default, so the class is mostly redundant.
   The spacing uses logical properties, which means it flips in RTL. */
.fa-ul {
  list-style-type: none;
  margin-inline-start: var(--fa-li-margin, 2.5em);
  padding-inline-start: 0;
}

.fa-li {
  position: absolute;
  inset-inline-start: calc(var(--fa-li-width, 2em) * -1);
  width: var(--fa-li-width, 2em);
  text-align: center;
}

/* Writing your own list markup with logical properties: identical behaviour
   in both directions. */
.settings { list-style: none; padding: 0; }

.settings li {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding-block: 0.375rem;
}

/* margin-inline-end, not margin-right: the gap lands on the correct side
   when the document direction flips. */
.settings .icon { margin-inline-end: 0.5rem; }
Old direction-aware ideaLogical propertyBehaviour in RTL
margin-leftmargin-inline-startSwaps to the right
margin-rightmargin-inline-endSwaps to the left
padding-leftpadding-inline-startSwaps
left: 0inset-inline-start: 0Swaps
text-align: lefttext-align: startSwaps
fa-flip-horizontal on an arrowNothing automaticA directional icon must be flipped deliberately

Directional icons are the exception to everything automatic. A back arrow, a progress chevron or a "send" glyph points in the reading direction, and no logical property fixes that. In an RTL locale, flip those specific icons — either with a direction-scoped rule or by mirroring the SVG path — and leave the non-directional ones alone.

FAQ

What is the difference between fa-rotate-90 and rotate-90?
The utility class fa-rotate-90 sets a fixed 90-degree rotation and is the simple case. rotate-90 inside data-fa-transform is the power transform, which can be combined with shrinking and moving in the same attribute — and can take fractional or negative values.
Why is my layered icon the wrong size?
A layer's size comes from the parent, not from the child. Put the sizing class on the fa-layers element and use fa-layers-1x-style classes on the children to position them relative to it. Adding a size to an individual child has no effect.

Custom icons, duotone and the styling toolkit Using, sizing and animating icons

Last refreshed 2026-09-18.