Input in div container, won't stretch - html

I have a div containing an input. I want the input to stretch to fill the available space, this works in Chrome but not IE and Firefox.
<div class="outer">
<input type="text" />
</div>
.outer{
width: 100%;
height: 40px;
position: relative;
}
input{
position: absolute;
top: 7px;
bottom: 7px;
left: 7px;
right: 7px;
}
JSFiddle: http://jsfiddle.net/wwMZg/1/
In Chrome it appears like this:
In Firefox and IE it appears like this:
In my real-use scenario there are other divs that contain images for corners, that's why the top, left, right, bottom values are set to 7px in this example.
I would like to avoid setting the width directly on the input, I wan't to set it on .outer.

Most input elements have padding/borders on them. You need to use the box-sizing property to adjust how the element dimensions are calculated.
http://jsfiddle.net/wwMZg/5/
.outer {
width: 100%;
height: 40px;
}
.outer input {
width: 100%;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
http://caniuse.com/#search=box-sizing

If you cant use box-sizing because you need to support older browsers, and don't mind adding another element to the markup, you can use an intermediate div
CSS
.outer{
width: 100%;
height: 40px;
position: relative;
}
.inner {
position: absolute;
top: 7px;
bottom: 7px;
left: 7px;
right: 7px;
}
input{
width: 100%;
}
HTML
<div class="outer">
<div class="inner">
<input type="text" />
</div>
</div>
Fiddle: http://jsfiddle.net/2mFgR/

Controlling the stretching and height of an input element
This styling problem is a bit intriguing since the input element seems to have its own set of rules.
Consider the following HTML:
<div class="outer">
<div class="inner">
<input type="text" />
</div>
</div>
and the CSS:
.outer {
width: 100%;
font-size: 20px;
background-color: green;
overflow: auto;
}
.inner {
margin: 7px;
}
input {
font-size: inherit;
width: 100%;
border: none;
}
Wrapping the input field in the .inner element allows it to expand to 100% without triggering horizontal overflow on the top level container.
However, the margins will not be fully symmetric unless you set border: none on the input field. This could be fixed using box-sizing to deal with the width of the borders.
With respect to the height property, input behaves like a regular inline, non-replaced element, that is, the height value does not apply and you need to use the font-size to get some control over the height.
See demo at jsFiddle

add width:100% to your input style
.outer{
width:100%;
height: 40px;
position:absolute;
}
input{
position:relative;
top: 7px;
bottom: 7px;
width:100%;
padding:0px;
margin-left:-1px;
border:1px solid gray;
}
It's the border that's offsetting it in IE

Related

Dynamically width (and center) input based on length of input

I have absolutely positioned inputs which usually have 1 digit length as their input.
I set the input's width to 8px and everything works great. However, sometimes we can have up to 4 digits in the input. In this case, I want the input to automatically expand to fit, while retaining center alignment.
The inputs are positioned on a grid in a specific fashion and require absolute positioning.
For a simplified example, https://jsfiddle.net/joshuaohana/2var8ftL/1/
In this case I want to be able to type 1234 as an input, the box should expand with the input getting longer, and the center of the input box should remain in the same location.
<div class="container">
<div class="input1">
<input placeholder="1" />
</div>
<div class="input2">
<input placeholder="2" />
</div>
</div>
and the css
.container {
position: relative;
padding: 10px;
border: 1px solid blue;
width: 150px;
height: 150px;
}
.input1 {
position: absolute;
top: 5px;
left: 5px;
}
.input2 {
position: absolute;
top: 50px;
left: 25px;
}
input {
width: 8px;
}
The easiest way to make it happen is to have an element reflecting the value of an invisible input field. There is no way to adjust input width by the content without heavy trickery. That is, if you don't need full edit capabilities, like moving the cursor.
If you do, I would opt for having an invisible <div> element and setting its value to whatever you type in your <input>. Then, you'd read the width of that <div> and set the same width to your <input>. Just remember that they both need to have the same font-family, font-size and any other font-related property.
If you're open to using contenteditable then this should be easy to accomplish
.container {
position: relative;
padding: 10px;
border: 1px solid blue;
width: 150px;
height: 150px;
}
.input1 {
position: absolute;
top: 5px;
left: 5px;
}
.input2 {
position: absolute;
top: 50px;
left: 25px;
transform:translateX(-50%);
}
[contenteditable] {
border: 1px solid;
min-width: 8px;
max-width: calc(8px * 4);
white-space:nowrap;
overflow:hidden;
}
<div class="container">
<div class="input1">
<div contenteditable></div>
</div>
<div class="input2">
<div contenteditable></div>
</div>
</div>

button position absolute not working as expected

Can anyone explain why this button is not absolute-positioned to the right? I would expect it to be 3px from every edge.
HTML:
<div class="wrapper">
<button>Hello world</button>
</div>
CSS:
.wrapper {
height: 300px;
width: 300px;
background-color: #f33;
position: relative;
}
.wrapper button {
position: absolute;
top: 3px;
bottom: 3px;
left: 3px;
right: 3px;
}
Also, how is it that the button is able to align its contents vertically?
button, like most form elements, is a replaced element. Replaced elements behave differently from regular non-replaced elements (such as div) when absolutely positioned. The following two points from section 10.3.8 of CSS2.1 apply:
The used value of 'width' is determined as for inline replaced elements. If 'margin-left' or 'margin-right' is specified as 'auto' its used value is determined by the rules below.
...
If at this point the values are over-constrained, ignore the value for either 'left' (in case the 'direction' property of the containing block is 'rtl') or 'right' (in case 'direction' is 'ltr') and solve for that value.
The width of the button is determined not based on the specified offsets, unlike for non-replaced elements, but by the contents of the button itself. Since the used value of width is not auto, and the specified values of left and right are not auto, the values are over-constrained and the browser is forced to ignore right in order to respect width.
If you want the button to fill the entire height and width of the wrapper, don't use absolute positioning. Instead, specify 100% height and width on the button, and use padding on the wrapper to offset the button:
.wrapper {
height: 300px;
width: 300px;
background-color: #f33;
padding: 3px;
box-sizing: border-box;
}
.wrapper button {
height: 100%;
width: 100%;
}
<div class="wrapper">
<button>Hello world</button>
</div>
(If you can't use box-sizing, subtract the padding from the dimensions of the wrapper.)
The vertical alignment of the text probably has to do with how the browser draws button controls by default, which is usually based on system button controls.
You can use calc to get the exact width minus the padding you get from the positioning:
width: calc(100% - 6px);
JSFiddle
You might want to use inherit/100% value for width and height css properties.
.wrapper {
height: 300px;
width: 300px;
background-color: #f33;
padding: 3px;
}
.wrapper button {
width: inherit;
height: inherit;
}
Fiddle
NOTE: If you want to have the dimensions exactly 300 then subtract padding. (which will be 294px)
please use below css ..
.wrapper {
height: 300px;
width: 300px;
background-color: #f33;
position: relative;
padding: 3px
}
.wrapper button {
position: absolute;
top: 0;
bottom:0;
left:0;
right:0;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
width:100%;
}
I think you are trying to put button in center.You declared top and left 3px so no matter what you define bottom and right button is going to to be 3px from top and left ignoring other.To put button in center use marginFirst define width of button and set marginLike thia
.
wrapper button{
Width:100px;
margin:0px auto;
}
not margin doesn't work with absolute position.
.wrapper {
height: 300px;
width: 300px;
background-color: #f33;
position: relative;
}
.wrapper button {
position: absolute;
top: 3px;
bottom: 3px;width:97.5%;
right: 3px;
}
Try this.
You need to set the width of the button, to make it fill the space.
The easiest way to do this is to set it to the correct size.
.wrapper {
height: 300px;
width: 300px;
background-color: #f33;
position: relative;
}
.wrapper button {
position: absolute;
top: 3px;
bottom: 3px;
left: 3px;
right: 3px;
height: 294px;
width: 294px;
}

Border-box not working, overlay div is including the padding

I'm creating a gallery with images having an overlay dark background and caption text. The placement is alright but the overlay div is falling out of the bounds of the image because a padding is used on the container element.
I read about it at several places and learned that border-box could solve this problem but it isn't. Am I doing something wrong here? Check out the code:
HTML:
<div class="dest-item">
<img src="http://lorempixel.com/500/400">
<div class="dest-caption">
<div class="dest-text">
<h3>This is a caption</h3>
</div>
</div>
</div>
CSS:
.dest-item{
position:relative;
overflow:hidden;
z-index:1;
padding:10px;
width: 500px;
}
.dest-item img{
width: 100%;
}
.dest-caption{
position: absolute;
top: 0px;
background: rgba(0,0,0,0.2);
z-index: 2;
width: 100%;
height: 100%;
box-sizing: border-box;
}
.dest-text{
position: absolute;
bottom: 0;
background: rgba(255,255,255,0.9);
width: 100%;
padding: 0px 10px;
}
Playground link: Code Pen
Try this (fork here:http://codepen.io/anon/pen/RNqbjB)
CSS:
/*remove the padding*/
.dest-item{
position:relative;
overflow:hidden;
z-index:1;
padding:0px;
width: 500px;
}
HTML:
<!--Add a wrapper and add the padding to that-->
<div style="padding:10px;">
<div class="dest-item">
<img src="http://lorempixel.com/500/400">
<div class="dest-caption">
<div class="dest-text">
<h3>This is a caption</h3>
</div>
</div>
</div>
</div>
Remove the padding from whole dest-item div. you don't need that padding over there as I think:
.dest-item {
position: relative;
overflow: hidden;
z-index: 1;
/* padding: 10px; */
width: 500px;
}
Not sure if this is along the right lines?
.dest-item{
position:relative;
overflow:hidden;
z-index:0;
padding:10px;
width: 500px;
}
.dest-item img{
width: 100%;
}
.dest-caption{
position: absolute;
top: 0;
left: 0;
background: rgba(0,0,0,0.2);
width: 100%;
height: 100%;
}
.dest-text{
color: black;
position: absolute;
text-shadow: 2px 2px 40px rgba(255,255,255, 1);
bottom: 0;
left: 0;
background: rgba(255,255,255,0.38);
width: 100%;
padding: 2px 0px 10px 20px;
}
<div class="dest-item">
<img src="http://lorempixel.com/500/400">
<div class="dest-caption">
<div class="dest-text">
<h3>This is a caption</h3>
</div>
</div>
</div>
You don't need border-box to do what you want.
There are 3 types of box-sizing:
content-box is the default behavior and only includes the width and height. It does not account for padding or border width. If you have an element with 500px width + 10px padding + 1px border then the display size of the whole element is 522px wide and the size of the available space for actual content is 500px.
padding-box includes the padding but not the border. Same example as above, if you are using padding-box then the display size is 502px but the available content space is 480px.
border-box covers everything. So in our example, the display size is 500px but available space for content is 478px.
Margins are never counted in the size, in any case.
Depending on how you want the end result to look, then you will achieve this differently but based on your Code Pen sample, it looks like you want to fill the entire item container so the overlay cover the 10px padding as well. You can do this without changing the box-sizing for anything.
First, you need to offset your .dest-caption element to the left by 10px to account for the padding. Then you need to add 10px padding and remove the border-box attribute.
Like this:
.dest-caption {
position: absolute;
top: 0px;
left: -10px; /* offset */
background: rgba(0,0,0,0.5);
z-index: 2;
width: 100%;
height: 100%;
padding: 10px; /* add padding */
}
With that fixed, your text and its box is misaligned and the size of the box is not well-controlled. It is affected by the margin of the H3 tag. Fix this by removing the margins from the H3 tag inside of any .dest-text elements:
.dest-text H3 {
margin: 0px;
}
Without the margins on the H3 tag, the text overlay actually disappears out of the drawable area because it's misaligned. You can fix this by offsetting .dest-text from the bottom by the .dest-caption padding width (x2). You will probably also want top and bottom padding for .dest-text.
.dest-text {
position: absolute;
bottom: 20px; /* account for padding on .dest-caption */
background: rgba(255,255,255,0.9);
width: 100%;
padding: 10px 10px; /* add top/bottom padding */
}
Code Pen Link

Nested Divs Malfunctioning in Chrome

So i have nested divs in chrome
<div id="wrapper">
<div id="content">
</div>
</div>
The wrapper div is just a bordered container in the shape of a box. On safari/firefox the content resides inside of the box and 50% of chrome the content div resides in the box however the other 50% of the time it is outside of the box. I don't really know what to do as it works in Safari and firefox and for some reason is a toss up in chrome. Could it just my computer? Has anyone experienced this problem?
Thanks
#wrapper{
display: block;
position: absolute;
top: 5%;
left: 0;
margin: 0;
padding: 0;
width: 100%;
height: 90%;
background-color: #efefef;
}
#content{
height:78px;
width:100%;
border-bottom:solid 1px gray;
font-weight:1000;
margin-left:0px !important;
background-color:white;
}
Have you tried box-sizing: border-box; on the #wrapper?
When you use position: absolute; it removes the element from the natural element flow on the page. If you're able to, you should remove the absolute position.
Keep in mind that if you want to use height percentages, you will need to define the top level element to be 100%.
body,html {
width: 100%;
height: 100%;
}
Body and HTML will inherit from Window. Then all other elements on the page will inherit from body or html.
Here's the full:
body, html {
width: 100%;
height: 100%;
}
#wrapper{
display: block;
margin: 0;
padding: 0;
width: 100%;
height: 90%;
background-color: #efefef;
}
#content{
height:78px;
width:100%;
border-bottom:solid 1px gray;
font-weight:1000;
margin-left:0px !important;
background-color:white;
}
http://jsfiddle.net/twqxoc0j/
The trade-off, and most important thing to remember, about absolute
positioning is that these elements are removed from the flow of
elements on the page. An element with this type of positioning is not
affected by other elements and it doesn't affect other elements. This
is a serious thing to consider every time you use absolute
positioning. It's overuse or improper use can limit the flexibility of
your site.
From: http://css-tricks.com/absolute-relative-fixed-positioining-how-do-they-differ/

make <input type="file"> element fill up its parent <div>

HTML:
<div>
<img src="some/path/" class="thumbnail" />
<input type="file" class="image_upload" />
</div>
CSS:
div
{
border: 2px solid #ccc;
width: 50px;
height: 50px;
overflow: hidden;
}
.thumbnail
{
width: 100%;
}
.image_upload
{
opacity: 0;
position: absolute;
}
I want <img> and <input type="file"> to overlap with each other and both fill up their parent <div>. How can I fix my CSS to achieve that?
It is not possible to change the size of a file input. You could redesign the file-input and, but the size of the clickable area isn't modifiable.
Edit: Aaron shows a first trick, and I added the second one, so see this fiddle in which the whole image is clickable for the file input.
The trick is to set font-size to a large value, then opacity to zero and finally add overflow: hidden to the parent element.
File input fields don't really play by the rules (or at least as you'd expect). To accomplish what it sounds like you're after, you've gotta get creative. Example: http://jsfiddle.net/ZTPCd/
Its Possible.
Add this css for input type file
.My_CSS {
opacity: 0;
border: none;
border-radius: 3px;
background: grey;
position: absolute;
left: 0px;
width: 100%;
top: 0px;
height: 100%;
}
You'll need to add relative positioning to the parent div, so the input field won't be positioned relatively to the browser window. (Google for more info about absolute/relative positioning).
And you'll have to add some specific positioning (top/left) to the input tag.
http://jsfiddle.net/NbhQY/
(Your outer div will have to be a little bit bigger, though, if it needs to include a file upload.)
Here you need to use some JavaScript. Since I don't see any way to change the CSS for input(type=file) itself, I made it hidden but the <div> responsible for <input type='file'>.
var box = document.getElementById("box");
var file = document.getElementById("file");
box.addEventListener('click', function(){
file.click();
})
#box {
font-size: 30px;
text-align: center;
width: 300px;
height: 200px;
padding: 10px;
border: 1px solid #999;
position: relative;
}
p {
position: absolute;
top: 80px;
color: white;
}
#file {
width: 100%;
height: 100%;
visibility: hidden;
z-index: 100;
}
<div id="box">
<img id="image" src="http://guide.denverpost.com/media/photos/full/mountain_600x600.jpg" width="100%" height="100%"/>
<input type="file" id="file"/>
<p>Click to import</p>
</div>