Padding changes width inside table - html

I have a table that has fixed width, and inside the table I need to have some inputs(text) that has the same width of the table, but I don't want the text of the inputs to be at left:0, I want them to have some padding from the left. But when I put the padding to those inputs the width changes to more than 100%.
Here the HTML:
<table cellspacing="25">
<tr>
<td><input type="text" placeholder="lalala"></td>
</tr>
</table>
And this is the CSS.
table {
background-color: red;
width: 300px;
}
table input {
width: 100%;
padding-left: 10px;
}
How can I ensure that the width of the input element is 100% the width of the table cell?
Check the fiddle

add this css rule to your input:
box-sizing: border-box;
The box-sizing property is used to tell the browser what the sizing
properties (width and height) should include.
Should they include the border-box? Or just the content-box.
Here is a snippet:
table {
background-color: red;
width: 300px;
}
table input {
width: 100%;
padding-left: 10px;
box-sizing: border-box;
}
<table cellspacing="25">
<tr>
<td><input type="text" placeholder="lalala"></td>
</tr>
</table>

You can use box-sizing: border-box; (support) in which "The width and height properties include the padding and border, but not the margin." in your CSS for the specified elements as #1l13v has done in his answer:
table input {
box-sizing: border-box;
}
Or you can use the calc function (support):
table input {
width: calc( 100% - 10px );
}

Another option would be to calculate the width and padding of the input with percentages. If the sum of the content, border, margin, and padding of the element is 100% then it should fit how you would like. See the box-model concept in css: http://www.w3schools.com/css/css_boxmodel.asp
All HTML elements can be considered as boxes. In CSS, the term "box
model" is used when talking about design and layout.
The CSS box model is essentially a box that wraps around HTML
elements, and it consists of: margins, borders, padding, and the
actual content.
The box model allows us to add a border around elements, and to define
space between elements.
For example, if you want 10% padding on the left then the width should be 90%.
See this fiddle: http://jsfiddle.net/3nk07y1x/1/
CSS:
table {
background-color: red;
width: 300px;
}
table input {
width: 90%;
padding-left: 10%;
}

The width of the table will be the width plus the padding. Try subtracting some percentage points from the width like this:
table input {
width: 90%;
padding-left: 1em;
}
I would also change pixels to ems, because these are a little bit more stable on different screen resolutions.

Related

The input text element flow out of the container element, when setting the width to 100% [duplicate]

This question already has answers here:
How to make an element width: 100% minus padding?
(15 answers)
Closed 1 year ago.
Now im having an input text element which be warpped by a div container (form-group)
And i set the width to the input text element become 100% (width: 100%). And i expect that the input text it will cover the entire width of the form-group div element. And the result is kinda weird to me. The input text, it likes it flow out of the form-group element, like the this picture here:
In this picture, im currently hover the form-group element, and you can see the orange part, is the margin of the it, but you can see, the input text element, the part i highlighed is like overlaying the margin of the form-group element, which proved that the input text element is flow out of the container element of it, which is the form-group element. And that's weird, at least to me, because I set the width to 100%, and so i think it should be cover the container element of it. Please help me to understand this.
I know i can use the overflow property to fix but, i want to know why this is happening, so hopefully, someone can help me with this, thank you so much.
.form-container {
background-color: black;
padding: 20px;
}
.form-group {
width: 50%;
font-size: 1.5rem;
background-color: red;
margin: 3rem auto;
display: block;
}
input {
padding: 1.5rem 2rem;
border-radius: 2px;
border: none;
outline: none;
width: 100%;
color: var(--primary-color);
}
<form action="#" class="form-container">
<div class="form-group">
<input type="text" placeholder="Enter text...">
</div>
</form>
This happens because by default the box-sizing property is content-box.
When you add padding to the input element, the input element size remains equal to the size of form-group div.
But, this increases the overall width of the input element and extends it outside as the padding adds up to the total width. It looks like the actual width of the input element has increased but actually just the padding is adding.
You can change this if you wish to, by changing the box-sizing to border-box. This way the padding gets added to the input element by compromising the actual size of the input element.
input {
box-sizing: border-box;
padding: 1.5rem 2rem;
border-radius: 2px;
border: none;
outline: none;
width: 100%;
color: var(--primary-color);
}
Also, after adding border-box, you can try adding some height to the form-group div to visualize their comparative heights.
Use this developer tool on your browser to help you see the width, padding and margins.
You are coming up against box-sizing.
The input has quite a noticeable padding added to it (3rem horizontally in all). While the basic element takes up the width of its parent on the width: 100% setting, the box-sizing is set to content by default in CSS. This means any padding (and borders) is outside the basic size.
Changing the box-sizing to border-box for the input means that the padding is included within the overall size so you get the width you expect - in total 100% of the parent:
input {
padding: 1.5rem 2rem;
border-radius: 2px;
border: none;
outline: none;
width: 100%;
color: var(--primary-color);
box-sizing: border-box; /* ADD THIS */
}
In html every elements have default padding and margin property..we overlapped this values.
use following code..to avoid these kind of issues.
* {
padding: 0px;
margin:0px;
box-sizing:border-box;
}

Padding overrides height of the element with box-sizing: border-box

In snippet below padding-top overrides the height and max-height properties of container:
I want this <div> to be 10px high, but its 100px because of padding-top
as far as I understand this should be solved by box-sizing: border-box but this doesn't help
w3schools - border-box: the width and height properties (and min/max properties)
includes content, padding and border, but not the margin
.padding-test {
background: linear-gradient(109deg, #3adffd, #00abfb);
outline: 1px solid #3b3c6d;
width: 100%;
padding-top: 100px;
max-height: 10px;
height: 10px;
box-sizing: border-box;
}
<div class='padding-test'></div>
Can someone explain why is this happening and how to fix this?
Same happens for width and padding-left
UPD: I faced this issue when tried to change max height for box sized by aspect-ratio approach. I solved initial issue by setting parent size, but I still want to understand how border-box works with the padding - does it shrinks only content? is this correct behavior? is there any solution for this exact situation - can I override padding somehow?
I had run into the same doubt. According to MDN:
border-box
The width and height properties include the content, padding, and border, but do not include the margin. Note that padding and border will be inside of the box. For example, .box {width: 350px; border: 10px solid black;} renders a box that is 350px wide, with the area for content being 330px wide. The content box can't be negative and is floored to 0, making it impossible to use border-box to make the element disappear.
so box-sizing: border-box doesn't mean you can set the "border box" directly, but only affects how "content box" is calculated, which cannot be negative.
And my solution is: avoid the paddings, use a height-holding div or ::before pseudo element with designated height instead. (may also need overflow: hidden.) For example:
.padding-test {
height: 10px;
box-sizing: border-box;
overflow: hidden;
}
.padding-test::before {
height: 100px;
content: '';
display: block;
}

Percentage padding is not adding up total height correctly

So I have a page with html, header, body, div tags etc. For the CSS, I have:
* {
margin: 0;
padding: 0;
}
html {
width: 100%;
height: 100%;
}
body {
width: 98%;
height: 98%;
padding: 1%;
}
My issue is there's a scrollbar on the right side of the browser. Meaning the height is too high?
The html is set to 100% height and width. The body has a 1% padding which adds 1% top, right, bottom and left, so that's width - 2 = 98 and height - 2 = 98.
So padding 1% height 98%, and width 98%. How am I getting a scrollbar?
It's not working as expected because the percentage-based padding is relative to the width of the element. If you resize the browser so that the height is greater than the width, you will notice that the scrollbar goes away (which is because the padding is relative to the width).
According to the spec:
8 Box model - 8.4 Padding properties:
The percentage is calculated with respect to the width of the generated box's containing block, even for 'padding-top' and 'padding-bottom'. If the containing block's width depends on this element, then the resulting layout is undefined in CSS 2.1.
One possible work-around is to use viewport-percentage units such as vw in order to make the percentage relative to the width:
body {
width: 98%;
height: 98%;
padding: 1vh 1vw;
}
You could also add box-sizing: border-box to include the padding in the element's dimensions:
body {
width: 100%;
height: 100%;
padding: 1%;
box-sizing: border-box;
}
In CSS, percentage margin and padding is relative to the width of the container, as Josh Crozier has already explained that in his answer.
I suggest to set the percentage padding on the <html> element, the root of the document, plus box-sizing: border-box; together it gives you the equal space around.
border-box Length and percentages values for width and height (and respective min/max properties) on this element determine the
border box of the element. That is, any padding or border specified on
the element is laid out and drawn inside this specified width and
height. The content width and height are calculated by subtracting the
border and padding widths of the respective sides from the specified
width and height properties. -W3C
html {
background: silver;
box-sizing: border-box;
height: 100%;
padding: 5%;
}
body {
background: pink;
height: 100%;
margin: 0;
}

Input element with padding and percentage width exceeds parent div

I have this:
<div class="wrapper">
<input type="text"/>
</div>
div{
border: 1px solid red;
width: 300px;
}
input{
width: 100%;
padding: 10px;
}
I need the input to be 100% of the parent div, but also I need this input to have 10px padding. Results can be seen here: http://jsfiddle.net/pdJYF/
How can I achieve this?
Add box-sizing to your input field:
input{
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
box-sizing: border-box;
width: 100%;
padding: 10px;
}
Example Fiddle
Browser Compatibility
The underlying "problem" is the box model of HTML/CSS. As you can see in the illustration of the respective MDN article each element's box has 4 different areas: margin box, border box, padding box and content box.
When you assign measures (width or height) to the element, this is applied to one of these areas. If the area is, e.g., the content box, then for the total size of the element margin, border and padding is added. So you wont set the total dimensions of the box, but one of its contained boxes.
The CSS property box-sizing tells the browser, which box to use, when calculating the element's dimensions. The default value is content-box. So in the above example values for margin, border and padding get added and hence the element is too big. By setting the box model to border-box, only the margin gets added to the dimensions (which is zero here) and the elements fits.
Why you don't put the padding in percentage too:
input{
width: 94%;
padding: 0 3%;
border:0;
}
You must decrease 2x padding from left and right, and decrease 2x for any pixel you want use like this and insert your input's width.
For example: 20px (paddings left & right) + 2px (borders left & Right )= 22px
300px - 22px = 278px
div { border: 1px solid red; width:300px; }
input { width: 278px;padding: 10px; }

Fluid CSS layout and Borders

In designing a fluid layout, how do you use borders without ruining the layout.
More specifically, I have a HTML widget which consists of five divs. I would like the five divs to take up all the room in the containing element. I would also like to have a 1px border around each.
I tried:
.box { float: left; height: 100%; width: 100%; border: 1px solid red; }
This doesn't work: there will be an extra 10px in width causing the boxes to wrap. Reducing the width percentage doesn't work as it will not take up the correct amount of space and for certain page sizes, will still wrap.
Whats the proper way to manage the interaction between these elements?
See this article.
Basically, in the "traditional" CSS box model, the width of a box element only specifies the width of the content of the box, excluding its border (and padding).
In CSS3, you can switch to a different box model as follows:
box-sizing: border-box;
Browser-specific implementations of this are:
-moz-box-sizing: border-box; // for Mozilla
-webkit-box-sizing: border-box; // for WebKit
-ms-box-sizing: border-box; // for IE8
This will cause the box sizes to include the element's border and padding. So you can now specify
.box {
box-sizing: border-box;
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
-ms-box-sizing: border-box;
width:20%;
border:1px solid red;
float:left
}
and have the five divs take up all the width of the containing element without wrapping.
Note that this is not supported by older browsers. For these, you'll have to wrap each box into a second box, as per other responses on this page.
Only put width: 100% on the outermost div, and don't put a border on it. If you do this, then the inner boxes will fill the space (assuming you haven't floated them or anything) since they're block elements, and you won't have to worry about borders adding to the total size.
If you really need the appearance of five solid single pixel nested borders, you can do something like this (with properly semantic names, hopefully):
<div class="one">
<div class="two">
<div class="three">
etc.
</div>
</div>
</div>
<style>
.one {
width: 100%;
}
.two {
border: 1px solid red;
padding: 1px;
background: red;
}
.three {
border: 1px solid red;
background: white;
}
</style>
As you can see, you can fake the second border using padding and background colors on the second div (might even cut down on the total number of divs by doing this; just remember you can't pad the outmost div without screwing up your width).
Oh boy, I almost hate to mention this, but there is a very easy way to do this in a horizontal bar. It isn't "pixel perfect" except at your minimum width, but is not discernible to the naked eye.
Divide the container div by the number of items. Let's say, you have six nav items with a white border (this is especially good for numbers that don't divide into 100 because it won't be perfect in any case).
Set your total width for each left-floated child div to the correct fraction (using % for left or right margin or padding) so that they equal # 100%. Go ahead and put a 1px border-right on the child divs. For the last div at the right end, either make a second class with no border or just use style='border:none'.
Then, at your minimum width, slowly drop the width of each child div until they fit.
Here is a bit of code from an old page of mine using this method for a liquid page with minimum width of 960px (958 px and a 1px border on each side):
.navitem {
width: 16.57%;
height: 35px;
float: left;
text-align: center;
font: 1em/35px arial,sans-serif;
border-right: 1px solid #eee;
margin: 0 auto 0 auto;
padding: 0;
}
I think it actually is as close to pixel perfect as you can get at minimum width, and at higher widths although the right-hand div is maybe 4 px wider than the others, you can't tell by looking at it. (Obviously, this wouldn't work if you need a right border on the right-most div, since you'd see a few pixels of background.)
This will get you fairly close but not 100% of the way (pun intended). To give an element 100% height it needs to know "100% of what?". All parent elements must also be given 100% height and this includes the body. Or as the W3C put it: "If the height of the containing block is not specified explicitly (i.e., it depends on content height), and this element is not absolutely positioned, the value computes to 'auto'." As you can see we also need to give the body "position: absolute;" for the height to be honored. This example also divides the width into five equal columns with borders (and some padding and margin just for fun):
<style>
body {
width: 100%;
height: 100%;
margin: 0;
position: absolute;
/* overflow: hidden; */
}
div.section {
float: left;
width: 19.95%;
height: 100%;
}
div.column {
height: 100%;
border: 1px solid blue;
margin: 1em;
padding: 2em;
}
</style>
<div class="section"><div class="column">one</div></div>
<div class="section"><div class="column">two</div></div>
<div class="section"><div class="column">three</div></div>
<div class="section"><div class="column">four</div></div>
<div class="section"><div class="column">five</div></div>
As you can see when you test it we have no problem with the witdh. This is because the "sections" that divide the width have no padding, margin or borders. Thus the width we set will be the width they occupy on screen. Now, this is not strictly true in practice. I have actually set the widths 19.95% and not the expected 20%. Problem is that some browsers (IE for one) have a rounding error when adding up percentages and the more subdivisions to add up the greater the error.
Where this method obviously fails is when it comes to the height. Unlike "width: auto;", which will make the div occupy the available horizontal space, "height: auto;" will only make the div as tall as its content. You have to specify "height: 100%;" to get the div to fill the height of the window but alas, when adding margin, padding and borders, the rendered height of the div becomes greater than the viewport, resulting in a vertical scrollbar.
Here I can only really see two choices; Either 1) accept that the divs don't quite fill the window height and set their height to maybe 80% or 2) Skip the bottom border and set the body to "overflow: hidden;", which will crop off the parts of the divs that protrude beyond the edge of the window.
Finally, of course you could also make use of some simple scripting to achieve what you're after. Shouldn't be very complicated at all - but that's a question with another tag... Happy coding!