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>| Transform | Effect | Units |
|---|---|---|
grow-N | Scale up by 6N% | N is a number, fractions allowed |
shrink-N | Scale down by 6N% | Same |
left-N / right-N | Translate horizontally | N/16 em |
up-N / down-N | Translate vertically | N/16 em |
rotate-N | Rotate by N degrees | Degrees, can be fractional or negative |
flip-h / flip-v / flip-both | Mirror on an axis | In data-fa-transform |
fa-rotate-by | A CSS custom-property rotation | Set --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;
}| Goal | fa-layers | CSS equivalent |
|---|---|---|
| An icon on a circle | Yes | A wrapper with position: relative |
| A count badge | Yes, with fa-layers-counter | Absolute positioning plus a pseudo-element |
| Text inside an icon | Yes, with fa-layers-text | Absolute positioning |
| A custom mask shape | Yes, with data-fa-mask | A CSS mask-image |
| Accessible composition | Needs care: layers are decorative | The wrapper carries the label |
| Dynamic layout inside the stack | Constrained | Full CSS |
fa-layerssets a fixed square box and positions the children absolutely. That is why it needsfa-fwfor 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-imagewith 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 idea | Logical property | Behaviour in RTL |
|---|---|---|
margin-left | margin-inline-start | Swaps to the right |
margin-right | margin-inline-end | Swaps to the left |
padding-left | padding-inline-start | Swaps |
left: 0 | inset-inline-start: 0 | Swaps |
text-align: left | text-align: start | Swaps |
fa-flip-horizontal on an arrow | Nothing automatic | A 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.Related
Custom icons, duotone and the styling toolkit Using, sizing and animating icons
Last refreshed 2026-09-18.