100% width minus margin and padding [duplicate]

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/


Solution 1:

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

Solution 2:

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/

Solution 3:

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.

Solution 4:

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!