Label and input layout using css - html

I'm trying to line up a label and an input box on the same line in such a way that the label takes up all the space it needs and then the input box uses all of the remaining space. For example if the container was 1000px and the label was 342px then the input should be 658px wide. But if the label changed to 100px the input should resize to 900px. I could do this using a table layout, or using JavaScript to resize the input box when the label width changes but ideally I would like to do this using only css. My html looks like this.
<div id="container">
<label for="inputBox">variable text</label>
<input type="text" id="inputBox" />
</div>
Thanks,
Edit: To help illustrate what I'm trying to do here is an example using tables.
<table style="background-color:#ddd;width:500px;">
<tr>
<td style="width:0;white-space:nowrap;"><label style="width:100%">text</label></td>
<td><input style="width:100%" type="text" /></td>
</tr>
</table>

The correct way would be:
#container { width: 1000px; display: table }
#container label { display: table-cell; white-space: nowrap; }
#inputBox { width: 100%; display: table-cell; }
but that won't work in IE 6 or 7.

#container { margin-left: 100px; position: relative; }
#container label { position: absolute; left: -100px; }
#container input { width: 100%; }
(You can use box-sizing and its browser-specific versions to make sure the borders of the input line up nicely if necessary, and if you need that in IE6-7 too, a bunch of padding hacks to accomodate the extra pixels.)
This requires that the size of the label be known. It can't be made to depend on the width of the text content of label (ie ‘shrink-wrap’) without a bunch of extra markup (which wouldn't really be any better than using tables).
When liquid-layout forms get any more complicated than this, you do typically need to go to tables. Traditional CSS positioning isn't great at distributing widths between fixed, liquid, and shrink-wrap contents.

This CSS should work:
#container { width: 1000px; white-space: nowrap; }
#inputBox { width: 100%; }
Of course you can adjust the width of the container to suit your needs.
EDIT:
The above CSS expands the inputBox to be 1000px and therefore makes the div width greater than wanted.
To achieve the effect you want you can use the overflow property as described in http://www.stubbornella.org/content/2009/07/23/overflow-a-secret-benefit/ and a bit of an additional markup:
<div id="container">
<label for="inputBox">variable text</label>
<div><input type="text" id="inputBox" /></div> <!-- Notice the input is wrapped in an additional div -->
</div>
The CSS:
#container { width: 1000px; white-space: nowrap; }
#container label { float: left; margin-right: 5px; /* The label must be a floating element, the margin adds a little space to visually separate it from the input field */ }
#container div { overflow: hidden; /* This does the trick */ }
#inputBox { width: 100%; }

Related

Centered table-like layout with columns of equal widths using CSS?

On a web page, I have a row of submit buttons.
This row of buttons should be centered on the page
Each button should be as wide as the widest button (i.e no fixed/hard-coded button widths).
This is easily done with a <table>, but as people keep telling me those are bad for you, I wondered if this can be done with CSS instead. So, I have tried the display: table and table-cell CSS classes, but either the buttons don't get equal widths, or the longest button's caption gets clipped:
.button-row {
display: table;
margin: auto;
table-layout: fixed;
}
.button-row button {
white-space: nowrap;
display: table-cell;
width: 50%;
}
<div class="button-row" >
<button>Short caption</button>
<button>A much longer caption</button>
</div>
Actually, it does look correct in IE, but not in Chrome and Firefox. Here is a fiddle with both my table- and CSS-attempt:
http://jsfiddle.net/kfwhpre8/
If possible, I would like to get rid of the width: 50% settings, because the number of buttons may vary, but that's easy enough to calculate.
Looking at your fiddle, keep in mind that in the table version the buttons are contained in tds. This is the essence of the problem. It appears using table-cell on buttons directly is problematic. If you don't mind chaniging your HTML you can try:
<div class="button-row">
<div>
<button>Short caption</button>
</div>
<div>
<button>A much longer caption</button>
</div>
</div>
.button-row {
display: table;
margin: auto;
table-layout: fixed;
}
.button-row>div {
display: table-cell;
width: 50%;
}
.button-row button {
width:100%;
}
Fiddle
prob not the answer you are looking for as you said you want to get rid of the width:50%
If you set the width:100% in the button-row button{}all the buttons will be as wide as the widest button
.button-row button {
display: table-cell;
width: 100%;
}
I'm unsure if this would suffice, as you'd have to check each time a new button was added, as to the best size for them. But you could simply add a width to each button and a margin to replicate the table layout.
At least in the HTML's current form.
.button-row button {
display: table-cell;
width: 150px;
margin: 1px;
}
Fiddle: http://jsfiddle.net/kfwhpre8/3/

Fill remaining width inside parent that is also filling remaining width

I have a fixed-size navbar (using Bootstrap) that contains four divs. These divs contain a logo, some links/dropdowns and a search box:
┌────────────────────────────navbar (fixed-size)──────────────────────────────┐
│┌───logo───┐┌───dropdown───┐┌───────────links──────────┐┌────search box─────┐│
││fixed-size││ fixed-size ││ variable width ││ fill remaining ││
│└──────────┘└──────────────┘└──────────────────────────┘└───────────────────┘│
└─────────────────────────────────────────────────────────────────────────────┘
I want the search box (the box on the far right) to fill the remaining space in the container. The search box comprises an input and a button:
┌─────────────────────────────────┐
│┌─────────────────────┐┌────────┐│
││ <input> ││<button>││
│└─────────────────────┘└────────┘│
└─────────────────────────────────┘
The button has a fixed size but I want the input to scale horizontally, stretching the search box to fill its parent (the nav-bar).
Edit: To clarify, I want the search box to take up the (horizontal) space left over from when it's siblings (logo, dropdown and links) have taken up their space. Since the search box is made out of an input and a button and the button will have a fixed width, I want the input to expand and push the search box's boundaries until the search box fills the space it's siblings left in the navbar
This is how I would do it: http://jsfiddle.net/vU52q/
You have your wrapper and child elements:
<div class="search">
<input type="text" />
<button type="submit">Go</button>
</div>
And you set the container to position: relative; and your submit button to position: absolute; and give the container enough padding for the button.
.search {
box-sizing: border-box;
background: #0f0;
padding: 5px 100px 5px 5px;
position: relative;
width: 300px;
}
.search input {
width: 100%;
}
.search button {
position: absolute;
top: 5px;
right: 5px;
width: 85px;
}
That way, the input is always the width of the parent element minus the width of the fixed width button.
You could also play with inline alignment and css calc, but this is my preferred way.
If you want to play with calc, you can check this out, and it might provide more of an option to add additional fixed size elements: http://jsfiddle.net/ug7a9/
This takes into account each section and explicitly adds it to the width calculation.
<div class="search">
<button type="submit">Go</button><!--
--><button type="submit">Go</button><!--
--><input type="text" /><!--
--><button type="submit">Go</button>
</div>
The comments are in there to prevent space in between elements (you can also do a font-size: 0) on the .search element.
* {
box-sizing: border-box;
}
.search {
background: #0f0;
position: relative;
width: 300px;
}
.search input {
display: inline-block;
width: calc(100% - 50px - 50px - 50px);
}
.search button {
display: inline-block;
width: 50px;
}
You'd want to be a bit more explicit with your selectors (i.e. don't do *), but for quick demo purposes I put this in.
you can use the calc function but not is cross-browser
calc(100% - element size);
http://jsfiddle.net/8CQHP/
You can see the support in caniuse.com
I ended up changing my code and using the idea from the solution Chad provided in the comment to his answer. I also used his absolute-positioned button trick. This is what I did:
I used a span for the search box and moved the button out of the search box straight into the nav:
<nav>
...
<span>
<input type="text" placeholder="Search...">
</span>
<button class="searchBtn" type="button"></button>
</nav>
Using this css:
span {
display: block; /*This is the trick from*/
overflow: hidden; /*the solution Chad provided*/
}
input {
width: 100%;
padding-right: 65px; /*This is to make room*/
} /*for the button*/
button {
position: absolute;
right: 0px;
top: 0px;
}
overflow: hidden on the span makes it all possible. Read about it here: http://colinaarts.com/articles/the-magic-of-overflow-hidden/#making-room-for-floats

How do i make a fieldset `display: block; overflow: auto` show a scrollbar?

I want my <fieldset> elements to behave like vanilla <div>'s by filling their containing element and showing a scrollbar when they are set to overflow: auto.
For instance, I don't see why the fieldset in this
example is wider than its containing div:
<div class=outer>
<fieldset class=inner>
fooooooooooooooooooooooooooooooooooooo
</fieldset>
</div>
<div class=outer>
<div class=inner>
fooooooooooooooooooooooooooooooooooooooo
</div>
</div>
and corresponding css:
.outer {
width: 60px;
}
.inner {
overflow: auto;
display: block;
height: 60px;
border: 1px solid red;
}
It turns out the culprit (in some cases) was the user-agent stylesheet in webkit was setting:
fieldset {
min-width: -webkit-min-content;
}
setting min-width: 0; in the stylesheet corrected the issue in Chrome 27, Safari 6.0.2, and WebKit Nightly r146031. It fails to correct the issue in Chrome 25 and FireFox 19.0.2.
Either way this does not solve the problem.
<fieldset> does not inherit the width from the parent div. The .inner div does inherit the width and shinks. You can solve this just by adding width: inherit as a rule to .inner. Note that <fieldset> may also get some extra padding and margin.
http://codepen.io/anon/pen/fxjek
To fix your fieldset or make it like the div below it in your example, add the following css::
fieldset{
margin:0px;
padding:0px
}
you need to reset the margin and padding first to act like the div below it then add the width you want :
.inner {
width:60px;
}
The reason the Fieldset version is wider than the div version is because
fieldset has its own default padding unless you specify otherwise.
See: http://jsfiddle.net/RDVY7/
I added this to your CSS:
fieldset {
margin:0 ;
padding:0 ;
}
and it fixed the problem. If you want spacing between your fieldset version
and your div, just adjust the margin: element.

Cannot set pixel width of div using css width attibute

I'm trying to set up a div which contains 4 divs. I want to set the width of the container and some of the contained divs to set values but they just seem to take the width of the content.
<html>
<head>
<style>
div {
border: 1px solid #888;
}
.container {
width: 300px;
position: relative;
}
.container div {
display: inline;
}
.div1 {
width: 20px;
overflow: hidden;
}
.div2 {
width: 80px;
overflow: hidden;
}
.div3 {
width: 160px;
overflow: hidden;
}
.div4 {
width: 20px;
overflow: hidden;
position: absolute;
top:0px;
right: 0px;
}
</style>
</head>
<body>
<div class="container">
<div class="div1"><img src="1x1.gif" width="1" height="1"/></div>
<div class="div2"><span>date</span></div>
<div class="div3"><span>text</span></div>
<div class="div4"><span>twistie</span></div>
</div>
</body>
</html>
The result looks like this:
+--+----+----+------------------------+---+
| |date|text| |twi|
+--+----+----+------------------------+---+
Can anyone explain why the left-hand divs are not being set to the required widths?
The reason you can't set the widths is because you are setting display:inline;.
When elements are displayed inline, they cannot have their dimensions specified because the size of the element is determined by the length of the text within it.
By default, <div> tags are set to display:block;. This mode can have its height and width specified, but defaults to being displayed below the preceding block.
There are two ways around this for you:
Use display:block; and float:left; -- This will change the blocks into floating elements, which means that subsequent elements will wrap around them. When used with other blocks, this effectively allows you to line them up. However using float can have other unexpected side-effects, due to the wrap-around effect I described.
Use display:inline-block; -- This is my preferred solution to this question. inline-block is a half-way house mode between block and inline. It allows an element to be treated as inline for the purposes of document flow, but still behave like a block internally, in that it will always be rectanguar and you are able to specify height and width, etc. It does have a few quirks (most notably poor support in IE6), but in general for what you're trying to achieve, it's a much cleaner solution and doesn't have the odd side-effects of float.
Hope that helps.
i think it's because of display:inline style
try this:
<div style='width:100px;overflow:hidden;'>
<div style='float:left;width:20px'></div>
<div style='float:left;width:20px'></div>
<div style='float:left;width:20px'></div>
<div style='clear:both;'></div>
</div>
Change your CSS as follows
.container div {
display: inline-block;
}
When you set the container div to inline, you actively set all of its children to inline as well, you may as well have just been using <span>s.
Here is an example for you to see.
http://jsfiddle.net/Kyle_Sevenoaks/ZwKDb/
.container {
float: left;
width: 300px;
position: relative;
}
.container div {
float: left;
}
Should do the trick. Remove the inline display on the interior divs, and float all the divs left. Then you can specify the widths of the divs and any margins between them.

HTML input element wider than Containing Div

I have an html element that is contained within a div. Height are dictated by the outer div and the height and width of the input control are 100%. At the most basic level, I am having an issue where the textbox extends past the right of the containing div.
Basic example code:
<div style="height:25px; width: 150px;">
<input type="text" style="height:100%; width:100%" />
</div>
The rendering of this control is far more complex than this, but still when the control is stripped down to this level, I have an issue where the textbox sticks out past the containing div.
You can use box-sizing:border-box to take care of this. Just put the following in your css file:
input{box-sizing:border-box}
It means that border on the input box is actually inside the width of the input rather than being added onto the outside. This is what is making the input larger than the container.
Paul Irish has really good post explaining this technique http://paulirish.com/2012/box-sizing-border-box-ftw
The points he makes about padding also apply for the border.
There's even a compass mixin to make it easier to support older browsers. (http://compass-style.org/reference/compass/css3/box_sizing/)
This did the job for me :
input {
padding: 0.2em;
box-sizing: border-box;
width: 100%
}
Try to give input width : 100%; box-sizing: border-box;
unfortunately this will depend on the browser you are working with but setting the width of the object (the textbox) does not take into account the width of the border on the object. most browsers only take into consideration any padding from the outer object and margins from the contained object but a few (i'm looking at you IE) do not add in the border when calculating percentages;
your best bet is to change the border on the textbox or to throw in another div between teh textbox and the container with a padding of say 2px with a margin-top: -2px and a margin-left:-2px (i'm guessing at the border width)
I'm assuming that you want the contained element (<input>) to be smaller than, or contained entirely within, the <div>?
You can either:
input {width: 50%; /* or whatever */ }
An html-element's width is calculated (I think) as the defined width + borders + margin + padding
If you've already defined the input as having 100% width of the parent, and then the other attributes are added it will definitely overflow the parent div.
You can set the margin/padding/borders to 0, but that would likely not look good. So it's easier, though not necessarily perfect, just to use a suitably-smaller width.
You could, of course, use
#parent_div {overflow: hidden; /* or 'auto' or whatever */}
to hide the portion of the input element that would normally overflow the container div.
Please apply the following css to your input elements.
{
box-sizing: border-box;
width: 100%;
}
if you use bootstrap or other css library, it will be not problem.
I know this post is fairly old, but it's a common problem and no one posted any good answers...
The following HTML code looks fine. But when I add the doctype, the problem appear
div.field_container
{
height: 25px;
width: 150px;
border: 1px solid red;
}
div.field_container input
{
height: 100%;
width: 100%;
}
<div class="field_container">
<input type="text" name="" value="" />
</div>
To fix the width / height problem, you can add padding to your field_container, but that will make the container bigger.
div.field_container
{
height: 25px;
width: 150px;
padding-bottom: 6px;
padding-right: 4px;
border: 1px solid red;
}
div.field_container input
{
height: 100%;
width: 100%;
}
<div class="field_container">
<input type="text" name="" value="" />
</div>
If you can't change the container width, you can also use the following trick, but that will still increase the height
div.field_container
{
height: 25px;
width: 150px;
padding-bottom: 6px;
border: 1px solid red;
}
div.field_container input
{
height: 100%;
width: 100%;
}
<div class="field_container">
<div style="height: 100%; margin-right:4px"><input type="text" name="" value="" /></div>
</div>
Instead of applying the style directly on the input element, maybe abstract the CSS into a file and use classes:
div.field_container
{
height: 25px;
width: 150px;
}
div.field_container input
{
height: 100%;
width: 100%;
}
<div class="field_container">
<input type="text" name="" value="" />
</div>
I am running out the door before I could test if this helps at all, but at the very least, you could play with max-height/width settings on the DIV css to make it not break if my solution doesn't work. And having the CSS abstracted like this makes problems easier to solve using a plugin like Firebug in Firefox.
Question though, is there a need to enclose the input tag in it's own DIV? I wouldn't be surprised if there is just a better layout you could build that would avoid the need to do this...