Does anyone have a solution for styling the borders of "select" elements in Internet Explorer using CSS?
问题:
回答1:
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.
Edit: The link is broken I'm dumping the content
<select>
Something New, Part 1
By Aaron Gustafson
So 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.
The Problem
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.
The <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?
The solution
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>
:
- click the list to open it,
- click on list items to change the value assigned & close the list,
- show the default value when nothing is selected, and
- show the chosen list item when something is selected.
With this plan, we can begin to tackle each part in succession.
Building the list
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.
Some clever CSS
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:
- CSS is for presentation, not behavior; and
- we want our faux-
<select>
behave like a real<select>
, we need the list to open in anonclick
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:
- show the complete faux-
<select>
when clicking the selected/default option when the list is collapsed; and - "select" a list item when it is clicked & collapse the faux-
<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.
JavaScript fu
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.
回答2:
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);
回答3:
From my personal experience where we tryed to put the border red when an invalid entry was selected, it is impossible to put border red of select element in IE.
As stated before the ocntrols in internet explorer uses WindowsAPI to draw and render and you have nothing to solve this.
What was our solution was to put the background color of select element light red (for text to be readable). background color was working in every browser, but in IE we had a side effects that the element where the same background color as the select.
So to summarize the solution we putted :
select
{
background-color:light-red;
border: 2px solid red;
}
option
{
background-color:white;
}
Note that color was set with hex code, I just don't remember which.
This solution was giving us the wanted effect in every browser except for the border red in IE.
Good luck
回答4:
i was having this same issue with ie, then i inserted this meta tag and it allowed me to edit the borders in ie
<meta http-equiv="X-UA-Compatible" content="IE=100" >
回答5:
Using ONLY css is impossbile. In fact, all form elements are impossible to customize to look in the same way on all browsers only with css. You can try niceforms though ;)
回答6:
IE < 8 does not render the dropdown list itself it just uses the windows control which cannot be styled this way. Beginning from IE 8 this has changed and the styling is now applied. Of course, its market share is rather negligible yet.
回答7:
I've worked around the inability to put a border on the select in IE7 (IE8 in compatibility mode)
By giving it a border as wel as a padding, it looks like something....
Not everything, but it's start...
回答8:
Check out this code... hope ur happy :)
<!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=iso-8859-1" />
<title>Untitled Document</title>
<style type="text/css">
<style type="text/css">
*{margin:0;padding:0;}
select {font: normal 13px Arial, SansSerif, Verdana; color: black;}
.wrapper{width:198px; position: relative; height: 20px; overflow: hidden; border-top:1px solid #dddddd; border-left:1px solid #dddddd;}
.Select{color: black; background: #fff;position: absolute; width: 200px; top: -2px; left: -2px;}
optgroup{background-color:#0099CC;color:#ffffff;}
</style>
</head>
<body>
<div class="wrapper">
<select class="Select">
<optgroup label="WebDevelopment"></optgroup>
<option>ASP</option>
<option>PHP</option>
<option>ColdFusion</option>
<optgroup label="Web Design"></optgroup>
<option>Adobe Photoshop</option>
<option>DreamWeaver</option>
<option>CSS</option>
<option>Adobe Flash</option>
</select>
</div>
</body>
</html>
Sajay
回答9:
The border-style property is a short-hand command to define the border styles of all sides an html element. Each side can have a different style.
http://www.handycss.com/tips/styling-borders-with-css/
回答10:
You'd need a custom-designed select box with CSS and JavaScript. You'd need to make absolutely sure it degrades perfectly to a standard select element should a user have JavaScript disabled.
IMO, it's just not worth the effort. Stick with font stylings within the select to make it close to your site's design; leave the borders, etc., to the box elements.
回答11:
To do a border along one side of a select in IE use IE's filters:
select.required { border-left:2px solid red; filter: progid:DXImageTransform.Microsoft.dropshadow(OffX=-2, OffY=0,color=#FF0000) }
I put a border on one side only of all my inputs for required status.
There is probably an effects that do a better job for an all-round border ...
http://msdn.microsoft.com/en-us/library/ms532853(v=VS.85).aspx
回答12:
Just add an doctype declaration before the html tag
ex.: <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/strict.dtd">
It is gonna work in JSP files as well. For further info: HTML Doctype Declaration
回答13:
It works!!! Use the following code:
<style>
div.select-container{
border: 1px black;width:200px;
}
</style>
<div id="status" class="select-container">
<select name="status">
<option value="" >Please Select...</option>
<option value="option1">Option 1</option>
<option value="option2">Option 2</option>
</select>
</div>
回答14:
It solves to me, for my purposes:
.select-container {
position:relative;
width:200px;
height:18px;
overflow:hidden;
border:1px solid white !important
}
.select-container select {
position:relative;
left:-2px;
top:-2px
}
To put more style will be necessary to use nested divs .