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

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.

Related

CSS - 100%px fixes my issue?

I have a question on something weird that is rendering on the latest IE and Chrome browsers. I have a div that is supposed to span 100% of a parent. So clumsily, I gave it - width: 100%px; as a CSS property. Here is my entire item:
.loc_vendiv{
position: relative;
margin-top: 5px;
left: 0px;
width: 100%px;
height: 120px;
border: 1px solid #333;
background-color: #fff;
}
The weird thing - that worked perfectly. So much so, that I just noticed today that this was wrong. Not wanting an ugly style sheet, I removed the px from the end. And... the div was two pixels too wide. Any explanation as to why this is happening? Here is the parent div:
#loc_catlist{
position: absolute;
width: 612px;
height: 720px;
top: 50px;
left: 0px;
background-color: #eee;
overflow-y: auto;
overflow-x: hidden;
}
I'm mildly annoyed, as the bad code works, yet the correct code doesn't do what I want. I don't think I can leave it, though. I don't like little hiccups like this...
It's because of your border.
Try adding :
box-sizing: border-box;
to your .loc_vendiv class, it will take the border in account.
Browsers usually ignore invalid css rules like width: 100%px; which means that to get the style you had with the mistake. you only have to remove the width rule.
2px too wide is likely caused because you have a width of 100% in addition to a border of 1px (all around adds up to 2px width).
A fix can be found here from "Paul Irish" about
box-sizing
what happens is that when the width value is wrong (100%px;) this part of the CSS is simply ignored by the browser. If this part of the css was deleted, the result would be the same.
About the 2 extra pixels, this happens because of the border set to the div.loc_vendiv.
The width of div.loc_vendiv is equal to the width of div#loc_catlist and to this is added the border value (1px for the left border and 1px for the right border = 2px).
Remember that the border width is added to the size of the object while the padding creates an internal space.

Why is the padding calculated differently between <a> and <button> elements?

Why exactly is the padding calculated differently between a and button elements?
HTML
<button type="button">CLICK</button>
LINK
CSS
button {
padding: 10px;
height: 30px;
border: 0;
background: #ccc;
line-height: 30px;
}
a {
display: inline-block;
padding: 10px;
height: 30px;
background: #ccc;
line-height: 30px;
}
The default box-sizing value for buttons in Chrome (and Firefox) is border-box:
DEMO
I.e. the total height, including padding (and border and margin), of the element is 30px, not 50px like for the link. You can fix this by setting
box-sizing: content-box;
explicitly.
DEMO
More info about the box model.
Why the border-box is the default value I cannot say. I haven't found a specification for it. Chrome, Firefox and Safari seem to do this (didn't test other browsers).
<a href...>
Links never have a set-height, if you inspect the html, you can see that; what is really done is giving it a line-height and padding. when you write height: 30px, it is useless.
With respect to that, you are defining a height for the <button>, which is why it does not look the same as how you styled your link
Here is a fiddle to show how to make them the same, by removing the set-height of the <button>

Reset a block element's width

I have a problem using a given CSS file I don't want to change. In this file there is a format for inputs:
input {
display:inline-block;
width:60%;
}
Now I want to use an additional CSS file and change this formatting to a normal block element width full width:
input {
display:block !important;
width:auto !important;
}
Unfortunately, this doesn't work. Unlike normal block elements, the input does not take all the available horizontal space with this setting. It is only as long as it would be as inline element. Additionally, I cannot use width:100%; due to padding, borders and margin. In my desperation I already tried something like width:none;, but I couldn't find a way to reset the width to a block element's default value.
I really hope that somebody can help me. Thank you in advance.
You must use width: 100%, so my answer shows how to fix the problems you're having with it.
https://developer.mozilla.org/en/CSS/box-sizing
input {
width: 100%;
margin: 0;
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
box-sizing: border-box;
}
If margin is required, then wrap the input in another element and apply the margin to that.

How to force Firefox to render textarea padding the same as in a div?

I'm attempting to provide a consistent width per line in pixels inside of a textarea across IE8, Firefox and Safari, so that text content wraps lines as predictably and consistently as possible.
Firefox is doing something a little bit odd: it has an extra pixel of padding eating out of the content space of the textarea vs the other two browsers, and vs a similarly equipped div block.
When applying this class to both a textarea and a div the difference is visible, with the text in the div touching the outer left edge of the red background but the text in the textarea have 1 px padding-like offset in spite of padding being zero:
.testbox{
padding:0;
margin:0;
border:0;
background: red;
width: 40px;
height: 40px;
font-size: 12px;
line-height: 16px;
}
Other values for padding wind up displaying one extra pixel of offset vs a div.
Any ideas on if there's a way to trick Firefox to render a textarea as if it were a div, or to adjust this not-padding-but-looks-like-padding property for a textarea?
I have recently been doing some researching on the problem described by OP for a similar question on SO. It seems that a bug in Firefox is causing the rendering of this so called "not-padding-but-looks-like-padding" on textarea elements.
Usually this extra padding is not really an issue, but it becomes an issue when you want to keep two elements the same width, and you care about getting its content to wrap the same way in both elements.
Getting textarea's to wrap content the same as e.g. div elements in Firefox
It seems to be impossible to get rid of this 1.5px wide padding on the textarea in Firefox, so if you want to ensure that the content wrapping inside a div in Firefox behaves exactly the same as the content wrapping inside a textarea in Firefox, the best approach seems to be to add an additional 1.5px of padding on the right and the left hand side inside the div, but only in Firefox. You can accomplish this by setting the following vendor specific prefixed CSS properties on your div:
-moz-box-sizing: border-box;
-moz-padding-end: 1.5px;
-moz-padding-start: 1.5px;
The first ensures that the padding set on the div does not increase the width of the div, and the next two ensure that 1.5px of padding will be set on the right and the left hand side of the div.
This approach does not affect the rendering of the div's in any other browsers, it doesn't need to, as textarea's in other browsers don't render any extra padding. But it ensures that there are no content wrapping differences between div's and textarea's inside Firefox as long as they share the same font-family and font-size properties and so on.
Here's a jsFiddle for demonstration purposes.
Getting textarea's to wrap content consistently across browsers
If you only wanted to ensure that a textarea in Firefox has the same width and wrapping behaviour as a textarea in other browsers, you can set its box-sizing to border-box, add a padding on both sides of 5.5px and set -moz-padding-end and -moz-padding-start to 0px.
textarea {
padding: 0 5.5px 0 5.5px;
-moz-padding-end: 0px;
-moz-padding-start: 0px;
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
box-sizing: border-box;
}
Here's a jsFiddle showing this approach.
Wow, I don't know the answer yet but I did try some stuff, and it appears as though a textarea, when you apply borders, margins and padding to it, doesn't change its width but puts the borders etc. on the inside. Try this:
.testbox {
padding: 10;
margin: 10;
border: 5px solid black;
background: red;
width: 40px;
height: 40px;
font-size: 12px;
line-height: 16px;
}
You could work around this by using something like this:
<div class="testbox">
<textarea class="testarea"></textarea>
</div>
css:
.testbox {
padding: 0;
margin: 0;
border: 0;
background: red;
width: 40px;
height: 40px;
font-size: 12px;
line-height: 16px;
}
.testarea {
padding: 0;
margin: 0 -1px;
border: 0;
background: red;
width: 100%;
height: 100%;
font-size: 12px;
line-height: 16px;
}
This also seems to work in IE, except for the -1px, which throws the layout off (by one).
This is a bug in firefox which got fixed a few days ago. The fix will be released with Firefox 29.
I already tried the latest nightly build and the textara bug is gone!
I was facing the same problem and although my solution seemed like bending backwards too much for that one pixle, but it fixed the problem, here goes: To unify the width because of this weird behavior, Instead of using a div, i used a disabled textarea with a white background and a default cursor to act as a mimic the div.
I was having a similar problem, a link tag with a background image and padding did not display well on firefox. The padding and background seemed to apply to the line of text, not the block of text, when multiline. I tested out a few things, and ended up using a "display:block;" on the element css. Worked for me.

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