So I came across a strange issue today, it only happens in Chrome.
Have a look at the fiddle:
https://jsfiddle.net/m1npLfcm/1/
<div class="table">
<div class="row">
<div class="cell">
<div class="content">
</div>
</div>
</div>
</div>
There is some basic table layout made of DIVs, a table, a row and a cell. All of them have 100% width and height. Inside the cell there's a regular DIV. It has 100% width and height and also some padding.
As we all know default box-sizing: content-box for div would push the boundaries by that padding. So I've made it box-sizing: border-box as I usually do and now I have this strange behavior.
Seems like in this situation, box-sizing: content-box is only applied to the width and height works just fine by default without pushing the boundaries. However if I add box-sizing: border-box - the width gets to work fine but the height gets total vertical padding subtracted from it as if previously content-box acted as it should have been.
Just what the hell is this? It only happens in Chrome and I'm totally confused. Has anyone seen this before and how this should be treated? Brief googling didn't help as this issue is quite hard to describe in a few words.
If you see the padding of 20px is the height you are talking about, since there is no elements or content inside the cell there browser only puts the padding.
In your fiddle I played around with the padding of the content and manage to fix the height with the size(red) with the value I want.
I hope that helps you.
Unfortunately an additional div wrapped around .content is required with a class like .inner that will serve specifically as a padding around content.
In this codepen I've changed a bit the CSS of your fiddle:
set box-sizing: border-box to all elements, as it's essential
replaced .cell with .inner (supported only by evergreen browsers, in IE <= 10 the .cell wrapper should remain)
removed the excessive width: 100% for block-level elements
The border/padding is applied correctly as long as the red background of the .table is covered by the .inner
Related
I simply can't figure this out: I have a div that is centered on screen with a width of 60%. Inside this div I have 3 more divs that float left with the width of 33% and have a gray bg color. The divs are filled with text and one image per div. Each div should now take 1/3 space inside the "maindiv". This works fine but as soon as I give my 3 "contentdivs" a padding so the text gets seperated a bit the third div wanders below the others. I also want a margin around my 3 divs so there is a gap between all the divs. But this only works if I give the divs a width of like 31%. As soon as I shrink my browser though, the third one pops up below the others again.
How it looks now:
How it looks with a width of 33.33%
How can fix this? I mean I set the divs to a relative width by setting the size in %. So the divs should just shrink as soon as I shrink my browser window. I tried to surround all the divs by other divs and messed around with margins and paddings but it just won't work.
Most likely it’s box model’s fault. Paddings, margins and borders can be added together in different ways. Add box-sizing:border-box to the container and its elements. Most certainly this brings about what you intended to do, and width:33.3333% wil work out as expected.
Adding margin still breaks the item? There’s another great thing called calc(). Assumed you have a margin of 8px, that’s just a few pixels too much. With calc(), you can subtract the additional margin like this:
.item{ width:calc(33.3333vw - 8px); }
Note that there must be whitespace around the minus. Try it and include your margin.
Apply box-sizing: border-box to all related elements (or the entire document, as Bootstrap does). http://developer.mozilla.org/en-US/docs/Web/CSS/box-sizing
Then, rather than margin, use padding for the outer spacing. This eliminates the need to do mental math altogether.
div {
box-sizing: border-box;
}
.one-third, .inner, .full-width {
padding: 8px;
}
.one-third {
float: left;
width: 33.333%;
}
.inner {
background-color: pink;
}
<div class="full-width">
<div class="inner">Full-width div</div>
</div>
<div class="one-third">
<div class="inner">Content</div>
</div>
<div class="one-third">
<div class="inner">Content</div>
</div>
<div class="one-third">
<div class="inner">Content</div>
</div>
Fiddle demo
Your best bet would be to get the three columns and margins to equal 100%. This is fairly easy if you know you are only having three columns:
.item {
width:32%;
margin-left:2%;
}
.item:first-child {
margin-left:0;
}
As long as there is only three it will always add up to 100% as you are overriding the first .item. If you don't override the first item then you will have a space before your columns and the last column won't fit. Mixing pixels and percentages will give you issues in a grid (unless they're paddings and you are using box-sizing). Margin is not included in the box-sizing as it is not part of the main box model.
I came across a strange issue when testing a site in FF.
The situation is this:
box-sizing: border-box is applied to everything.
I have a floated wrapper <div>, with a fixed height.
Inside the wrapper is an <img> with height: 100%.
When I add padding to the wrapper, I expect the wrapper to remain the same height, and the image to remain the same aspect ratio, but shrink to fit the height minus the padding. The width of the wrapper should change to match the new width of the image, plus the padding.
This behaves as expected in Chrome and IE on both OSX and Win7, but in FF the width of the wrapper seems to remain the same as if no padding was added.
Am I missing something, or is this a bug in the implementation of box-sizing in Firefox?
This fiddle demonstrates the issue:
http://jsfiddle.net/3j43Y/1/
Screenshots:
First image is the result in Firefox, the second one is Chrome.
This appears to be a bug, but it's not calculating the width as if no padding is applied. It's calculating the width as if the content (the <img> tag) has the width it would have were there no padding applied. It's then adding padding on top of this incorrectly calculated content width.
i.e. With no padding, the <img> element has a width of 167px. If you then add padding it should shrink (because of the height constraint) and .wrapper's width should now be the width of the shrunken <img> width plus the padding. Instead, (in FF at least) .wrapper's width is the width of the unshrunken <img> width plus the padding (167 + 16).
At least, that's what I'm seeing.
Also, it looks like you can see the same in Chrome (35.0.1916.114) if you toggle the padding rule on/off in dev tools. Initially Chrome gets it right, but then you see the same erroneous behaviour after toggling padding.
#BYossarian's answer is correct. The answer below is a possible workaround when coming across the issue.
Since .wrapper is set to a specific height, we can add the padding to the image and get the desired effect we are looking for.
Demo:
<style type="text/css">
* {
-moz-box-sizing: border-box;
box-sizing: border-box;
}
.wrapper {
float: left;
height: 100px;
background: #99ccff;
}
.wrapper img {
height: 100%;
padding: 8px;
}
</style>
<div class="wrapper">
<img src="http://placehold.it/250x150" alt="">
</div>
Another way to analyze, it is also necessary to be careful with the statement of the doctype of the document.
If you have an old doctype,
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
Firefox will not consider box-sizing: border-box;
For html 5,
it is necessary to declare the doctype as follows:
<!doctype html>
it will fix Firefox, it will take the box-sizing correctly.
On my page I have several elements defined to be 100% of the window's width, however I'm getting unexpected results from some of the divs. For example, if I use console.log to print out the window.innerWidth, I get a value of 1541, but when inspecting the html, body, and a few other divs that are set to width=100%, their calculated widths are 1526.
Even stranger, I'll begin to see a horizontal scroll bar before the content begins to be too wide for the browser and some of the elements span past the scrollbar and some do not.
A very strange issue indeed, please have a look at the site if anyone can point me in the right direction that would be wonderful:
http://www.newnoisegroup.org
div elements (and other display:block elements) default to stretching to the width of their container anyway, so setting width:100% for them is usually unnecessary anyway.
However if you do set them to width:100%, you can get issues like this because width:100% is not the same as stretch to full width.
The difference is that in the standard box model, the width of an element is the inner width; the border and margin are added on outside of box.
Therefore, if you have a box with width:100%and, for example,border:1pxandmargin:5px`, you will get 100% width plus an additional 12 pixels. This will clearly give you unwanted scroll bars as the box is wider than its container.
There are two solutions here:
Use width:auto or no width setting at all rather than width:100%.
Use box-sizing:border-box to switch the box model so that the border and margin are inside the width, so that width:100% will then produce a box that is actually 100% of the width of its container.
Hope that helps.
using box-sizing can fix width issues.
box-sizing: border-box;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
-o-box-sizing: border-box;
-ms-box-sizing: border-box;
It often resolves issues with width and margin/padding
I'm using box-sizing: border-box to everything on my page. However, when I add padding to the container element in my 960.gs grid, it bumps the second grid to the next line. It does, however work as expected if I add it to individual grid classes.
<header role="banner" id="header">
<div class="container container_12">
<div class="grid_4">
logo here
</div>
<div class="grid_8">
tagline here
</div>
</div> </header>
Adding 10px of padding to .conatiner wraps grid_8 to the next line. Adding 10px to both grid_4 and grid_8 doesn't (box-sizing works). Any help is appreciated.
I believe it is working correctly.
box-sizing: border-box overrides the default behaviour where adding padding and borders to an (non-absolutely sized) element increases that element's total size. With border-box, all elements behave as if they've been absolutely sized with respect to padding: adding padding increases the internal space between the element's borders and its contents, but does not increase the total size of the element.
So what's happening is that by adding padding: 10px to .container, you decrease the amount of horizontal internal space available for .container's contents. And since .container's width does not grow (as specified by the box-sizing rule), and the child elements do not shrink, the second child must wrap, since the combined width of both child elements is now greater than the available internal space of .container.
Adding padding to the .grid_ elements "works" (your definition of "works" assumed to be that .container's children fit in one row and do not wrap) because according to the box-sizing rule, those elements should not gain width in addition to their set width (set by 960 gs) when they are given padding. The result of the added padding is instead to increase the space between the .grid_ elements' borders and their contents ("logo here" / "tagline here"), and to decrease the .grid_ elements' "internal width".
Basically, box-sizing: border-box means that padding (and borders!) gets added internally, rather than externally, and your example demonstrates this behaviour consistently.
Here is more info on box-sizing values, plus some demos.
i am wondering why the textarea refuses to stay aligned with the containing div?
<!-- the textarea pokes out-->
<div style="border:1px solid #ccc; width:300px">
<textarea style="width:100%"></textarea>
</div>
It is causing me difficulty in ensuring alignment of elements
By default, a <textarea> element is rendered with a border around it. The problem with this is that when you set the width property on an element, you're only setting the content width, not the total width. The total width of the element is (width + border + padding + margin) so when you set the width on the <textarea> to be 100% it sets the content width to 300px but the total width is that 300px plus the default borders, which causes it to exceed the 300px width of the <div>.
You'll could accommodate these borders in the <div> using padding/margins, but a better solution would be to set the box-sizing property on the <textarea> to border-box to force the width property to define the total width of everything up to and including the border of the element.
You'll need to do a bit of research on that property because it's declared differently in all browsers (e.g. -moz-box-sizing, -ms-box-sizing, -webkit-box-sizing, etc.). Here is the QuirksMode page on box-sizing for you to look through.
The box-sizing fix works for Firefox, but I haven't tested it in other browsers. It's possible that some of them, particularly when in quirks/legacy mode, could also apply a margin to the element. If this is the case, then all you would need to do would be to remove the margins with CSS (AFAIK, there isn't a widely supported option for box-sizing that extends to margins - only ones for content, padding, and border).
I'd suggest being specific with this fix, and only removing the left/right margins (i.e. margin-left: 0; margin-right: 0;) rather than removing margins entirely (i.e. margin: 0;) to preserve any top/bottom margins if they exist (and if you want to keep them). I know Firefox applies a 1px margin to the top/bottom, and other browsers might as well.
I tried that in Firefox, Chrome and IE, and they all show it properly. I suspect that you DIV is inside of another container and that's causing the problem.
Please add a part of your code.
The textarea may have a margin being applied to it. Try this:
<div style="border:1px solid #ccc; width:300px">
<textarea style="width:100%; margin: 0;"></textarea>
</div>
<div style="border:1px solid #ccc; width:300px">
<textarea style="width:100%"></textarea>
</div>
Tested working on Firefox 3.6.10, Internet Explorer 8 and Google Chrome.
But, maybe instead of enclosing it in a DIV, you can also try this:
<textarea style="border:1px solid #ccc; width:300px"></textarea>
Which about has the same looks as your original code.