Does anyone have a solution for styling the borders of "select" elements in Internet Explorer using CSS?
To make a border around an element, all you need is border-style . The values can be solid , dotted , dashed , double , groove , ridge , inset and outset .
The border shorthand CSS property sets an element's border. It sets the values of border-width , border-style , and border-color .
Above, we have the div class to no-border class and this allow us to remove the borders from the element.
The CSS border properties allow you to specify the style, width, and color of an element's border. I have borders on all sides. I have a red bottom border.
As far as I know, it's not possible in IE because it uses the OS component.
Here is a link where the control is replaced, but I don't know if thats what you want to do.
<select>
Something New, Part 1So you've built a beautiful, standards-compliant site utilizing the latest and greatest CSS techniques. You've mastered control of styling every element, but in the back of your mind, a little voice is nagging you about how ugly your <select>
s are. Well, today we're going to explore a way to silence that little voice and truly complete our designs. With a little DOM scripting and some creative CSS, you too can make your <select>
s beautiful… and you won't have to sacrifice accessibility, usability or graceful degradation.
We all know the <select>
is just plain ugly. In fact, many try to limit its use to avoid its classic web circa 1994 inset borders. We should not avoid using the <select>
though--it is an important part of the current form toolset; we should embrace it. That said, some creative thinking can improve it.
<select>
We'll use a simple for our example:
<select id="something" name="something"> <option value="1">This is option 1</option> <option value="2">This is option 2</option> <option value="3">This is option 3</option> <option value="4">This is option 4</option> <option value="5">This is option 5</option> </select>
[Note: It is implied that this <select>
is in the context of a complete form.]
So we have five <option>
s within a <select>
. This <select>
has a uniquely assigned id
of "something." Depending on the browser/platform you're viewing it on, your <select>
likely looks roughly like this:
(source: easy-designs.net)
or this
(source: easy-designs.net)
Let's say we want to make it look a little more modern, perhaps like this:
(source: easy-designs.net)
So how do we do it? Keeping the basic <select>
is not an option. Apart from basic background color, font and color adjustments, you don't really have a lot of control over the .
However, we can mimic the superb functionality of a <select>
in a new form control without sacrificing semantics, usability or accessibility. In order to do that, we need to examine the nature of a <select>
.
A <select>
is, essentially, an unordered list of choices in which you can choose a single value to submit along with the rest of a form. So, in essence, it's a <ul>
on steroids. Continuing with that line of thinking, we can replace the <select>
with an unordered list, as long as we give it some enhanced functionality. As <ul>
s can be styled in a myriad of different ways, we're almost home free. Now the questions becomes "how to ensure that we maintain the functionality of the <select>
when using a <ul>
?" In other words, how do we submit the correct value along with the form, if we are no longer using a form control?
Enter the DOM. The final step in the process is making the <ul>
function/feel like a <select>
, and we can accomplish that with JavaScript/ECMA Script and a little clever CSS. Here is the basic list of requirements we need to have a functional faux <select>
:
With this plan, we can begin to tackle each part in succession.
So first we need to collect all of the attributes and s out of the and rebuild it as a . We accomplish this by running the following JS:
function selectReplacement(obj) { var ul = document.createElement('ul'); ul.className = 'selectReplacement'; // collect our object's options var opts = obj.options; // iterate through them, creating <li>s for (var i=0; i<opts.length; i++) { var li = document.createElement('li'); var txt = document.createTextNode(opts[i].text); li.appendChild(txt); ul.appendChild(li); } // add the ul to the form obj.parentNode.appendChild(ul); }
You might be thinking "now what happens if there is a selected <option>
already?" We can account for this by adding another loop before we create the <li>
s to look for the selected <option>
, and then store that value in order to class
our selected <li>
as "selected":
… var opts = obj.options; // check for the selected option (default to the first option) for (var i=0; i<opts.length; i++) { var selectedOpt; if (opts[i].selected) { selectedOpt = i; break; // we found the selected option, leave the loop } else { selectedOpt = 0; } } for (var i=0; i<opts.length; i++) { var li = document.createElement('li'); var txt = document.createTextNode(opts[i].text); li.appendChild(txt); if (i == selectedOpt) { li.className = 'selected'; } ul.appendChild(li); …
[Note: From here on out, option 5 will be selected, to demonstrate this functionality.]
Now, we can run this function on every <select>
on the page (in our case, one) with the following:
function setForm() { var s = document.getElementsByTagName('select'); for (var i=0; i<s.length; i++) { selectReplacement(s[i]); } } window.onload = function() { setForm(); }
We are nearly there; let's add some style.
I don't know about you, but I am a huge fan of CSS dropdowns (especially the Suckerfish variety). I've been working with them for some time now and it finally dawned on me that a <select>
is pretty much like a dropdown menu, albeit with a little more going on under the hood. Why not apply the same stylistic theory to our faux-<select>
? The basic style goes something like this:
ul.selectReplacement { margin: 0; padding: 0; height: 1.65em; width: 300px; } ul.selectReplacement li { background: #cf5a5a; color: #fff; cursor: pointer; display: none; font-size: 11px; line-height: 1.7em; list-style: none; margin: 0; padding: 1px 12px; width: 276px; } ul.selectOpen li { display: block; } ul.selectOpen li:hover { background: #9e0000; color: #fff; }
Now, to handle the "selected" list item, we need to get a little craftier:
ul.selectOpen li { display: block; } ul.selectReplacement li.selected { color: #fff; display: block; } ul.selectOpen li.selected { background: #9e0000; display: block; } ul.selectOpen li:hover, ul.selectOpen li.selected:hover { background: #9e0000; color: #fff; }
Notice that we are not using the :hover pseudo-class for the <ul>
to make it open, instead we are class
-ing it as "selectOpen". The reason for this is two-fold:
<select>
behave like a real <select>
, we need the list to open in an onclick
event and not on a simple mouse-over.To implement this, we can take what we learned from Suckerfish and apply it to our own JavaScript by dynamically assigning and removing this class
in ``onclickevents for the list items. To do this right, we will need the ability to change the
onclick` events for each list item on the fly to switch between the following two actions:
<select>
when clicking the selected/default option when the list is collapsed; and<select>
.We will create a function called selectMe()
to handle the reassignment of the "selected" class
, reassignment of the onclick
events for the list items, and the collapsing of the faux-<select>
:
As the original Suckerfish taught us, IE will not recognize a hover state on anything apart from an <a>
, so we need to account for that by augmenting some of our code with what we learned from them. We can attach onmouseover and onmouseout events to the "selectReplacement" class
-ed <ul>
and its <li>
s:
function selectReplacement(obj) { … // create list for styling var ul = document.createElement('ul'); ul.className = 'selectReplacement'; if (window.attachEvent) { ul.onmouseover = function() { ul.className += ' selHover'; } ul.onmouseout = function() { ul.className = ul.className.replace(new RegExp(" selHover\\b"), ''); } } … for (var i=0; i<opts.length; i++) { … if (i == selectedOpt) { li.className = 'selected'; } if (window.attachEvent) { li.onmouseover = function() { this.className += ' selHover'; } li.onmouseout = function() { this.className = this.className.replace(new RegExp(" selHover\\b"), ''); } } ul.appendChild(li); }
Then, we can modify a few selectors in the CSS, to handle the hover for IE:
ul.selectReplacement:hover li, ul.selectOpen li { display: block; } ul.selectReplacement li.selected { color: #fff; display: block; } ul.selectReplacement:hover li.selected**, ul.selectOpen li.selected** { background: #9e0000; display: block; } ul.selectReplacement li:hover, ul.selectReplacement li.selectOpen, ul.selectReplacement li.selected:hover { background: #9e0000; color: #fff; cursor: pointer; }
Now we have a list behaving like a <select>
; but we still need a means of changing the selected list item and updating the value of the associated form element.
We already have a "selected" class
we can apply to our selected list item, but we need a way to go about applying it to a <li>
when it is clicked on and removing it from any of its previously "selected" siblings. Here's the JS to accomplish this:
function selectMe(obj) { // get the <li>'s siblings var lis = obj.parentNode.getElementsByTagName('li'); // loop through for (var i=0; i<lis.length; i++) { // not the selected <li>, remove selected class if (lis[i] != obj) { lis[i].className=''; } else { // our selected <li>, add selected class lis[i].className='selected'; } } }
[Note: we can use simple className
assignment and emptying because we are in complete control of the <li>
s. If you (for some reason) needed to assign additional classes to your list items, I recommend modifying the code to append and remove the "selected" class to your className
property.]
Finally, we add a little function to set the value of the original <select>
(which will be submitted along with the form) when an <li>
is clicked:
function setVal(objID, selIndex) { var obj = document.getElementById(objID); obj.selectedIndex = selIndex; }
We can then add these functions to the onclick
event of our <li>
s:
… for (var i=0; i<opts.length; i++) { var li = document.createElement('li'); var txt = document.createTextNode(opts[i].text); li.appendChild(txt); li.selIndex = opts[i].index; li.selectID = obj.id; li.onclick = function() { setVal(this.selectID, this.selIndex); selectMe(this); } if (i == selectedOpt) { li.className = 'selected'; } ul.appendChild(li); } …
There you have it. We have created our functional faux-. As we have not hidden the original
yet, we can [watch how it behaves](files/4.html) as we choose different options from our faux-
. Of course, in the final version, we don't want the original
to show, so we can hide it by
class`-ing it as "replaced," adding that to the JS here:
function selectReplacement(obj) { // append a class to the select obj.className += ' replaced'; // create list for styling var ul = document.createElement('ul'); …
Then, add a new CSS rule to hide the
select.replaced { display: none; }
With the application of a few images to finalize the design (link not available) , we are good to go!
And here is another link to someone that says it can't be done.
extrapolate it! :)
filter: progid:DXImageTransform.Microsoft.dropshadow(OffX=-1, OffY=0,color=#FF0000) progid:DXImageTransform.Microsoft.dropshadow(OffX=1, OffY=0,color=#FF0000) progid:DXImageTransform.Microsoft.dropshadow(OffX=0, OffY=-1,color=#FF0000) progid:DXImageTransform.Microsoft.dropshadow(OffX=0, OffY=1,color=#FF0000);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With