Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
418 views
in Technique[技术] by (71.8m points)

internet explorer - IE6/IE7 css border on select element

Does anyone have a solution for styling the borders of "select" elements in Internet Explorer using CSS?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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:

A <select> as rendered in Windows XP/Firefox 1.0.2.
(source: easy-designs.net)

or this

A <select> as rendered in Mac OSX/Safari 1.2.
(source: easy-designs.net)

Let's say we want to make it look a little more modern, perhaps like this:

Our concept of a nicely-styled <select>.
(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:

  1. CSS is for presentation, not behavior; and
  2. we want our faux-<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 theonclick` events for each list item on the fly to switch between the following two actions:

  1. show the complete faux-<select> when clicking the selected/default option when the list is collapsed; and
  2. "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.sele

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...