Can I stop 100% Width Text Boxes from extending beyond their containers?

HtmlCss

Html Problem Overview


Lets say I have a text box that I want to fill a whole line. I would give it a style like this:

input.wide {display:block; width: 100%}

This causes problems because the width is based on the content of the text box. Text boxes have margin, borders, & padding by default, which makes a 100% width text box larger than its container.

For example, here on the right:

enter image description here

Is there any way to make a text box fill the width of its container without expanding beyond it?

Here is some example HTML to show what I mean:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head>
    <title>Untitled Page</title>
    <style type="text/css">
        #outer{border: 1px solid #000; width: 320px; margin: 0px;padding:0px}
        #inner{margin: 20px; padding: 20px; background: #999;border: 1px solid #000;}
        input.wide {display:block; margin: 0px}
        input.normal {display:block; float: right}
    </style>
</head>
<body>
    <div id="outer">
        <div id="inner">
            <input type="text" class="wide" />
            <input type="text" class="normal" />
            <div style="clear:both;"></div>
        </div>
    </div>
</body>
</html>

If this is run, you can see by looking at the "normal" text box that the "wide" text box is sticking out beyond the container. The "normal" text box floats to the actual edge of the container. I'm trying to make the "wide" text box fill its container, without expanding beyond edge like the "normal" text box is.

Html Solutions


Solution 1 - Html

> Is there any way to make a text box fill the width of its container without expanding beyond it?

Yes: by using the CSS3 property ‘box-sizing: border-box’, you can redefine what ‘width’ means to include the external padding and border.

Unfortunately because it's CSS3, support isn't very mature, and as the spec process isn't finished yet, it has different temporary names in browsers in the meantime. So:

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

The old-school alternative is simply to put a quantity of ‘padding-right’ on the enclosing <div> or <td> element equal to about how much extra left-and-right padding/border in ‘px’ you think browsers will give the input. (Typically 6px for IE<8.)

Solution 2 - Html

What you could do is to remove the default "extras" on the input:

input.wide {display:block; width:100%;padding:0;border-width:0}

This will keep the input inside its container. Now if you do want the borders, wrap the input in a div, with the borders set on the div (that way you can remove the display:block from the input too). Something like:

<div style="border:1px solid gray;">
 <input type="text" class="wide" />
</div>

Edit: Another option is to, instead of removing the style from the input, compensate for it in the wrapped div:

input.wide {width:100%;}

<div style="padding-right:4px;padding-left:1px;margin-right:2px">
  <input type="text" class="wide" />
</div>

This will give you somewhat different results in different browsers, but they will not overlap the container. The values in the div depend on how large the border is on the input and how much space you want between the input and the border.

Solution 3 - Html

This solved the problem for me!

Without the need for an external div. Just apply it to your given text box.

box-sizing: border-box; 

With this property "The width and height properties (and min/max properties) includes content, padding and border, but not the margin"

See description of property at w3schools.

Hope this helps someone!

Solution 4 - Html

Just came across this problem myself, and the only solution I could find that worked in all my test browsers (IE6, IE7, Firefox) was the following:

  1. Wrap the input field in two separate DIVs
  2. Set the outer DIV to width 100%, this prevents our container from overflowing the document
  3. Put padding in the inner DIV of the exact amount to compensate for the horizontal overflow of the input.
  4. Set custom padding on the input so it overflows by the same amount as I allowed for in the inner DIV

The code:

<div style="width: 100%">
    <div style="padding-right: 6px;">
        <input type="text" style="width: 100%; padding: 2px; margin: 0;
                                  border : solid 1px #999" />
    </div>
</div>

Here, the total horizontal overflow for the input element is 6px - 2x(padding + border) - so we set a padding-right for the inner DIV of 6px.

Solution 5 - Html

box-sizing support is pretty good actually: http://caniuse.com/#search=box-sizing

So unless you target IE7, you should be able to solve this kind of issues using this property. A layer such as sass or less makes it easier to handle prefixed rules like that, btw.

Solution 6 - Html

Actually, it's because CSS defines 100% relative to the entire width of the container, including its margins, borders, and padding; that means that the space avail. to its contents is some amount smaller than 100%, unless the container has no margins, borders, or padding.

This is counter-intuitive and widely regarded by many to be a mistake that we are now stuck with. It effectively means that % dimensions are no good for anything other than a top level container, and even then, only if it has no margins, borders or padding.

Note that the text field's margins, borders, and padding are included in the CSS size specified for it - it's the container's which throw things off.

I have tolerably worked around it by using 98%, but that is a less than perfect solution, since the input fields tend to fall further short as the container gets larger.


EDIT: I came across this similar question - I've never tried the answer given, and I don't know for sure if it applies to your problem, but it seems like it will.

Solution 7 - Html

One solution that may work (it works for me) is to apply negative margin at input (textbox)... or fixed width for ie7 or to drop ie7 support. This results to pixel perfect width.. For me its 7 so i added 3 and 4 but it is still pixel perfect..

I had the same problem and i hated to have extra divs for border etc!

So here is my solution which seems to work!

You should use a ie7 only stylesheet to avoid the starhacks.

input.text{
    background-color: #fbfbfb;
    border : solid #eee 1px;
    width: 100%;
    -box-sizing: border-box;
    -moz-box-sizing: border-box;
    box-sizing: border-box;
    height: 32px;

    *line-height:32px;
    *margin-left:-3px;
    *margin-right:-4px;
    display: inline;   
    padding: 0px 0 0 5px;
    
}

Solution 8 - Html

If you can't use box-sizing:border-box you could try removing the width:100% and putting a very large size attribute in the <input> element, drawback is however you have to modify the html, and can't do it with CSS only:

<input size="1000"></input>

Solution 9 - Html

If you don't need to do it dynamically (for example, your form is of a fixed width) you can just set the width of child <input> elements to the width of their container minus any decorations like padding, margin, border, etc.:

 // the parent div here has a width of 200px:
.form-signin input[type="text"], .form-signin input[type="password"], .form-signin input[type="email"], .form-signin input[type="number"] {
  font-size: 16px;
  height: auto;
  display: block;
  width: 280px;
  margin-bottom: 15px;
  padding: 7px 9px;
}

Solution 10 - Html

If you can't use box-sizing (e.g. when you convert HTML to PDF using iText). Try this:

CSS

.input-wrapper { border: 1px solid #ccc; padding: 0 5px; min-height: 20px; } 
.input-wrapper input[type=text] { border: none; height: 20px; width: 100%; padding: 0; margin: 0; }

HTML

<div class="input-wrapper">
     <input type="text" value="" name="city"/>
</div>

Solution 11 - Html

This works:

<div>
    <input type="text" 
        style="margin: 5px; padding: 4px; border: 1px solid; 
        width: 200px; width: calc(100% - 20px);">
</div>

The first 'width' is a fallback rule for older browsers.

Solution 12 - Html

Just style the input to offset for the extra padding. In the following example the padding on the input would be 10px on the left and right for a total padding offset of 20px:

input[type=text]{
   width: calc(100% - 20px);
}

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
QuestionDan HerbertView Question on Stackoverflow
Solution 1 - HtmlbobinceView Answer on Stackoverflow
Solution 2 - HtmlHilbrand BouwkampView Answer on Stackoverflow
Solution 3 - HtmlJack TrowbridgeView Answer on Stackoverflow
Solution 4 - HtmlTobias CohenView Answer on Stackoverflow
Solution 5 - HtmlchikamichiView Answer on Stackoverflow
Solution 6 - HtmlLawrence DolView Answer on Stackoverflow
Solution 7 - HtmlGorillaApeView Answer on Stackoverflow
Solution 8 - HtmlsiddhadevView Answer on Stackoverflow
Solution 9 - HtmlAvishaiView Answer on Stackoverflow
Solution 10 - HtmlrobertadView Answer on Stackoverflow
Solution 11 - HtmlMo'in CreemersView Answer on Stackoverflow
Solution 12 - HtmlquinloView Answer on Stackoverflow