Padding within inputs breaks width 100% - css

Ok, so we know that setting padding to an object causes its width to change even if it is set explicitly. While one can argue the logic behind this, it causes some problems with some elements.
For most cases, you just add a child element and add padding to that one instead of the one set to 100%, but for form inputs, that's not a possible step.
Take a look at this:
body {
font-size: 14px;
margin: 0px;
padding: 0px;
}
DIV.formfield {
clear: both;
margin: 0px;
padding: 10px;
}
DIV.formlabel {
margin-top: 20px;
padding: 5px;
font-weight: bold;
text-align: left;
}
DIV.formvalue {
background-color: #eee;
border: 1px solid red;
padding: 10px;
margin: 0px;
}
DIV.formvalue.correct {
border: 1px solid green;
}
textarea.textarea {
width: 100%;
min-height: 80px;
}
input.input {
width: 100%;
padding: 5px;
}
input.input2 {
width: 100%;
}
input.input3 {
width: 100%;
padding: 5px;
margin: -5px;
}
input.input4 {
width: 100%;
padding: 10px;
margin: -10px;
}
input.input5 {
width: 100%;
padding: 10px;
box-sizing: border-box;
}
<div class='formfield' id='field_text'>
<div class='formlabel'>No padding</div>
<div class='formvalue'>
<textarea class='textarea' cols='80' rows='10' name='text'>No padding here</textarea>
</div>
<div class='formlabel'>Also no padding</div>
<div class='formvalue'>
<input type='text' class='input2' name='apa' value='Or here...' />
</div>
<div class='formlabel'>5px padding, which extends the parent element, d'oh!</div>
<div class='formvalue'>
<input type='text' class='input' name='apa' value='I dont want to extend outside the square!' />
</div>
<div class='formlabel'>5px padding and -5px margin, this does the trick, almost...</div>
<div class='formvalue'>
<input type='text' class='input3' name='apa' value='I dont want to extend outside the square!' />
</div>
<div class='formlabel'>10px padding and -10px margin, things are falling apart on the right side</div>
<div class='formvalue'>
<input type='text' class='input4' name='apa' value='I dont want to extend outside the square!' />
</div>
<div class='formlabel'><img src="/bilder/icons/badges/ok.png" width="16" height="16" border="0"> 10px padding and box-sizing: border-box</div>
<div class='formvalue correct'>
<input type='text' class='input5' name='apa' value='I dont want to extend outside the square!' />
</div>
</div>
The second input has its padding set to 5px which I very much prefer to the default setting. But unfortunately that makes the input grow 10px in all directions, including adding 10px to the 100% width.
Problem here is that I can't add a child element inside the input so I can't fix it. So the question is:
Is there any way to add padding inside the input while still keeping the width 100%? It need to be 100% since the forms will render in different width parents so I don't know beforehand the width of the parent.

Using CSS3 you can use the property box-sizing to alter how the browser calculate the width of the input.
input.input {
width: 100%;
box-sizing: border-box;
}
You can read more about it here: http://css-tricks.com/box-sizing/

I don't know how cross browser compatible it is (it works in firefox and safari), but you could try this solution:
DIV.formvalue {
padding: 15px;
}
input.input {
margin: -5px;
}
(Only posted the values that I changed)

One option is to wrap the INPUT in a DIV which has the padding.
CSS:
div.formvalue {
background-color: #eee;
border: 1px solid red;
padding: 10px;
margin: 0px;
}
div.paddedInput {
padding: 5px;
border: 1px solid black;
background-color: white;
}
div.paddedInput input {
border: 0px;
width: 100%;
}
HTML:
<div class="formvalue">
<div class="paddedInput"><input type="text" value="Padded!" /></div>
</div>

The oft-forgotten calc can come to the rescue here:
input {
width: calc(100% - 1em);
padding: 0.5em;
}
Since we know the padding will add to the width of the element, we simply subtract the padding from the overall width. It's supported by all major browsers, is responsive, and doesn't require messy wrapper divs.

I've been having some issues with something similar to this. I have tds with inputs of 100% and a small padding. What I did was compensate for the padding on the td as follows:
.form td {
padding-right:8px;
}
.form input, .form textarea {
border: 1px solid black;
padding:3px;
width:100%;
}
padding of 8px to include the border and padding of the input/textarea.
Hope this helps!

Perhaps take the border+background off the input, and instead enclose it in a div with border+background and width:100%, and set a margin on the input?

One solution I have found works is to absolutely position the input with a relatively positioned parent tag.
<p class="full-width-input">
<input type="text" class="text />
</p>
The apply the style:
p.full-width-input {
position: relative;
height: 35px;
}
p.full-width-input input.text {
position: absolute;
top: 0;
left: 0;
right: 0;
padding: 5px;
}
The only thing to be aware of is that the paragraph tag needs a height setting as its absolutely positioned children will not expand its height. This avoids the need to set width: 100% by locking it to the left and right sides of the parent element.

Try using percentages for your padding:
.input {
// remove border completely
border: none;
// don't forget to use the browser prefixes
box-shadow: 0 0 0 1px silver;
// Use PERCENTAGES for at least the horizontal padding
padding: 5%;
// 100% - (2 * 5%)
width: 90%;
}
If you're worried about users on old browsers who can't see the box-shadow, just give the input a subtle background colour as backup. If you're using pixels for this sort of thing, then the chances are you're using them elsewhere, which could present a few extra-challenges, let me know if you encounter them.

Only thing I know to prevent this is assign values like that 100%-10. But it has some compatibility issues tho.

Related

How do i wrap a parent div to the width of a child div (dialog)?

Jsfiddle to demonstrate my issue.
I have a SPA (Single Page Application).
In the appliation several dialogs can popup on the screen.
Every popup has it own width and height.
The title and content of the dialogs are added by angularJs
The problem i have here is the size of the dialog.
Currently all popups are made and added seperatly. I want to change this into one popup with variable content. The problem that comes with this is that the popup must wrap the contents width.
Example (as shown in the Jsfiddle)
<div class="dialog">
<div class="titlebar"></div>
<div class="content">
The content that is added has css that tells it has a width of 400px
This means the dialog needs to wrap to this 400px
</div>
</div>
How do i solve this by only using CSS?
Some examples of the variation of popups (although the width of both look the same, this is not the case)
Use display:table for the dialog.
Here is your Updated Fiddle.
For young browser you may use :
1) display:flex; property (includes centering) DEMO
.backdrop {
position: fixed;
top:0;
}
.backdrop {
width: 100%;
height: 100%;
z-index: 100;
background-color: rgba(0, 0, 0, 0.2);
display: flex;
align-items: center;
justify-content: center;
}
.dialog {
margin:auto;
position:relative;
}
2) max-content as value for width and not set any width to inner
content . (exept some padding to keep room for the close button) :
DEMO
Info on W3C about those new keywords value, soon avalaible i hope.
CSS updated
.dialog {
width: max-content;
z-index: 101;
margin: auto;
/* basic way t o center */
top:50%;
left:50%;
margin:-80px -150px;
}
.titlebar {
height: 50px;
line-height: 50px;
background-color: #000000;
border-radius: 10px 10px 0px 0px;
}
.title{
color:#FFFFFF;
font-size: x-large;
padding:0 50px 0 10px;
}
.close_button {
position: absolute;
right: 0px;
top: 0px;
line-height:30px;
padding: 5px;
margin: 5px;
border-radius: 10px;
background-color: #ffd549;
color: #000000;
}
.content {
background-color: #FFFFFF;
}
.content-width {
background-color:#FFF000;
}
or as already said , use the display: table, inline-table
Using display: inline-block; text-align: center;
Works in ie >= 8.
Fiddle.
I don't understand the problem.
If you want to center the content-width div element, simply add margin: auto;.
If you want the container to fit the WIDTH of its content, you must change the display property from block to something else, like inline-block or table (as suggested by #jacelysh).
What is it exactly that you are trying to do?
A div without a set width will take up the width of the parent.
try this.
.content {
background-color: #FFFFFF;
min-width: 100%;
}
.content-width {
width: 100%;
background-color:#FFF000;
}
http://jsfiddle.net/VQA4k/6/
Checking again now. You can just remove the width from those two classes and it will work.
This is what you want I think.
http://jsfiddle.net/VQA4k/16/

Addthis sharing padding/margins

I've added addthis share buttons to a page here and I can't get equal margins/distribution across the div width, so there's a gap on the right hand side which takes into account the fluid width.
I've tried proportional margins/paddings at different percentages, but can't seem to make it responsive.
Here's the CSS and the rest is viewable in an inspector:
.bg.social {
border: 1px solid #FCFCFD;
padding: 15px 0;
background: #E4E4E4;
text-align: center;
width: 94%;
margin: 0 0 2em;
height: 32px;
}
.bg.social a {
margin: 0 4%;
padding: 0;
float: none;
}
.addthis_toolbox {
margin: 0 2%;
}
Update: Got it to work with the following, the same as Bartdude's answer:
.bg.social a {
padding: 0 3%;
display: inline-block;
}
.bg.social {
border: 1px solid #FCFCFD;
padding: 15px 0;
background: #E4E4E4;
text-align: center;
width: 95%;
margin: 0 0 2em;
}
Basically, what you want is to be able to use text-align:center on your button links. Problem is you can't do that, as you floated them for them to appear side-by-side.
I would then suggest to change the display of those anchors to display:inline-block (be carefull though it's not supported by older IE versions... I don't find it important myself but maybe your target audience is using it), so that you can both make use of the text-align:center of the parent and still have a margin around each anchor.
Alternatively, I would suggest only putting a right or left margin, and use CSS pseudo classes :last-child or :first-child so that the first or last element don't have that margin. This shouldn't actually make no visible difference, but your CSS would be a bit more clean and modern...
Try setting margin to
.addthis_toolbox {
margin: 0 10%; // from 2 to 10%
}
.addthis_toolbox {
margin: 0 5%;
}
I cleared all the margins and divs in parent and child divs. Then :
.bg.social a { width:20% }// divided to 5 equal part
and dicreased the margin of .addthis_toolbox.addthis_32x32_style span {
.addthis_toolbox.addthis_32x32_style span {margin-left: 20px;}
everything is ok.
Try it, add to your css:
div.foraddthis {
text-align: center;
width: 100%;
}
.addthis_toolbox {
display: -webkit-inline-box;
display: -moz-inline-box;
display: inline-flex;
}
.addthis_default_style .at300b {
float: none;
}
And HTML:
<div class="foraddthis">
<!-- AddThis Button BEGIN -->
<div class="addthis_toolbox addthis_default_style addthis_32x32_style"> <a class="addthis_button_facebook"></a>
<a class="addthis_button_twitter"></a>
<a class="addthis_button_google_plusone_share"></a>
<a class="addthis_button_pinterest_share"></a>
<a class="addthis_button_tumblr"></a>
</div>
<script type="text/javascript" src="//s7.addthis.com/js/300/addthis_widget.js#pubid=xa-529d1f4f354abd32"></script>
</div>
<!-- AddThis Button END -->
Demo: http://jsfiddle.net/vPw7u/

How to create a flexible leader line in div after a label field

<div class="titelcontent">
<div class="name">Name</div>
<div class="hzline"></div>
</div>
I want name div and hzline div to auto fit 100% in titelcontent.
The label (for example, Name) will vary in length and I want the red underline to span the remainding space of the titlecontent div.
How do I achieve the following? It is easy to do this using tables but I can't figure out how to do this via span or div.
You can use div like a table by using table-cell.
.titlecontent {
display: table;
}
.name {
display: table-cell;
white-space: nowrap;
}
.hzline {
display: table-cell;
border-bottom: 3px solid red;
width: 100%;
}
See DEMO.
Updated to allow background images to show through
You can make the mark-up a bit tighter by using a pseudo-element as follows:
<div class="wrapper">
<div class="inner">Photoshop</div>
</div>
and use the following CSS styling:
div.wrapper {
color:#82439a;
font-size: 16px;
font-weight: bold;
font-family: tahoma;
line-height: 180%;
background: red url(http://placekitten.com/1000/500) no-repeat left top;
overflow: hidden;
}
div.inner {
position: relative;
display: inner;
color: yellow;
padding-right: 0.50em;
border: 1px dotted yellow;
}
div.inner:after {
content: "\A0";
position: absolute;
bottom: 0;
left: 100%;
border-bottom: 5px solid #d71d00;
width: 1000%;
}
Demo fiddle: http://jsfiddle.net/audetwebdesign/wE8bC/
How It Works
The parent element div.wrapper may contain a background image or be transparent and show the background of some ancestor element. You need to set overflow: hidden.
For the label (<div.inner>), set position: relative and then generate a 100% width pseudo-element with a bottom border to serve as an underline. Use absolute positioning to place div.inner:after to the right of <div.inner> (left: 100%) and make the width relatively large. The pseudo-element will trigger an overflow condition but this is taken care of by hiding the overflow in the parent element. You can control left/right spacing using padding.
You can use set the display property to either inline or inline-block. If you use display: inline, it will work in IE7; adjust the line height as needed for styling.
Note that the generated content is a non-breaking space, hex code "\A0".
Support for IE7
If you need to support IE7, you will need a hack if you use inline-block as discussed in a previous question: IE7 does not understand display: inline-block
IE7 also does not support table-cell so some of the other posted solutions will face the same limitation.
Or an alternative to using display: table:
.name {
float: left;
}
.line-wrapper {
display: block;
overflow: hidden;
padding-top: 6px;
}
.hzline {
border-bottom: 3px solid red;
width: 100%;
}
See example.
I've guessed you are looking something like this. Please find my solution based on my understanding about the image you posted.
HTML
<div>
<span>Photoshop</span>
</div>
<div>
<span>Adobe Illustrator</span>
</div>
<div>
<span>3D Max</span>
</div>
<div>
<span>Maya</span>
</div>
<div>
<span>Windows 8 Pro</span>
</div>
CSS
div {
line-height: 150%;
border-bottom: 5px solid #d71d00;
}
div span{
position:relative;
bottom: -10px;
background:#fff;
padding: 0 5px;
color:#82439a;
font-size: 16px;
font-weight: bold;
font-family: tahoma;
}
Please do let me know your feedback. Thanks

How can I create a line after my text to the width of the container?

Yes, I'm a newb so please go easy. I know there's got to be several ways to accomplish this. Basically I've been trying to come up with a consistent way to have a header with a line after the text that will run to the full width of a container element.
Something like this:
This is my header _______________________________________________________ |<- end container
This is another header __________________________________________________ |<- end container
I'm trying to create a .line class that will use bottom-border to create the line but I've been unsuccessful at creating a variable length line that will extend the full width of the container.
Here's what I've tried:
CSS:
.line
{
display:inline-block;
border-bottom:2px #5B3400 solid;
margin-left:5px;
width:80%;
}
HTML:
<h2>Our Mission<span class="line"></span></h2>
Of course this only gives me a line 80% of the container from the left border including the width of the text. How can I create a line that begins after the text and runs the full width of the border regardless of how much text is on the same line?
I know this should be easy but I haven't been able to find a solution yet.
Thanks!
THIS METHOD WILL WORK WITH TEXTURED BACKGROUNDS (background images):
You can try using this method instead, if your <h2> is on top of a background image.
HTML:
<h2 class="line-title"><span>This is my title</span><hr /></h2>
CSS:
.line-title {
font-size: 20px;
margin-bottom: 10px;
padding-top: 1px; /* Allows for hr margin to start at top of h2 */
}
/* clearfix for floats */
.line-title:after {
content: "";
display: table;
clear: both;
}
.line-title span {
padding-right: 10px;
float: left;
}
.line-title hr {
border:1px solid #DDD;
border-width: 1px 0 0 0;
margin-top: 11px;
}
See the working example here: http://jsfiddle.net/yYBDD/1/
How it Works:
the <h2> tag acts as a container for a floated element.
the <span> is floated left, causing the <hr /> to collapse to the left and fill the right space.
the <hr /> acts as the line, and fills up the remaining space to the right.
THIS METHOD WILL WORK WITH SOLID BACKGROUND COLORS:
HTML:
<h2 class="line-title"><span>This is my title</span></h2>
CSS:
.line-title {
border-bottom: 1px solid #DDD;
font-size: 20px;
height: 12px;
margin-bottom: 10px;
}
.line-title span {
background: #FFF;
padding-right: 10px;
}
You can see a working example here: http://jsfiddle.net/yYBDD/
How it works.
the <h2> tag has a class that sets the height to half of the height of the text it contains.
the <h2> has a bottom border, that extends to the width of it's parent container (since it's a block element).
the <span> inside of the <h2> has a white background, which will cover the area where the text and border overlap.
And finally, the <h2>> has a bottom margin, that compensates for the reduced height of the <h2>.
You could use flexbox to do this.
http://jsfiddle.net/eHHep/ (prefixes not included)
<h1 class="lineme">This is my header</h1>
<h2 class="lineme">This is another header</h2>
.lineme {
display: flex;
}
.lineme:after {
display: block;
content: " ";
border-bottom: 1px solid;
flex: 1 1 auto;
}
Advantages over other methods:
No extra markup required
Background color is not required
Down side:
Support for flexbox is low due to IE10 being the first IE to support it (see http://caniuse.com/#search=flexbox)
Your line goes away if your text wraps around
HTML:
<h2><span>Our Mission</span></h2>
CSS:
h2{
border-bottom: 1px solid #000;
height: 20px;
overflow: visible;
display: block;
width: 100%;
}
h2 span{
display: inline-block;
background: #fff;
height: 21px;
}
This way it'll overflow on the bottom border as it has bigger height.
Demo: http://jsfiddle.net/afuzk/
Here's something I tried and that worked:
HTML
<h2>Our Mission</h2>
CSS
h2:after
{
content: "\00a0";
border-bottom: solid 2px black;
position: fixed;
top: 0;
width: 100%;
margin-left: 3px;
}
The JS Bin to test: http://jsbin.com/ayuvuc/4

css margin problem

My css looks like this
* {
margin: 0;
padding: 0;
}
body {
background-color: #FFFFFF;
}
div#header {
background-color: #969696;
height: 80px;
}
div#mid-bar {
background: url(images/home.jpg) left no-repeat #6f6565;
height: 200px;
}
#searchbox {
background-color: #c1c1c1;
width: 200px;
height: 180px;
margin: 10px 20px 10px 350px;
}
and my html
<div id="header">
</div>
<div id="mid-bar">
<div id="searchbox">
</div>
</div>
you can see the problem. the space between header and mid-bar which is created due to the margin given in the searchbox div.
i want this margin for searchbox within the mid-bar div... and not from header div.
I's a known bug: would use padding instead of margin. so:
div#mid-bar {
background: url(images/home.jpg) left no-repeat #6f6565;
height: 200px;
padding-top: 10px;
}
#searchbox {
background-color: #c1c1c1;
width: 200px;
height: 180px;
margin: 0px 20px 10px 350px;
}
Give padding to #mid-bar instead of searchbox margin
I have seen this happen when you don't give margins to parents and the first element, even a child that you give margin to, causes gaps in the parents by creating margins. One way I've overcome this is by using paddings on the parent containers instead of margins.
See your example here with paddings: http://jsbin.com/ememi3
If you are intent on using margins, try setting margin:0; in #mid-bar. Otherwise give #mid-bar a padding-top:10px; and remove top margin from #searchbox.
Everyone seems to agree on this one, padding will work much better then margins will. I looked into it a little and it seems Pixeline is right, it's a known bug in Firefox, hopefully they will fix it in 4.

Resources