inline-block elements are line breaking for seemingly no reason? - html

I have some pretty basic HTML/CSS that isn't working as I expect. Basically I have my body setup to be 400px wide. I then have two divs inside of the body with explicit widths of 300px and 100px. Additionally, both of these divs are set to display: inline-block. For some reason, the 100px div breaks out of the body's content area and appears below it. I don't know why this is happening. If I set the width from 100px to 96px, it works. However, if I set it to 97px, 98px, 99px, or back to 100px, it doesn't work. I find this behavior very odd. Can someone explain what is going wrong?
Note that I am testing this on Chrome (Beta Channel). Code is below.
The CSS:
body {
margin: 4px;
width: 400px;
height: 250px;
border: 1px solid black;
}
.list-container {
display: inline-block;
width: 300px;
height: 100%;
background-color: red;
}
.button-container {
display: inline-block;
width: 100px;
height: 100%;
background-color: blue;
}
The HTML:
<body>
<div class="list-container">
</div>
<div class="button-container">
</div>
</body>

It's because of the way white-space collapses in html.
If you remove the line-breaks from between the two div elements, everything's fine:
<div class="list-container">
</div><div class="button-container">
</div>
JS Fiddle demo.
You could, also, just comment-out the between divs:
<div class="list-container">
</div><!--
--><div class="button-container">
</div>
JS Fiddle demo.
Or even set the font-size to zero for the body element (but you'll have to redefine it for the child elements, obviously:
body {
margin: 4px;
width: 400px;
height: 250px;
border: 1px solid black;
padding: 0;
font-size: 0;
}
JS Fiddle demo.

Another possibility with odd inline-block behaviour in Chrome is if you have text-render: optimizeLegibility set. I was struggling with inexplicable line-breaks in inline block elements in Chrome, and found that removing text-render: optimizeLegibility fixed the problem.
I've had at least one other hard-to-figure-out problem (inexplicable non-rendering of web fonts) that turned out to be caused by optimizeLegibility in the past, so from now on that's going to be a prime suspect when things behave strangely in Chrome.
(nb. Even if you don't think you're using it, if you're using a framework like Twitter Bootstrap you may be using it unwittingly)

It's the margin in your body:
margin: 4px;
Because the margin counts as part of the total width. 300px for the first one + 100px for the second div + 8px (4 on either side) for the margin = 408px. That forces the second div down to the next line.
I'm actually kind of surprised that it works at 96. It acts like it's only accounting for the margin on one side. I'd expect it to only work at 92 or below. Either way account for the margin size in the width of your body or set the margin to 0 and that should fix the problem.

Related

Why is padding right clipped with overflow:scroll

In the snippet below, padding-right for .ctr is not visible when content starts to overflow at small viewports.
I've read other answers and I know how to fix it.
I just need to move padding:20px from .ctr to .row. Or just add margin-right:20px to last child.
But, I couldn't find the reason as to why this happens. Could someone please explain, what's going on? any resource for further learning will be highly appreciated 🙏
Thanks!
.ctr {
display: flex;
overflow-x: auto;
padding: 20px;
}
.row {
margin: 0 auto;
display: flex;
}
.child {
margin-right: 20px;
width: 600px;
height: 100px;
background: red;
}
.child:last-child {
margin-right: 0;
}
<div class="ctr">
<div class="row">
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
</div>
</div>
The padding is actually there when the content overflow it hides it.
we can illustrate this using background and background-origin
.container {
display: flex;
overflow-x: auto;
padding: 20px;
width: 200px;
background: linear-gradient(red, red) no-repeat;
background-origin: content-box;
border: 1px solid;
}
.overflow {
background: pink;
min-width: 400px;
height: 100px;
border: 1px solid;
}
<div class="container">
<div class="overflow"></div>
</div>
the white space you see on the edges is the padding
background-origin: content-box; makes the background exclude border and padding which will show us that the padding isn't clipped only covered, this happens because padding is part of the parent and the content overflow the parent so it covers it.
There's nothing special about this.
Dude the reason is the rendering or calculation in browsers (or the logic or system that we have developed starts from the top/left and ends at right/bottom). So, padding the hierarchy of placement is:
margin > border > padding > content
(And, remember it starts with top/left).
Now the issue you are seeing is only because you have not increased the height of item. If you do so - You will not only find issue on the right-padding but also on the bottom-padding.
Padding is only an effort to wrap something which is flexible. When you give a 600 * 5 width to items then they take more width than available.
padding is not as strong contender like margin. Because, margin you apply on same element - whose width or height you are manipulating. padding is being applied on an element which is trying to impose restrictions on some other element (usually direct child). So, this is the difference between padding and margin and how they get applied on browsers via Box-Model.
Hope, this clarifies a bit.

Browser Rendering Issues

I have noticed a tiny rendering issue across borwsers, and i was wondering if anyone knew how to fix it.
This does not happen when the browser is full screen or maximized but rather only when the browser is resized to a smaller window. I have noticed it on Chrome,Firefox and opera for now.
image of rendering issue
So what I have here is a nested DIV.
Here is my Scss code so you can see what I am describing:
<div class="parent">
<div class="child"></div>
</div>
.parent {
width: 600px;
height: 400px;
border: 1px solid black;
margin: auto;
padding: 0;
overflow: hidden;
.child{
width: 100%;
height: 50px;
background: #000;
}
}
You will see in the image there is a small white space between the parent div and child div.
the white space is circled in red.
So does anyone know what causes this minor issue?
This may be caused by a whitespace in your html between the parent and child. You could test this by removing all whitespace and seeing it if fixes the problem, so instead of this:
<div>
<h1>Title here</h1>
</div>
you could try:
<div><h1>Title here</h1></div>
If this doesn't work, a quick fix might also be to add a 1px negative margin on the child ( margin-left: -1px)

CSS3 columns in Chrome with child DIV elements

I'm having trouble with CSS3 columns, they don't work as I would have expected in Chrome 53.0.2785 - they work as I'd expect in Firefox 49, IE11, EDGE 38.14393
The first two child DIVs of my "container" DIV display under each other in Chrome, but next to each other in Firefox
HTML:
<div class="container">
<div>
Some content 1
</div>
<div>
Some content 2
</div>
</div>
CSS:
* {
box-sizing: border-box;
}
.container {
column-width: 100px;
column-gap: 12px;
}
.container > div {
display: inline-block;
width: 100px;
border: 1px solid black;
padding: 20px;
}
Test it here: https://jsfiddle.net/s7cfbqzt/3/
Now, there's a few strange things happening in Chrome:
if I only remove "display: inline-block", Chrome breaks up the DIVs (even the border gets distributed) - Firefox does not
Please note that I can't set column-count in the parent (which in combination with removing inline-block seems to kind-of-work) as it's supposed to be a fluid layout. The height of each DIV is dynamic as well, so if that's a requirement I'd have to write some JS for this (but I'd prefer to have this working without JS).
if I remove border-sizing and all properties of the child DIVs it works as expected, but as soon as I start filling the inner DIVs with some other content (that might have border or paddings or box-shadows), it breaks again
If I add a third child DIV
<div>Some content 3</div>
there will be columns in Chrome, but is displayed as
1..3
2
A fourth DIV would then be display underneath DIV3, a fifth DIV in the first "row" again.
1..3..5
2..4
Is this a bug in Chrome or am I doing something wrong?
Chrome is actually probably the one browser doing it correctly:
https://drafts.csswg.org/css-break/#widows-orphans
Name: orphans, widows
Value: <integer>
Initial: 2
IE 11, EDGE and Firefox (49) do not (yet?) support widows and orphans, even though http://caniuse.com/#feat=css-widows-orphans claims that IE11 and EDGE do support it - see https://jsfiddle.net/s7cfbqzt/13/ in IE11 and EDGE. If IE and EDGE actually would support it, they'd set the initial values to 1 instead of 2.
Fix for my use-case is to add
orphans: 1;
widows: 1;
to the container-class in CSS.
Thanks #Jay for taking the time to look into this!
You can achieve this by floating the divs within the container, you will also need to float their container, or they won't display correctly.
* {
box-sizing: border-box;
}
.container {
column-width: 100px;
column-gap: 12px;
float: left;
}
.container > div {
display: inline-block;
width: 100px;
border: 1px solid black;
padding: 20px;
float: left;
}
EDIT:
then instead of using column-gap, i would apply margin left to each of the divs inside the container. like so;
.container {
width: 100%;
float: left;
}
.container > div {
width: 100px;
border: 1px solid black;
padding: 20px;
float: left;
margin-left: 12px;
}
.container > div:first-child {
margin-left: 0;
}
EDIT:
If the height does not need to match - remove column-width from the container div. see https://jsfiddle.net/0sz6t3ft/1/

Children divs not being sized equally

I am trying to display a four grid with different items for my web, however now all children divs have the same size:
<div class="container">
<div class="grid4">
<input type="submit" name="input1" value="input1"/>
</div>
<div class="grid4">
<input type="submit" name="input2" value="input2"/>
</div>
<div class="grid4">
<input type="submit" name="input3" value="input3"/>
</div>
<div class="grid4 no-border">
<input type="submit" name="input4" value="input4"/>
</div>
</div>
CSS:
.container {
width: 100%;
margin: 30px 0 30px 0;
}
.grid4 {
width: 25%;
padding: 20px;
border-right: 2px solid rgba(40,40,40,0.8);
display: inline;
}
.no-border {
border: none;
}
I tested it in jsfiddle and they indeed have the same size:
http://jsfiddle.net/ME7k8/
However, you can clearly see that the last chil div is smaller:
Why?! Any help?
edit In case it is too small in the image:
elemento {
}
.grid4 {
width: 25%;
padding: 20px;
border-right: 2px solid rgba(40, 40, 40, 0.8);
display: inline;
}
div {
text-align: left;
}
body, div, td {
font-family: 'Noto Sans',Arial,Helvetica,sans-serif;
font-size: 12px;
color: #666;
}
Inherited from body
body {
text-align: center;
}
edit I checked again with the browser inspector and I can see that the first div is about 50% of the .container div. It has exactly the same css properties than the rest of the divs.
The 3 first divs are wider than the last due to:
1. They have the CSS display:inline (meaning their width gets effected by white-spaces, line breaks etc).
2. The last div has no border unlike the first 3.
Give them identical width
So what you need to do to make sure all 4 divs have the same width is removing all white-space between the submit buttons and their parent divs, and also add padding-right:22px; to the last div (if you want the 4 divs exactly identical wide).
jsFiddle demo.
I use your jdFiddle and put a blue background to see the difference, all divs have the same size, however, I declare a size for the container
.container {
width: 1200px;
background-color: tomato;
}
and re adjust the size of the divs with the grid4 attribute
.grid4 {
display: block;
float: left;
width: 20%;
padding: 2.3%;
border-right: 0.2% solid rgba(40,40,40,0.8);
display: inline;
background-color: blue;
}
when you put padding to each one (20px) that pixels are added to the "25%" of total size.. so this make it a bigger element, and probably that's the difference you couldn't see... with that on mind, may be you could solve your problem... Check This...
Your last element has no border, while the others probably do.
Borders take up space, as do margin and padding.
Check out the box model by pressing ctrl + shift + i in your browser and hovering over an Also,
http://www.w3schools.com/css/css_boxmodel.asp
From inside to outside, there is padding, borderin, margin, outline.
The first three add size to your "box model". Outline does not.
If you specify a width or height, any padding, border, or margin will make your element not that specified width or height anymore. Needless to say, this makes for all kinds of headaches
One solution around this is to use box-sizing: border-box;
This makes specified padding and border actually be your specified width or height. Margin will still add to the dimension, which makes sense if you think about it.
http://css-tricks.com/box-sizing/
Also be sure to take care of prefixes so that it works on all browsers.
You may not want to deal with this at this point, but check out the example in the last link, as well as caniuse.com.
If you don't want to handle cross browser support manually, there is a library to automatically post-process your CSS to add the appropriate prefixes. This uses the caniuse.com database so as long as you update this library, your post-processed css file will have the up to date prefixes without you having to worry about keeping up with browser versions or individual css feature deprecations.
https://github.com/ai/autoprefixer
article on auto prefixing
http://css-tricks.com/autoprefixer/

How can I force overflow: hidden to not use up my padding-right space

I have the following code:
<div style="width: 100px;
overflow: hidden;
border: 1px solid red;
background-color: #c0c0c0;
padding-right: 20px;
">
2222222222222222222222111111111111111111111111113333333333333333333</div>
(XHTML 1.0 transitional)
What happens is that the padding-right doesn't appear, it's occupied by the content, which means the overflow uses up the padding right space and only "cuts off" after the padding.
Is there any way to force the browser to overflow before the padding-right, which means my div will show with the padding right?
What I get is the first div in the following image, what i want is something like the 2nd div:
image
I have the same problem with the overflow:hidden; obeying all the padding rules, except for the right hand side. This solution works for browsers that support independent opacity.
I just changed my CSS from:
padding: 20px;
overflow: hidden;
to
padding: 20px 0 20px 20px;
border-right: solid 20px rgba(0, 0, 0, 0);
Having container divs works fine, but that effectively doubles the amount of divs on a page, which feels unnecessary.
Unfortunately, in your case this won't work so well, as you need a real border on the div.
Your best bet is to use a wrapping div and set the padding on that.
I had a similar problem that I solved by using clip instead of overflow. This allows you to specify the rectangular dimensions of the visible area of your div (W3C Recommendation). In this case, you should specify only the area within the padding to be visible.
This may not be a perfect solution for this exact case: as the div's border is outside the clipping area, that will become invisible too. I got around that by adding a wrapper div and setting the border on that, but since the inner div must be absolutely positioned for clip to apply, you would need to know and specify the height on the wrapper div.
<div style="border: 1px solid red;
height: 40px;">
<div style="position: absolute;
width: 100px;
background-color: #c0c0c0;
padding-right: 20px;
clip: rect(auto, 80px, auto, auto);">
2222222222222222222222111111111111111111111111113333333333333333333</div>
</div>
Wrap the div and apply padding to the parent
.c1 {
width: 200px;
border: 1px solid red;
background-color: #c0c0c0;
padding-right: 50px;
}
.c1 > .c1-inner {
overflow: hidden;
}
<div class="c1">
<div class="c1-inner">2222222222222222222222111111111111111111111111113333333333333333333
</div>
</div>
If you have a right-adjacent element to the one in question, put padding on its left. That way the content from the left element will flow up to but not past its margin, and the left padding on the right-adjacent element will create the desired separation. You can use this trick for a series of horizontal elements which may have content that needs to be cut off because it is too long.