Add padding without changing overall width - css

How can I add padding to an element without adding on top of the predefined width?
It's good to define the width of a column to make a clean grid for the layout; but also wants to add padding to the contents inside the column. Any way to specify that?

element {
-webkit-box-sizing: border-box; /* Safari/Chrome, other WebKit */
-moz-box-sizing: border-box; /* Firefox, other Gecko */
box-sizing: border-box; /* Opera/IE 8+ */
}

Use box-sizing, it makes padding inclusive:
https://developer.mozilla.org/en-US/docs/CSS/box-sizing
Example:
div {
box-sizing:border-box;
-moz-box-sizing:border-box; /* Firefox */
-webkit-box-sizing:border-box; /* Safari */
}
It's worth noting that this won't work on IE7.
For IE8, please see the top answer to this Q: box-sizing: border-box => for IE8?

Everytime you add padding to block element, the width of this element changes. This problem has many solutions. I usually set margin to first child element and set width: 100% for this element.
For example, we have:
<div id="main">
<div id="child">
This is content with margin
</div>
</div>
CSS style for these elements:
#main {
border: solid 1px red;
float: left;
width: 5em;
}
#child {
border: solid 1px blue;
float: left;
width: 100%;
margin: 0.5em;
}
This is a solution for any browser

It's an old thread, I know. But last time I had a complete black hole about making a DIV with a NOT set width and with paddings, so it will not blow up my 3-columns row and with CSS2. So I put one DIV with float left, on with right and between them a DIV with no float and no fixed width, but I wanted to have padding in it. How about that...
I gived up. :D But I put an inner DIV in the center one and give it width=90%. So far so good, a very simple and not great solution, but sometimes it helps to achieve the look you need. ;]
b.r.

Related

CSS display:inline-table = strange 1px margin right on div

i'm writing my little css framework but i got a strange problem, check this jsfiddle please: http://jsfiddle.net/76y8B/
as you can see the red div has 1px margin right but i setted all to margin:0;
Any help please?
Your making a calculation error. You've sized your div to 96% of the body. Say the body is 1000 pixels wide, that means the div is now 960 pixels. You then give it a padding of 2% on both left and right side, meaning 2% of 960 pixels, or 19.2 pixels on both ends. 960+19.2+19.2 = 998.4 pixels total width. That's where the minor gap comes from.
The only way to fix this without fixing other markup is to correct for the calculation origin of the padding, ie. set the paddings not to (100-96)/2 but ((100/96)-1)/2 or 2.08333%. The following thus solves the gap:
.heading {
padding: 13px 2.08333% 8px;
}
Alternatively you can use border-box to change how these values are calculated, see this other answer here.
Another solution is to set 100% width and a cooler box-sizing: border-box.
.heading {
/* new stuff */
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
-ms-box-sizing: border-box;
box-sizing: border-box;
width: 100%;
/* end of new stuff */
clear: both;
color: #FFFFFF;
line-height: 25px;
margin: 0;
min-height: 28px;
padding: 13px 2% 8px;
}
Running demo
Read more on Box-sizing, and on the differences between the W3C Box model and the Traditional Box Model:
Box models
In the W3C box model, the width of an element gives the width of the content of the box, excluding padding and border.
In the traditional box model, the width of an element gives the width between the borders of the box, including padding and border.
The element has the display property inline-table. Is the per design? That, in combination with the 2%+2%+96% logic is what is causing the margin, change it to inline-block and you’ll see.
display:inline-table in .row-fluid is causing problem.
Remove it or write display:block.
Updated fiddle here.

html - how to make a scroll with the width on auto?

I have a div with lots of content in it, and trying to set a width to be 100% of the parent element. This div also uses a padding, so I thought I should be setting the width to auto.
But for some reason it always expands past the parent width. I even have overflow set to scroll.
What I want is the div to have a scroll bar (only horizontal), and its width to fit the parent width.
Does anyone know how I can fix this?
100% width of its parent, with padding:
Given that the padding you mention is applied to the 100% wide element, the problem is within the box model that browsers use. If you apply 100% width and some padding, the element will get width + padding as its complete width, thus causing it to become too large. There are a few ways to solve this:
CSS3 introduces a new property called box-sizing, by setting it to border-box, the padding will be added within the given width of the element, instead of adding to the width causing the element to become "to big". (Notice the lack of support by older browsers).
I believe it would be possible to use left: 0; right: 0; instead of using width: 100%;. In that case you can add padding, without the element becoming to wide.
The second option in practice:
<!-- The markup -->
<div class="parent">
<div class="child">Child</div>
</div>​
/* The CSS */
.parent {
width: 200px;
height: 200px;
position: relative;
background-color: #666;
}
.child {
position: absolute;
left: 0;
right: 0;
padding: 10px;
background-color: #888;
}
​
Here is a working example of the second option: http://jsfiddle.net/mGLRD/
Horizontal scroll-bar:
To get a horizontal scroll-bar, you will have to look in to the overflow-x CSS-property. By setting it to scroll, you will see a disabled scrollbar when there is no content to scroll, so the scrollbar is always visible. Your other option is to set it to auto, where the scrollbar will become visible if needed (may vary between different browsers).
Try:
div#content {
width:auto;
padding:20px;
overflow-x:auto;
}
See my demo: http://jsfiddle.net/HRRsU/3/
box-sizing: border-box;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
http://www.w3schools.com/cssref/css3_pr_box-sizing.asp

CSS side by side layout

When I shrink the browser width past a certain point the spec div drops below the main div. I want to prevent this from happening. I thought perhaps I could make a div that holds both #main and #spec and set a min-width for it, but that does not seem to work.
#main {
clear: both;
width: 400px;
min-width: 400px;
float:left;
padding: 10px;
}
#spec{
padding: 4px;
float: left;
width: 270px;
}
I tested this out using min-width and it definitely works. Because the elements are floated they need to be cleared inside the container for it to work.
See the example here, http://jsfiddle.net/3TDNf/
Cheers
I am willing to bet you are running in to an issue with the CSS Box-Model.
In a nutshell, the box model for some reason, does not include the border or padding, which most people expect that it will (and in fact it used to, further confusing the situation)
I suggest adding the following rule to your CSS:
*{
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
box-sizing: border-box;
}
This will cause your web pages to use the border-box style of box model, which means everything except the margin will be counted in the element's width.
You said:
I could make a div that holds both #main and #spec and set a min-width
for it
Yet your posted css shows that you placed the min-width: 400px; on the #main div. Perhaps you need to move the min-width:400px; so that it applies to the div that contains both #main and #spec.

<input> in <div> takes up extra space on right

I have an input element inside a div element:
...
<div id="calculator-container">
<input type="text" />
</div>
....
In CSS I make the input width 100%:
#calculator-container {
border: 1px solid black;
background-color: lightgrey;
width: 200px;
padding: 10px;
}
#calculator-container input {
width: 100%;
}
I can't figure out why is there less free space on the right side of the input than on the left (please see the screenshot below). Maybe somebody can advise. Thanks.
Pointing out that on jsfiddle it looks fine but if you copy it locally it looks bad in both IE and Firefox. Here is the jsfiddle link just so you can copy the code: jsfiddle just to get the code
It’s because width means the width of the element’s content area. The <input>’s content area is surrounded by its padding and border.
http://jsfiddle.net/3f7RB/
If you set those to 0, the input no longer takes up more space than is available:
input {
width: 100%;
border-style: none;
padding: 0;
}
http://jsfiddle.net/3f7RB/1/
(Of course, form elements are often rendered a bit differently from regular elements, so different browsers may do different things.)
If you want padding on the <input>, you can either declare that as a percentage too:
input {
width: 96%;
border-style: none;
padding: 4px 2%;
}
http://jsfiddle.net/3f7RB/5/
Or use box-sizing (not supported in IE 6 or 7) so that width: 100% applies to the <input>’s content, padding and border combined:
input {
width: 100%;
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
box-sizing: border-box;
}
http://jsfiddle.net/3f7RB/6/
Because the input element gets width:100% which is 200px. this however doesnt take into account that it has a border of 2px, meaning it actually should be 196px.
try this:
http://jsfiddle.net/QLFrj/
#calculator-container input {
width: 196px;
}
Only problem is that it is no longer a percentage...
the reason why it's to right because of the border because it's to the width of input field means the width of input field is 100% + 2px. So, you can use box-sizing property got this:
Check this
http://jsfiddle.net/3f7RB/4/
OR
you can use outline property also . like this:
Check this
http://jsfiddle.net/3f7RB/7/
I've tried here and it works fine. Maybe another CSS statement is overriding some attributes of your div or input. You may try to inspect the elements with Firebug (on Firefox) or Google Chrome.
This happens because your input element wants to be 200px too. The width: 100% applies to the parent-element. In this case the #calculator-container.

CSS 100% height with padding/margin

With HTML/CSS, how can I make an element that has a width and/or height that is 100% of it's parent element and still has proper padding or margins?
By "proper" I mean that if my parent element is 200px tall and I specify height = 100% with padding = 5px I would expect that I should get a 190px high element with border = 5px on all sides, nicely centered in the parent element.
Now, I know that that's not how the standard box model specifies it should work (although I'd like to know why, exactly...), so the obvious answer doesn't work:
#myDiv {
width: 100%
height: 100%;
padding: 5px;
}
But it would seem to me that there must be SOME way of reliably producing this effect for a parent of arbitrary size. Does anyone know of a way of accomplishing this (seemingly simple) task?
Oh, and for the record I'm not terribly interested in IE compatibility so that should (hopefully) make things a bit easier.
EDIT: Since an example was asked for, here's the simplest one I can think of:
<html style="height: 100%">
<body style="height: 100%">
<div style="background-color: black; height: 100%; padding: 25px"></div>
</body>
</html>
The challenge is then to get the black box to show up with a 25 pixel padding on all edges without the page growing big enough to require scrollbars.
I learned how to do these sort of things reading "PRO HTML and CSS Design Patterns". The display:block is the default display value for the div, but I like to make it explicit. The container has to be the right type; position attribute is fixed, relative, or absolute.
.stretchedToMargin {
display: block;
position:absolute;
height:auto;
bottom:0;
top:0;
left:0;
right:0;
margin-top:20px;
margin-bottom:20px;
margin-right:80px;
margin-left:80px;
background-color: green;
}
<div class="stretchedToMargin">
Hello, world
</div>
Fiddle by Nooshu's comment
There is a new property in CSS3 that you can use to change the way the box model calculates width/height, it's called box-sizing.
By setting this property with the value "border-box" it makes whichever element you apply it to not stretch when you add a padding or border. If you define something with 100px width, and 10px padding, it will still be 100px wide.
box-sizing: border-box;
See here for browser support. It does not work for IE7 and lower, however, I believe that Dean Edward's IE7.js adds support for it. Enjoy :)
The solution is to NOT use height and width at all! Attach the inner box using top, left, right, bottom and then add margin.
.box {margin:8px; position:absolute; top:0; left:0; right:0; bottom:0}
<div class="box" style="background:black">
<div class="box" style="background:green">
<div class="box" style="background:lightblue">
This will show three nested boxes. Try resizing browser to see they remain nested properly.
</div>
</div>
</div>
The better way is with the calc() property. So, your case would look like:
#myDiv {
width: calc(100% - 10px);
height: calc(100% - 10px);
padding: 5px;
}
Simple, clean, no workarounds. Just make sure you don't forget the space between the values and the operator (eg (100%-5px) that will break the syntax. Enjoy!
According the w3c spec height refers to the height of the viewable area e.g. on a 1280x1024 pixel resolution monitor 100% height = 1024 pixels.
min-height refers to the total height of the page including content so on a page where the content is bigger than 1024px min-height:100% will stretch to include all of the content.
The other problem then is that padding and border are added to the height and width in most modern browsers except ie6(ie6 is actually quite logical but does not conform to the spec). This is called the box model. So if you specify
min-height: 100%;
padding: 5px;
It will actually give you 100% + 5px + 5px for the height. To get around this you need a wrapper container.
<style>
.FullHeight {
height: auto !important; /* ie 6 will ignore this */
height: 100%; /* ie 6 will use this instead of min-height */
min-height: 100%; /* ie 6 will ignore this */
}
.Padded {
padding: 5px;
}
</style>
<div class="FullHeight">
<div class="Padded">
Hello i am padded.
</div
</div>
1. Full height with padding
body {
margin: 0;
}
.container {
min-height: 100vh;
padding: 50px;
box-sizing: border-box;
background: silver;
}
<div class="container">Hello world.</div>
2. Full height with margin
body {
margin: 0;
}
.container {
min-height: calc(100vh - 100px);
margin: 50px;
background: silver;
}
<div class="container">Hello world.</div>
3. Full height with border
body {
margin: 0;
}
.container {
min-height: 100vh;
border: 50px solid pink;
box-sizing: border-box;
background: silver;
}
<div class="container">Hello world.</div>
This is one of the outright idiocies of CSS - I have yet to understand the reasoning (if someone knows, pls. explain).
100% means 100% of the container height - to which any margins, borders and padding are added. So it is effectively impossible to get a container which fills it's parent and which has a margin, border, or padding.
Note also, setting height is notoriously inconsistent between browsers, too.
Another thing I've learned since I posted this is that the percentage is relative the container's length, that is, it's width, making a percentage even more worthless for height.
Nowadays, the vh and vw viewport units are more useful, but still not especially useful for anything other than the top-level containers.
Another solution is to use display:table which has a different box model behaviour.
You can set a height and width to the parent and add padding without expanding it. The child has 100% height and width minus the paddings.
JSBIN
Another option would be to use box-sizing propperty. Only problem with both would be they dont work in IE7.
Another solution: You can use percentage units for margins as well as sizes. For example:
.fullWidthPlusMargin {
width: 98%;
margin: 1%;
}
The main issue here is that the margins will increase/decrease slightly with the size of the parent element. Presumably the functionality you would prefer is for the margins to stay constant and the child element to grow/shrink to fill changes in spacing. So, depending on how tight you need your display to be, that could be problematic. (I'd also go for a smaller margin, like 0.3%).
A solution with flexbox (working on IE11): (or view on jsfiddle)
<html>
<style>
html, body {
height: 100%; /* fix for IE11, not needed for chrome/ff */
margin: 0; /* CSS-reset for chrome */
}
</style>
<body style="display: flex;">
<div style="background-color: black; flex: 1; margin: 25px;"></div>
</body>
</html>
(The CSS-reset is not necessarily important for the actual problem.)
The important part is flex: 1 (In combination with display: flex at the parent). Funnily enough, the most plausible explanation I know for how the Flex property works comes from a react-native documentation, so I refer to it anyway:
(...) flex: 1, which tells a component to fill all available space, shared evenly amongst other components with the same parent
To add -webkit and -moz would be more appropriate
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
Frank's example confused me a bit - it didn't work in my case because I didn't understand positioning well enough yet. It's important to note that the parent container element needs to have a non-static position (he mentioned this but I overlooked it, and it wasn't in his example).
Here's an example where the child - given padding and a border - uses absolute positioning to fill the parent 100%. The parent uses relative positioning in order to provide a point of reference for the child's position while remaining in the normal flow - the next element "more-content" is not affected:
#box {
position: relative;
height: 300px;
width: 600px;
}
#box p {
position: absolute;
border-style: dashed;
padding: 1em;
top: 0;
right: 0;
bottom: 0;
left: 0;
}
<div id="box">
<p>100% height and width!</p>
</div>
<div id="more-content">
</div>
A useful link for quickly learning CSS positioning
This is the default behavior of display: block The fastest way that you can fix it in 2020 is to set display: 'flex' of parent element and padding e.g. 20px then all its children will have 100% height relative to its height.
Border around div, rather than page body margin
Another solution - I just wanted a simple border around the edge of my page, and I wanted 100% height when the content was smaller than that.
Border-box didn't work, and the fixed positioning seemed wrong for such a simple need.
I ended up adding a border to my container, instead of relying on the margin of the body of the page - it looks like this :
body, html {
height: 100%;
margin: 0;
}
.container {
width: 100%;
min-height: 100%;
border: 8px solid #564333;
}
<style type="text/css">
.stretchedToMargin {
position:absolute;
width:100%;
height:100%;
}
</style>

Resources