44

I have been searching around but I can't find a solution to apply to my own problem.

I am working on a mobile website and need the input boxes to be 100% width of the screen. But I have padding-left: 16px and margin: 5px that makes the boxes go outside of the screen so I have to scroll to the right to see the end of the box. How do I make the boxes 100% minus the padding and margin?

To try it out: http://jsfiddle.net/wuSDh/

Joakim Melin
  • 459
  • 1
  • 4
  • 4
  • 6
    With `box-sizing: border-box` you can manage to work around the padding, but not margin. – mash Jul 13 '13 at 15:38
  • Can't answer anymore for some reason but the right answer is `width: auto; left: 0px; right: 0px; max-width: 100%;` All of these other answers have drawbacks/issues. – Emperor Eto Apr 06 '21 at 22:46

6 Answers6

66

You can use calc, modern browsers support it and IE9+ as well.

div {
  margin: 10px;
  width: calc(100% - 20px);
  height: 10px;
  background: teal;
}
<div></div>

Browser support

Jonathan
  • 8,771
  • 4
  • 41
  • 78
  • 2
    This is not supported in Android Safari: http://caniuse.com/calc (the OP stated he was working on a mobile website) – David Hellsing Jul 13 '13 at 16:39
  • 2
    This is now supported on all major mobile browsers except Opera mini. – VVV Jul 10 '14 at 02:11
  • Didn't knew about this css feature, it helps a lot on certain design situations and it's current browser support is quite wide. +1 – Bardo Feb 02 '16 at 08:40
  • Is there a way that I can make a CSS property that only has padding and corrects width? Something like setting width to the previous value minus padding. – Aaron Franke Oct 11 '19 at 19:51
  • Dangerous way. It's better to use box-sizing: border-box on absolute element which means it's width will be the same as parent but without padding, margin and borders – Igor Shumichenko Feb 01 '21 at 10:28
7

Block level elements naturally fill their parent, however if you specifically set width, you override this behavior, allowing margin and border to be added to the specified width. You specify 100% width on the body, thus giving an opportunity for it to overflow the document horizontally if there is an element rendered to it's right inner edge.

Example: http://jsfiddle.net/trex005/6earf674/

The simple remedy to this is to stop declaring the body's width. If for some reason this is required, you can set the margin to 0; The same principle applies to the input, but it is a little more complicated. Inputs(text/password) and textareas, even when set to display as block will derive their widths from size and cols respectively. This can be overridden by specifying a width in CSS, however they also have user agent specified borders and margins so you have the overflow problem again. To fix this overflow, you need to set the input's display to block and it's box-sizing:border-box. Border box will calculate the borders and padding as part of the width.

input[type="text"], input[type="password"] {
    width: 100% !important;
    margin: 5px !important;
    box-sizing:border-box;
    display:block;
}

Once you do that, you will notice there is extra spacing between the elements. This is because the display:block forces the line break, and the <br> tags that you added are redundant. Remove those, and you are in business!

Demo: http://jsfiddle.net/trex005/6earf674/1/

trex005
  • 5,015
  • 4
  • 28
  • 41
  • 1
    I love this one! I have been looking for other ways rather than using `calc` because I don't want to repeat the padding code. Note that `display` can be `flex` too. – Wit Dec 08 '19 at 07:01
  • Doesn't work for me. The inputs are still wider than the container in your jsfiddle. The login button is centered and the inputs are sticking out to the right. – Curtis Sep 23 '22 at 19:16
6

I had this issue with 100% heights, and eventually it struck me that the answer is to use a padding on the element above the 100% height/width (i.e. the parent).

<div style="padding: 1rem;">
    <div style="height:100%; width:100%">
        <p>The cat sat on the mat</p>
    </div>
</div>

In short, the padding of the parent has the same effect as the margin of the child!

Dagmar
  • 2,968
  • 23
  • 27
4

Looe the width:100%; then simply use as much padding as you like:

#login_box {
    padding:10px;
    margin:50px;
}

Demo http://jsfiddle.net/PFm3h/

Isolated effect:

Demo http://jsbin.com/ozazat/1/edit

Lots of padding, lots of margin, no problem at all.

Jonathan Hall
  • 75,165
  • 16
  • 143
  • 189
user1721135
  • 6,864
  • 8
  • 34
  • 63
  • 2
    Note: This won’t work if you add padding to the INPUTs, unless you also adjust the box-sizing: http://jsfiddle.net/PFm3h/1/ – David Hellsing Jul 13 '13 at 16:36
  • Yes, box-sizing would come in handy for this. – user1721135 Jul 13 '13 at 16:43
  • And for vertical fill? For example: supposed you have text overlaying an image, and you want that text div to occupy a max-height of 100%, taking margin/padding into consideration while remaining docked at the bottom? And that's not even considering the fact that percentages for top and bottom margins are calculated relative to the width of the container, not the height, for some insane reason. – Triynko Jan 04 '16 at 22:17
  • @Triynko Im not sure I follow you here... Do you have a jsfiddle and a better description of what you are trying to accomplish? Also congrats on replying to a 2 yars old answer :) – user1721135 Jan 04 '16 at 23:26
1

Another solution is to position the INPUT’s absolute and add left/right props:

#login_box {
    width: 100%;
    position:relative;
}

input[type="text"], input[type="password"] {
    position:absolute;
    left:5px;
    right: 5px
}

You would need to adjust margins etc, since they will be out of the relative layout flow. You can also add padding without trouble, since you didn’t set a fixed width.

This technique is widely supported in all browsers.

Demo: http://jsfiddle.net/wuSDh/3/

David Hellsing
  • 106,495
  • 44
  • 176
  • 212
  • 1
    Does not work in Chrome, Firefox or IE because the inputs do not stretch to meet both the left and the right designations. It seems that left takes priority in all of these browsers. – trex005 Jan 12 '15 at 17:57
-5

You can adjust your textbox width 100% to 95% .Now it's looking good

input[type="text"], input[type="password"] {
    width: 95% !important;
    margin: 5px !important;
}

See this : http://jsfiddle.net/wuSDh/