428

I have an html input.

The input has padding: 5px 10px; I want it to be 100% of the parent div's width(which is fluid).

However using width: 100%; causes the input to be 100% + 20px how can I get around this?

Example

TylerH
  • 19,065
  • 49
  • 65
  • 86
Hailwood
  • 79,753
  • 103
  • 257
  • 412
  • 1
    See this answer I posted not 15 minutes ago: http://stackoverflow.com/questions/5219030/content-of-div-is-longer-then-div-itself-when-width-is-set-to-100/5219090#5219090 This should work perfectly for you, unless you require it to work in IE7. – thirtydot Mar 07 '11 at 11:38
  • If you used my method, see the slight edit I just made on my answer. It ensures "even padding" in some browsers. – thirtydot Mar 09 '11 at 12:06
  • @Hailwood i have solution which keeping padding for `input` and supporting IE7 – Vladimir Starkov Jun 28 '12 at 05:56
  • Please also see the answer below using the calc function – Daan Oct 13 '14 at 15:17

15 Answers15

544

box-sizing: border-box is a quick, easy way to fix it:

This will work in all modern browsers, and IE8+.

Here's a demo: http://jsfiddle.net/thirtydot/QkmSk/301/

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

The browser prefixed versions (-webkit-box-sizing, etc.) are not needed in modern browsers.

thirtydot
  • 210,355
  • 44
  • 377
  • 337
  • 5
    I don't think this is that bad of a solution. In general, wrapping elements in an extra div is a good way to pad elements without pushing the overall width of the element beyond it's parent container. – Jake Wilson Aug 23 '11 at 22:13
  • 1
    Padding a wrapping div also produces non-identical results to adding padding to the input directly. – Felix Fung Jun 05 '12 at 00:27
  • @thirtydot i have some more flexible and elegant solutions which keeps input's width – Vladimir Starkov Jun 28 '12 at 05:52
  • 8
    @thirtydot yeah, just leave it broken for IE7 and let M$ fix that :) – Petr Peller Jul 04 '13 at 11:59
  • This also preserves auto resizing textareas for any of you jQuery people vs. box-sizing screws it up unless you apply that to the hidden div. – Michael J. Calkins Sep 02 '13 at 21:54
  • You could just use text-indent if all you want to change is the left padding of an input box. This will not change the width of the element. – m1. Feb 13 '14 at 01:10
  • It doesn't work when input has border... it is displaced by border width – Flash Thunder Mar 11 '14 at 22:26
  • See my answer below for a simpler and better solution or see here: http://stackoverflow.com/questions/651317/div-width-100-minus-fixed-amount-of-pixels – Daan May 20 '14 at 09:40
  • @FlashThunder You're right but that's covered by the inputContainer element. This element is used to define a border and the padding that you want for the input. – jakubiszon Jul 10 '14 at 10:57
  • @thirtydot Could you explain why `display: block` is needed for the `input` element? – jakubiszon Jul 10 '14 at 11:04
  • Please also see the answer below using the calc function – Daan Oct 13 '14 at 15:17
  • I don't understand this answer -- i've removed ` box-sizing: border-box; `, clicked `Run`, and i'm getting the exact same results as before. Using Mozilla SeaMonkey. – cnst Mar 08 '15 at 05:31
  • This was the first time I learned what `box-sizing` is for, great answer! – Andy Aug 02 '15 at 17:08
  • If you need this to work in IE7, you can read [an old revision of this answer](https://stackoverflow.com/revisions/5219611/2). And I feel really bad for you. – thirtydot Jun 28 '18 at 07:42
281

This is why we have box-sizing in CSS.

I’ve edited your example, and now it works in Safari, Chrome, Firefox, and Opera. Check it out: http://jsfiddle.net/mathias/Bupr3/ All I added was this:

input {
  -webkit-box-sizing: border-box;
     -moz-box-sizing: border-box;
          box-sizing: border-box;
}

Unfortunately older browsers such as IE7 do not support this. If you’re looking for a solution that works in old IEs, check out the other answers.

johannchopin
  • 7,327
  • 6
  • 22
  • 62
Mathias Bynens
  • 130,201
  • 49
  • 208
  • 240
  • 3
    +1, but http://caniuse.com/#search=box-sizing IE 8? Also, https://github.com/Schepp/box-sizing-polyfill seems to provide a solution for IE 6-7. – Alix Axel Jan 31 '12 at 03:07
  • 1
    +1, this is great if you don't care about IE (when using PhoneGap for instance) – Luke B. Sep 10 '12 at 15:06
  • 3
    What kind of wizardry is this? +1 for the answer and +1 for the comment above me (that's exactly what I need it for). – Eduard Luca Dec 19 '12 at 21:29
  • 21
    This should be the default behavior.. instead of +20 to width. Sometimes CSS seems seriously messed up. – Soth May 09 '13 at 03:24
  • 2
    To clarify box-sizing support on IE, for IE box-sizing property depends on IE Document Mode, it works on "IE8 Standards mode" & higher. So it will work in IE8 browser version also if document mode is "IE8 Standards mode". Hope this helps. – Sanjeev Jun 25 '14 at 08:03
  • 1
    This should be the selected answer. box-sizing solves all problems related with padding-width/max-width relations. – tolga Jul 24 '14 at 23:21
  • @Soth unfortunately "default" in new CSS properties means "the way old browsers did it", right? – Andy Aug 02 '15 at 17:10
42

Use padding in percentages too and remove from the width:

padding: 5%;
width: 90%;
Alex
  • 7,134
  • 1
  • 16
  • 31
  • 19
    Fyi, this solution is only ideal for non-flexible layouts. – muffs Dec 15 '11 at 21:25
  • +1, The problem with this would be the borders I guess. Normally, they only look "right" with 1 to 3 pixels max. The results are too unpredictable considering the the browser inconsistencies regarding sub-pixel rounding. – Alix Axel Jan 31 '12 at 03:11
29

You can do it without using box-sizing and not clear solutions like width~=99%.

Demo on jsFiddle:
enter image description here

  • Keep input's padding and border
  • Add to input negative horizontal margin = border-width + horizontal padding
  • Add to input's wrapper horizontal padding equal to margin from previous step

HTML markup:

<div class="input_wrap">
    <input type="text" />
</div>

CSS:

div {
    padding: 6px 10px; /* equal to negative input's margin for mimic normal `div` box-sizing */
}

input {
    width: 100%; /* force to expand to container's width */ 
    padding: 5px 10px;
    border: none;
    margin: 0 -10px; /* negative margin = border-width + horizontal padding */ 
}
Vladimir Starkov
  • 17,483
  • 4
  • 56
  • 113
  • 4
    That's a good trick, to use margin for input and padding for wrapper to compensate for the input padding. – maulik13 Sep 12 '12 at 10:21
  • Agree totally!!! I have used this solution and it works widely with no dirty tricks! This had to be the solution to every kind of these answers.. – Andre Figueiredo Sep 11 '13 at 19:07
  • I don't quite understand what role the negative margin has - all I know is that if the value is wrong, then the box ends up to one side, but somehow a symmetric margin fixes this – Casebash Nov 18 '13 at 04:52
  • Why not use box-sizing? it is there for the purpose. – Ninthu Jul 22 '20 at 13:19
  • @Ninthu, because box-sizing didnt work in all appropriate browsers back in '12 – Vladimir Starkov Jul 27 '20 at 12:57
23

Use css calc()

Super simple and awesome.

input {
    width: -moz-calc(100% - 15px);
    width: -webkit-calc(100% - 15px);
    width: calc(100% - 15px);
}​

As seen here: Div width 100% minus fixed amount of pixels
By webvitaly (https://stackoverflow.com/users/713523/webvitaly)
Original source: http://web-profile.com.ua/css/dev/css-width-100prc-minus-100px/

Just copied this over here, because I almost missed it in the other thread.

johannchopin
  • 7,327
  • 6
  • 22
  • 62
Daan
  • 1,443
  • 1
  • 13
  • 12
12

Assuming i'm in a container with 15px padding, this is what i always use for the inner part:

width:auto;
right:15px;
left:15px;

That will stretch the inner part to whatever width it should be less the 15px either side.

TylerH
  • 19,065
  • 49
  • 65
  • 86
Andology
  • 121
  • 1
  • 4
  • Could you post a complete example of `width:auto` applied to an `input` field? – jakubiszon Jul 10 '14 at 11:26
  • thats only half an answer. default position of elements is static, so left & right will do exactly nothing here. and width auto is also the initial value, so.. all this answer does is nothing :) – honk31 Sep 14 '17 at 09:25
5

Here is the recommendation from codeontrack.com, which has good solution examples:

Instead of setting the width of the div to 100%, set it to auto, and be sure, that the <div> is set to display: block (default for <div>).

Sumner Evans
  • 8,302
  • 5
  • 27
  • 44
M.YPC
  • 71
  • 1
  • 1
  • 3
    You shouldn't post link directly. You can include the information from that link. Reason being is, may be tomorrow that link won't be available and your answer will then no longer valid.. – Amnesh Goel Sep 21 '15 at 12:12
5

You can try some positioning tricks. You can put the input in a div with position: relative and a fixed height, then on the input have position: absolute; left: 0; right: 0;, and any padding you like.

Live example

Felix
  • 84,032
  • 41
  • 145
  • 163
  • What browsers did you test this in? :( – thirtydot Mar 07 '11 at 12:00
  • Hmm, works only in Chrome. But I know I got something very similar to work in FF & IE as well. – Felix Mar 07 '11 at 12:55
  • Seems like it's not working with `` elements in Firefox (idk about IE). It works with `
    `s, though. And no, `display: block` on the `` doesn't work either :-/
    – Felix Mar 07 '11 at 13:02
4

Move the input box' padding to a wrapper element.

<style>
div.outer{ background: red; padding: 10px; }
div.inner { border: 1px solid #888; padding: 5px 10px; background: white; }
input { width: 100%; border: none }
</style>

<div class="outer">
    <div class="inner">
       <input/>
    </div>
</div>

See example here: http://jsfiddle.net/L7wYD/1/

Martin Jespersen
  • 23,663
  • 6
  • 52
  • 66
2

Just understand the difference between width:auto; and width:100%; Width:auto; will (AUTO)MATICALLY calculate the width in order to fit the exact given with of the wrapping div including the padding. Width 100% expands the width and adds the padding.

user3849374
  • 127
  • 1
  • 3
  • Can you include an example where this works with ? Otherwise you're just sending people on a wild goose chase. – Mr Lister Jun 24 '18 at 10:55
0

What about wrapping it in a container. Container shoud have style like:

{
    width:100%;
    border: 10px solid transparent;
}
Didier Aupest
  • 2,840
  • 2
  • 22
  • 32
0

Try this:

width: 100%;
box-sizing: border-box;
0

Maybe browsers have changed since this question was last answered, but this is the only thing that has ever worked reliably for me to accomplish this:

    width: auto;
    left: 0;
    right: 0;

Then you can make the margins / padding anything you want and the element will not expand past its available width.

This is similar to @andology's answer from way back but if you make left/right both 0 then you can make margin and/or padding whatever you want. So this is always my default div.

Peter Moore
  • 690
  • 8
  • 14
-1

For me, using margin:15px;padding:10px 0 15px 23px;width:100%, the result was this:

enter image description here

The solution for me was to use width:auto instead of width:100%. My new code was:

margin:15px;padding:10px 0 15px 23px;width:auto. Then the element aligned properly:

enter image description here

Jaime Montoya
  • 4,817
  • 4
  • 48
  • 75
-9

You can do this:

width: auto;
padding: 20px;
karthikr
  • 87,486
  • 24
  • 182
  • 182
MissHD
  • 7