Question
In CSS, inline-block elements often show a small horizontal gap between them. For example, the following code produces a gap of about 4 pixels between the two span elements:
<p>
<span>Foo</span>
<span>Bar</span>
</p>
span {
display: inline-block;
width: 100px;
background-color: palevioletred;
}
I understand that one way to remove the gap is to delete the whitespace between the elements in the HTML, like this:
<p>
<span>Foo</span><span>Bar</span>
</p>
However, I want a CSS-only solution that does not require:
- changing the HTML structure
- using JavaScript
How can the space between inline or inline-block elements be removed using CSS?
Short Answer
By the end of this page, you will understand why gaps appear between inline and inline-block elements, how browsers treat HTML whitespace, and which CSS techniques can remove or avoid that spacing. You will also learn the trade-offs of each approach and when a layout method like Flexbox is a better choice.
Concept
inline-block elements participate in inline layout. That means the browser places them similarly to words in a sentence. In HTML, spaces, tabs, and line breaks between inline-level elements are treated as text whitespace. That whitespace is rendered just like the space between words.
So in code like this:
<span>Foo</span>
<span>Bar</span>
there is a newline and indentation between the tags. The browser collapses that into a single visible space. Because the elements are inline-block, that space appears as a small gap between them.
This matters because developers often use inline-block for:
- horizontal navigation items
- button groups
- image grids
- small card layouts
If you do not understand that the gap comes from HTML whitespace in inline formatting, the layout can feel inconsistent or broken.
A CSS-only solution usually works by changing how the whitespace is measured or by using a different layout system entirely.
Common approaches include:
- setting the parent
font-sizeto0 - using a small negative margin
- switching to Flexbox or Grid when appropriate
The key idea is this:
- The gap is not a margin added by the browser to
inline-block. - The gap is rendered whitespace from the HTML source.
- CSS can suppress or offset that effect, but some methods are more reliable than others.
Mental Model
Think of inline-block elements as words in a sentence.
If you write:
Foo Bar
there is a visible space between Foo and Bar because you typed one. The same thing happens with inline-block elements. The browser sees whitespace between the tags and lays it out like a word space.
So this:
<span>Foo</span>
<span>Bar</span>
acts a bit like:
[Foo] [Bar]
To remove the gap, you can:
- remove the space from the source
- make the space take up no width with CSS
- use a layout model that does not treat items like words, such as Flexbox
A useful mental shortcut:
inline-block= box that still behaves like text in a lineblock= box on its own lineflex= box arranged by layout rules, not text spacing
Syntax and Examples
Basic example that creates the gap
<p class="wrapper">
<span>Foo</span>
<span>Bar</span>
</p>
.wrapper span {
display: inline-block;
width: 100px;
background: palevioletred;
}
The space between the two span tags is rendered as visible whitespace.
CSS solution 1: font-size: 0 on the parent
<p class="wrapper">
<span>Foo</span>
<span>Bar</span>
</p>
.wrapper {
font-size: 0;
}
.wrapper span {
display: inline-block;
width: 100px;
background: palevioletred;
font-size: 16px;
}
Why it works
The whitespace between the inline-block elements is text spacing. Setting the parent's font-size to 0 makes that whitespace take up no width.
Important note
You usually need to restore a normal font-size on the child elements, otherwise their text will also be invisible or tiny.
CSS solution 2: negative margin
.wrapper span {
display: inline-block;
width: 100px;
background: palevioletred;
margin-right: -4px;
}
This can visually pull elements together, but it is less reliable because the actual width of the whitespace depends on the font and browser rendering.
Better modern solution: Flexbox
<p class="wrapper">
<span>Foo</span>
<span>Bar</span>
</p>
.wrapper {
display: flex;
}
.wrapper span {
width: 100px;
background: palevioletred;
}
Flexbox does not treat child spacing as text whitespace, so there is no unwanted gap from the HTML source.
If you specifically need inline-block, use font-size: 0. If you are building layout, prefer Flexbox.
Step by Step Execution
Example
<p class="wrapper">
<span>A</span>
<span>B</span>
</p>
.wrapper {
font-size: 0;
}
.wrapper span {
display: inline-block;
width: 60px;
font-size: 16px;
background: orange;
}
What happens step by step
- The browser reads the HTML and finds two
spanelements inside ap. - There is whitespace between
</span>and<span>in the source code. - Because
spanelements are participating in inline layout, that whitespace is treated like a normal text space. - The parent
.wrapperhasfont-size: 0, so any text whitespace inside it has zero width. - Each
spanisinline-block, so it still sits next to the others horizontally. - Each child
spanrestores its own text size withfont-size: 16px. - Result: the boxes appear side by side with no visible gap.
Without font-size: 0
If you remove this line:
font-size: 0;
the whitespace between the elements will once again take up horizontal space, producing the visible gap.
Real World Use Cases
Where this comes up in practice
Navigation menus
Horizontal menu items built with inline-block can show tiny unwanted gaps.
Button groups
Adjacent buttons may look uneven if whitespace creates extra spacing.
Thumbnail galleries
Small gaps between image tiles can break exact alignment.
Tag or badge lists
Pills or labels laid out in a row may appear misaligned if the whitespace is not intentional.
Legacy codebases
Older projects often use inline-block instead of Flexbox. Knowing how to handle whitespace helps when maintaining those systems.
Example: button group
<div class="buttons">
<button>Save</button>
<button>Cancel</button>
</div>
.buttons {
font-size: 0;
}
.buttons button {
display: inline-block;
font-size: 14px;
}
This removes the accidental gap while keeping the buttons on one line.
Real Codebase Usage
In real projects, developers usually choose one of these patterns:
1. Use Flexbox for layout
This is the most common modern choice.
.toolbar {
display: flex;
align-items: center;
}
Why developers prefer it:
- no whitespace gap issue
- easier alignment
- built-in spacing with
gap - better control for responsive layouts
2. Use font-size: 0 for legacy inline-block layouts
This is common when updating older code without changing markup.
.list {
font-size: 0;
}
.list-item {
display: inline-block;
font-size: 14px;
}
This is useful when:
- markup cannot be changed
- layout must stay
inline-block - you need a quick CSS-only fix
3. Add intentional spacing explicitly
Instead of relying on HTML whitespace, developers often control spacing directly.
.nav {
display: flex;
gap: 8px;
}
This makes spacing predictable.
Related codebase patterns
Guard against accidental text effects
If you use font-size: 0 on a parent, always restore text styles on children.
Prefer explicit layout systems
For components, Flexbox or Grid is usually easier to maintain than inline-block hacks.
Use utility classes carefully
Some codebases create utility classes like:
.no-inline-gap {
font-size: 0;
}
This can be useful, but it should be documented so other developers know why child text sizes must be reset.
Common Mistakes
1. Thinking the gap is a margin
Beginners often assume the browser added margin to span elements.
span {
display: inline-block;
margin: 0;
}
This does not remove the gap, because the gap is whitespace, not margin.
2. Setting font-size: 0 and forgetting to restore child text size
Broken example:
.wrapper {
font-size: 0;
}
.wrapper span {
display: inline-block;
}
Now the text inside the spans may appear at zero size.
Fix:
.wrapper span {
display: inline-block;
font-size: 16px;
}
3. Using a hardcoded negative margin everywhere
span {
margin-right: -4px;
}
This may work in one browser or font size and fail in another. It is a workaround, not a robust solution.
4. Using inline-block for full layout when Flexbox is better
If the goal is horizontal alignment, spacing, wrapping, or centering, display: flex is usually simpler and clearer.
5. Removing all whitespace assumptions without testing
Whitespace rendering can vary depending on:
- font
- font size
- browser
- zoom level
So if you use tricks like negative margin, test carefully.
6. Forgetting that inline and inline-block both participate in inline formatting
This issue is not unique to inline-block. Inline-level elements are affected by source whitespace too.
Comparisons
| Approach | Removes gap? | CSS-only? | Reliable? | Best use case |
|---|---|---|---|---|
| Remove whitespace in HTML | Yes | No | Yes | When editing markup is allowed |
font-size: 0 on parent | Yes | Yes | Mostly yes | Legacy inline-block layouts |
| Negative margin | Sometimes | Yes | No | Quick workaround only |
| Float elements | Yes | Yes | Older technique | Legacy layouts, not recommended for new UI |
| Flexbox | Yes | Yes | Yes | Modern horizontal layout |
| Grid | Yes | Yes | Yes | Two-dimensional layout |
inline-block vs Flexbox
| Feature | inline-block | Flexbox |
|---|---|---|
| Affected by HTML whitespace | Yes | No |
| Easy horizontal alignment | Moderate | Easy |
| Built-in spacing control | No | Yes, with gap |
| Vertical alignment control | Limited | Strong |
| Best for modern layout | No | Yes |
font-size: 0 vs negative margin
| Technique | Advantage | Drawback |
|---|---|---|
font-size: 0 | Predictable and common | Must restore child font size |
| Negative margin | Short and simple-looking | Fragile and font-dependent |
Cheat Sheet
Quick fix for inline-block gap
.parent {
font-size: 0;
}
.parent > * {
display: inline-block;
font-size: 16px;
}
Why the gap happens
- Whitespace between inline-level elements is rendered like text space.
inline-blockstill participates in inline layout.- The gap is not a margin.
Common solutions
1. Parent font-size: 0
.parent { font-size: 0; }
.child { font-size: 16px; }
2. Negative margin
.child { margin-right: -4px; }
Use with caution.
3. Flexbox
.parent { display: flex; }
Best modern option for layout.
Rules to remember
- If you must keep
inline-block, usefont-size: 0. - If you are creating layout, prefer Flexbox.
- Restore child text styles after
font-size: 0. - Do not assume the gap is always exactly
4px.
Safe pattern
.container {
font-size: 0;
}
.container .item {
display: inline-block;
font-size: 14px;
vertical-align: top;
}
FAQ
Why is there space between inline-block elements?
Because whitespace in the HTML source is rendered in inline layout, similar to the space between words.
Is the gap always exactly 4px?
No. It is often around 4px in common setups, but the actual width depends on the font, font size, and rendering.
What is the best CSS-only fix for inline-block gaps?
If you must keep inline-block, use font-size: 0 on the parent and restore the font size on the children.
Why does margin: 0 not remove the gap?
Because the gap is not margin. It is rendered whitespace from the HTML.
Should I use Flexbox instead of inline-block?
Usually yes, if you are building a layout. Flexbox is more predictable and easier to control.
Does this affect inline elements too?
Yes. Inline elements also render source whitespace between them.
Can I solve this without changing the HTML?
Yes. font-size: 0 is the most common CSS-only solution. Flexbox is often a better redesign if possible.
Mini Project
Description
Build a small horizontal badge list that shows how to remove unwanted gaps between inline-block elements using CSS only. This mirrors a real UI pattern used for tags, labels, or status chips in dashboards and admin panels.
Goal
Create a row of badges displayed side by side with no accidental spacing between them, while keeping the HTML readable.
Requirements
- Create a container with at least three badge elements.
- Use
inline-blockfor the badges. - Remove the unwanted gap using only CSS.
- Keep the badge text readable by restoring text styling correctly.
- Add visible styling so the spacing behavior is easy to see.
Keep learning
Related questions
Angular ngClass Conditional Class Binding Explained
Learn how to use Angular ngClass for conditional classes, fix common binding mistakes, and understand why this template error happens.
CSS :not() Selector for Elements Without a Class or Attribute
Learn how to use the CSS :not() selector to target elements that do not have a specific class or attribute, with examples and common pitfalls.
CSS Font Scaling Relative to Container Size: %, em, rem, vw, and Responsive Text
Learn how CSS font scaling really works and how to make text responsive using %, em, rem, vw, clamp(), and media queries.