There’s a widespread design sample that typically will get missed or neglected. It’s having an inventory of things, every with an icon. When the textual content is one line, the icon is centered, however when the textual content has a number of strains, the icon remains to be centered however seems odd.
Right here is an instance:
All through this text, I’ll present two options that I take advantage of based mostly on the HTML:
- The icon is an HTML factor (e.g.,
<svg>or<img>) - The icon is added by way of a pseudo-element as a background picture
The icon within the markup
On this case, we now have a container with the icon and the content material. Often, we use flexbox. Like so:
<ul class="checklist">
<li class="list-item">
<svg class="icon"></svg>
<span class="label">How one can align an icon to a label.</span>
</li>
</ul>
.list-item {
show: flex;
align-items: middle;
hole: 0.5rem;
}
By default, it seems okay. Right here it’s:
- How one can align an icon to a label.
Nevertheless, when the checklist width is smaller and the textual content wraps, the icon will probably be centered. This isn’t the conduct we wish.
- How one can align an icon to a label.
How can we hold the icon aligned vertically when the textual content is wrapped? First, I went again to the fundamentals. As an alternative of utilizing align-items: middle, I used begin as a worth.
.list-item {
show: flex;
align-items: begin;
hole: 0.5rem;
}
However this induced a fair greater alignment problem. The highlighted space is the road peak. The textual content factor peak has an empty area above and beneath it that comes from the font itself. When align-items: begin is utilized, the icon will probably be aligned to the highest of the container.
- How one can align an icon to a label.
What if we pushed the icon right down to have it aligned with the highest line?
- How one can align an icon to a label.
.list-item {
show: flex;
align-items: begin;
hole: 0.5rem;
}
.icon {
remodel: translateY(3px);
}
That works. Let’s push the bounds of it and see if it persists! To try this, I constructed the demo in a means that modifications a number of of the next:
- Record merchandise font measurement
- Icon measurement
- Record container width
Strive it and see how the icon turns into misaligned.
- How one can align an icon to a label.
Utilizing a hard and fast worth for the remodel gained’t work when the icon measurement, font measurement, or container width modifications.
The answer: utilizing the lh unit
If we are able to get the line-height worth and we now have a recognized icon measurement, we are able to make the offset relative to them. I wrote about the road peak unit on the weblog if you wish to dig additional.
.icon {
--size: var(--icon-size);
--offset: calc((1lh - var(--size)) / 2);
remodel: translateY(var(--offset));
}
- How one can align an icon to a label.
On this answer, in case you change any of the three values, the alignment will simply work. In some instances, the offset is perhaps detrimental, similar to the next instance:
- How one can align an icon to a label.
Icon as a pseudo-element
Generally, we don’t want so as to add the icon as an HTML factor, so we use a pseudo-element for that.
Right here is the essential CSS:
.list-item {
show: flex;
hole: 0.5rem;
}
.list-item::earlier than {
content material: "";
--size: var(--icon-size);
width: var(--size);
peak: var(--size);
background-image: url("knowledge:picture/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' peak='24' viewBox='0 0 24 24' fill='none' stroke='%23222' stroke-width='2' stroke-linecap='spherical' stroke-linejoin='spherical'%3Epercent3Ccircle cx='12' cy='12' r='10'/%3Epercent3Cpath d='m9 12 2 2 4-4'/%3Epercent3C/svgpercent3E");
background-repeat: no-repeat;
}
At first look, it seems effective, proper? Attempt to enhance the font measurement a bit.
- How one can align an icon to a label.
Did you discover that the icon is lower off? It is because we have to restrict the background measurement.
.list-item {
show: flex;
hole: 0.5rem;
}
.list-item::earlier than {
content material: "";
--size: var(--icon-size);
width: var(--size);
peak: var(--size);
background-image: url("knowledge:picture/svg+xml,%3Csvg ....");
background-size: comprise;
background-repeat: no-repeat;
}
- How one can align an icon to a label.
Attempt to make the font measurement bigger. Did you discover that the icon width shrinks? It is because, by default, a flex merchandise will shrink. We have to override that.
.list-item {
show: flex;
hole: 0.5rem;
}
.list-item::earlier than {
content material: "";
--size: var(--icon-size);
flex-shrink: 0;
width: var(--size);
peak: var(--size);
background-image: url("knowledge:picture/svg+xml,%3Csvg ....");
background-size: comprise;
background-repeat: no-repeat;
}
- How one can align an icon to a label.
Once more… attempt to enhance the font measurement of the label. The icon measurement stays as is. The subsequent step is to deal with centering whereas elements like icon measurement, font measurement, and container width change.
The answer
Presently, the checklist merchandise is a flexbox container, and by default, the gadgets stretch (vertically). Why isn’t the icon stretching in our case? Properly, it’s because we set a hard and fast peak.
I set the peak property to auto.
.list-item {
show: flex;
hole: 0.5rem;
}
.list-item::earlier than {
content material: "";
--size: var(--icon-size);
flex-shrink: 0;
width: var(--size);
peak: auto;
background-image: url("knowledge:picture/svg+xml,%3Csvg ....");
background-size: comprise;
background-repeat: no-repeat;
}
- How one can align an icon to a label.
Now it’s a bit trickier. In case you enhance the font measurement, the icon width will keep square-like. In case you lower it, it would grow to be rectangle-like with additional spacing.
Have a look:
- How one can align an icon to a label.
To keep away from that, we have to drive the side ratio to a sq..
.list-item {
show: flex;
hole: 0.5rem;
}
.list-item::earlier than {
content material: "";
--size: var(--icon-size);
flex-shrink: 0;
aspect-ratio: 1;
width: var(--size);
peak: auto;
background-image: url("knowledge:picture/svg+xml,%3Csvg ....");
background-size: comprise;
background-repeat: no-repeat;
}
- How one can align an icon to a label.
With that, we are going to use the identical method as earlier than and offset the pseudo-element by just a few pixels.
.list-item {
show: flex;
hole: 0.5rem;
}
.list-item::earlier than {
content material: "";
--size: var(--icon-size);
--offset: calc((1lh - var(--size)) / 2);
flex-shrink: 0;
aspect-ratio: 1;
width: var(--size);
peak: auto;
background-image: url("knowledge:picture/svg+xml,%3Csvg ....");
background-size: comprise;
background-repeat: no-repeat;
remodel: translateY(var(--offset));
}
- How one can align an icon to a label.
The icon is now centered. It’s attention-grabbing to see what’s been used right here:
- flexbox
- aspect-ratio
- the lh unit
- calc()
- peak: auto
Outro
And that’s it. I solved an issue whereas engaged on a challenge and needed to share it. Hope you’ve discovered one thing new.
Thanks for studying.
The Format Maestro
Constructing layouts could be a difficult process, particularly in case you don’t know the core psychological mannequin of CSS layouts. You don’t have to fret about that anymore. I launched an interactive CSS format course, and I known as it The Format Maestro.
Take a look at The Format Maestro course and degree up your CSS format abilities.

