I have a dynamically generated form that displays fine in all browsers that I have tested except IE6 & 7. I have headings that should be able to be placed either above or to the side of the form inputs. For radio buttons and check boxes I want the control to the left of the label, for all other inputs I want the control to the right. The HTML should be the same for both, only the CSS should change.
() Radio 1 () Radio 2
[] Checkbox 1 [] Checkbox 2
Text |____________|
etc.
or
Radio 1 Radio 2
() ()
Checkbox 1 Checkbox 2
[] []
Text
|____________|
etc.
So far I've got
<span class="control">
<label for="a1" class="forbutton">A1</label>
<input type="checkbox" id="a1" class="form-input-checkbox" name="a" value="1"/>
</span>
or something similar for each input. The CSS is
.forbutton {
margin-bottom: 0.20em;
float: right;
}
.control {
display: inline-block;
vertical-align: text-top;
position: relative;
}
/* Only if you want labels above inputs */
.form-input-checkbox,
.form-input-radio {
display: block;
clear: both;
}
In IE6 & 7 the <span>s end up being 100% width instead of taking the width of their content (as with the other browsers, including IE8). How can I fix this easily? If I give the span a width it does fix it, however, I don't know how wide it should be since the labels are dynamically generated.
Goals:
Valid HTML
Valid CSS
Labels before inputs in HTML code
Same HTML code for labels above and labels to the side
Any solution that achieves the same outcome will be gratefully accepted!
I would recommend getting rid of "display:inline-block" on that span. IE7 and earlier versions do not understand it.
Additionally, the other styles that you have on that element, in this example, don't really warrant the use of inline-block. Span is inline by default, I would just leave it that way.
I only have this problem in chrome. How remove the border around the image? please see the fiddle in chrome.
<form>
<input type="image" class="searchbox_submit search_btn" value="">
</form>
form input[type=text]:focus, form input[type=password]:focus, textarea:focus {
outline: none;
}
.search_btn {
background: url("http://static.ak.fbcdn.net/rsrc.php/v1/yu/r/yo348KDuskF.png") no-repeat scroll 0px -200px transparent;
height: 25px;
width: 30px;
outline: none;
border: none;
outline-width: 0;
-webkit-appearance: none;
}
Demo: http://jsfiddle.net/TXYg6/
You're using <input type="image" />, so a src attribute is expected. You haven't specified one, so Chrome shows a grey border, in the same way it does for an img with no src attribute.
If you want to stick to using <input type="image" /> and using a CSS sprite, you're going to have to specify something as the src, such as a 1x1 transparent "blank.gif".
http://jsfiddle.net/thirtydot/TXYg6/14/
However, that just seems horrible. Instead, I recommend switching to <input type="submit" />, which solves the problem.
replace it like that with submit type
<input type="submit" class="searchbox_submit search_btn" value="">
correct your css height and width
Give it a blank image as a src using a data: URI. Since you're only concerned with Chrome, there's no problem:
<input type="image" class="searchbox_submit search_btn" value="" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAadEVYdFNvZnR3YXJlAFBhaW50Lk5FVCB2My41LjEwMPRyoQAAAA1JREFUGFdj+P//PwMACPwC/ohfBuAAAAAASUVORK5CYII=">
http://jsfiddle.net/TXYg6/23/
Chrome gives a border/outline thingo to any image without a src, you could set the input type to 'submit' and this will go away.
Alternatively, use an with a src and trigger the submit from this, but you may as well just use a type="submit"
unwanted chrome borders
Do you really need that att type="image"? Because that's the thing causing the problem...
Semantically I'd say use a button since you don't actually have an associated input value, and as such it's not an input:
<button type="submit" class="searchbox_submit search_btn"></button>
From the docs:
Buttons created with the BUTTON element function just like buttons
created with the INPUT element, but they offer richer rendering
possibilities: the BUTTON element may have content. For example, a
BUTTON element that contains an image functions like and may resemble
an INPUT element whose type is set to "image", but the BUTTON element
type allows content.
Cheers
I'm working on a mobile template for my site and I want a textbox inside a div to be width:100% with an html submit button beside it, however the button always seems to wrap to the second line. Can someone help me out with some CSS for this?
<style type="text/css">
.form_input {}
.form_submit{}
</style>
<div>
<input type="text" name="s" value="" class="form_input" />
<input type="submit" value="Search" class="form_submit" />
</div>
The wrapping happens because of the workings of the css box model. 100% means 100% of the context box. So the input field will fill the line completely -> the submit button has to wrap to the next line. You can give the input box a width of e.g. 80% and the submit button a width of 20%.
I guess what you really want to do is something like input{ width: 100% - 200px }, submit {width: 200px}. That is not possible with css2.
Set the div to position:relative; and then set both the textbox and submit button to absolute position:
div.box{ position:relative; }
input[type="text"]{position:absolute;left:0;top:0;}
input[type="submit"]{positon:absolute;right:0;top:0;}
If you set the textbox to width: 100%;, then it will take up all the space available, and always push the submit button down.
This code specifies a width for both input elements:
.form_input {
width: 70%;
}
.form_submit{
width: 20%;
}
and they will be on the same line. (70% + 20% = 90% because I've left a little room for margins.)
Newbie CSS question. I thought width:auto for a display:block element meant 'fill available space'. However for an <input> element this doesn't seem to be the case. For example:
<body>
<form style='background:red'>
<input type='text' style='background:green; display:block; width:auto'>
</form>
</body>
Two questions then:
Is there a definition of exactly what width:auto does mean? The CSS spec seems vague to me, but maybe I missed the relevant section.
Is there a way to achieve my expected behavior for a input field - ie. fill available space like other block level elements do?
Thanks!
An <input>'s width is generated from its size attribute. The default size is what's driving the auto width.
You could try width:100% as illustrated in my example below.
Doesn't fill width:
<form action='' method='post' style='width:200px;background:khaki'>
<input style='width:auto' />
</form>
Fills width:
<form action='' method='post' style='width:200px;background:khaki'>
<input style='width:100%' />
</form>
Smaller size, smaller width:
<form action='' method='post' style='width:200px;background:khaki'>
<input size='5' />
</form>
UPDATE
Here's the best I could do after a few minutes. It's 1px off in FF, Chrome, and Safari, and perfect in IE. (The problem is #^&* IE applies borders differently than everyone else so it's not consistent.)
<div style='padding:30px;width:200px;background:red'>
<form action='' method='post' style='width:200px;background:blue;padding:3px'>
<input size='' style='width:100%;margin:-3px;border:2px inset #eee' />
<br /><br />
<input size='' style='width:100%' />
</form>
</div>
"Is there a definition of exactly what width:auto does mean? The CSS
spec seems vague to me, but maybe I missed the relevant section."
No one actually answered the above part of the original poster's question.
Here's the answer:
http://www.456bereastreet.com/archive/201112/the_difference_between_widthauto_and_width100/
As long as the value of width is auto, the element can have horizontal
margin, padding and border without becoming wider than its container...
On the other hand, if you specify width:100%, the element’s total
width will be 100% of its containing block plus any horizontal margin,
padding and border... This may be what you want, but most likely it isn’t.
To visualise the difference I made an example:
http://www.456bereastreet.com/lab/width-auto/
ORIGINAL answer using Angular: Because input's width is controlled by it's size attribute, this is how I initialize an input width according to its content:
<input type="text" class="form-list-item-name" [size]="myInput.value.length" #myInput>
UPDATE for JavaScript (10/01/2022): My original answer was from the time I was studying Angular. If you need pure, Vanilla JavaScript the solution is even simpler:
<input type="text" oninput="this.size = this.value.length">
Or add an "input" event listener to your input html element and run a code like this:
const myInput = document.querySelector('input');
myInput.addEventListener('input', this.typing);
(...)
typing(e) {
e.target.setAttribute('size', e.target.value.length);
}
Obs: Depending on the browser, input may restore to its default size of something between 150px and 250px if/when size gets the 0 value. In this case, just add +1 to value.length:
<input type="text" oninput="this.size = this.value.length + 1">
OR:
typing(e) {
e.target.setAttribute('size', e.target.value.length + 1);
}
As stated in the other answer, width: auto doesn't work due to the width being generated by the input's size attribute, which cannot be set to "auto" or anything similar.
There are a few workarounds you can use to cause it to play nicely with the box model, but nothing fantastic as far as I know.
First you can set the padding in the field using percentages, making sure that the width adds up to 100%, e.g.:
input {
width: 98%;
padding: 1%;
}
Another thing you might try is using absolute positioning, with left and right set to 0. Using this markup:
<fieldset>
<input type="text" />
</fieldset>
And this CSS:
fieldset {
position: relative;
}
input {
position: absolute;
left: 0;
right: 0;
}
This absolute positioning will cause the input to fill the parent fieldset horizontally, regardless of the input's padding or margin. However a huge downside of this is that you now have to deal with the height of the fieldset, which will be 0 unless you set it. If your inputs are all the same height this will work for you, simply set the fieldset's height to whatever the input's height should be.
Other than this there are some JS solutions, but I don't like applying basic styling with JS.
It may not be exactly what you want, but my workaround is to apply the autowidth styling to a wrapper div - then set your input to 100%.
If you're willing to include a little JavaScript to solve this, you can get exact sizing. This doesn't rely on approximating width with size or ems, doesn't rely on any hardcoded element widths, and works for e.g., type="number", which don't accept a size attribute.
The trick is to get your input sized exactly like a span with the same content, by actually having an invisible span with the same content.
Put your input inside a div along with a span that mirrors the input's value. Give both the input and the span the same styling, give the input 100% width, then hide the span and absolute-position the input to sit on top of the span.
This way, the container (and thus the input) are automatically sized by the visual appearance of the content of the invisible span.
https://codepen.io/spiffytech/pen/abwWRqo
<div id="relative-parent">
<span id="size-calibration"></span>
<input id="autosized-input" />
</div>
<style>
#relative-parent {
position: relative;
/* Have some width if the input is empty */
min-width: 1em;
/* Adjust size to match the span */
width: min-content;
}
#size-calibration {
visibility: hidden;
/* Prevent the span from wrapping the text when input value has multiple words, or collapsing multiple spaces into one */
white-space: pre;
}
#autosized-input {
position: absolute;
left: 0;
width: 100%;
}
#size-calibration, #autosized-input {
/* Normalize styles that the browser sets differently between spans and inputs.
Ideally, use a "CSS reset" here. */
font-family: "Arial";
padding: 0;
/* Demonstrate that this works for input with custom styles */
font-size: 24px;
}
</style>
<script>
function updateSize() {
const span = document.getElementById('size-calibration');
const input = document.getElementById('autosized-input')
span.innerText = input.value;
}
document.addEventListener('DOMContentLoaded', () => {
const input = document.getElementById('autosized-input');
input.oninput = updateSize;
// Provide some initial content
input.value = "I'm sized exactly right!"
updateSize();
})
</script>
After tried methods all above and failed, I workaround by modifying width property in style by unit em:
tgt.style.width = `${(tgt.value.length + 1) / 2}em`
The only option I can think of is using width:100%. If you want to have a padding on the input field too, than just place a container label around it, move the formatting to that label instead, while also specify the padding to the label. Input fields are rigid.
Answer 1 - "response" gave a nice answer/link for it. To put it in short, "auto" is the default, so it is like removing any changes in the width of an element
Answer 2 - use width: 100% instead. It will fill the 100% of the parent container, in this case, the "form".
Using JQuery
$(document).on('input', '.input-fit-width', (e) => {
$(e.currentTarget).attr('size',e.currentTarget.value.length);
})
Nowdays, flex or grid makes it much easier , it overrides default style/behaviors of https://developer.mozilla.org/en-US/docs/Web/HTML/Element/Input#size which has a default value set at 20 see : https://developer.mozilla.org/en-US/docs/Web/HTML/Element/Input#size
Giving you 2 plain CSS options without requiring JavaScript nor setting width to 100% and deal with box-sizing.
flex/flex-grow
<form style='background:red;display:flex;'>
<input type='text' style='background:green; flex-grow:1'>
</form>
grid
<form style='background:red;display:grid;'>
<input type='text' style='background:green;'>
</form>
Jquery way of adjusting size of input automatically.
In general:
$('#my_input_id').width( ($('#my_input_id').val().length) + "ch" );
On text input:
$(document).on("input", '#my_input_id', function () {
$(this).width( ($(this).val().length) + "ch" );
});
I think the simplest solution is to set parent element's width:
form{
width: 100%!important;
}
I am creating an MVC 1.0 form to use in multiple views. I have some elements that need to be shown on the same line, and I have done this by setting the display to "display: inline" for the style. I have also added the margin-left setting to the CSS in order to force the gap between the inline elements but this doesn't appear to be being set.
My CSS has:
fieldset label.inline
{
display: inline;
margin-left: 2em;
}
The view code is:
<fieldset>
<legend>Details</legend>
<p>
<label for="StartTime">Start Time:</label>
<%= Html.TextBox("StartTime", Model.StartTime.ToShortTimeString())%>
<label for="NextDay" class="inline">Next Day?</label>
<%= Html.CheckBox("NextDay") %>
<%= Html.ValidationMessage("StartTime", "*")%>
</p>
</fieldset>
Setting the size in the "margin-left" style has no impact on the space between the StartTime control and the NextDay label. How can I create this gap between the elements?
Use display: inline-block;
What browser are you testing in?
If you're using Firefox, use the Firebug extension. Use the pointer tool to select one of your elements, and then use the Layout tab to look at the box model. That will show you the padding, border and margins that are being applied. If you post the HTML being generated and the box model properties that are being calculated you might get better answers.
The "margin" style works different for inline elements. You can use the "inline-block" display-mode:
fieldset label.inline { display: inline-block; margin-left: 2em; }