Padding within inputs breaks width 100%

CssInputPadding

Css Problem Overview


Ok, so we know that setting padding to an object causes its width to change even if it is set explicitly. While one can argue the logic behind this, it causes some problems with some elements.

For most cases, you just add a child element and add padding to that one instead of the one set to 100%, but for form inputs, that's not a possible step.

Take a look at this:

body {
  font-size: 14px;
  margin: 0px;
  padding: 0px;
}

DIV.formfield {
  clear: both;
  margin: 0px;
  padding: 10px;
}

DIV.formlabel {
  margin-top: 20px;
  padding: 5px;
  font-weight: bold;
  text-align: left;
}

DIV.formvalue {
  background-color: #eee;
  border: 1px solid red;
  padding: 10px;
  margin: 0px;
}

DIV.formvalue.correct {
  border: 1px solid green;
}

textarea.textarea {
  width: 100%;
  min-height: 80px;
}

input.input {
  width: 100%;
  padding: 5px;
}

input.input2 {
  width: 100%;
}

input.input3 {
  width: 100%;
  padding: 5px;
  margin: -5px;
}

input.input4 {
  width: 100%;
  padding: 10px;
  margin: -10px;
}

input.input5 {
  width: 100%;
  padding: 10px;
  box-sizing: border-box;
}

<div class='formfield' id='field_text'>
  <div class='formlabel'>No padding</div>
  <div class='formvalue'>
    <textarea class='textarea' cols='80' rows='10' name='text'>No padding here</textarea>
  </div>
  <div class='formlabel'>Also no padding</div>
  <div class='formvalue'>
    <input type='text' class='input2' name='apa' value='Or here...' />
  </div>
  <div class='formlabel'>5px padding, which extends the parent element, d'oh!</div>
  <div class='formvalue'>
    <input type='text' class='input' name='apa' value='I dont want to extend outside the square!' />
  </div>
  <div class='formlabel'>5px padding and -5px margin, this does the trick, almost...</div>
  <div class='formvalue'>
    <input type='text' class='input3' name='apa' value='I dont want to extend outside the square!' />
  </div>

  <div class='formlabel'>10px padding and -10px margin, things are falling apart on the right side</div>
  <div class='formvalue'>
    <input type='text' class='input4' name='apa' value='I dont want to extend outside the square!' />
  </div>

  <div class='formlabel'><img src="/bilder/icons/badges/ok.png" width="16" height="16" border="0"> 10px padding and box-sizing: border-box</div>
  <div class='formvalue correct'>
    <input type='text' class='input5' name='apa' value='I dont want to extend outside the square!' />
  </div>
</div>

The second input has its padding set to 5px which I very much prefer to the default setting. But unfortunately that makes the input grow 10px in all directions, including adding 10px to the 100% width.

Problem here is that I can't add a child element inside the input so I can't fix it. So the question is:

Is there any way to add padding inside the input while still keeping the width 100%? It need to be 100% since the forms will render in different width parents so I don't know beforehand the width of the parent.

Css Solutions


Solution 1 - Css

Using CSS3 you can use the property box-sizing to alter how the browser calculate the width of the input.

input.input {
    width: 100%;
    box-sizing: border-box;
}

You can read more about it here: http://css-tricks.com/box-sizing/

Solution 2 - Css

I don't know how cross browser compatible it is (it works in firefox and safari), but you could try this solution:

DIV.formvalue {
padding: 15px;
}
input.input {
margin: -5px;
}

(Only posted the values that I changed)

Solution 3 - Css

One option is to wrap the INPUT in a DIV which has the padding.

CSS:

div.formvalue {
    background-color: #eee;
    border: 1px solid red;
    padding: 10px;
    margin: 0px;
}

div.paddedInput {
    padding: 5px;
    border: 1px solid black;
    background-color: white;
}

div.paddedInput input {
    border: 0px;
    width: 100%;
}

HTML:

<div class="formvalue">
    <div class="paddedInput"><input type="text" value="Padded!" /></div>
</div>

Solution 4 - Css

The oft-forgotten calc can come to the rescue here:

input {
  width: calc(100% - 1em);
  padding: 0.5em;
}

Since we know the padding will add to the width of the element, we simply subtract the padding from the overall width. It's supported by all major browsers, is responsive, and doesn't require messy wrapper divs.

Solution 5 - Css

I've been having some issues with something similar to this. I have tds with inputs of 100% and a small padding. What I did was compensate for the padding on the td as follows:

.form td {
    padding-right:8px;
}

.form input, .form textarea {
    border: 1px solid black;
    padding:3px;
    width:100%;
}

padding of 8px to include the border and padding of the input/textarea. Hope this helps!

Solution 6 - Css

Perhaps take the border+background off the input, and instead enclose it in a div with border+background and width:100%, and set a margin on the input?

Solution 7 - Css

One solution I have found works is to absolutely position the input with a relatively positioned parent tag.

<p class="full-width-input">
    <input type="text" class="text />
</p>

The apply the style:

p.full-width-input {
    position: relative;
    height: 35px;
}

p.full-width-input input.text {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    padding: 5px;
}

The only thing to be aware of is that the paragraph tag needs a height setting as its absolutely positioned children will not expand its height. This avoids the need to set width: 100% by locking it to the left and right sides of the parent element.

Solution 8 - Css

Try using percentages for your padding:

.input { 

  // remove border completely
  border: none;

  // don't forget to use the browser prefixes
  box-shadow: 0 0 0 1px silver;

  // Use PERCENTAGES for at least the horizontal padding
  padding: 5%; 

  // 100% - (2 * 5%)
  width: 90%; 

}

If you're worried about users on old browsers who can't see the box-shadow, just give the input a subtle background colour as backup. If you're using pixels for this sort of thing, then the chances are you're using them elsewhere, which could present a few extra-challenges, let me know if you encounter them.

Solution 9 - Css

Only thing I know to prevent this is assign values like that 100%-10. But it has some compatibility issues tho.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionSandmanView Question on Stackoverflow
Solution 1 - CssVíctor Dieppa GarrigaView Answer on Stackoverflow
Solution 2 - CssmichaelkView Answer on Stackoverflow
Solution 3 - Cssuser7116View Answer on Stackoverflow
Solution 4 - CssXanderStrikeView Answer on Stackoverflow
Solution 5 - CssKeyeView Answer on Stackoverflow
Solution 6 - CssAmberView Answer on Stackoverflow
Solution 7 - CssGabzView Answer on Stackoverflow
Solution 8 - CssstephenmurdochView Answer on Stackoverflow
Solution 9 - CssTarikView Answer on Stackoverflow