css - display: inline-flex vs display: inline behave unexpectedly - Stack Overflow

admin2025-05-01  0

Why does adding display:inline-flex mess with the vertical aligning of these buttons?

Notice in the code that the three buttons aren't aligned in the y direction, but changing the 'display: inline-flex' property to 'display: inline' fixes that problem. Why?

:root {
  --color-primary: green;
  --btn-padding-x: 1rem;
  --btn-padding-y: 0.5rem;
  --border-radius: 0.5rem;
  --btn-stroke-width: 0.1rem;
  font-family: 'Inter Variable', sans-serif;
}

.btn {
   border-radius: var(--border-radius);
  padding: var(--btn-padding-y) var(--btn-padding-x);
  background-color: var(--color-primary);
  color: white;
  display: inline-flex; /* toggle this to see the effect */
  
  /* FIX ALIGNMENT
  vertical-align: middle; */
}

.icon-container {
  width: 40px;
}

svg {
  stroke: white;
  stroke-width: var(--btn-stroke-width);
  fill: none;
}

.wrapper {
  background-color: gold;
}
<div class="wrapper">
  Some text before the buttons
  <button class="full-width btn btn-primary btn-high">
  <span>Default</span>
</button>

<button class="btn">
  <div class="icon-container">
    <svg xmlns="" viewBox="0 0 24 24">
      <path
        d="M12 21.35l-1.45-1.32C5.4 15.36 2 12.28 2 8.5 2 5.42 4.42 3 7.5 3c1.74 0 3.41.81 4.5 2.09C13.09 3.81 14.76 3 16.5 3 19.58 3 22 5.42 22 8.5c0 3.78-3.4 6.86-8.55 11.54L12 21.35z"
      />
    </svg>
  </div>
  <span>Icon L</span>
</button>

<button class="btn">
  <span>Icon R</span>
  <div class="icon-container">
    <svg xmlns="" viewBox="0 0 24 24">
      <path
        d="M12 21.35l-1.45-1.32C5.4 15.36 2 12.28 2 8.5 2 5.42 4.42 3 7.5 3c1.74 0 3.41.81 4.5 2.09C13.09 3.81 14.76 3 16.5 3 19.58 3 22 5.42 22 8.5c0 3.78-3.4 6.86-8.55 11.54L12 21.35z"
      />
    </svg>
  </div>
  </div>

Why does adding display:inline-flex mess with the vertical aligning of these buttons?

Notice in the code that the three buttons aren't aligned in the y direction, but changing the 'display: inline-flex' property to 'display: inline' fixes that problem. Why?

:root {
  --color-primary: green;
  --btn-padding-x: 1rem;
  --btn-padding-y: 0.5rem;
  --border-radius: 0.5rem;
  --btn-stroke-width: 0.1rem;
  font-family: 'Inter Variable', sans-serif;
}

.btn {
   border-radius: var(--border-radius);
  padding: var(--btn-padding-y) var(--btn-padding-x);
  background-color: var(--color-primary);
  color: white;
  display: inline-flex; /* toggle this to see the effect */
  
  /* FIX ALIGNMENT
  vertical-align: middle; */
}

.icon-container {
  width: 40px;
}

svg {
  stroke: white;
  stroke-width: var(--btn-stroke-width);
  fill: none;
}

.wrapper {
  background-color: gold;
}
<div class="wrapper">
  Some text before the buttons
  <button class="full-width btn btn-primary btn-high">
  <span>Default</span>
</button>

<button class="btn">
  <div class="icon-container">
    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
      <path
        d="M12 21.35l-1.45-1.32C5.4 15.36 2 12.28 2 8.5 2 5.42 4.42 3 7.5 3c1.74 0 3.41.81 4.5 2.09C13.09 3.81 14.76 3 16.5 3 19.58 3 22 5.42 22 8.5c0 3.78-3.4 6.86-8.55 11.54L12 21.35z"
      />
    </svg>
  </div>
  <span>Icon L</span>
</button>

<button class="btn">
  <span>Icon R</span>
  <div class="icon-container">
    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
      <path
        d="M12 21.35l-1.45-1.32C5.4 15.36 2 12.28 2 8.5 2 5.42 4.42 3 7.5 3c1.74 0 3.41.81 4.5 2.09C13.09 3.81 14.76 3 16.5 3 19.58 3 22 5.42 22 8.5c0 3.78-3.4 6.86-8.55 11.54L12 21.35z"
      />
    </svg>
  </div>
  </div>

My understanding was that display: inline-flex is equivalent to saying "this element is display: inline to all its siblings, but its children are all governed by flexbox". But in that case, adding this property to .btn shouldn't mess with its vertical aligning?

i.e there should be no difference in the vertical aligning of the buttons between writing:

.btn {
display: inline-flex;
}

and

.btn {
display: inline;
}
Share Improve this question edited Jan 2 at 15:18 Temani Afif 276k28 gold badges368 silver badges487 bronze badges asked Jan 2 at 14:54 victorinovictorino 111 silver badge1 bronze badge 2
  • Please include a minimal reproducible example within the question, not (only) on external sites. – cafce25 Commented Jan 2 at 14:56
  • This question is similar to: What's the difference between display:inline-flex and display:flex?. If you believe it’s different, please edit the question, make it clear how it’s different and/or how the answers on that question are not helpful for your problem. – Naeem Akhtar Commented Jan 2 at 15:08
Add a comment  | 

2 Answers 2

Reset to default 1

The difference is the baseline of each element.

For inline-block you have the following (button will have a display computed to inline-block even if you specify inline)

The baseline of an 'inline-block' is the baseline of its last line box in the normal flow, unless it has either no in-flow line boxes or if its 'overflow' property has a computed value other than 'visible', in which case the baseline is the bottom margin edge. ref

For inline-flex you have a more complex configuration explained here: https://www.w3.org/TR/css-flexbox-1/#flex-baselines and since the order of the elements inside your buttons aren't not the same, you get a different baseline for each one hence the alignment is also different.

It looks like the first item in each button is defining the baseline in your case.

As you already guessed, you can either change the default alignment from baseline to something else (example: vertical-align: top) or you update the alignment of the elements inside the button so both have the same baseline again.

:root {
  --color-primary: green;
  --btn-padding-x: 1rem;
  --btn-padding-y: 0.5rem;
  --border-radius: 0.5rem;
  --btn-stroke-width: 0.1rem;
  font-family: 'Inter Variable', sans-serif;
}

.btn {
  border-radius: var(--border-radius);
  padding: var(--btn-padding-y) var(--btn-padding-x);
  background-color: var(--color-primary);
  color: white;
  display: inline-flex;
}
.fix .btn{
  align-items: end;
}

.icon-container {
  width: 40px;
}

svg {
  stroke: white;
  stroke-width: var(--btn-stroke-width);
  fill: none;
}

.wrapper {
  background-color: gold;
}
<div class="wrapper">
  Some text before the buttons
  <button class="full-width btn btn-primary btn-high">
  <span>Default</span>
</button>

  <button class="btn">
  <div class="icon-container">
    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
      <path
        d="M12 21.35l-1.45-1.32C5.4 15.36 2 12.28 2 8.5 2 5.42 4.42 3 7.5 3c1.74 0 3.41.81 4.5 2.09C13.09 3.81 14.76 3 16.5 3 19.58 3 22 5.42 22 8.5c0 3.78-3.4 6.86-8.55 11.54L12 21.35z"
      />
    </svg>
  </div>
  <span>Icon L</span>
</button>

  <button class="btn">
  <span>Icon R</span>
  <div class="icon-container">
    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
      <path
        d="M12 21.35l-1.45-1.32C5.4 15.36 2 12.28 2 8.5 2 5.42 4.42 3 7.5 3c1.74 0 3.41.81 4.5 2.09C13.09 3.81 14.76 3 16.5 3 19.58 3 22 5.42 22 8.5c0 3.78-3.4 6.86-8.55 11.54L12 21.35z"
      />
    </svg>
  </div>
</button>
</div>
<hr>
<div class="wrapper fix" >
  Some text before the buttons
  <button class="full-width btn btn-primary btn-high">
  <span>Default</span>
</button>

  <button class="btn">
  <div class="icon-container">
    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
      <path
        d="M12 21.35l-1.45-1.32C5.4 15.36 2 12.28 2 8.5 2 5.42 4.42 3 7.5 3c1.74 0 3.41.81 4.5 2.09C13.09 3.81 14.76 3 16.5 3 19.58 3 22 5.42 22 8.5c0 3.78-3.4 6.86-8.55 11.54L12 21.35z"
      />
    </svg>
  </div>
  <span>Icon L</span>
</button>

  <button class="btn">
  <span>Icon R</span>
  <div class="icon-container">
    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
      <path
        d="M12 21.35l-1.45-1.32C5.4 15.36 2 12.28 2 8.5 2 5.42 4.42 3 7.5 3c1.74 0 3.41.81 4.5 2.09C13.09 3.81 14.76 3 16.5 3 19.58 3 22 5.42 22 8.5c0 3.78-3.4 6.86-8.55 11.54L12 21.35z"
      />
    </svg>
  </div>
</button>
</div>

What I have understood is that display: flex-inline; will apply flex property with items align vertically center.

display: inline; property will simply put items in a line without applying vertical alignment.

And if you remove that property from there and apply it on the .wrapper with flex properties then it will be aligned in a line vertically centered as done in the following example.

Hope, this helps.

:root {
  --color-primary: green;
  --btn-padding-x: 1rem;
  --btn-padding-y: 0.5rem;
  --border-radius: 0.5rem;
  --btn-stroke-width: 0.1rem;
  font-family: 'Inter Variable', sans-serif;
}

.btn {
  border-radius: var(--border-radius);
  padding: var(--btn-padding-y) var(--btn-padding-x);
  background-color: var(--color-primary);
  color: white;
  /* FIX ALIGNMENT
  vertical-align: middle; */
}

.icon-container {
  width: 40px;
}

svg {
  stroke: white;
  stroke-width: var(--btn-stroke-width);
  fill: none;
}

.wrapper {
  background-color: gold;
  display: flex;
  /* toggle this to see the effect */
  flex-direction: row;
  align-items: center;
  gap: 1rem;
}
<div class="wrapper">
  Some text before the buttons
  <button class="full-width btn btn-primary btn-high">
  <span>Default</span>
</button>

  <button class="btn">
  <div class="icon-container">
    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
      <path
        d="M12 21.35l-1.45-1.32C5.4 15.36 2 12.28 2 8.5 2 5.42 4.42 3 7.5 3c1.74 0 3.41.81 4.5 2.09C13.09 3.81 14.76 3 16.5 3 19.58 3 22 5.42 22 8.5c0 3.78-3.4 6.86-8.55 11.54L12 21.35z"
      />
    </svg>
  </div>
  <span>Icon L</span>
</button>

  <button class="btn">
  <span>Icon R</span>
  <div class="icon-container">
    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
      <path
        d="M12 21.35l-1.45-1.32C5.4 15.36 2 12.28 2 8.5 2 5.42 4.42 3 7.5 3c1.74 0 3.41.81 4.5 2.09C13.09 3.81 14.76 3 16.5 3 19.58 3 22 5.42 22 8.5c0 3.78-3.4 6.86-8.55 11.54L12 21.35z"
      />
    </svg>
  </div>
  </div>

转载请注明原文地址:http://anycun.com/QandA/1746111191a91822.html