Wait, My Buttons Are Still Side-by-Side Without Flex? Understanding inline-block vs Flexbox
I removed flex from my button container, expecting them to stack vertically, but they're still sitting side-by-side! π€¨ I thought flex was what made them horizontal. My frontend mentor corrected my misunderstanding: buttons are inline-block by default, which means they naturally sit beside each other. This conversation taught me the crucial difference between "happens to be side-by-side" and "controlled side-by-side layout."
The Buttons That Stayed Side-by-Sideβ
Me (Backend Dev): I have these two buttons:
<div class="flex gap-2">
<button class="flex-1">Fill User</button>
<button class="flex-1">Fill Admin</button>
</div>
They're side-by-side as expected. But when I remove flex:
<div class="gap-2">
<button class="flex-1">Fill User</button>
<button class="flex-1">Fill Admin</button>
</div>
They're STILL side-by-side! I thought flex was what made them horizontal. Is it because of their default inline thing?
The Misconception Correctedβ
Frontend Mentor: Not quite! This is a very common misunderstanding. Let me explain what's really happening:
Default Button Behaviorβ
By default, <button> elements have:
button {
display: inline-block; /* β The key! */
}
What inline-block means:
- β Elements CAN sit side by side (like words in a sentence)
- β They wrap to new lines if there's not enough space
- β
You can set width and height (unlike pure
inline) - β NO control over spacing between them
- β NO control over alignment
- β Layout depends on available space
What You're Actually Seeingβ
Without flex (current state):
<div>
<button>Fill User</button>
<button>Fill Admin</button>
</div>
Result:
[Fill User] [Fill Admin] β Side by side because:
- They're inline-block by default
- There's enough room in the container
- They have default spacing (from HTML whitespace)
Why they're side-by-side:
- NOT because of flexbox (you removed it!)
- Because
inline-blockelements naturally flow horizontally - Just like words in a paragraph!
The Real Difference: Controlβ
Without flex (uncontrolled):
<div>
<button>Fill User</button>
<button>Fill Admin</button>
</div>
- β Unpredictable spacing (depends on HTML whitespace)
- β No gap control
- β Buttons wrap if container is narrow
- β No equal width distribution
- β Hard to align
With flex (controlled):
<div class="flex gap-2">
<button class="flex-1">Fill User</button>
<button class="flex-1">Fill Admin</button>
</div>
- β
Precise spacing (
gap-2= 8px) - β Controlled layout direction
- β
Equal width distribution (
flex-1) - β Easy alignment options
- β Predictable behavior
The Experiment: Seeing the Differenceβ
Me: Can you show me experiments to see this clearly?
Frontend Mentor: Absolutely! Let's do some tests:
Experiment 1: Remove flex, Keep gap-2β
<div class="gap-2">
<button class="flex-1">Fill User</button>
<button class="flex-1">Fill Admin</button>
</div>
What happens:
[Fill User] [Fill Admin] β Side by side, but:
- gap-2 does NOTHING (gap only works with flex/grid!)
- Spacing is from HTML whitespace
- flex-1 does NOTHING (only works in flex containers!)
Key insight: gap-2 and flex-1 are IGNORED without flex!
Experiment 2: Add w-full to Each Buttonβ
<div>
<button class="w-full">Fill User</button>
<button class="w-full">Fill Admin</button>
</div>
What happens:
[βββββββββ Fill User βββββββββ] β Full width
[βββββββββ Fill Admin ββββββββ] β Full width
β NOW they stack!
Why: Each button takes 100% width, forcing them to separate lines!
Experiment 3: Add Back flex, Keep w-fullβ
<div class="flex gap-2">
<button class="w-full">Fill User</button>
<button class="w-full">Fill Admin</button>
</div>
What happens:
[ββββ Fill User ββββ] [8px] [ββββ Fill Admin ββββ]
β gap-2 spacing
β Equal width (flex magic!)
Why: Flexbox overrides w-full and distributes available space!
Experiment 4: Use flex-1 (Original Design)β
<div class="flex gap-2">
<button class="flex-1">Fill User</button>
<button class="flex-1">Fill Admin</button>
</div>
What happens:
[ββββ Fill User ββββ] [8px] [ββββ Fill Admin ββββ]
β gap-2 spacing
β Each button gets equal flex space (flex-1)
This is the professional approach! β¨
Understanding inline-block Behaviorβ
Me: So inline-block is why they sit side-by-side naturally?
Frontend Mentor: Exactly! Let me show you how inline-block works:
Inline-Block Flowβ
Think of inline-block elements like words in a paragraph:
<div style="width: 300px; border: 1px solid;">
<button>Button 1</button>
<button>Button 2</button>
<button>Button 3</button>
<button>Button 4</button>
</div>
Result:
ββββββββββββββββββββββββββββββ
β [Button 1] [Button 2] β β Fit on one line
β [Button 3] [Button 4] β β Wrapped to next line
ββββββββββββββββββββββββββββββ
Just like text wrapping!
The Whitespace Problemβ
HTML whitespace creates spacing:
<!-- Spacing from line breaks and indentation -->
<div>
<button>Button 1</button>
<button>Button 2</button>
</div>
Browser sees:
<button>Button 1</button>[space]<button>Button 2</button>
β This creates a small gap!
Result:
[Button 1] [Button 2] β Small gap from HTML whitespace
β ~4px gap (browser-dependent)
Remove whitespace:
<div>
<button>Button 1</button><button>Button 2</button>
</div>
Result:
[Button 1][Button 2] β No gap! Buttons touching!
This is why we use flexboxβpredictable spacing!
Display Types Comparisonβ
Me: Can you compare all the display types?
Frontend Mentor: Great question! Here's a comprehensive comparison:
1. display: block (Default for <div>)β
<div>
<button style="display: block;">Button 1</button>
<button style="display: block;">Button 2</button>
</div>
Result:
[βββββββ Button 1 βββββββ] β Full width
[βββββββ Button 2 βββββββ] β Full width
β Stacked vertically
Characteristics:
- Takes full width (100%)
- Forces new line before and after
- Can set width and height
- Respects vertical margins
2. display: inline (Default for <span>, <a>)β
<div>
<button style="display: inline;">Button 1</button>
<button style="display: inline;">Button 2</button>
</div>
Result:
[Button 1] [Button 2] β Side by side
β Wraps like text
Characteristics:
- Flows like text
- β Cannot set width and height
- β Ignores vertical margins
- Wraps to new line if needed
3. display: inline-block (Default for <button>)β
<div>
<button>Button 1</button>
<button>Button 2</button>
</div>
Result:
[Button 1] [Button 2] β Side by side
β Can set width/height
Characteristics:
- Flows like inline (side by side)
- β Can set width and height (like block)
- β Respects all margins
- Best of both worlds!
4. display: flex (Modern Layout)β
<div style="display: flex; gap: 8px;">
<button>Button 1</button>
<button>Button 2</button>
</div>
Result:
[Button 1] [8px gap] [Button 2] β Controlled side-by-side
β Precise spacing
Characteristics:
- Full control over layout
- Precise gap control
- Easy alignment
- Equal width distribution
- Modern standard!
The Magic of flex-1β
Me: What exactly does flex-1 do?
Frontend Mentor: Great question! flex-1 is incredibly powerful:
Without flex-1β
<div class="flex gap-2">
<button>Fill User</button>
<button>Fill Admin</button>
</div>
Result:
[Fill User] [8px] [Fill Admin] [remaining space]
β Auto width (content size)
Buttons are only as wide as their content!
With flex-1β
<div class="flex gap-2">
<button class="flex-1">Fill User</button>
<button class="flex-1">Fill Admin</button>
</div>
Result:
[ββββββββ Fill User ββββββββ] [8px] [ββββββββ Fill Admin ββββββββ]
β Each button grows to fill available space equally
What flex-1 means:
flex-1 {
flex-grow: 1; /* Can grow to fill space */
flex-shrink: 1; /* Can shrink if needed */
flex-basis: 0%; /* Start from 0, then grow */
}
Effect: All items with flex-1 share available space equally!
Unequal Distributionβ
<div class="flex gap-2">
<button class="flex-1">Fill User</button>
<button class="flex-2">Fill Admin</button>
</div>
Result:
[ββ Fill User ββ] [8px] [βββββββββ Fill Admin βββββββββ]
β 1/3 width β 2/3 width (flex-2 = twice as much)
Real-World Button Group Patternsβ
Me: What are common patterns for button groups?
Frontend Mentor: Here are professional button group patterns:
Pattern 1: Equal Width Buttons (Your Case)β
<div class="flex gap-2">
<button class="flex-1 bg-blue-600 text-white py-2 rounded-md hover:bg-blue-700">
Fill User
</button>
<button class="flex-1 bg-green-600 text-white py-2 rounded-md hover:bg-green-700">
Fill Admin
</button>
</div>
Use for: Form actions, modal buttons, toggle groups
Pattern 2: Auto-Width Buttonsβ
<div class="flex gap-2">
<button class="px-4 py-2 bg-blue-600 text-white rounded-md hover:bg-blue-700">
Save
</button>
<button class="px-4 py-2 border border-gray-300 rounded-md hover:bg-gray-50">
Cancel
</button>
</div>
Use for: Action buttons, toolbar buttons
Pattern 3: One Primary, One Secondaryβ
<div class="flex gap-2">
<button class="flex-1 px-4 py-2 border border-gray-300 rounded-md hover:bg-gray-50">
Cancel
</button>
<button class="flex-1 px-4 py-2 bg-blue-600 text-white rounded-md hover:bg-blue-700">
Confirm
</button>
</div>
Use for: Confirmation dialogs, important decisions
Pattern 4: Icon Buttonsβ
<div class="flex gap-2">
<button class="p-2 border border-gray-300 rounded-md hover:bg-gray-50">
<svg class="w-5 h-5"><!-- Edit icon --></svg>
</button>
<button class="p-2 border border-gray-300 rounded-md hover:bg-gray-50">
<svg class="w-5 h-5"><!-- Delete icon --></svg>
</button>
<button class="p-2 border border-gray-300 rounded-md hover:bg-gray-50">
<svg class="w-5 h-5"><!-- Share icon --></svg>
</button>
</div>
Use for: Toolbars, action menus
Pattern 5: Responsive Button Groupβ
<div class="flex flex-col sm:flex-row gap-2">
<button class="flex-1 px-4 py-2 bg-blue-600 text-white rounded-md">
Save
</button>
<button class="flex-1 px-4 py-2 border border-gray-300 rounded-md">
Cancel
</button>
</div>
Result:
Mobile (stacked):
[βββββββββ Save βββββββββ]
[βββββββ Cancel βββββββββ]
Desktop (side-by-side):
[ββββ Save ββββ] [8px] [ββββ Cancel ββββ]
Use for: Mobile-friendly forms
Debugging: How to See What's Happeningβ
Me: How can I debug layout issues like this?
Frontend Mentor: Great question! Here's how to debug:
Method 1: Browser DevTools Computed Tabβ
- Right-click button β Inspect
- Go to "Computed" tab
- Look for
displayproperty
You'll see:
display: inline-block β Without flex
display: flex β Inside flex container (button becomes flex item)
Method 2: Visual Bordersβ
<!-- Add borders to see layout -->
<div class="border-2 border-red-500 gap-2">
<button class="border-2 border-blue-500">Fill User</button>
<button class="border-2 border-green-500">Fill Admin</button>
</div>
You'll see:
ββββββββββββββββββββββββββββ red border (container)
β βββ blue border (button 1)
β β Fill User
β βββ
β βββ green border (button 2)
β β Fill Admin
β βββ
ββββββββββββββββββββββββββββ
Without flex: Small gap from whitespace
With flex gap-2: Precise 8px gap
Method 3: Add Background Colorsβ
<div class="bg-gray-200 p-4">
<button class="bg-blue-200">Fill User</button>
<button class="bg-green-200">Fill Admin</button>
</div>
Makes spacing issues visible!
Common Mistakes with Button Groupsβ
Me: What mistakes do people make?
Frontend Mentor: Here are the most common ones:
Mistake 1: Using gap Without flexβ
β Doesn't work:
<div class="gap-2">
<button>Button 1</button>
<button>Button 2</button>
</div>
Why: gap only works with display: flex or display: grid!
β
Works:
<div class="flex gap-2">
<button>Button 1</button>
<button>Button 2</button>
</div>
Mistake 2: Using flex-1 Without flex Containerβ
β Doesn't work:
<div>
<button class="flex-1">Button 1</button>
<button class="flex-1">Button 2</button>
</div>
Why: flex-1 only works inside a flex container!
β
Works:
<div class="flex gap-2">
<button class="flex-1">Button 1</button>
<button class="flex-1">Button 2</button>
</div>
Mistake 3: Expecting inline-block to Respect gapβ
β Won't work:
<div class="gap-4">
<button style="display: inline-block;">Button 1</button>
<button style="display: inline-block;">Button 2</button>
</div>
Why: inline-block doesn't understand gap!
β
Use margins instead:
<div>
<button class="mr-4">Button 1</button>
<button>Button 2</button>
</div>
β
Or use flex:
<div class="flex gap-4">
<button>Button 1</button>
<button>Button 2</button>
</div>
Mistake 4: Fighting inline-block Whitespaceβ
β Unpredictable spacing:
<div>
<button>Button 1</button>
<button>Button 2</button>
</div>
Problem: HTML whitespace creates small gaps (browser-dependent)
β
Use flexbox for predictable spacing:
<div class="flex gap-2">
<button>Button 1</button>
<button>Button 2</button>
</div>
When to Use Each Approachβ
Me: So when should I use flex vs just letting buttons be inline-block?
Frontend Mentor: Excellent question! Here's the decision guide:
Use inline-block (No Flexbox) When:β
β Buttons are in flowing text content β You want natural text-like wrapping β Simple single-line layouts β Legacy browser support needed
Example:
<p>
Click here to
<button class="px-2 py-1 bg-blue-600 text-white rounded">
Sign Up
</button>
or continue reading.
</p>
Use flex When:β
β
Precise spacing needed (gap)
β
Equal width distribution (flex-1)
β
Alignment control needed
β
Modern, predictable layouts
β
Button groups and toolbars
Example (Your case):
<div class="flex gap-2">
<button class="flex-1">Fill User</button>
<button class="flex-1">Fill Admin</button>
</div>
Quick Decision Treeβ
Need precise spacing?
ββ YES β Use flex with gap
ββ NO β inline-block might be fine
Need equal width buttons?
ββ YES β Use flex with flex-1
ββ NO β inline-block might be fine
Need vertical/horizontal alignment control?
ββ YES β Use flex with items-center/justify-between
ββ NO β inline-block might be fine
Building modern UI?
ββ YES β Use flex (best practice)
Key Takeawaysβ
Me: Let me make sure I understand this correctly:
Frontend Mentor: Perfect! Here's the summary:
Why Buttons Stay Side-by-Side Without Flex:β
- Buttons are
inline-blockby default in all browsers inline-blockflows horizontally like words in text- They wrap to new lines if container is too narrow
- NOT because of flexbox (you removed it!)
The Difference:β
Without flex (uncontrolled):
- β Unpredictable spacing (HTML whitespace)
- β No gap control (
gap-2ignored) - β No flex utilities (
flex-1ignored) - β Works without modern CSS
With flex (controlled):
- β
Precise spacing (
gap-2= 8px) - β
Equal width distribution (
flex-1) - β Easy alignment
- β Modern, predictable
The Professional Approach:β
<div class="flex gap-2">
<button class="flex-1 bg-blue-600 text-white py-2 rounded-md hover:bg-blue-700">
Fill User
</button>
<button class="flex-1 bg-green-600 text-white py-2 rounded-md hover:bg-green-700">
Fill Admin
</button>
</div>
Why this works:
flexcreates flex containergap-2adds precise 8px spacingflex-1makes buttons equal width- Predictable, modern layout!
Remember:β
inline-block= "happens to be side-by-side" (depends on space)flex= "controlled to be side-by-side" (intentional layout)
Always use flex for button groups in modern applications! π―
Me: This makes so much sense! I thought removing flex would break the layout, but now I understand it just removes the control. The buttons were always capable of being side-by-side!
Frontend Mentor: Exactly! The inline-block default lets buttons sit beside each other naturally, but flexbox gives you control. It's the difference between "it works by accident" and "it works by design."
Now you understand when buttons are side-by-side by default vs. when you need flexbox for precise control! π
Did you have similar misconceptions about flexbox? Share in the comments! π¬
