Why dont DIVs with display in-line block seat next to each other with width 50%

Hey all,

I have been wondering for some time about this bizarre behavior of CSS where DIVs with display in-line block do not seat next to each other in same line even though their width is 50%
You can see it in problem mode here:

And oh yes, we have the DIVs even next to each other on the same line of HTML to address that quirck of CSS that 2 DIVs in seperate lines will have a break line. But still they are not on the same line when they have width is 50%!

So how does one get around this and have 2 DIVs with display: inline-block; fill the entire Width of their containing DIV?

Thanks,

That’s because whitespace nodes are created when the divs are formatted on their own line in the html. The width of the node is enough to force the other 50% width div down below to another line when the browser renders it.

An old hacky way around was to chain the tags together in the html. It is not recommended to do that, but it will show you that the whitespace node is indeed eliminated.


<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Test Page</title>
<style>

.wrap {
  margin:1em
}
.wrap div {
  display:inline-block;
  width:50%;
  background:wheat;
}

</style>

</head>
<body>

<div class="wrap">
   <div>div with whitespace node</div>
   <div>div with whitespace node</div>
</div>

<div class="wrap">
   <div>div tag chain</div><div>
   div tag chain</div>
</div>

</body>
</html>

Now that old IE browsers are dead and gone you can use display:table and table-cell to achieve the same effect. That way you don’t have to mangle up your html. :grinning:

You can also use display:flex

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Test Page</title>
<style>

.wrap {
  display:table;
  width:100%;
}
.wrap div {
  display:table-cell;
  width:50%;
  background:wheat;
}

</style>

</head>
<body>

<div class="wrap">
   <div>display:table-cell</div>
   <div>display:table-cell</div>
</div>

</body>
</html>
3 Likes

A simple way to explain the behaviour is that inline-block makes the element behave as those it was a word and if you have space between words then you see a gap.

That’s why the space between the elements is honoured when they are inline-block but not when they are block level.

4 Likes

Ray,
I really do not like using CSS Tables, for various reasons. Such as why go from HTML tables to CSS tables, must be better CSSish ways :slight_smile:

Paul,

But we have NO space between the inline-block in question. Here it is:

<div id="top_area_l">Advertising that is Easy, Effective & Low Cost </div><div id="top_area_r">The non-profit Social Search Network</div>

Sorry, I should have posted this with OP.
As you can see we have NO space between these 2 DIVs:

#top_area_l, #top_area_r {
display: inline-block;
width: 50%;
padding: 10px;
margin: 0px;
color: white;
font-size: 22px;
font-weight: bold;
}

#top_area_l {
background: #336699;
}

#top_area_r {
background: #FF6600;
}

HTML tables and CSS tables are very different beasts. There really is no reason not to use CSS tables if they do the job required.

1 Like

If you realy would like to stick to inline-blocks try this:

.wrapper
{
	width: 80%;
	margin: 100px auto 0;	
}

.wrapper div {
	width: 50%;
	display: inline-block;
	padding: 10px; //to have the padding included use box-sizing
	margin-right: -4px;
		

html

<div class="wrapper">
	<div class="blue"></div>
    <div class="red"></div>
</div>

I’m afraid you don’t fully understand CSS table layout. It is entirely different from html tables, html tables should only be used for true tabular data, not for page layout. And it is for use with html table elements only.

CSS tables on the other hand allow you you to mimic html tables for page layout with ANY html element. I imagine it was W3C’s answer to people abusing html tables for page layout. That, and to bypass the problems that came with float layouts. CSS tables will match their sibling’s height whereas floats will not.

Fast forward a decade and now we have flexbox and grid layout in addition to CSS table layout.

3 Likes

You have tag chained those divs, so a whitespace node was NOT created in the html.
That was explained in my first post along with an example.

</div><div id="top_area_r">

1 Like

The negative margin hack is not a reliable method to remove the node, in fact it just drags the div on top of the node.

It is prone to fail when the user’s base font-size is unknown.

The more reliable method in the past was to use word-spacing to kill the node. But there is a long standing Webkit bug that makes that method fail in Chrome. The workaround to make webkit behave was display:table

See the CSS Quiz # 35 - inline-block for the cross browser solution in 2010’

But there is no need to go down that road now in 2018’ with old IE gone. As mentioned earlier display:table or display:flex can be used when the whitespace nodes cause problems for a layout.

There are plenty of times when the nodes are not an issue, such as with gallery images. In a case like that I would have no problem using inline-blocks. :grinning:

3 Likes

Yes, there are times when you want the inline behavior of inline-block, when you want that wrapping to new lines which tables don’t give you. Though these days I would be more inclined to use flex for that kind of thing.
In this scenario I think the display: table is appropriate, as the OP specifically wants to avoid the wrapping behavior.

3 Likes

Ok but how big is 50% + 10px padding either side?

You would need to be using the box-sizing:border-box model for the padding to be on the inside of the 50%. I am not on a computer at the moment so couldn’t see if you had changed to that model which is not the default.

3 Likes

Paul,

But the padding affects the content that is inside the DIV, so that should have nothing to do with the actual Width of the DIV. I mean the Margin value would affect this issue as it impacts the total area that the DIV takes, but the Padding only affects inside of the DIV so it should have NO affect on total area that the DIV takes!

At least that is what for ions I have understood Padding be vs Margins.
Dont tell me that I understood this basic wrong :slight_smile:

It depends on whether the box-sizing is content-box (the default) or border-box

By default in the CSS box model, the width and height you assign to an element is applied only to the element’s content box. If the element has any border or padding, this is then added to the width and height to arrive at the size of the box that’s rendered on the screen. This means that when you set width and height, you have to adjust the value you give to allow for any border or padding that may be added.

Don’t feel bad about being a bit confused. Yes, padding is inside the border and margin is outside the border. And it’s easy and intuitive to think dimensions are for the border not the content inside it.

4 Likes

Mitti,

Glad to know that I had a firm grasp of the Margin vs Padding.
Woooosh that would have been really bad if I did not :slight_smile:
But anyway, that still does not answer my rather basic question of how do you place multiple DIVs with display inline-block inside another DIV to fill the entire available space without the right most DIV breaking into another line? I mean without using Tables.
Thanks.

Well, if it’s just two divs as shown in your first post that is quite simple.
Use border-box as was suggested already

#top_area_l, #top_area_r {
    display: inline-block;
    width: 50%;
    padding: 10px;
    margin: 0px;
    color: white;
    font-size: 22px;
    font-weight: bold;
    box-sizing: border-box; /*add this */
}

Of course you must keep your divs tag chained in the html like you have it now.

If it’s ten divs that would be another story, if there were ten divs at 10% width the content would probably overflow each div.

I can already see that you need to vertical-align also, when you reduce the viewport width one div is taller than the other.

It is set at the default right now which is vertical-align: baseline;

If you want the top of the divs even change it to top

I wouldn’t change the HTML to <table> <tr> <td> etc. tags. But you could certainly use the CSS display properties without any problem.

I guess the CSS could be abused so that all <table> related tags were replaced with <div>s and <span>s and styled so that the markup was de facto table tags written with non table tags. But used in moderation there is nothing wrong with using what tools are available.

In any case, if you don’t want to do that, @donboe posted the solution back in post #7 as a comment. Did you try that?

1 Like

That negative margin hack is not a solution, I explained the problems with it in post #10.

display:table is what the OP should be using but he thinks it is the same as html tables

When you view the page source you can see that the inline-block divs are tag chained

		<div class="w3-animate-left page_left" style="font-size: 20px;">

			<div id="top_area_l">Advertising that is Easy, Effective & Low Cost </div><div id="top_area_r">The non-profit Social Search Network</div>
	
		</div>

That’s why there is no node to contend with and thus 50% width will work with padding and box-sizing.

When you use inspector to view the html it corrects the chained tags and makes it look correct. It misleads you into thinking there is a node there, but there isn’t.

4 Likes
<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Test Page</title>
<style>
html {
  box-sizing: border-box;
}
*, *:before, *:after {
  box-sizing: inherit;
}
.page_left {
  display:table;
  width: calc(100% - 20px);
  margin:auto;
}
.w3-animate-left {
  position: relative;
  -webkit-animation: animateleft 0.4s;
  animation: animateleft 0.8s;
}
#top_area_l {
  background: #336699;
}
#top_area_r {
  background: #FF6600;
}
#top_area_l, #top_area_r {
  display: table-cell;
  width: 50%;
  padding: 10px;
  margin: 0px;
  color: white;
  font-size: 22px;
  font-weight: bold;
}
</style>

</head>
<body>

<div class="w3-animate-left page_left">
  <div id="top_area_l">Advertising that is Easy, Effective & Low Cost </div>
  <div id="top_area_r">The non-profit Social Search Network</div>
</div>

</body>
</html>
4 Likes

Lose the padding or change 50% to something like 48%, although 48% may not be reliable on all screen sizes.