Keep Icons Aligned When Text Wraps

Build icon and label rows that stay aligned as text wraps and sizes change.

Introduction

30 Second Summary

Feature lists and settings menus often pair a small icon with a short label. The layout can look polished until a longer label wraps onto a second line.

In this project, you will build a single HTML file that keeps five icons aligned with the first line of their labels. You will use CSS to make the alignment survive wrapped text, larger type, narrower screens, and image-based icons.

What You'll Build

Your finished page keeps every icon pinned beside the first line through wrapped labels, larger text, and a phone-width browser window.

By the end of this project, you'll have:

  • A five-row feature list that you can resize from a wide window to phone width without losing first-line icon alignment.
  • A clear before-and-after demo showing why centred Flexbox alignment drifts when a label wraps.
  • A resilient image-based icon row that stays square, sharp, and correctly sized inside a narrow layout.
  • Secret Mission: Turn the finished rows into a compact settings menu with labels of different lengths.

Are there any prerequisites?

You only need a text editor and a web browser. This project runs locally with no account, framework, build step, or ongoing cost.

Before We Start

A browser-based page gives you an immediate place to test icon alignment. Keeping the workspace local makes every change easy to see.

A code editor saves the page. A modern web browser renders its HTML.

This project needs no account. It also needs no framework or build tool.

In this step, get ready to:
  • Confirm that a code editor is available.
  • Confirm that a modern web browser opens.
  • Prepare an empty folder for the project.
Confirm your local tools

Your editor is where you write the page. Your browser is where you see how each row behaves.

✔️ I have a code editor

  • Press Cmd+Space on macOS or the Windows key on Windows to open your search bar.
  • Type the name of your code editor into the search bar.
  • Press Enter to open the editor.

You should see a blank editor window ready to open a folder.

ⓧ I need a code editor

A plain-text editor is enough for this project. Choose one that can open a folder.

  • Use this guide to choose an editor for your device.
  • Download your chosen editor from its publisher's official website.

You should see the editor installer in your Downloads folder.

  • Complete the installer with its default options.
  • Press Cmd+Space on macOS or the Windows key on Windows to open your search bar.
  • Type the name of your installed editor into the search bar.
  • Press Enter to open the editor.

You should see a blank editor window ready to open a folder.

  • Return to your operating system's search bar.
  • Type the name of your preferred browser into the search bar.
  • Press Enter to open the browser.

You should now have a browser window ready to open local pages.

Create the project folder

The folder keeps the whole experiment together. It starts empty so the first file you add can be index.html.

macOS

  • Click an empty area of your Desktop.
  • Click File in the menu bar.
  • Click New Folder.
  • Type keep-icons-lined-up as the folder name.
  • Press Return to create the folder.

You should see the empty keep-icons-lined-up folder on your Desktop.

  • Return to the code editor from earlier.
  • Drag the keep-icons-lined-up folder from your Desktop onto the editor window.

You should see keep-icons-lined-up listed in the editor sidebar.

Windows

  • Press the Windows key to open your search bar.
  • Type File Explorer into the search bar.
  • Press Enter to open File Explorer.
  • Select Desktop in the left navigation pane.
  • Select New in the toolbar.
  • Select Folder.
  • Type keep-icons-lined-up as the folder name.
  • Press Enter to create the folder.

You should see the empty keep-icons-lined-up folder on your Desktop.

  • Return to the code editor from earlier.
  • Drag the keep-icons-lined-up folder from File Explorer onto the editor window.

You should see keep-icons-lined-up listed in the editor sidebar.

Verify the empty workspace
  • Predict whether the editor sidebar should contain a file at this point.
  • Inspect the folder shown in your editor sidebar.
  • Switch back to the browser from earlier.

You should see keep-icons-lined-up open in the editor with no files beneath it. Your browser should be open for the page you create next.

That is the groundwork done. Your editor now has a clean place for the project.

Folder not opening in the editor?

  • Bring the editor window to the front.
  • Drag keep-icons-lined-up onto the editor window again.
  • Use your editor's folder-opening option if dragging has no effect.

Help me open my project folder in my code editor.

Your local workspace is ready for index.html. Next, you'll build the five rows that expose the alignment problem.

Build the Centered Icon List

Icon-and-label rows can look perfectly balanced while every label fits on one line. That clean case gives you a baseline for spotting alignment problems later.

This step gives you a plain HTML page with five short feature rows. Each icon starts vertically centered beside its label.

In this step, get ready to:
  • Build a single index.html page with five icon-and-label rows.
  • Apply Flexbox with align-items: center to every row.
  • Display all five rows in your browser.
Set the one-line baseline

Each row needs one container for its icon plus its label. The same class lets one alignment rule control all five rows.

  • Create index.html inside the open project folder with the code below using your editor's new-file control:
<!doctype html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Centered Icon List</title>
  <style>
    /* Turn every feature row into a flex container. */
    .feature-row {
      display: flex;
      align-items: center;
    }
  </style>
</head>
<body>
  <!-- Keep each icon and label together in one row. -->
  <div class="feature-list">
    <div class="feature-row"><span class="icon">[+]&nbsp;&nbsp;</span><span>Quick setup</span></div>
    <div class="feature-row"><span class="icon">[*]&nbsp;&nbsp;</span><span>Clear navigation</span></div>
    <div class="feature-row"><span class="icon">[#]&nbsp;&nbsp;</span><span>Secure access</span></div>
    <div class="feature-row"><span class="icon">[?]&nbsp;&nbsp;</span><span>Helpful alerts</span></div>
    <div class="feature-row"><span class="icon">[@]&nbsp;&nbsp;</span><span>Flexible layouts</span></div>
  </div>
</body>
</html>

What Does This Code Do?

  • The feature-list container keeps all five rows together.
  • Each feature-row becomes a flex container through display: flex.
  • The align-items: center declaration centers the icon and label on the row's cross axis.
  • The short labels keep every row on one line for this baseline.
  • Save index.html.
  • Locate index.html in your project folder using your operating system's file browser.
  • Double-click index.html to display it in your browser.

You should see five short feature rows. Each row has a symbol positioned beside a one-line label.

Page Blank or Unstyled?

  • Confirm that the file is named index.html.
  • Check that every row uses the exact feature-row class name.
  • Compare the opening and closing HTML tags to catch a missing bracket.

Still stuck with the page layout?

✔️ Awesome, I've got everything!

Your baseline file contains five feature rows plus the centered alignment rule.

ⓧ I'd like to double check the full code

<!doctype html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Centered Icon List</title>
  <style>
    /* Turn every feature row into a flex container. */
    .feature-row {
      display: flex;
      align-items: center;
    }
  </style>
</head>
<body>
  <!-- Keep each icon and label together in one row. -->
  <div class="feature-list">
    <div class="feature-row"><span class="icon">[+]&nbsp;&nbsp;</span><span>Quick setup</span></div>
    <div class="feature-row"><span class="icon">[*]&nbsp;&nbsp;</span><span>Clear navigation</span></div>
    <div class="feature-row"><span class="icon">[#]&nbsp;&nbsp;</span><span>Secure access</span></div>
    <div class="feature-row"><span class="icon">[?]&nbsp;&nbsp;</span><span>Helpful alerts</span></div>
    <div class="feature-row"><span class="icon">[@]&nbsp;&nbsp;</span><span>Flexible layouts</span></div>
  </div>
</body>
</html>
Confirm the centered alignment

This clean one-line layout is your control case. Every icon should appear vertically balanced beside its label.

Before you refresh the page, consider whether the five rows will keep the same centered alignment.

  • Return to the browser tab showing index.html.
  • Refresh the page.
  • Inspect the vertical space above and below each icon.

You'll see five one-line labels. Each icon sits at the vertical middle of its row because align-items: center is active.

Your five-row baseline is working. Next, you'll make a label wrap so you can see where centered alignment starts to drift.

Expose the Wrapping Problem

Your five feature rows already look balanced at full width. Each icon sits neatly beside a one-line label.

Real feature labels often wrap when space gets tight. You will recreate that pressure to see whether centered Flexbox alignment keeps the icon beside the first line.

In this step, get ready to:
  • Lengthen one feature label until it can wrap onto two lines.
  • Narrow the browser window to expose the icon alignment problem.
  • Capture the wrapped row as evidence of the problem.
Make one label wrap

A longer label gives the layout a realistic condition to handle. You only need to change the text inside one existing row.

  • Choose the label text inside one feature row in the index.html file from earlier.
  • Replace only that label with Priority support from our team whenever you need help setting up a new workspace.
  • Save index.html.
  • Switch back to the browser tab from earlier.
  • Refresh the page from the browser toolbar.
  • Widen the browser window until the longer label fits on one line.

Good. The longer label is now in place while the wide layout still looks balanced.

Label did not change?

Confirm that you replaced text inside a feature row without changing the surrounding elements. Save index.html before refreshing the browser again.

Help me troubleshoot why my updated feature label is not appearing in the browser.

Narrow the browser window

A narrower window gives the label less horizontal space. Once the sentence wraps, its text box becomes taller.

Before you resize, where do you expect the icon to sit when the label becomes two lines?

  • Drag one side edge of the browser window inward slowly.
  • Stop as soon as the longer label wraps onto two lines.

You will see the icon slide down beside the midpoint of the two-line text block. It no longer lines up with the first line.

Why did the icon drift?

Flexbox calculates alignment from each item's full box. The wrapped label creates a taller box.

Center alignment places the icon at the midpoint of that taller box. The icon therefore drops below the first line.

Label still stays on one line?

Narrow the browser window farther. The available width must become small enough for the longer sentence to wrap.

If the text still stays on one line, confirm that the longer sentence is saved in index.html. Refresh the page again.

Help me work out why my long feature label is not wrapping in the browser.

You have exposed the weakness in centered alignment. Next, you will test a first attempt at pinning the icon to the first line.

Test a Fixed Icon Nudge

Your narrow browser test exposed the weakness in your Flexbox rows. The wrapped label pulls its icon toward the middle of the two-line text block.

A quick CSS patch starts each row at the top. You will test a fixed three-pixel nudge at two text sizes to see how durable that patch really is.

In this step, get ready to:
  • Top-align the five feature rows with align-items: start.
  • Nudge each icon into place with translateY(3px).
  • Increase the page font size to test the fixed offset.
Top-align the rows

The start value anchors each flex item to the beginning of the row's cross axis. This gives every icon the top of its label as a consistent reference point.

  • Switch back to index.html in the code editor from earlier.
  • Find align-items: center in the rule shared by the five feature rows.
  • Replace align-items: center with align-items: start.
  • Save index.html.
  • Return to the browser from earlier.
  • Refresh the page at the same narrow width.

You should see every icon move from the vertical center to the top of its row. The wrapped label remains two lines tall.

Why Does the Icon Move?

The align-items: start declaration places each flex item at the top of the row. The wrapped text keeps its full height without pulling the icon downward.

Icons Still Centered?

Confirm that you edited the shared row rule in index.html. A later rule may still apply align-items: center.

Help me find why my flex icons remain vertically centered.

Nudge the icons into place

Top alignment gives each icon a stable anchor. The visible icon may still sit slightly above the first line of text.

A small transform adjusts that optical position at the current font size.

  • Switch back to index.html in the code editor.
  • Find the existing CSS rule that styles the icon elements.
  • Add the transform property with the value translateY(3px).
  • Save index.html.
  • Return to the browser.
  • Refresh the page while the long label remains wrapped.
  • Compare each icon with the first line of its label.

You should see the icons sit alongside the first line at the current font size. The wrapped row now looks aligned with the one-line rows.

What Does the Fixed Nudge Do?

The transform property moves the icon's painted box without changing the flex layout.

The translateY(3px) value shifts every icon down by a fixed three-pixel distance. That distance is tuned to the current text size.

Nudge Not Showing?

Confirm that the transform property sits inside the rule for the icon elements. Check that its value is exactly translateY(3px).

Help me debug why translateY is not moving my icons.

Increase the page font size

The alignment now looks convincing at one font size. A durable layout must also survive larger text because its line height grows.

Before you change the size, predict whether the three-pixel nudge can stay aligned when the text grows.

  • Switch back to index.html in the code editor.
  • Find the page-level declaration that controls the text size.
  • Replace its current numeric value with twice that number using the same unit.
  • Save index.html.
  • Return to the browser.
  • Keep the browser narrow enough for the long label to wrap.
  • Refresh the page.

Your text is now larger. Its line height grows with it.

The fixed translateY(3px) offset stays three pixels. You will see the icons miss their earlier first-line position.

You have just proved why the quick patch is fragile. The intended shortfall is now visible in your browser.

Text Size Did Not Change?

Confirm that you changed the page-level text size declaration in index.html. Make sure the new number is larger than the original value.

Help me find why my larger font size is not appearing.

At this checkpoint, index.html still contains five feature rows. The long label wraps at the narrow browser width.

The shared row rule uses align-items: start. The icon rule applies translateY(3px) through transform.

The page uses a larger font size. The fixed nudge no longer aligns the icons correctly.

Your fixed offset has reached its limit. Next, you will replace the guessed distance with an offset that follows the text's line height.

Align Icons with Line Height

Your five rows already hold each icon at the top of its label. The larger font size exposed the weakness in the fixed pixel nudge.

The offset needs to respond to the same line height that shapes the text. In this step, you will replace the guessed distance with a CSS calculation that scales with the label.

In this step, get ready to:
  • Replace the fixed pixel nudge with an offset based on line height.
  • Test the alignment at another font size.
  • Confirm that every icon stays beside the first line of its label.
Build the offset from line height

The lh unit equals the element's computed line height. Pairing it with calc() lets the browser derive a fresh offset whenever the text size changes.

  • Switch back to index.html in your code editor.
  • Locate the icon style rule that contains the fixed transform declaration.
  • Replace that declaration with the line below:
transform: translateY(calc((1lh - 1em) / 2));

How Does the Calculation Work?

  • The 1lh value supplies the height of one text line.
  • The 1em value represents the font-relative height of the icon.
  • The calc() expression subtracts the icon height from the line height.
  • Dividing the difference by 2 places the icon in the vertical centre of the first line.
  • Save index.html.
  • Refresh the page in your browser.

At the current larger text size, each icon should sit beside the first line. The wrapping label should keep its icon near the top.

Icons Still Look Misaligned?

Confirm that the old pixel-based transform declaration has been fully replaced. Check that every parenthesis in calc() has a matching closing parenthesis.

If the browser ignores the declaration, inspect the spacing around the subtraction operator. CSS calculations require spaces around -.

Still stuck? Help me debug my line-height-based icon offset.

Stress-test the calculation

The first refresh proves the calculation works at the current size. A second size change tests whether the offset continues to follow the typography.

  • Switch back to index.html.
  • Find the existing page font-size declaration.
  • Increase its current value by 8px.
  • Save index.html.

Before you refresh, do you expect the icon offset to stay visually tied to the first line at this larger size?

  • Refresh the page to test the new computed line height.
  • Narrow the browser window until the long label wraps across multiple lines.

You should see every icon remain aligned with the first line of its label. The long label can wrap without pulling its icon towards the middle.

Alignment Changes at the New Size?

Check that the active icon rule still contains 1lh. A later duplicate transform declaration can override the calculation.

Need help finding the override? Help me inspect which CSS transform rule controls my icons.

Great work. The icon offset now scales with the computed line height at different text sizes.

Your icon rows now survive changes in typography. Next, you will make the same layout resilient when an icon comes from a background image.

Protect the Background Icon

Your lh-based offset now keeps each icon beside the first line when the page font size changes. That adaptive alignment gives you a stable baseline for a more demanding icon type.

A background icon adds a new sizing layer because its image depends on the box created by a pseudo-element. You will expose that box under pressure before protecting its shape.

In this step, get ready to:
  • Move one existing icon from visible markup into a pseudo-element background.
  • Test the unprotected background icon at a narrow width.
  • Protect the icon box when space becomes constrained.
Move one icon into a pseudo-element

A pseudo-element lets CSS generate an icon without adding another HTML node. The icon still needs a real box for its background image.

  • Switch back to index.html in the code editor from earlier.
  • Choose the feature row with the long label.
  • Record the chosen icon's image reference here: your icon image reference.
  • Remove the visible icon markup from that row.
  • Save index.html.
  • Refresh the browser.

You'll see the long label without its icon. This proves the icon no longer comes from the HTML.

  • Create a ::before rule for the selected row using content: "", your icon image reference as its background-image, the existing icon width, and the existing lh-based calc() transform.
  • Save index.html.
  • Pause to predict whether the new background icon will keep the original square footprint.
  • Refresh the browser.
  • Narrow the browser window until the long label wraps.

You'll see the background icon look clipped or squashed as space tightens. That shortfall is intentional.

Protect the icon box

The failed test shows that alignment and image shape need separate rules. Three declarations protect the pseudo-element without changing your lh-based offset.

How the three protections work

  • The flex-shrink: 0 declaration stops Flexbox from compressing the icon box.
  • The aspect-ratio: 1 declaration keeps the box square as its width changes.
  • The background-size: contain declaration scales the whole image inside that square box.
  • Return to the pseudo-element rule in index.html.
  • Add flex-shrink: 0, aspect-ratio: 1, and background-size: contain to the rule.
  • Save index.html.
  • Pause to predict whether the protected icon will still compress at the width that exposed the problem.
  • Refresh the browser.
  • Narrow the browser window to the same width used in the failed test.
  • Compare the icon box with the first line of the wrapped label.

You'll see the entire background image inside a sharp square box. Its top edge remains beside the wrapped label's first line.

Icon still clipped or stretched?

Check that all three protective declarations sit inside the same ::before rule. Confirm that the saved image reference is still assigned to background-image.

Check that the pseudo-element still uses the same icon width and lh-based calc() transform as the other icons.

Help me debug the background icon.

✔️ Awesome, I've got everything!

The protected pseudo-element now preserves the image that lost its shape during the narrow-width test.

ⓧ I'd like to double check the full code

Your index.html should contain five icon-and-label feature rows. One long label should wrap at a narrow width.

Each row should use align-items: start with an lh-based calc() icon offset. One row should render its background icon through ::before using flex-shrink: 0, aspect-ratio: 1, and background-size: contain.

Your pseudo-element icon is protected. Next, you'll resize the full five-row list and confirm every icon holds its position.

Verify the Responsive List

Your pseudo-element icon now keeps its square shape at narrow widths. The full list has every CSS alignment safeguard in place.

A responsive list can still hide problems when it is tested at only one width. This final check proves that every icon stays with the first line as the browser moves from a wide window to phone width.

In this step, get ready to:
  • Check all five rows in a wide browser window.
  • Narrow the browser until the longer labels wrap.
  • Confirm every icon holds its first-line alignment at phone width.
Check the wide layout

The wide layout gives you a clean baseline before wrapping puts the alignment under pressure. All five rows should use the same first-line reference point.

  • Switch back to the browser from earlier.
  • Resize the browser window to a wide desktop width.

You should see all five feature rows. Each icon should sit beside the first line of its label.

What Counts as Aligned?

Focus on where each icon sits beside the first line of text. A wrapped label can continue below without pulling its icon toward the middle of the full text block.

The pseudo-element icon should match the other icon boxes. Its background image should remain fully visible inside a square area.

Test the list at phone width

A narrower viewport forces the labels to use more lines. This is where the finished alignment rules prove that they respond to the text instead of relying on one fixed layout.

Before you resize, do you expect any icon to drift when another label wraps?

  • Drag one side of the browser window inward slowly.
  • Pause each time another label wraps.
  • Stop when the browser content area is about as wide as a phone screen.

You should see the longer labels wrap across multiple lines. Their icons should remain beside the first line.

  • Scan all five rows from top to bottom.
  • Compare every icon with the first line of its label.
  • Inspect the pseudo-element icon for a square shape.
  • Confirm the pseudo-element background image remains fully visible.

At phone width, you should still see all five rows with every icon holding its first-line alignment. The pseudo-element icon should remain square without clipping or squashing.

Does an Icon Drift or Distort?

  • Return to index.html in the code editor from earlier.
  • Confirm each row still uses align-items: start.
  • Confirm each icon offset still uses calc() with the lh unit.
  • Confirm the pseudo-element icon still uses flex-shrink: 0.
  • Confirm the pseudo-element icon still uses aspect-ratio: 1.
  • Confirm the pseudo-element icon still uses background-size: contain.

Help me diagnose the responsive alignment.

You have now proved that the list survives real responsive conditions. Every icon stays anchored to the first line from a wide window down to phone width.

Secret mission

Stress-Test the Alignment System

Stress-test the finished list by combining increased browser zoom with a phone-width window. Prove every icon holds the first line while the background icon stays square.

Clean Up Your Resources

Clean Up Your Resources

Your cleanup choice is to keep the completed index.html file, pause by closing your tools, or delete the file entirely. This project runs locally with no ongoing costs.

Resources you used:

  • The completed index.html file containing your five responsive icon rows.

Keep everything running

No action needed. Choose this if you want to reuse the alignment pattern in future interfaces.

  • Keep index.html in its current location.
  • Reuse the file as a reference for feature lists, settings pages, or navigation menus.

Pause - I'll come back to this later

There is no server or cloud resource to pause. Your completed file stays ready for your return after you close your tools.

  • Save index.html in the code editor from earlier.
  • Close the browser tab showing the icon list.
  • Close the code editor from earlier.

Delete - I don't want to use this again

Deleting your only project file can feel final. The completed reference page is removed from your computer once you permanently clear the deleted file.

  • Locate index.html in the file list of the code editor from earlier.
  • Use the code editor's file deletion control to remove index.html.
  • Confirm the file list no longer shows index.html.
  • Permanently clear the deleted file using your computer's file removal process.

Nice Work!

Nice Work!

You did it! Your five-row icon list now keeps every icon aligned with the first line from wide screens down to phone width.

What you learned:

  • Exposed a real wrapping bug by narrowing the browser until a long label wrapped. You saw how align-items: center pulls an icon toward the middle of a multi-line label.
  • Built a durable CSS alignment fix with align-items: start plus an lh-based calc() offset. The offset now follows the line height when the font size changes.
  • Hardened a pseudo-element background icon with flex-shrink: 0. You preserved its square shape with aspect-ratio: 1 plus background-size: contain.
  • Secret Mission: Completed the optional challenge to extend your responsive icon-list pattern further.

Ready to quiz yourself?