Input Element CSS woes are over
Somewhere between January and now, my head has been so far stuck up the DOM, I’m out to figure out every last browser annoyance I’ve ran into and fix it with javascript.
First off; The problem
. I want to style my <input /> elements differently depending whether they are type=”text” or type=”input” (or “button”).
If we all lived in the future of css 3, we could easily do the following…
input[type="text"] {
font:bold 10px/12px verdana,arial,serif;
padding:3px;
}
input[type="button"],input[type="submit"] {
/* you know what to do */
}
Get over it. Use CSS 2.1
Being the “non-browser Elitist” I am (meaning, I’m not going to ignore the fact that 85% of users are browsing with a device that won’t understand CSS3), I decided to fix this.
Quick solution
Let’s just change our HTML to this.
<input type="text" class="text" value="" />
<input type="button" class="button" value="I am a button" />
<input type="submit" class="button" value="I am a submit" />
Then have the complimenting CSS:
input.text { /* my text css */ }
input.button { /* my button css */ }
Simple enough… but I’m still not satisifed. I’m thinking to myself, What a hassle
. Who really wants to append all those classes.
Javascript will do it for you
Need I say more….
function changeInputs()
{
var els = document.getElementsByTagName('input');
var elsLen = els.length;
var i = 0;
for ( i=0;i<elsLen;i++ )
{
if ( els[i].getAttribute(’type’) )
{
if ( els[i].getAttribute(’type’) == “text” )
els[i].className = ‘text’;
else
els[i].className = ‘button’;
}
}
}
With this, simply keep your CSS as it was with the input.text and input.button, but this time you don’t need to write the class names in your HTML. It works out just great.
Oh. And don’t forget to attach this function to an onload event handler.
Eg.
window.onload = function() { changeInputs(); }
There ya go.




July 1st, 2005 at 10:32 am
But what about those without Javascript enabled? I’d rather just to bite the nail and apply the classes, letting all (minus those without CSS enabled) see your styles rather than saving myself a few minutes.
July 1st, 2005 at 10:48 am
oh right… what about that 1%?
They’re purely missing out on better asthetics. I say it’s well worth it.
The page still works doesn’t it?
July 1st, 2005 at 11:03 am
Nice, cool idea Dustin.
I tend to give my buttons a class of “btn” and then give global stylings to all input controls, then some targeted rules to the input.btn to differentiate it from the other input controls. I know it’s wacky, but it does the job for me.
To add to your code, I think it should append the class name, not overwrite the class name…
if ( els[i].getAttribute(’type’) == “text” )
els[i].className += ‘ text’;
else
els[i].className += ‘ button’;
Really cool though, make that DOM work for you!
July 1st, 2005 at 11:13 am
Justin. I like your suggestion. I’m going to ammend it to do just so.
July 5th, 2005 at 7:18 am
I was just figuring.. will
if ( els[i].getAttribute(’type’) == “text” )
identify any inputs initiated with no such attribute?
(i.e.
)
July 5th, 2005 at 7:21 am
(html stripped..)
<input name=”whatev”>
July 5th, 2005 at 2:55 pm
technically, without a type attribute, you have malformed html.
if you want your js to validate against such an error, you could check to see if the type exists first…
eg.
if ( els[i].getAttribute(’type’) && els[i].getAttribute(’type’) == ‘text’
August 19th, 2006 at 1:37 am
I like this hole concept of changing things with js.
Could you guys also help me and tell how do i make the js external file and call it on onload and where?
September 29th, 2006 at 5:43 am
I’ve been a web admin at several companies over the last 8 years. I keep hearing this idea of people having javascript disabled and yet to find one person who actually disabled their javascript.
November 21st, 2006 at 3:01 am
BTW, attribute selectors are CSS2.1.
December 4th, 2006 at 7:09 am
Amol,
How to put it in a external file and how to call onload;
window.onload = function() { changeInputs(); }
January 5th, 2007 at 12:21 pm
Damn, I missed one paren. sorry.
-
March 24th, 2007 at 12:39 pm
Just found this and having heard of you though boagworld, this is a great tip - thank you.
I know this may increase the number of classes, but why not do the following instead of the if statements.
May 16th, 2007 at 5:56 am
Hey guys it was posted earlier! It is possible to do this: attribute selectors are CSS2.1! This is great, thank you trovster! \n ex: input[type=text]{//css}
June 20th, 2007 at 8:35 am
What a great method. It’s so obviouse… I used alot of your ideas in a project I’m currently working on. For my purposes, I ammended your script to check if the input element is already assigned a style class name, if so I leave it alone, otherwise assign the default style name “textbox”. Great solution, can’t wait until CSS 3 is better supported so we dont have to worry about this anymore.
July 6th, 2007 at 12:18 pm
As of July 1, 07 Firefox 2.0.2, Opera 9.1, Safari’s 3.0 beta and even IE 7 can handle this kind of form styling. No need for javascript or extra classes anymore. Move on and give users a reason to upgrade instead of coddling their laziness.
July 16th, 2007 at 8:23 pm
Hey, with your code you also get password fields marked as buttons. One fix is to change the if statement to if:
August 18th, 2007 at 9:20 am
Ahhhh!!! Been beating my head on the keyboard all morning. We are migrating a HUGE site, and the nimrod that did the site before me didn’t use CSS AT ALL!.
This script works great. You ROCK!
September 5th, 2007 at 4:18 am
Damn :)
November 14th, 2007 at 2:55 am
Lets not forget that this does not work on the “browse” button that the input type file creates. This button is not accessible at all… grrrrrr
November 17th, 2007 at 6:22 pm
I’m just getting nuts trying to apply some style to that “Browse” button… Damn it…
January 17th, 2008 at 11:19 pm
You could also decide NOT TO USE javascript….Why?
It only causes problems if you try hack solutions like the one above. BTW…less javascript on a page and less memory stack problems in your browsers.
Use javascript to solve every little quirky problem and you end up slowing down the page download. Remember that to this day people don’t have superfast machines to render pages fast enough. If it takes a page more than 5 seconds to upload then that’s only driving “consumed” internet users away.
So the trick is to use more of the css without id’ing everything as this also requires memory in your browser especially IE and less of the javascript.
April 9th, 2008 at 10:42 am
@ionut:
Attribute selectors are part of CSS2.1, but they don’t work in IE6. http://www.quirksmode.org/css/selector_attribute.html
Regrettably, this will rule them out for most people.
April 9th, 2008 at 8:59 pm
@Tony: You’re an idiot. Javascript doesn’t cause memory stack problems any more than C++ causes the Blue Screen of Death. It’s just a programming language, and a well-written bit of Javascript can improve the user experience, save on download times (because external Javascript files can be cached and reused site-wide), and can offer features that static pages can’t.
Images increase download time. Perhaps you’d recommend that we do away with those, too?
If it takes a page more than 5 seconds to load, and this drives you away from sites you’d otherwise want to visit, perhaps you should: a) clean out any spyware you’ve accumulated, b) invest in a faster Internet connection, and/or c) try to cultivate a little patience.
May 2nd, 2008 at 1:33 pm
You guys are amazing.
I wanted a “global” solution to style my buttons (submit and otherwise) with my CSS file but DID NOT want to have to rely on tagging every single input control with an class ID tag… not only would that be a pain and I’d forget to include the tag invariably, but many .Net controls (like the gridview) create button controls as part of their featureset but don’t let you add any style class reference to the dynamically generated buttons! I needed something that would just “see” every button for what it was… and style it (just like I can do for A tags, H1 tags etc).
And you guys solved the riddle. Thanks.
May 12th, 2008 at 4:01 pm
Awesome snippet man, exactly what I needed.
Re: Tony’s comment - keep in mind that a LOT of developers do corporate in house work where download speeds are not an issue because the only users are on the local network. I use EXT’s entire library and the initial page load comes at at near 1MB. From my user’s POV though, it takes maybe 1-2 seconds - which is sometimes what it takes them for Google or MSN during peak times, so nobody notices. As mentioned, it is cached after that and performance is lightning fast. Point is - just because there are a handful of people that will or can NOT use javascript doesn’t mean there aren’t millions of others - on high bandwidth pipes - that will.
June 22nd, 2008 at 10:58 pm
Hey, thanks, seriously, for the snippet. Never thought anything like it.
A plus i added to the code is that instead of hardcoding in text strings the types, you the type assign as the class for each element, like:
window.onload = function()
{
var coll = document.getElementsByTagName(”input”);
for(var i=0; i<coll.length; i++)
{
if(coll[i].type)
{
coll[i].className += ‘ ‘ + coll[i].type + ‘ ‘;
}
}
}
That way, all inputs are asigned classes with their own names (without overwritting any additional clases the input might have)
Thanks for everything!! Keep the cool ideas up!!!