How to make an element width: 100% minus padding?
Asked Answered
H

15

501

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

Hypnotic answered 7/3, 2011 at 11:35 Comment(4)
See this answer I posted not 15 minutes ago: #5219530 This should work perfectly for you, unless you require it to work in IE7.Russianize
If you used my method, see the slight edit I just made on my answer. It ensures "even padding" in some browsers.Russianize
@Hypnotic i have solution which keeping padding for input and supporting IE7Amalamalbena
Please also see the answer below using the calc functionBilbrey
R
661

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.

Russianize answered 7/3, 2011 at 12:15 Comment(16)
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.Matchbox
Padding a wrapping div also produces non-identical results to adding padding to the input directly.Excoriation
@Russianize i have some more flexible and elegant solutions which keeps input's widthAmalamalbena
@Russianize yeah, just leave it broken for IE7 and let M$ fix that :)Orta
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.Coextensive
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.Execute
It doesn't work when input has border... it is displaced by border widthWeig
See my answer below for a simpler and better solution or see here: #651817Bilbrey
@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.Janaye
@Russianize Could you explain why display: block is needed for the input element?Janaye
Please also see the answer below using the calc functionBilbrey
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.Graveclothes
This was the first time I learned what box-sizing is for, great answer!Feer
If you need this to work in IE7, you can read an old revision of this answer. And I feel really bad for you.Russianize
WOW! -- This was exactly what I needed. I couldn't figure out why my H2 I had set to width:100% was longer than its container. I already had border-box set on body tag, but this answer made me realize I needed to set border-box on all child elements also. Thank you so much!!Flywheel
now this is real answer!Hotchpot
T
295

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.

Thedrick answered 7/3, 2011 at 12:34 Comment(7)
+1, but caniuse.com/#search=box-sizing IE 8? Also, github.com/Schepp/box-sizing-polyfill seems to provide a solution for IE 6-7.Lilas
+1, this is great if you don't care about IE (when using PhoneGap for instance)Celie
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).Checkbook
This should be the default behavior.. instead of +20 to width. Sometimes CSS seems seriously messed up.Disruption
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.Whelp
This should be the selected answer. box-sizing solves all problems related with padding-width/max-width relations.Clarify
@Disruption unfortunately "default" in new CSS properties means "the way old browsers did it", right?Feer
B
47

Use padding in percentages too and remove from the width:

padding: 5%;
width: 90%;
Beitris answered 7/3, 2011 at 12:0 Comment(2)
Fyi, this solution is only ideal for non-flexible layouts.Stature
+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.Lilas
A
30

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 */ 
}
Amalamalbena answered 28/6, 2012 at 5:46 Comment(5)
That's a good trick, to use margin for input and padding for wrapper to compensate for the input padding.Platy
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..Obovoid
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 thisOstium
Why not use box-sizing? it is there for the purpose.Profession
@Ninthu, because box-sizing didnt work in all appropriate browsers back in '12Amalamalbena
B
30

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.

Bilbrey answered 14/3, 2014 at 15:14 Comment(1)
You need to manually program that in, though. Ideally it would be automatically determined.Liggitt
G
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.

Grillwork answered 29/11, 2013 at 12:42 Comment(2)
Could you post a complete example of width:auto applied to an input field?Janaye
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 :)Bildungsroman
A
8

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>).

Acerbate answered 21/9, 2015 at 12:4 Comment(2)
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..Boughpot
To clarify, and I think this is what Amnesh was trying to communicate, you CAN and should post a link your source(s), but it is even more important to post a working code sample to demonstrate how to implement your suggestionFlywheel
O
7

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

Oaf answered 7/3, 2011 at 11:58 Comment(3)
What browsers did you test this in? :(Russianize
Hmm, works only in Chrome. But I know I got something very similar to work in FF & IE as well.Oaf
Seems like it's not working with <input> elements in Firefox (idk about IE). It works with <div>s, though. And no, display: block on the <input> doesn't work either :-/Oaf
T
5

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/

Twilatwilight answered 7/3, 2011 at 12:11 Comment(0)
M
5

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.

Monoplane answered 7/4, 2021 at 12:23 Comment(1)
Thank you. This solution helped me. I had a slightly different problem. Parent element had padding and I needed a fixed child element to be 100% but it kept being pushed over by the parent padding. left: 0; right: 0; seemed to be all I needed.Leer
D
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.

Determinism answered 15/5, 2017 at 17:18 Comment(1)
Can you include an example where this works with <input>? Otherwise you're just sending people on a wild goose chase.Antigen
C
0

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

{
    width:100%;
    border: 10px solid transparent;
}
Crispate answered 21/8, 2015 at 13:31 Comment(0)
C
0

Try this:

width: 100%;
box-sizing: border-box;
Conaway answered 3/12, 2015 at 15:55 Comment(0)
A
0

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

Antimony answered 14/10, 2019 at 22:2 Comment(0)
Y
-9

You can do this:

width: auto;
padding: 20px;
Yentai answered 1/7, 2012 at 16:1 Comment(1)
This is not the same 100% - margin.Greatgrandaunt

© 2022 - 2024 — McMap. All rights reserved.