I have design problem with Google Chrome and its form autofill function.
If Chrome remembers some login/password it changes a background color to a yellow one.
Here are some screenshots:
How to remove that background or just disable this autofill ?
Change "white" to any color you want.
input:-webkit-autofill {
-webkit-box-shadow: 0 0 0 1000px white inset !important;
}
If you guys want transparent input fields you can use transition and transition delay.
input:-webkit-autofill,
input:-webkit-autofill:hover,
input:-webkit-autofill:focus,
input:-webkit-autofill:active {
-webkit-transition-delay: 9999s;
-webkit-transition: color 9999s ease-out, background-color 9999s ease-out;
}
Solution here:
if (navigator.userAgent.toLowerCase().indexOf("chrome") >= 0) {
$(window).load(function(){
$('input:-webkit-autofill').each(function(){
var text = $(this).val();
var name = $(this).attr('name');
$(this).after(this.outerHTML).remove();
$('input[name=' + name + ']').val(text);
});
});
}
In Firefox you can disable all autocomplete on a form by using the autocomplete="off/on" attribute. Likewise individual items autocomplete can be set using the same attribute.
<form autocomplete="off" method=".." action="..">
<input type="text" name="textboxname" autocomplete="off">
You can test this in Chrome as it should work.
If you want to preserve the autofill, as well as any data, attached handlers and functionality attached to your input elements, try this script:
if (navigator.userAgent.toLowerCase().indexOf("chrome") >= 0)
{
var _interval = window.setInterval(function ()
{
var autofills = $('input:-webkit-autofill');
if (autofills.length > 0)
{
window.clearInterval(_interval); // stop polling
autofills.each(function()
{
var clone = $(this).clone(true, true);
$(this).after(clone).remove();
});
}
}, 20);
}
It polls until it finds any autofill elements, clones them including data and events, then inserts them into the DOM in the same location and removes the original. It stops polling once it finds any to clone since the autofill sometimes takes a second after page load. This is a variation of a previous code sample, but more robust and keeps as much functionality intact as possible.
(Confirmed working in Chrome, Firefox and IE 8.)
The following CSS removes the yellow background color and replaces it with a background color of your choosing. It doesn't disable auto-fill and it requires no jQuery or Javascript hacks.
input:-webkit-autofill {
-webkit-box-shadow:0 0 0 50px white inset; /* Change the color to your own background color */
-webkit-text-fill-color: #333;
}
input:-webkit-autofill:focus {
-webkit-box-shadow: /*your box-shadow*/,0 0 0 50px white inset;
-webkit-text-fill-color: #333;
}
Solution copied from:
Override browser form-filling and input highlighting with HTML/CSS
Worked for me, only the css change required.
input:-webkit-autofill {
-webkit-box-shadow: 0 0 0px 1000px #ffffff inset!important;
}
you can put any color in place of #ffffff.
A little bit hacky but works perfectly for me
input:-webkit-autofill {
-webkit-box-shadow: 0 0 0px 1000px white inset;
}
A combination of answers worked for me
<style>
input:-webkit-autofill,
input:-webkit-autofill:hover,
input:-webkit-autofill:focus,
input:-webkit-autofill:active {
-webkit-box-shadow: 0 0 0px 1000px #373e4a inset !important;
-webkit-text-fill-color: white !important;
}
</style>
Here's the MooTools version of Jason's. Fixes it in Safari too.
window.addEvent('domready',function() {
$('username').focus();
if ((navigator.userAgent.toLowerCase().indexOf(\"chrome\") >= 0)||(navigator.userAgent.toLowerCase().indexOf(\"safari\") >= 0))
{
var _interval = window.setInterval(function ()
{
var autofills = $$('input:-webkit-autofill');
if (autofills.length > 0)
{
window.clearInterval(_interval); // stop polling
autofills.each(function(el)
{
var clone = el.clone(true,true).inject(el,'after');;
el.dispose();
});
}
}, 20);
}
});
This fixes the problem on both Safari and Chrome
if(navigator.userAgent.toLowerCase().indexOf("chrome") >= 0 || navigator.userAgent.toLowerCase().indexOf("safari") >= 0){
window.setInterval(function(){
$('input:-webkit-autofill').each(function(){
var clone = $(this).clone(true, true);
$(this).after(clone).remove();
});
}, 20);
}
This helped me, a CSS only version.
input:-webkit-autofill {
-webkit-box-shadow: 0 0 0px 1000px white inset;
}
where white can be any color you want.
I use this,
input:-webkit-autofill { -webkit-box-shadow: 0 0 0px 1000px white inset !important; }
input:focus:-webkit-autofill { -webkit-box-shadow: 0 0 0px 1000px white inset !important; }
/* You can use color:#color to change the color */
In your tag, simply insert this small line of code.
autocomplete="off"
However, do not place this in the username/email/idname field because if you are still looking to use autocomplete, it will disable it for this field. But I found a way around this, simply place the code in your password input tag because you never autocomplete passwords anyways. This fix should remove the color force, matinain autocomplete ability on your email/username field, and allows you to avoid bulky hacks like Jquery or javascript.
If you want to get rid of it entirely, I've adjusted the code in the previous answers so it works on hover, active and focus too:
input:-webkit-autofill, input:-webkit-autofill:hover, input:-webkit-autofill:active, input:-webkit-autofill:focus {
-webkit-box-shadow: 0 0 0 1000px white inset;
}
If you want to avoid the yellow flicker until your css is applied slap a transition on that bad boy like so:
input:-webkit-autofill {
-webkit-box-shadow: 0 0 0 1000px white inset !important;
transition: background-color 10s ease-in-out 0s;
}
Here's a Mootools solution doing the same as Alessandro's - replaces each affected input with a new one.
if (Browser.chrome) {
$$('input:-webkit-autofill').each(function(item) {
var text = item.value;
var name = item.get('name');
var newEl = new Element('input');
newEl.set('name', name);
newEl.value = text;
newEl.replaces(item);
});
}
What about that solution:
if ($.browser.webkit) {
$(function() {
var inputs = $('input:not(.auto-complete-on)');
inputs.attr('autocomplete', 'off');
setTimeout(function() {
inputs.attr('autocomplete', 'on');
}, 100);
});
}
It turns off the auto-complete and auto-fill (so yellow backgrounds disappear), waits 100 milliseconds an then turns the auto-complete functionality back without auto-fill.
If you have inputs that need to be auto-filled, then give them auto-complete-on css class.
None of the solutions worked for me, the username and password inputs were still being populated and given the yellow background.
So I asked myself, "How does Chrome determine what should be autofilled on a given page?"
"Does it look for input ids, input names? Form ids? Form action?"
Through my experimentation with the username and the password inputs, there were only two ways I found that would cause Chrome to not be able to find the fields that should be autofilled:
1) Put the password input ahead of the text input.
2) Give them the same name and id ... or no name and id.
After the page loads, with javascript you can either change the order of the inputs on the page, or dynamically give them their name and id ...
And Chrome doesn't know what hit it ... autocomplete stays off.
Crazy hack, I know. But it's working for me.
Chrome 34.0.1847.116, OSX 10.7.5
The only way that works for me was:(jQuery required)
$(document).ready(function(e) {
if ($.browser.webkit) {
$('#input_id').val(' ').val('');
}
});
I fixed this issue for a password field i have like this:
Set the input type to text instead of password
Remove the input text value with jQuery
Convert the input type to password with jQuery
<input type="text" class="remove-autofill">
$('.js-remove-autofill').val('');
$('.js-remove-autofill').attr('type', 'password');
An update to Arjans solution. When trying to change the values it wouldnt let you. This works fine for me. When you focus on an input then it will go yellow. its close enough.
$(document).ready(function (){
if(navigator.userAgent.toLowerCase().indexOf("chrome") >= 0 || navigator.userAgent.toLowerCase().indexOf("safari") >= 0){
var id = window.setInterval(function(){
$('input:-webkit-autofill').each(function(){
var clone = $(this).clone(true, true);
$(this).after(clone).remove();
});
}, 20);
$('input:-webkit-autofill').focus(function(){window.clearInterval(id);});
}
});
$('input:-webkit-autofill').focus(function(){window.clearInterval(id);});
Try this code:
$(function(){
setTimeout(function(){
$('[name=user_password]').attr('type', 'password');
}, 1000);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.0/jquery.min.js"></script>
<input name="user_password" type="password">
fareed namrouti answer is correct. But the background still get yellow when the input is selected. Adding !important fix the problem. If you want also textarea and select with the same behavior just add textarea:-webkit-autofill, select:-webkit-autofill
Only input
input:-webkit-autofill {
background-color: rgb(250, 255, 189) !important;
}
input, select, textarea
input:-webkit-autofill, textarea:-webkit-autofill, select:-webkit-autofill {
background-color: rgb(250, 255, 189) !important;
}
Adding autocomplete="off" is not gonna cut it.
Change input type attribute to type="search".
Google doesn't apply auto-fill to inputs with a type of search.
Hope this saves you some time.
The only solution that worked in my case:
:-webkit-autofill {
-webkit-text-fill-color: #000; /* ok for text, no hack */
transition-property: background-color; /* begin hack for background... */
transition-delay: 100000s; /* ...end hack for background */
}
This solution is not ideal, it is while waiting to find better ...
The final solution:
$(document).ready(function(){
var contadorInterval = 0;
if (navigator.userAgent.toLowerCase().indexOf("chrome") >= 0)
{
var _interval = window.setInterval(function ()
{
var autofills = $('input:-webkit-autofill');
if (autofills.length > 0)
{
window.clearInterval(_interval); // stop polling
autofills.each(function()
{
var clone = $(this).clone(true, true);
$(this).after(clone).remove();
setTimeout(function(){
// $("#User").val('');
$("#Password").val('');
},10);
});
}
contadorInterval++;
if(contadorInterval > 50) window.clearInterval(_interval); // stop polling
}, 20);
}else{
setTimeout(function(){
// $("#User").val('');
$("#Password").val('');
},100);
}
});
<input type="text" name="foo" autocomplete="off" />
Similar Question: Link
Just found myself with the same question. This works for me:
form :focus {
outline: none;
}
Related
Is there any way that i could add a background color after placing a content inside an input field? Just like what happens when an autocomplete works.
Thanks!
There are a few ways you could achieve this. You could make the input mandatory by adding the required attribute. Doing this means that as soon as the user enters anything into the field, it is now in the valid state and you can target it in your CSS using the :valid pseudo-class:
input:valid{
background:#ff9;
}
<input required>
Or, if you don't want to make the field mandatory and as others have suggested, you could set the new background-color when the field receives focus. To prevent it from reverting to its initial color when it loses focus, you will need to add a transition to the background, setting the transition-delay to some ridiculously high number when the input is in its normal state and resetting it to 0s when it is focused. Obviously, though, this change will occur whether or not the user actually enters anything in the field or not.
input{
transition-delay:9999s;
transition-property:background;
}
input:focus{
background:#ff9;
transition-delay:0s;
}
<input>
If neither of those options suit your needs then you will probably need to resort to using JavaScript to add or remove a class, depending on whether or not the value of the input is empty.
document.querySelector("input").addEventListener("input",function(){
this.value?this.classList.add("filled"):this.classList.remove("filled");
},0);
.filled{
background:#ff9;
}
<input>
Html
First name: <input type="text" name="firstname">
Css
input:focus {
background-color: yellow;
}
Demo in JsFiddle
Here is a solution with pure javascript
var input = document.getElementById("test");
input.addEventListener('input', function() {
if (input.value)
input.style.backgroundColor = '#90EE90';
else
input.style.backgroundColor = '#fff';
});
<input id="test" type="text" value="">
Add a Css class like
.myCSSClass
{
background-color:red;
}
Now using jquery on blur function you add this class
$("#myTextBox").on('blur',function(){
if($("#myTextBox").val()==""){
if($("#myTextBox").hasClass("myCSSClass")){
$("#myTextBox").removeClass("myCSSClass");
}
}
else
{
$("#myTextBox").addClass("myCSSClass")
}
});
Using Jquery,
$( "#target" ).blur(function() {
$( "#target" ).css('background-color','red');
});
DEMO
I have design problem with Google Chrome and its form autofill function.
If Chrome remembers some login/password it changes a background color to a yellow one.
Here are some screenshots:
How to remove that background or just disable this autofill ?
Change "white" to any color you want.
input:-webkit-autofill {
-webkit-box-shadow: 0 0 0 1000px white inset !important;
}
If you guys want transparent input fields you can use transition and transition delay.
input:-webkit-autofill,
input:-webkit-autofill:hover,
input:-webkit-autofill:focus,
input:-webkit-autofill:active {
-webkit-transition-delay: 9999s;
-webkit-transition: color 9999s ease-out, background-color 9999s ease-out;
}
Solution here:
if (navigator.userAgent.toLowerCase().indexOf("chrome") >= 0) {
$(window).load(function(){
$('input:-webkit-autofill').each(function(){
var text = $(this).val();
var name = $(this).attr('name');
$(this).after(this.outerHTML).remove();
$('input[name=' + name + ']').val(text);
});
});
}
In Firefox you can disable all autocomplete on a form by using the autocomplete="off/on" attribute. Likewise individual items autocomplete can be set using the same attribute.
<form autocomplete="off" method=".." action="..">
<input type="text" name="textboxname" autocomplete="off">
You can test this in Chrome as it should work.
If you want to preserve the autofill, as well as any data, attached handlers and functionality attached to your input elements, try this script:
if (navigator.userAgent.toLowerCase().indexOf("chrome") >= 0)
{
var _interval = window.setInterval(function ()
{
var autofills = $('input:-webkit-autofill');
if (autofills.length > 0)
{
window.clearInterval(_interval); // stop polling
autofills.each(function()
{
var clone = $(this).clone(true, true);
$(this).after(clone).remove();
});
}
}, 20);
}
It polls until it finds any autofill elements, clones them including data and events, then inserts them into the DOM in the same location and removes the original. It stops polling once it finds any to clone since the autofill sometimes takes a second after page load. This is a variation of a previous code sample, but more robust and keeps as much functionality intact as possible.
(Confirmed working in Chrome, Firefox and IE 8.)
The following CSS removes the yellow background color and replaces it with a background color of your choosing. It doesn't disable auto-fill and it requires no jQuery or Javascript hacks.
input:-webkit-autofill {
-webkit-box-shadow:0 0 0 50px white inset; /* Change the color to your own background color */
-webkit-text-fill-color: #333;
}
input:-webkit-autofill:focus {
-webkit-box-shadow: /*your box-shadow*/,0 0 0 50px white inset;
-webkit-text-fill-color: #333;
}
Solution copied from:
Override browser form-filling and input highlighting with HTML/CSS
Worked for me, only the css change required.
input:-webkit-autofill {
-webkit-box-shadow: 0 0 0px 1000px #ffffff inset!important;
}
you can put any color in place of #ffffff.
A little bit hacky but works perfectly for me
input:-webkit-autofill {
-webkit-box-shadow: 0 0 0px 1000px white inset;
}
A combination of answers worked for me
<style>
input:-webkit-autofill,
input:-webkit-autofill:hover,
input:-webkit-autofill:focus,
input:-webkit-autofill:active {
-webkit-box-shadow: 0 0 0px 1000px #373e4a inset !important;
-webkit-text-fill-color: white !important;
}
</style>
Here's the MooTools version of Jason's. Fixes it in Safari too.
window.addEvent('domready',function() {
$('username').focus();
if ((navigator.userAgent.toLowerCase().indexOf(\"chrome\") >= 0)||(navigator.userAgent.toLowerCase().indexOf(\"safari\") >= 0))
{
var _interval = window.setInterval(function ()
{
var autofills = $$('input:-webkit-autofill');
if (autofills.length > 0)
{
window.clearInterval(_interval); // stop polling
autofills.each(function(el)
{
var clone = el.clone(true,true).inject(el,'after');;
el.dispose();
});
}
}, 20);
}
});
This fixes the problem on both Safari and Chrome
if(navigator.userAgent.toLowerCase().indexOf("chrome") >= 0 || navigator.userAgent.toLowerCase().indexOf("safari") >= 0){
window.setInterval(function(){
$('input:-webkit-autofill').each(function(){
var clone = $(this).clone(true, true);
$(this).after(clone).remove();
});
}, 20);
}
This helped me, a CSS only version.
input:-webkit-autofill {
-webkit-box-shadow: 0 0 0px 1000px white inset;
}
where white can be any color you want.
I use this,
input:-webkit-autofill { -webkit-box-shadow: 0 0 0px 1000px white inset !important; }
input:focus:-webkit-autofill { -webkit-box-shadow: 0 0 0px 1000px white inset !important; }
/* You can use color:#color to change the color */
In your tag, simply insert this small line of code.
autocomplete="off"
However, do not place this in the username/email/idname field because if you are still looking to use autocomplete, it will disable it for this field. But I found a way around this, simply place the code in your password input tag because you never autocomplete passwords anyways. This fix should remove the color force, matinain autocomplete ability on your email/username field, and allows you to avoid bulky hacks like Jquery or javascript.
If you want to get rid of it entirely, I've adjusted the code in the previous answers so it works on hover, active and focus too:
input:-webkit-autofill, input:-webkit-autofill:hover, input:-webkit-autofill:active, input:-webkit-autofill:focus {
-webkit-box-shadow: 0 0 0 1000px white inset;
}
If you want to avoid the yellow flicker until your css is applied slap a transition on that bad boy like so:
input:-webkit-autofill {
-webkit-box-shadow: 0 0 0 1000px white inset !important;
transition: background-color 10s ease-in-out 0s;
}
Here's a Mootools solution doing the same as Alessandro's - replaces each affected input with a new one.
if (Browser.chrome) {
$$('input:-webkit-autofill').each(function(item) {
var text = item.value;
var name = item.get('name');
var newEl = new Element('input');
newEl.set('name', name);
newEl.value = text;
newEl.replaces(item);
});
}
What about that solution:
if ($.browser.webkit) {
$(function() {
var inputs = $('input:not(.auto-complete-on)');
inputs.attr('autocomplete', 'off');
setTimeout(function() {
inputs.attr('autocomplete', 'on');
}, 100);
});
}
It turns off the auto-complete and auto-fill (so yellow backgrounds disappear), waits 100 milliseconds an then turns the auto-complete functionality back without auto-fill.
If you have inputs that need to be auto-filled, then give them auto-complete-on css class.
None of the solutions worked for me, the username and password inputs were still being populated and given the yellow background.
So I asked myself, "How does Chrome determine what should be autofilled on a given page?"
"Does it look for input ids, input names? Form ids? Form action?"
Through my experimentation with the username and the password inputs, there were only two ways I found that would cause Chrome to not be able to find the fields that should be autofilled:
1) Put the password input ahead of the text input.
2) Give them the same name and id ... or no name and id.
After the page loads, with javascript you can either change the order of the inputs on the page, or dynamically give them their name and id ...
And Chrome doesn't know what hit it ... autocomplete stays off.
Crazy hack, I know. But it's working for me.
Chrome 34.0.1847.116, OSX 10.7.5
The only way that works for me was:(jQuery required)
$(document).ready(function(e) {
if ($.browser.webkit) {
$('#input_id').val(' ').val('');
}
});
I fixed this issue for a password field i have like this:
Set the input type to text instead of password
Remove the input text value with jQuery
Convert the input type to password with jQuery
<input type="text" class="remove-autofill">
$('.js-remove-autofill').val('');
$('.js-remove-autofill').attr('type', 'password');
An update to Arjans solution. When trying to change the values it wouldnt let you. This works fine for me. When you focus on an input then it will go yellow. its close enough.
$(document).ready(function (){
if(navigator.userAgent.toLowerCase().indexOf("chrome") >= 0 || navigator.userAgent.toLowerCase().indexOf("safari") >= 0){
var id = window.setInterval(function(){
$('input:-webkit-autofill').each(function(){
var clone = $(this).clone(true, true);
$(this).after(clone).remove();
});
}, 20);
$('input:-webkit-autofill').focus(function(){window.clearInterval(id);});
}
});
$('input:-webkit-autofill').focus(function(){window.clearInterval(id);});
Try this code:
$(function(){
setTimeout(function(){
$('[name=user_password]').attr('type', 'password');
}, 1000);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.0/jquery.min.js"></script>
<input name="user_password" type="password">
fareed namrouti answer is correct. But the background still get yellow when the input is selected. Adding !important fix the problem. If you want also textarea and select with the same behavior just add textarea:-webkit-autofill, select:-webkit-autofill
Only input
input:-webkit-autofill {
background-color: rgb(250, 255, 189) !important;
}
input, select, textarea
input:-webkit-autofill, textarea:-webkit-autofill, select:-webkit-autofill {
background-color: rgb(250, 255, 189) !important;
}
Adding autocomplete="off" is not gonna cut it.
Change input type attribute to type="search".
Google doesn't apply auto-fill to inputs with a type of search.
Hope this saves you some time.
The only solution that worked in my case:
:-webkit-autofill {
-webkit-text-fill-color: #000; /* ok for text, no hack */
transition-property: background-color; /* begin hack for background... */
transition-delay: 100000s; /* ...end hack for background */
}
This solution is not ideal, it is while waiting to find better ...
The final solution:
$(document).ready(function(){
var contadorInterval = 0;
if (navigator.userAgent.toLowerCase().indexOf("chrome") >= 0)
{
var _interval = window.setInterval(function ()
{
var autofills = $('input:-webkit-autofill');
if (autofills.length > 0)
{
window.clearInterval(_interval); // stop polling
autofills.each(function()
{
var clone = $(this).clone(true, true);
$(this).after(clone).remove();
setTimeout(function(){
// $("#User").val('');
$("#Password").val('');
},10);
});
}
contadorInterval++;
if(contadorInterval > 50) window.clearInterval(_interval); // stop polling
}, 20);
}else{
setTimeout(function(){
// $("#User").val('');
$("#Password").val('');
},100);
}
});
<input type="text" name="foo" autocomplete="off" />
Similar Question: Link
Just found myself with the same question. This works for me:
form :focus {
outline: none;
}
I recently discovered that the :invalid pseudo-class applies to required form elements as soon as the page loads. For example, if you have this code:
<style>
input:invalid { background-color: pink; color: white; }
input:valid { background-color: white; color: black; }
</style>
…
<input name="foo" required />
Then your page will load with an empty pink input element on it. Having validation built in to HTML5 is great, but I don't think most users expect the form to validate before they've had a chance to enter any values at all. Is there any way to delay the application of the pseudo-class until the first event affecting that element (form submit, blur, change, whatever's appropriate)? Is it possible to do this without JavaScript?
http://www.alistapart.com/articles/forward-thinking-form-validation/
Since we only want to denote that a field is invalid once it has
focus, we use the focus pseudo-class to trigger the invalid styling.
(Naturally, flagging all required fields as invalid from the start
would be a poor design choice.)
Following this logic, your code would look something like this...
<style>
input:focus:required:invalid {background-color: pink; color: white;}
input:required:valid {background-color: white; color: black; }
</style>
Created a fiddle here: http://jsfiddle.net/tbERP/
As you'd guess, and as you'll see from the fiddle, this technique only shows the validation styling when the element has focus. As soon as you move focus off, the styling is dropped, regardless of whether it is valid or not. Not ideal by any means.
These answers are out of date. Now you can do this by checking for a placeholder pseudo-class with CSS.
input:not(:placeholder-shown):invalid {
background-color: salmon;
}
form:invalid button {
background-color: salmon;
pointer-events: none;
}
<form>
<input type="email" placeholder="me#example.com" required>
<button type="submit">Submit</button>
</form>
It starts with a normal background and turns pink as you enter you incomplete email address into it.
This is not possible in pure CSS, but can be done with JavaScript. This is a jQuery example:
// use $.fn.one here to fire the event only once.
$(':required').one('blur keydown', function() {
console.log('touched', this);
$(this).addClass('touched');
});
/**
* All required inputs initially are yellow.
*/
:required {
background-color: lightyellow;
}
/**
* If a required input has been touched and is valid, it should be white.
*/
.touched:required:valid {
background-color: white;
}
/**
* If a required input has been touched and is invalid, it should be pink.
*/
.touched:required:invalid {
background-color: pink;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p>
<label>
Name:
<input type="text" required> *required
</label>
</p>
<p>
<label>Age:
<input type="text">
</label>
</p>
This is a VanillaJS (no jQuery) version of kzh's answer
{
let f = function() {
this.classList.add('touched')
}
document
.querySelectorAll('input')
.forEach((e) => {
e.addEventListener('blur', f, false)
e.addEventListener('keydown', f, false)
})
}
/**
* All required inputs initially are yellow.
*/
:required {
background-color: lightyellow;
}
/**
* If a required input has been touched and is valid, it should be white.
*/
.touched:required:valid {
background-color: white;
}
/**
* If a required input has been touched and is invalid, it should be pink.
*/
.touched:required:invalid {
background-color: pink;
}
<p><label>
Name:
<input type="text" required> *required
</label></p>
<p><label>Age:
<input type="text">
</label></p>
Mozilla takes care of this with its own :-moz-ui-invalid pseudoclass that only applies to forms after they've been interacted with. MDN does not recommend using this due to a lack of support. However, you can modify it for Firefox.
There's a level 4 spec for a :user-invalid spec on the horizon that will offer similar behavior.
I created a small shim to deal with this in my codebase. I just start off with my <form/> element having the novalidate property along with a data-validate-on="blur" attribute. This watches for the first event of that type. This way you can still use the native :invalid css selectors for the form styling.
$(function () {
$('[data-validate-on]').each(function () {
var $form = $(this);
var event_name = $form.data('validate-on');
$form.one(event_name, ':input', function (event) {
$form.removeAttr('novalidate');
});
});
});
There is a html5 invalid event that fires on form elements before the submit event occurs for each element that does not pass checkValidity. You can use this event to apply a class for example to the surrounding form and display :invalid styles only after this event occurs.
$("form input, form select, form textarea").on("invalid", function() {
$(this).closest('form').addClass('invalid');
});
Your CSS would then look something like this:
:invalid { box-shadow: none; }
.invalid input:invalid,
.invalid textarea:invalid,
.invalid select:invalid { border: 1px solid #A90909 !important; background-color: #EEC2C2; }
The first line removes the default styling, so form elements look neutral at page load. As soon as the invalid event fires (when a user tries to submit the form), the elements are visibly rendered invalid.
You could make it so that only elements that have a certain class on them and are required, are pink. Add an event handler to each required element that adds that class when you leave the element.
Something like:
<style>
input.touched:invalid { background-color: pink; color: white; }
input.touched:valid { background-color: white; color: black; }
</style>
<script>
document.addEventListener('DOMContentLoaded', function() {
var required = document.querySelectorAll('input:required');
for (var i = 0; i < required.length; ++i) {
(function(elem) {
function removeClass(name) {
if (elem.classList) elem.classList.remove(name);
else
elem.className = elem.className.replace(
RegExp('(^|\\s)\\s*' + name + '(?:\\s+|$)'),
function (match, leading) {return leading;}
);
}
function addClass(name) {
removeClass(name);
if (elem.classList) elem.classList.add(name);
else elem.className += ' ' + name;
}
// If you require a class, and you use JS to add it, you end up
// not showing pink at all if JS is disabled.
// One workaround is to have the class on all your elements anyway,
// and remove it when you set up proper validation.
// The main problem with that is that without JS, you see what you're
// already seeing, and stuff looks hideous.
// Unfortunately, you kinda have to pick one or the other.
// Let non-blank elements stay "touched", if they are already,
// so other stuff can make the element :invalid if need be
if (elem.value == '') addClass('touched');
elem.addEventListener('blur', function() {
addClass('touched');
});
// Oh, and when the form submits, they need to know about everything
if (elem.form) {
elem.form.addEventListener('submit', function() {
addClass('touched');
});
};
})(required[i]);
}
});
</script>
And of course, it won't work as is in IE8 or below, as (a) DOMContentLoaded is relatively new and wasn't standard when IE8 came out, (b) IE8 uses attachEvent rather than the DOM-standard addEventListener, and (c) IE8 isn't going to care about :required anyway, as it doesn't technically support HTML 5.
While using HTML5 form validation, try to use the browser to detect for invalid submissions/fields, rather than re-inventing the wheel.
Listen for the invalid event to add a class of 'invalid' to your form. With the 'invalid' class added, you can go to town with styling your form using CSS3 :pseudo selectors.
For example:
// where myformid is the ID of your form
var myForm = document.forms.myformid;
var checkCustomValidity = function(field, msg) {
if('setCustomValidity' in field) {
field.setCustomValidity(msg);
} else {
field.validationMessage = msg;
}
};
var validateForm = function() {
// here, we're testing the field with an ID of 'name'
checkCustomValidity(myForm.name, '');
if(myForm.name.value.length < 4) {
checkCustomValidity(
// alerts fields error message response
myForm.name, 'Please enter a valid Full Name, here.'
);
}
};
/* here, we are handling your question above, by adding an invalid
class to the form if it returns invalid. Below, you'll notice
our attached listener for a form state of invalid */
var styleInvalidForm = function() {
myForm.className = myForm.className += ' invalid';
}
myForm.addEventListener('input', validateForm, false);
myForm.addEventListener('keyup', validateForm, false);
myForm.addEventListener('invalid', styleInvalidForm, true);
Now, simply style your form as you see fit based on the 'invalid' class we've attached.
For example:
form.invalid input:invalid,
form.invalid textarea:invalid {
background: rgba(255, 0, 0, .05);
border-color: #ff6d6d;
-webkit-box-shadow: 0 0 6px rgba(255, 0, 0, .35);
box-shadow: 0 0 6px rgba(255, 0, 0, .35);
}
A good way is to abstract :invalid, :valid with a CSS classes and then some JavaScript to check if the input field was focused or not.
CSS:
input.dirty:invalid{ color: red; }
input.dirty:valid{ color: green; }
JS:
// Function to add class to target element
function makeDirty(e){
e.target.classList.toggle('dirty');
}
// get form inputs
var inputs = document.forms[0].elements;
// bind events to all inputs
for(let input of inputs){
input.addEventListener('invalid', makeDirty);
input.addEventListener('blur', makeDirty);
input.addEventListener('valid', makeDirty);
}
DEMO
Following on from agouseh's idea, you can have a bit of javascript to tell when the submit button has been focussed, and have validation show up at that time.
The javascript will add a class (eg. submit-focussed) to the form field when the submit button is focussed or clicked, which then allows the CSS to style invalid inputs.
This follows the best practice of showing validation feedback after the user has finished filling in the fields, as according to research there is no additional benefit to showing it during the process.
document
.querySelector('input[type=submit]')
.onfocus = function() {
this
.closest('form')
.classList
.add('submit-focussed');
};
form.submit-focussed input:invalid {
border: thin solid red;
}
<form>
<label>Email <input type="email" required="" /></label>
<input type="submit" />
</form>
jQuery alternative
(function($) {
$('input[type=submit]').on('focus', function() {
$(this)
.parent('form')
.addClass('submit-focussed');
});
})(jQuery); /* WordPress compatible */
Here is my method to avoid the default styling of any unfocused input as invalid, you just have to add a simple js command onFocus to let the webpage to identify focused and unfocused inputs, so all the input will not appear in the style of invalid at first place.
<style>
input.focused:required:invalid { background-color: pink; color: white; }
input:valid { background-color: white; color: black; }
</style>
…
<input name="foo" class="notfocused" onFocus="document.activeElement.className='focused';" required />
Try it yourself below:
input.focused:required:invalid {
background-color: pink;
color: white;
}
input:required:valid {
background-color: darkseagreen;
color: black;
}
<label>At least 1 charater:</label><br />
<input type="text" name="foo" class="notfocused" onFocus="document.activeElement.className='focused';" required />
I can't comment, but to go with #Carl's very useful answer regarding using :not(:placeholder-shown). As another comment mentioned, this will still show the invalid state if you have NO placeholder (as some form designs call for).
To solve this, simply add an empty placeholder like so
<input type="text" name="username" placeholder=" " required>
Then your CSS, something like
:not(:placeholder-shown):invalid{ background-color: #ff000038; }
Worked for me!
Is there any way to change the asterisks (*), or in some browsers a bullet (•), that appears in password fields in HTML?
Create your own font and use #font-face and font-family (and font-size) for input[type="password"]. It should help to solve your problem. But... you must create font with replaced bullet and asterisk character. All character numbers in font may represent the same character. Use google to find free program to edit vector fonts.
Never say "it is impossible". You should find a hack for your problem.
Characters to be replaced with your symbol (for Chrome, Firefox and MSIE):
26AB, 25E6, 25CF, 25D8, 25D9, 2219, 20F0, 2022, 2024, 00B7, 002A.
(18C)
You can't change the password masking character in the standard password field. You can fake it with a textbox, but it makes for a weak security model because you don't get the protection you do from the password textbox. As a side note, it's generally not a good idea to change the behaviour of items like this because users have become used to one form of masking, and you will be introducing a different one - if there's no good reason to do this, I'd avoid it.
As of now, it appears as though this is possible in webkit browsers. Please see http://help.dottoro.com/lcbkewgt.php for examples and documentation.
Does not apply to password input
<input type="text" style="-webkit-text-security: square;" />
There is no good solution for other browsers as of when this answer was written and even in webkit browsers, the characters you are allowed to specify are very limited.
I know that is a very old question, but I faced this problem today, and I solved it using this approach: https://github.com/Mottie/input-password-bullet
Basically, I created a new font where assign the default point, to another icon. Then, only need to import the font files to the project and add a css similar to this:
#font-face {
font-family: 'fontello';
src: url('/fonts/fontello.eot');
src: url('/fonts/fontello.eot') format('embedded-opentype'),
url('/fonts/fontello.woff') format('woff'),
url('/fonts/fontello.ttf') format('truetype'),
url('/fonts/fontello.svg') format('svg');
font-weight: normal;
font-style: normal;
}
input[type="password"] {
font-family: "fontello";
font-style: normal;
font-weight: normal;
speak: none;
color: red;
font-size: 16px;
/* For safety - reset parent styles, that can break glyph codes*/
font-variant: normal;
text-transform: none;
/* Font smoothing. That was taken from TWBS */
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
/* Uncomment for 3D effect */
/* text-shadow: 1px 1px 1px rgba(127, 127, 127, 0.3); */
/* add spacing to better separate each image */
letter-spacing: 2px;
}
Hope this helps!
No - the user agent chooses its own default style, and there is (to my knowledge) no CSS attributes you can change to determine the masking character.
Of course, this would be possible if the password field was just a standard text field, and you manually masked the input with a javascript event handler (onKeyPress, probably). You could even declare the field as type="password" in the HTML, then have your JS function modify the DOM to change its type. I'd be a little wary about doing this, though; the browser implementation is almost certainly pretty solid, and circumventing established security functionality to roll your own is rarely a good idea.
<input type="text" style="-webkit-text-security: circle;" />
Looks like I'm pretty late, but another potential solution is below for any looking for a workaroud. The only "bug" I didn't bother to look into was that you can't highlight and delete everyhting at once. Other than that, it works as intended, the user can input their password and they will see a string of whatever you want (in this example, a star) and their recently pressed key.
//window.onload = () => {
// sessionStorage.text = "";
// sessionStorage.visible = false
//}
//We will use the text and visible variables for demonstration purposes as session storage does not work with code snippets. The star can really be anything you want
const star = "*";
let text = "";
let isVisible = false;
function toggle(id) {
const button = document.getElementById(id);
const input = document.getElementById("password-input");
switch (isVisible) {
case false:
button.innerText = "Hide Password";
input.value = text;
isVisible = true;
break;
case true:
button.innerText = "Show Password";
input.value = star.repeat(text.length);
isVisible = false;
}
console.log(`Text When Button Clicked: ${text}`);
}
function formatInput(id) {
//The tl:dr of this is that each key pressed (so long as it's valid which is to be determined by you) will be added to session storag which you can call from anywhere, allowing you to register stars of the correct length or text of the correct value
const elem = document.getElementById(id);
const keyPressed = event.key;
//event.key should be equal to 1 unless you want it to register "Backspace" and so on as inputs. The elem.value change in the first conditional is necessary to avoid removing more than 1 character on the input; Wihtout it, we would get something like text.length = x and elem.value.length = x - 1
if (keyPressed == "Backspace") {
text = text.substring(0, text.length - 1);
elem.value = elem.value.substring(0, elem.value.length);
console.log(`Text at Backspace: ${text}`)
return;
}
if (keyPressed.length == 1) {
text = text + keyPressed;
elem.value = text;
}
//You could use a conditional here, I just prefer switches in the case that we are checking one simple thing
switch (isVisible) {
case false:
elem.value = star.repeat(text.length - 1)
console.log(`Text When Password = Hidden: ${text}`)
break;
case true:
elem.value = text;
//This is required as wihtout it there is a bug that duplicated the first entry if someone decides to show the password
elem.value = elem.value.substring(0, text.length - 1)
console.log(`Text When Password = Visible: ${text}`)
}
}
div {
display: flex;
flex-direction: column;
align-items: center;
}
input {
width: 50%;
height: 35px;
border: 0px;
box-shadow: 1px 1px 3px rgba(0, 0, 0, 0.2) inset;
border-radius: 5px;
padding-left: 15px;
letter-spacing: 2px;
outline: none;
}
input:focus {
border: 1px green solid;
}
button {
height: 35px;
background-color: rgb(94, 124, 153);
border-radius: 5px;
border: 0px;
box-shadow: 1px 1px 3px rgba(0, 0, 0, 0.5);
cursor: pointer;
width: 30%;
margin-top: 30px;
color: white;
}
<div>
<input type="text" id="password-input" placeholder="Password" onkeydown="formatInput(this.id)" value="">
<button id="toggle-button" onclick="toggle(this.id)">Show Passowrd</button>
</div>
The issue:
Some of the items in the select require more than the specified width of 145px in order to display fully.
Firefox behavior: clicking on the select reveals the dropdown elements list adjusted to the width of the longest element.
IE6 & IE7 behavior: clicking on the select reveals the dropdown elements list restricted to 145px width making it impossible to read the longer elements.
The current UI requires us to fit this dropdown in 145px and have it host items with longer descriptions.
Any advise on resolving the issue with IE?
The top element should remain 145px wide even when the list is expanded.
Thank you!
The css:
select.center_pull {
background:#eeeeee none repeat scroll 0 0;
border:1px solid #7E7E7E;
color:#333333;
font-size:12px;
margin-bottom:4px;
margin-right:4px;
margin-top:4px;
width:145px;
}
Here's the select input code (there's no definition for the backend_dropbox style at this time)
<select id="select_1" class="center_pull backend_dropbox" name="select_1">
<option value="-1" selected="selected">Browse options</option>
<option value="-1">------------------------------------</option>
<option value="224">Option 1</option>
<option value="234">Longer title for option 2</option>
<option value="242">Very long and extensively descriptive title for option 3</option>
</select>
Full html page in case you want to quickly test in a browser:
<!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>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>dropdown test</title>
<style type="text/css">
<!--
select.center_pull {
background:#eeeeee none repeat scroll 0 0;
border:1px solid #7E7E7E;
color:#333333;
font-size:12px;
margin-bottom:4px;
margin-right:4px;
margin-top:4px;
width:145px;
}
-->
</style>
</head>
<body>
<p>Select width test</p>
<form id="form1" name="form1" method="post" action="">
<select id="select_1" class="center_pull backend_dropbox" name="select_1">
<option value="-1" selected="selected">Browse options</option>
<option value="-1">------------------------------------</option>
<option value="224">Option 1</option>
<option value="234">Longer title for option 2</option>
<option value="242">Very long and extensively descriptive title for option 3</option>
</select>
</form>
</body>
</html>
For IE 8 there is a simple pure css-based solution:
select:focus {
width: auto;
position: relative;
}
(You need to set the position property, if the selectbox is child of a container with fixed width.)
Unfortunately IE 7 and less do not support the :focus selector.
I did Google about this issue but didn't find any best solution ,So Created a solution that works fine in all browsers.
just call badFixSelectBoxDataWidthIE() function on page load.
function badFixSelectBoxDataWidthIE(){
if ($.browser.msie){
$('select').each(function(){
if($(this).attr('multiple')== false){
$(this)
.mousedown(function(){
if($(this).css("width") != "auto") {
var width = $(this).width();
$(this).data("origWidth", $(this).css("width"))
.css("width", "auto");
/* if the width is now less than before then undo */
if($(this).width() < width) {
$(this).unbind('mousedown');
$(this).css("width", $(this).data("origWidth"));
}
}
})
/* Handle blur if the user does not change the value */
.blur(function(){
$(this).css("width", $(this).data("origWidth"));
})
/* Handle change of the user does change the value */
.change(function(){
$(this).css("width", $(this).data("origWidth"));
});
}
});
}
}
Here is a little script that should help you out:
http://www.icant.co.uk/forreview/tamingselect/
For a simple Javascript-free solution, adding a title-attribute to your <option>s holding the text might be enough, depending on your requirements.
<option value="242" title="Very long and extensively descriptive text">
Very long and extensively descriptive text
</option>
This will show the cut-off text in a tool-tip fashion on hovering the <option>, regardless of the width of the <select>.
Works for IE7+.
Not javascript free i'm afraid, but I managed to make it quite small using jQuery
$('#del_select').mouseenter(function () {
$(this).css("width","auto");
});
$('#del_select').mouseout(function () {
$(this).css("width","170px");
});
Simply you can use this plugin for jquery ;)
http://plugins.jquery.com/project/skinner
$(function(){
$('.select1').skinner({'width':'200px'});
});
Small, but hopefully useful update to the code from MainMa & user558204 (thanks guys), which removes the unnecessary each loop, stores a copy of $(this) in a variable in each event handler as it's used more than once, also combined the blur & change events as they had the same action.
Yes, it's still not perfect as it resizes the select element, rather than just the drop-down options. But hey, it got me out of a pickle, I (very, very unfortunately) still have to support an IE6-dominant user base across the business.
// IE test from from: https://gist.github.com/527683
var ie = (function () {
var undef, v = 3, div = document.createElement('div'), all = div.getElementsByTagName('i');
while (
div.innerHTML = '<!--[if gt IE ' + (++v) + ']><i></i><![endif]-->',
all[0]
);
return v > 4 ? v : undef;
} ());
function badFixSelectBoxDataWidthIE() {
if (ie < 9) {
$('select').not('[multiple]')
.mousedown(function() {
var t = $(this);
if (t.css("width") != "auto") {
var width = t.width();
t.data("ow", t.css("width")).css("width", "auto");
// If the width is now less than before then undo
if (t.width() < width) {
t.unbind('mousedown');
t.css("width", t.data("ow"));
}
}
})
//blur or change if the user does change the value
.bind('blur change', function() {
var t = $(this);
t.css("width", t.data("ow"));
});
}
}
A different approach:
instead of a select make it an edit box, disabled so noone can enter anything manually or change contents after selection
another hidden edit to contain an id of a selected option (explained below)
make a button [..] and script it to show that div below
make a hidden div with absolute position under or near the edit box
make that div to contain a select with style size="6" (to show 6 options and a scrollbar rather than a drop-down list) and a button "select" and maybe "cancel"
Do not style width so the whole thing will assume width of the widest option or the button plus maybe some padding of your choice
script the "select" button to copy id of the selected option to the hidden edit box and it's value to the visible one, also to hide the div again.
4 simple javascript commands total.
I found a pretty straightforward fix for this. In the <select> html element add these properties:
onmouseover="autoWidth(this)"
onblur="resetWidth(this)"
So whenever user clicks on that the width will automatically expand, and user moves out of the select box, the width will be reset to original.
similar solution can be found here using jquery to set the auto width when focus (or mouseenter) and set the orignal width back when blur (or mouseleave) http://css-tricks.com/select-cuts-off-options-in-ie-fix/.
for (i=1;i<=5;i++){
idname = "Usert" + i;
document.getElementById(idname).style.width = "100%";
}
I used this way to showed the drop down list when the width is not showed correctly.
It work for IE6, Firefox and Chrome.
A full fledged jQuery plugin is available, check out the demo page: http://powerkiki.github.com/ie_expand_select_width/
disclaimer: I coded that thing, patches welcome
Why would anyone want a mouse over event on a drop down list? Here's a way of manipulating IE8 for the way a drop down list should work:
First, let's make sure we are only passing our function in IE8:
var isIE8 = $.browser.version.substring(0, 2) === "8.";
if (isIE8) {
//fix me code
}
Then, to allow the select to expand outside of the content area, let's wrap our drop down lists in div's with the correct structure, if not already, and then call the helper function:
var isIE8 = $.browser.version.substring(0, 2) === "8.";
if (isIE8) {
$('select').wrap('<div class="wrapper" style="position:relative; display: inline-block; float: left;"></div>').css('position', 'absolute');
//helper function for fix
ddlFix();
}
Now onto the events. Since IE8 throws an event after focusing in for whatever reason, IE will close the widget after rendering when trying to expand. The work around will be to bind to 'focusin' and 'focusout' a class that will auto expand based on the longest option text. Then, to ensure a constant min-width that doesn't shrink past the default value, we can obtain the current select list width, and set it to the drop down list min-width property on the 'onchange' binding:
function ddlFix() {
var minWidth;
$('select')
.each(function () {
minWidth = $(this).width();
$(this).css('min-width', minWidth);
})
.bind('focusin', function () {
$(this).addClass('expand');
})
.change(function () {
$(this).css('width', minWidth);
})
.bind('focusout', function () {
$(this).removeClass('expand');
});
}
Lastly, make sure to add this class in the style sheet:
select:focus, select.expand {
width: auto;
}
Not javascript free, I am afraid too and my solution do require a js library, however, you can only use those files which you need rather than using them all, maybe best suited for those who are already using YUI for their projects or deciding which one to use. Have a look at: http://ciitronian.com/blog/programming/yui-button-mimicking-native-select-dropdown-avoid-width-problem/
My blog post also discusses other solutions as well, one is referenced back to here on stackoverflow, why I went back to create my own SELECT element is because of simple reason, I don't like mouseover expand events. Maybe if that helps anyone else too!
The jquery BalusC's solution improved by me. Used also: Brad Robertson's comment here.
Just put this in a .js, use the wide class for your desired combos and don't forge to give it an Id. Call the function in the onload (or documentReady or whatever).
As simple ass that :)
It will use the width that you defined for the combo as minimun length.
function fixIeCombos() {
if ($.browser.msie && $.browser.version < 9) {
var style = $('<style>select.expand { width: auto; }</style>');
$('html > head').append(style);
var defaultWidth = "200";
// get predefined combo's widths.
var widths = new Array();
$('select.wide').each(function() {
var width = $(this).width();
if (!width) {
width = defaultWidth;
}
widths[$(this).attr('id')] = width;
});
$('select.wide')
.bind('focus mouseover', function() {
// We're going to do the expansion only if the resultant size is bigger
// than the original size of the combo.
// In order to find out the resultant size, we first clon the combo as
// a hidden element, add to the dom, and then test the width.
var originalWidth = widths[$(this).attr('id')];
var $selectClone = $(this).clone();
$selectClone.addClass('expand').hide();
$(this).after( $selectClone );
var expandedWidth = $selectClone.width()
$selectClone.remove();
if (expandedWidth > originalWidth) {
$(this).addClass('expand').removeClass('clicked');
}
})
.bind('click', function() {
$(this).toggleClass('clicked');
})
.bind('mouseout', function() {
if (!$(this).hasClass('clicked')) {
$(this).removeClass('expand');
}
})
.bind('blur', function() {
$(this).removeClass('expand clicked');
})
}
}
Its tested in all version of IE, Chrome, FF & Safari
// JavaScript code
<script type="text/javascript">
<!-- begin hiding
function expandSELECT(sel) {
sel.style.width = '';
}
function contractSELECT(sel) {
sel.style.width = '100px';
}
// end hiding -->
</script>
// Html code
<select name="sideeffect" id="sideeffect" style="width:100px;" onfocus="expandSELECT(this);" onblur="contractSELECT(this);" >
<option value="0" selected="selected" readonly="readonly">Select</option>
<option value="1" >Apple</option>
<option value="2" >Orange + Banana + Grapes</option>
I've got yet another contribution to this. I wrote this a while back that you may find helpful: http://dpatrickcaldwell.blogspot.com/2011/06/giantdropdown-jquery-plugin-for-styling.html
It's a jquery plugin to make a styleable unordered list backed by the hidden select element.
The source is on github: https://github.com/tncbbthositg/GiantDropdown
You'd be able to handle behaviors and styles on the UL that you can't with the SELECT. Everything else should be the same because the select list is still there, it's just hidden but the UL will use it as a backing data store (if you will).
I wanted this to work with selects that I added dynamically to the page, so after a lot of experimentation, I ended up giving all the selects that I wanted to do this with the class "fixedwidth", and then added the following CSS:
table#System_table select.fixedwidth { width: 10em; }
table#System_table select.fixedwidth.clicked { width: auto; }
and this code
<!--[if lt IE 9]>
<script type="text/javascript">
jQuery(document).ready(function() {
jQuery(document).on(
{
'mouseenter': function(event) {
jQuery(this).addClass('clicked');
},
'focusout change blur': function() {
jQuery(this).removeClass('clicked');
}
}, 'select.fixedwidth');
});
</script>
<![endif]-->
A couple of things to note:
In spite of the fact that my selects are all in a table, I had to do "on" to the jQuery(document).on instead of to jQuery('table#System_table').on
In spite of the fact that the jQuery documentation says to use "mouseleave" instead of "blur", I found that in IE7 when I moved the mouse down the drop down list, it would get a mouseleave event but not a blur.
Here is a solution that actually works.
It sets the width in IE and doesn't mess up your page layout and doesn't close the dropdown when you mouse over the select options like some of the other solutions on this page.
You will need however to change the margin-right value and width values to match what you have for your select fields.
Also you can replace the $('select') with $('#Your_Select_ID_HERE') to only effect a specific select field. As well you will need to call the function fixIESelect() on the body onload or via jQuery using DOM ready as I did in my code below:
//////////////////////////
// FIX IE SELECT INPUT //
/////////////////////////
window.fixIESelect_clickset = false;
function fixIESelect()
{
if ($.browser.msie)
{
$('select').mouseenter(function ()
{
$(this).css("width","auto");
$(this).css("margin-right","-100");
});
$('select').bind('click focus',function ()
{
window.fixIESelect_clickset = true;
});
$('select').mouseout(function ()
{
if(window.fixIESelect_clickset != true)
{
$(this).css("width","93px");
window.fixIESelect_clickset = false;
}
});
$('select').bind('blur change',function ()
{
$(this).css("width","93px");
});
}
}
/////////////
// ONLOAD //
////////////
$(document).ready(function()
{
fixIESelect();
});
For my layout, I didn't want a hack (no width increasing, no on click with auto and then coming to original). It broke my existing layout. I just wanted it to work normally like other browsers.
I found this to be exactly like that :-
http://www.jquerybyexample.net/2012/05/fix-for-ie-select-dropdown-with-fixed.html
A workaround if you don't care about the strange view after an option is selected (i.e. Select to jump to a new page):
<!-- Limit width of the wrapping div instead of the select and use 'overflow: hidden' to hide the right part of it. -->
<div style='width: 145px; overflow: hidden; border-right: 1px solid #aaa;'>
<select onchange='jump();'>
<!-- '▼(▼)' produces a fake dropdown indicator -->
<option value=''>Jump to ... ▼</option>
<option value='1'>http://stackoverflow.com/questions/682764/select-dropdown-with-fixed-width-cutting-off-content-in-ie</option>
...
</select>
</div>
A pure css solution : http://bavotasan.com/2011/style-select-box-using-only-css/
.styled-select select {
background: transparent;
width: 268px;
padding: 5px;
font-size: 16px;
line-height: 1;
border: 0;
border-radius: 0;
height: 34px;
-webkit-appearance: none;
}
.styled-select {
width: 240px;
height: 34px;
overflow: hidden;
background: url(http://cdn.bavotasan.com/wp-content/uploads/2011/05/down_arrow_select.jpg) no-repeat right #ddd;
border: 1px solid #ccc;
}
<div class="styled-select">
<select>
<option>Here is the first option</option>
<option>The second option</option>
</select>
</div>
Best solution: css + javascript
http://css-tricks.com/select-cuts-off-options-in-ie-fix/
var el;
$("select")
.each(function() {
el = $(this);
el.data("origWidth", el.outerWidth()) // IE 8 can haz padding
})
.mouseenter(function(){
$(this).css("width", "auto");
})
.bind("blur change", function(){
el = $(this);
el.css("width", el.data("origWidth"));
});