4

This might sound like an outdated topic since no one still uses inline-block property thanks to flex-box and grid but I was wondering about it and I would like to inquire about it.

When creating two divs and assigning them both to display as inline-block and then adding any element inside one of them, the result is quite strange, where the div which contains that element will slide down to the bottom of the other div minus the height of the added element.

div {
    display: inline-block;
    width: 100px;
    height: 150px;
    background: gray;
}
<div id="left">
  <span>Text</span>
</div>
<div id="right"></div>

To fix the issue it's only enough to align the div vertically to the top, but what is strange too is that we get the same result even if we align the other div which is not affected without aligning the affected one, so what exactly is happening here?

div {
    display: inline-block;
    width: 100px;
    height: 150px;
    background: gray;
}

#left{
     vertical-align: baseline;
}

#right{
      vertical-align: top;
}
<div id="left">
  <span>text</span>
</div>
<div id="right"></div>

UPDATE:

To clarify things more I removed the child element and added a text outside the two divs, and added two more divs, now all divs are without a flow content, but the first two both of them have a top property while the last two are different, one top and the other is baseline:

div {
  display: inline-block;
  width: 100px;
  height: 150px;
  background: gray;
}
.right{
  vertical-align:baseline;
}
.left{
  vertical-align:top;
}
Text
<div class="right"></div>
<div class="left"></div>

<br>

Text
<div class="left"></div>
<div class="left"></div>

In the first case the Text aligned to the top and in the next aligned to the baseline of the divs even they don't have a flow content.

Tarek.hms
  • 1,243
  • 1
  • 10
  • 15
  • 1
    try adding max-width and max-height to the textarea textarea { margin: 0; padding: 0; width: 50px; height: 50px; border: 0; max-width:100%; max-height:100%; } – McRist Aug 15 '18 at 07:15
  • 2
    As IE is not dead (yet) `inline-block` still has it's place as `grid` and `flex` are buggy (at best) in even the most recent versions of IE (NOT edge) – Jon P Aug 15 '18 at 07:29
  • @JonP lol so true. – Tarek.hms Aug 15 '18 at 07:38
  • 1
    this is not a bug, it's vertical alignment which is by default `baseline` – Temani Afif Aug 15 '18 at 08:17
  • @TemaniAfif what are you talking about?!!.. you are totally off topic and that question is completely different than this one. – Tarek.hms Aug 15 '18 at 08:21
  • 1
    am not completely off topic, this is exactly the answer you need. The behavior you are having is due to the alignment which is baseline and this explain everything .. I am adding more duplicates so you can understand this logical behavior – Temani Afif Aug 15 '18 at 08:22
  • check this : https://stackoverflow.com/a/31063197/8620333 and this https://stackoverflow.com/a/12950536/8620333 – Temani Afif Aug 15 '18 at 08:24
  • @TemaniAfif is correct. See my answer. – Robby Cornelissen Aug 15 '18 at 08:24
  • @TemaniAfif Since when the parent element inherits its properties from an element within, how come the alignment of the child affect the parent? that's basically my question. – Tarek.hms Aug 15 '18 at 08:25
  • 1
    read the duplicates and you will understand :) that the purpose of closing as duplicate .. I cannot explain within comments this behavior – Temani Afif Aug 15 '18 at 08:26
  • 1
    now you have a complete list of duplicate, read all of them and everything will be very clear in your mind and you will learn more than you expected ;) – Temani Afif Aug 15 '18 at 08:29
  • @TemaniAfif you are also ignoring the fact which I mentioned that you don't need to change the alignment of the element which has inline-block property and to prove it to you I edited my question and this time with alignment to baseline and no problems occur, so explain that now. – Tarek.hms Aug 15 '18 at 08:34
  • 1
    Yes I know you don't need to change the alignment of both element, only one element need vertical-align and it's not the one how contain the text and this is also explained in the duplicate ... you simply need to understand the concept of baseline and containing block (which is described in all the duplicates) – Temani Afif Aug 15 '18 at 08:39
  • 1
    Both divs are inline-block and both are affected, you are wrong thinking that only the one that conain the text is affected and move down. BOTH divs are aligned to the baseline. Simply take the time to read about this, it's not easy at the start but you will get it – Temani Afif Aug 15 '18 at 08:41
  • 1
    I started on an answer, but it was locked as a dupe before I was finished, so I posted answer [there](https://stackoverflow.com/a/51857106/109392) instead. What I answer there that is not covered by the other answers, is why it behave like it does when one of the boxes is `vertical-align:top`. – awe Aug 15 '18 at 10:56
  • 1
    As [Eric Meyer once said](http://meyerweb.com/eric/thoughts/2008/05/06/line-height-abnormal/) "... knowledge of what goes into the layout of lines of text imparts a sense of astonishment that any page can be successfully displayed in less than the projected age of the universe. " – Alohci Aug 15 '18 at 11:20
  • As a comment to the statement "This might sound like an outdated topic since no one still uses inline-block property thanks to flex-box and grid" I would say that it is still useful to enable smaller boxes to wrap dynamically by enabling different number of boxes on each line dependent on window width. – awe Aug 15 '18 at 11:37

2 Answers2

4

The reason this happens, is because the default vertical-align value for inline elements is baseline.

Then the question becomes: what is the baseline of an inline-block element? Here, we have to make a distinction between elements with and without flow content:

  • For elements with flow content, such as the left div in your question, the baseline is the same as the baseline of the last content element.(*) For the left div, this corresponds to the baseline of the inner span.
    (*) There are some additional considerations when setting the element's overflow, but I'll leave that out of scope.
  • For elements without flow content, such as the right div in your question, the baseline is the bottom of the element's margin box. For the right div, this corresponds to the bottom of the div itself.

So, to summarize: the reason you're seeing a vertical shift is because the elements are vertically aligned according to their baseline, and the baselines for elements with and without content are calculated differently.

To test this out, just try adding some text to the right div, and you'll see how both baselines are now the same.

div {
  display: inline-block;
  width: 100px;
  height: 100px;
  background: gray;
}
<div id="left">Text</div>
<div id="right">Other text</div>

By animating the font size, the example below demonstrates even more clearly how changes in the baseline affect vertical positioning:

div {
  display: inline-block;
  width: 100px;
  height: 100px;
  background: gray;
}

#left {
  transition: all 2s ease;
  animation: anim 2s infinite linear alternate;
}

@keyframes anim {
  0% {font-size: 100%;}
  100% {font-size: 300%;}
}
<div id="left">Text</div>
<div id="right"></div>
Robby Cornelissen
  • 91,784
  • 22
  • 134
  • 156
  • to make it more tricky and also clear I would add text to the next div with a bigger font-size so we can clearly see the baseline ;) probably an animation that increase decrease the font-size – Temani Afif Aug 15 '18 at 08:27
  • @TemaniAfif Thanks for your feedback. I've added the animation :) – Robby Cornelissen Aug 15 '18 at 09:10
  • 2
    That explains the initial state when both divs are on the baseline. I'm not convinced that it answers the OP's question, which is why does setting *either* div to `vertical-align:top` remove the offset. – Alohci Aug 15 '18 at 09:48
  • Exactly and that's the core question, I don't need an explanation that setting the vertical alignment to top will move the element from baseline to the top, I already mentioned that in my text but the real question remains why the second dev affect the baseline of the body which is the actual parent for both divs and for more clarity see my last update. – Tarek.hms Aug 15 '18 at 10:33
  • @Tarek.hms read this: https://developer.mozilla.org/en-US/docs/Web/CSS/vertical-align ... you need to first understand how the baseline of the parent element is caclulated (because this is what is used for the baseline value) and you need to also understand how the line box of an element is calculated (because top consider this) ... then you will understand how each element is aligned ... The duplicate questions contains link to specfication that explain all this, you simply need to take the time understanding them. All your examples are almost the same even you last edit. – Temani Afif Aug 15 '18 at 10:56
  • And am pretty sure @Alohci will agree with me since he wrote one of those answers and he knows better than me those stuffs ... even if you reopen the quesiton, you will simply get the same answers already provided. All the example you made deal with the same thing: What is baseline?, how its caclulated? what is a line box? how vertical-align:top behave? how vertical-align:baseline behave? why adding text change things? etc .. all these answers are in the duplicate – Temani Afif Aug 15 '18 at 10:58
  • @Tarek.hms and here is the relevant part of the documentation : https://www.w3.org/TR/CSS2/visudet.html#line-height – Temani Afif Aug 15 '18 at 11:05
  • 1
    @TemaniAfif - Well actually, I think a full answer to the question, especially in its latest form, requires an explanation of how the line box is constructed. That the items not aligned to the top and bottom line box edges are aligned with each other first, and then the top and bottom items added. I'm not sure any of the duplicates actually does that. I don't have time at present to write a proper answer though. – Alohci Aug 15 '18 at 11:10
  • 1
    @Alohci you already did it here if I am not wrong https://stackoverflow.com/questions/43305825/understand-inline-elemnt-vertical-align-line-box-and-line-height – Temani Afif Aug 15 '18 at 11:18
  • Well, I have actually written an answer that covers this, but the question was lacked as dupe before I was finished, so I posted it [on this linked question](https://stackoverflow.com/a/51857106/109392) instead. – awe Aug 15 '18 at 11:19
  • 1
    @TemaniAfif - so I did. Thanks. – Alohci Aug 15 '18 at 11:22
  • 1
    Ok, I admit it, I was wrong, it makes me feel like I'm learning CSS all over again, I used to believe that CSS is much simpler but now I see the principle logic behind all this, thank you guys for these explanations and sorry for any inconvenience. – Tarek.hms Aug 15 '18 at 21:25
  • @Tarek.hms Don't feel too bad about it. The logic behind vertical-align is not easy to understand. – awe Aug 16 '18 at 08:41
0

The display: inline-block Value

Compared to display: inline, the major difference is that display: inline-block allows to set a width and height on the element.

Also, with display: inline-block, the top and bottom margins/paddings are respected, but with display: inline they are not.

Compared to display: block, the major difference is that display: inline-block does not add a line-break after the element, so the element can sit next to other elements.

and

excuse me textarea is inline-block, but what line is correct, the browser think the bottom of second inline-block is position of line so when he go to draw children he see the textarea must be inline and change position of it to the bottom of second inline-block is position of line and because it is any padding and it position are relative it cause to parent div move to bottom just for textarea be inline

Mahdi Aslami Khavari
  • 1,755
  • 15
  • 23