[html] CSS technique for a horizontal line with words in the middle

I'm trying to make a horizontal rule with some text in the middle. For example:

----------------------------------- my title here -----------------------------

Is there a way to do that in CSS? Without all the "-" dashes obviously.

This question is related to html css cross-browser

The answer is


I use a table layout to fill the sides dynamically and 0-height, absolute-position divs for dynamic vertical positioning:

enter image description here

  • no hard-coded dimensions
  • no images
  • no pseudo-elements
  • respects background
  • control bar appearance

https://jsfiddle.net/eq5gz5xL/18/

I found that a little below true center looks best with text; this can be adjusted where the 55% is (taller height makes the bar lower). The appearance of the line can be changed where the border-bottom is.

HTML:

<div class="title">
  <div class="title-row">
    <div class="bar-container">
      <div class="bar"></div>
    </div>
    <div class="text">
      Title
    </div>
    <div class="bar-container">
      <div class="bar"></div>
    </div>
  </div>
</div>

CSS:

.title{
  display: table;
  width: 100%
  background: linear-gradient(to right, white, lightgray);
}
.title-row{
  display: table-row;
}
.bar-container {
  display: table-cell;
  position: relative;
  width: 50%;
}
.bar {
  position: absolute;
  width: 100%;
  top: 55%;
  border-bottom: 1px solid black;
}
.text {
  display: table-cell;
  padding-left: 5px;
  padding-right: 5px;
  font-size: 36px;
}

I am not too sure, but you could try using a horizontal rule and pushing the text above its top margin. You will need a fixed width on your paragraph tag and a background too. It's a little hacky and I don't know if it will work on all browsers, and you need to set the negative margin based on the size of the font. Works on chrome though.

<style>   
 p{ margin-top:-20px; background:#fff; width:20px;}
</style>

<hr><p>def</p>

For me this solution works perfectly fine...

HTML

<h2 class="strikethough"><span>Testing Text</span></h2>

CSS

.strikethough {
 width:100%; 
 text-align:left; 
 border-bottom: 1px solid #bcbcbc; 
 overflow: inherit;
 margin:0px 0 30px;
 font-size: 16px;
 color:#757575;
 }
.strikethough span {
 background:#fff; 
 padding:0 20px 0px 0px;
 position: relative;
 top: 10px;
}

Not to beat a dead horse, but I was searching for a solution, ended up here, and was myself not satisfied with the options, not least for some reason I wasn't able to get the provided solutions here to work well for me. (Likely due to errors on my part...) But I've been playing with flexbox and here's something I did get to work for myself.

Some of the settings are hard-wired, but only for purposes of demonstration. I'd think this solution ought to work in just about any modern browser. Just remove/adjust the fixed settings for the .flex-parent class, adjust colors/text/stuff and (I hope) you'll be as happy as I am with this approach.

HTML:

_x000D_
_x000D_
.flex-parent {_x000D_
  display: flex;_x000D_
  width: 300px;_x000D_
  height: 20px;_x000D_
  align-items: center;_x000D_
}_x000D_
_x000D_
.flex-child-edge {_x000D_
  flex-grow: 2;_x000D_
  height: 1px;_x000D_
  background-color: #000;_x000D_
  border: 1px #000 solid;_x000D_
}_x000D_
.flex-child-text {_x000D_
  flex-basis: auto;_x000D_
  flex-grow: 0;_x000D_
  margin: 0px 5px 0px 5px;_x000D_
  text-align: center;_x000D_
}
_x000D_
<div class="flex-parent">_x000D_
  <div class="flex-child-edge"></div>_x000D_
  <div class="flex-child-text">I found this simpler!</div>_x000D_
  <div class="flex-child-edge"></div>_x000D_
</div>
_x000D_
_x000D_
_x000D_

I also saved my solution here: https://jsfiddle.net/Wellspring/wupj1y1a/1/


No pseudo-element, no additional element. Only single div:

I used some CSS variables to control easily.

_x000D_
_x000D_
div {
  --border-height: 2px;
  --border-color: #000;
  background: linear-gradient(var(--border-color),var(--border-color)) 0% 50%/ calc(50% - (var(--space) / 2)) var(--border-height),
              linear-gradient(var(--border-color),var(--border-color)) 100% 50%/ calc(50% - (var(--space) / 2)) var(--border-height);
  background-repeat:no-repeat;
  text-align:center;
}
_x000D_
<div style="--space: 100px">Title</div>
<div style="--space: 50px;--border-color: red;--border-height:1px;">Title</div>
<div style="--space: 150px;--border-color: green;">Longer Text</div>
_x000D_
_x000D_
_x000D_

But the above method is not dynamic. You have to change the --space variable according to the text length.


CSS grids to the rescue

Similar to the flex answers above, this can also be done using CSS Grids. This gives you more scope to offset the title, and a more simple way of expanding the gap between the lines (using grid-template-columns) and the content (using grid-gap).

The benefits of this method over flex methods is the ease of being able to offset the lines, and additionally only needing to add in a gap between columns once (not twice, for each the :before and :after pseudo element). It is also much more syntactically cleaner and obvious IMO.

_x000D_
_x000D_
h1 {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  grid-gap: 1rem;
}

h1:before,
h1:after {
  content: "";
  display: block;
  border-top: 2px solid currentColor;
}

h1.offset {
  grid-template-columns: 1fr auto 3fr;
}

h1.biggap {
  grid-gap: 4rem;
}
_x000D_
<h1>This is a title</h1>

<h1 class="offset">Offset title</h1>

<h1 class="biggap">Gappy title</h1>

<h1>
  <span>Multi-line<br />title</span>
</h1>
_x000D_
_x000D_
_x000D_


Shortest and best method:

_x000D_
_x000D_
span:after,_x000D_
span:before{_x000D_
    content:"\00a0\00a0\00a0\00a0\00a0";_x000D_
    text-decoration:line-through;_x000D_
}
_x000D_
<span> your text </span>
_x000D_
_x000D_
_x000D_


h6 {
    font: 14px sans-serif;
    margin-top: 20px;
    text-align: center;
    text-transform: uppercase;
    font-weight: 900;
}

    h6.background {
        position: relative;
        z-index: 1;
        margin-top: 0%;
        width:85%;
        margin-left:6%;
    }

        h6.background span {
            background: #fff;
            padding: 0 15px;
        }

        h6.background:before {
            border-top: 2px solid #dfdfdf;
            content: "";
            margin: 0 auto; /* this centers the line to the full width specified */
            position: absolute; /* positioning must be absolute here, and relative positioning must be applied to the parent */
            top: 50%;
            left: 0;
            right: 0;
            bottom: 0;
            width: 95%;
            z-index: -1;
        }

this will help you


between line

_x000D_
_x000D_
.hr-sect {_x000D_
 display: flex;_x000D_
 flex-basis: 100%;_x000D_
 align-items: center;_x000D_
 color: rgba(0, 0, 0, 0.35);_x000D_
 margin: 8px 0px;_x000D_
}_x000D_
.hr-sect::before,_x000D_
.hr-sect::after {_x000D_
 content: "";_x000D_
 flex-grow: 1;_x000D_
 background: rgba(0, 0, 0, 0.35);_x000D_
 height: 1px;_x000D_
 font-size: 0px;_x000D_
 line-height: 0px;_x000D_
 margin: 0px 8px;_x000D_
}
_x000D_
<div class="hr-sect">Text</div>
_x000D_
_x000D_
_x000D_


If anyone is wondering how to set the heading such that it appears with a fixed distance to the left side (and not centered as presented above), I figured that out by modifying @Puigcerber's code.

h1 {
  white-space: nowrap;
  overflow: hidden;
}

h1:before, 
h1:after {
  background-color: #000;
  content: "";
  display: inline-block;
  height: 1px;
  position: relative;
  vertical-align: middle;
}

h1:before {
  right: 0.3em;
  width: 50px;
}

h1:after {
  left: 0.3em;
  width: 100%;
}

Here the JSFiddle.


After trying different solutions, I have come with one valid for different text widths, any possible background and without adding extra markup.

_x000D_
_x000D_
h1 {_x000D_
  overflow: hidden;_x000D_
  text-align: center;_x000D_
}_x000D_
_x000D_
h1:before,_x000D_
h1:after {_x000D_
  background-color: #000;_x000D_
  content: "";_x000D_
  display: inline-block;_x000D_
  height: 1px;_x000D_
  position: relative;_x000D_
  vertical-align: middle;_x000D_
  width: 50%;_x000D_
}_x000D_
_x000D_
h1:before {_x000D_
  right: 0.5em;_x000D_
  margin-left: -50%;_x000D_
}_x000D_
_x000D_
h1:after {_x000D_
  left: 0.5em;_x000D_
  margin-right: -50%;_x000D_
}
_x000D_
<h1>Heading</h1>_x000D_
<h1>This is a longer heading</h1>
_x000D_
_x000D_
_x000D_

I tested it in IE8, IE9, Firefox and Chrome. You can check it here http://jsfiddle.net/Puigcerber/vLwDf/1/


I've been looking around for some solutions for this simple decoration and I've found quite a few ones, some weird, some even with JS to calculate the height of the font and bla,bla,bla, then I've read the one on this post and read a comment from thirtydot speaking about fieldset and legend and I thought that was it.

I'm overriding those 2 elements styles, I guess you could copy the W3C standards for them and include it on your .middle-line-text class (or whatever you want to call it) but this is what I did:

<fieldset class="featured-header">
    <legend>Your text goes here</legend>
</fieldset>

<style>
.featured-header{
    border-bottom: none;
    border-left: none;
    border-right: none;
    text-align: center;
 }

.featured-header legend{
    -webkit-padding-start: 8px; /* It sets the whitespace between the line and the text */
    -webkit-padding-end: 8px; 
    background: transparent; /** It's cool because you don't need to fill your bg-color as you would need to in some of the other examples that you can find (: */
    font-weight: normal; /* I preffer the text to be regular instead of bold  */
    color: YOU_CHOOSE;
}   

</style>

Here's the fiddle: http://jsfiddle.net/legnaleama/3t7wjpa2/

I've played with the border styles and it also works in Android ;) (Tested on kitkat 4.XX)

EDIT:

Following Bekerov Artur's idea which is a nice option too, I've changed the .png base64 image to create the stroke with an .SVG so you can render in any resolution and also change the colour of the element without any other software involved :)

/* SVG solution based on Bekerov Artur */
/* Flexible solution, scalable, adaptable and also color customizable*/
.stroke {
background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' x='0px' y='0px' width='1px' height='1px' viewBox='0 0 1 1' enable-background='new 0 0 1 1' fill='%23ff6600' xml:space='preserve'><rect width='1' height='1'/></svg>");
background-repeat: repeat-x;
background-position: left;
text-align: center;
}
.stroke h3 {
background-color: #ffffff;
margin: 0 auto;
padding:0 10px;
display: inline-block;
font-size: 66px;
}

This code will work properly:

_x000D_
_x000D_
/* ??? ????*/
  .div-live {
    text-align: center;
}
.span-live {
    display: inline-block;
    color: #b5b5b5;
  
}
.span-live:before,
.span-live:after {
    border-top: 1px solid #b5b5b5;
    display: block;
    height: 1px;
    content: " ";
    width: 30%;
    position: absolute;
    left: 0;
    top: 3rem;


}
.span-live:after {
   right: 0;
   left: auto;
}
_x000D_
  <div class="div-live">
            <span class="span-live">??? ????</span>

    </div>
_x000D_
_x000D_
_x000D_


Here is Flex based solution.

A heading with a central horizontal line to its sides

_x000D_
_x000D_
h1 {
  display: flex;
  flex-direction: row;
}
h1:before, h1:after{
  content: "";
  flex: 1 1;
  border-bottom: 1px solid;
  margin: auto;
}
h1:before {
  margin-right: 10px
}
h1:after {
  margin-left: 10px
}
_x000D_
<h1>Today</h1>
_x000D_
_x000D_
_x000D_

JSFiddle: https://jsfiddle.net/j0y7uaqL/


<div><span>text TEXT</span></div>

div { 
  height: 1px; 
  border-top: 1px solid black; 
  text-align: center; 
  position: relative; 
}
span { 
  position: relative; 
  top: -.7em; 
  background: white; 
  display: inline-block; 
}

Give the span a padding to make more space between the text and the line.

Example: http://jsfiddle.net/tUGrf/


I have tried most of the ways suggested but ends with some problems like full width, or Not suitable for dynamic content. Finally i modified a code, and works perfectly. This example code will draw those lines before and after, and it is flexible in content change. Center aligned too.

HTML

        <div style="text-align:center"> 
            <h1>
                <span >S</span>
            </h1> 
        </div> 

        <div style="text-align:center"> 
            <h1>
                <span >Long text</span>
            </h1> 
        </div> 

CSS

      h1 {
            display: inline-block;
            position: relative;
            text-align: center;
        }

        h1 span {
            background: #fff;
            padding: 0 10px;
            position: relative;
            z-index: 1;
        }

        h1:before {
            background: #ddd;
            content: "";
            height: 1px;
            position: absolute;
            top: 50%;
            width: calc(100% + 50px);//Support in modern browsers
            left: -25px;
        }

        h1:before {
            left: ;
        }

Result: https://jsfiddle.net/fasilkk/vowqfnb9/


Horizontal and Vertical line with words in the middle

_x000D_
_x000D_
.box{_x000D_
    background-image: url("https://i.stack.imgur.com/N39wV.jpg");_x000D_
    width: 350px;_x000D_
    padding: 10px;_x000D_
}_x000D_
_x000D_
/*begin first box*/_x000D_
.first{_x000D_
    width: 300px;_x000D_
    height: 100px;_x000D_
    margin: 10px;_x000D_
    border-width: 0 2px 0 2px;_x000D_
    border-color: red;_x000D_
    border-style: solid;_x000D_
    position: relative;_x000D_
}_x000D_
_x000D_
.first span {_x000D_
    position: absolute;_x000D_
    display: flex;_x000D_
    right: 0;_x000D_
    left: 0;_x000D_
    align-items: center;_x000D_
}_x000D_
.first .foo{_x000D_
    top: -8px;_x000D_
}_x000D_
.first .bar{_x000D_
    bottom: -8.5px;_x000D_
}_x000D_
.first span:before{_x000D_
    margin-right: 15px;_x000D_
}_x000D_
.first span:after {_x000D_
    margin-left: 15px;_x000D_
}_x000D_
.first span:before , .first span:after {_x000D_
    content: ' ';_x000D_
    height: 2px;_x000D_
    background: red;_x000D_
    display: block;_x000D_
    width: 50%;_x000D_
}_x000D_
_x000D_
_x000D_
/*begin second box*/_x000D_
.second{_x000D_
    width: 300px;_x000D_
    height: 100px;_x000D_
    margin: 10px;_x000D_
    border-width: 2px 0 2px 0;_x000D_
    border-color: red;_x000D_
    border-style: solid;_x000D_
    position: relative;_x000D_
}_x000D_
_x000D_
.second span {_x000D_
    position: absolute;_x000D_
    top: 0;_x000D_
    bottom: 0;_x000D_
    display: flex;_x000D_
    flex-direction: column;_x000D_
    align-items: center;_x000D_
}_x000D_
.second .foo{_x000D_
    left: -15px;_x000D_
}_x000D_
.second .bar{_x000D_
    right: -15.5px;_x000D_
}_x000D_
.second span:before{_x000D_
    margin-bottom: 15px;_x000D_
}_x000D_
.second span:after {_x000D_
    margin-top: 15px;_x000D_
}_x000D_
.second span:before , .second span:after {_x000D_
    content: ' ';_x000D_
    width: 2px;_x000D_
    background: red;_x000D_
    display: block;_x000D_
    height: 50%;_x000D_
}
_x000D_
<div class="box">_x000D_
    <div class="first">_x000D_
        <span class="foo">FOO</span>_x000D_
        <span class="bar">BAR</span>_x000D_
    </div>_x000D_
_x000D_
   <br>_x000D_
_x000D_
    <div class="second">_x000D_
        <span class="foo">FOO</span>_x000D_
        <span class="bar">BAR</span>_x000D_
    </div>_x000D_
</div>
_x000D_
_x000D_
_x000D_

This is also answered in https://stackoverflow.com/a/57279326/6569224


Ok, this one is more complicated but it works in everything but IE<8

<div><span>text TEXT</span></div>

div {
    text-align: center;
    position: relative;
}
span {
    display: inline-block;    
}
span:before,
span:after {
    border-top: 1px solid black;
    display: block;
    height: 1px;
    content: " ";
    width: 40%;
    position: absolute;
    left: 0;
    top: 1.2em;
}
span:after {
   right: 0;  
   left: auto; 
}

The :before and :after elements are positioned absolutely so we can pull one to the left and one to the right. Also, the width (40% in this case) is very dependent of the width of the text inside.. have to think about a solution for that. At least the top: 1.2em makes sure the lines stay more or less in the center of the text even if you have different font size.

It does seem to work well though: http://jsfiddle.net/tUGrf/3/


I went for a simpler approach:

HTML

<div class="box">
  <h1 class="text">OK THEN LETS GO</h1>
  <hr class="line" />
</div>

CSS

.box {
  align-items: center;
  background: #ff7777;
  display: flex;
  height: 100vh;
  justify-content: center;
}

.line {
  border: 5px solid white;
  display: block;
  width: 100vw;
}

.text {
  background: #ff7777;
  color: white;
  font-family: sans-serif;
  font-size: 2.5rem;
  padding: 25px 50px;
  position: absolute;
}

Result

Result


Just in case anyone wants to, IMHO the best solution using CSS is by a flexbox.

Here is an example:

_x000D_
_x000D_
.kw-dvp-HorizonalButton {_x000D_
    color: #0078d7;_x000D_
    display:flex;_x000D_
    flex-wrap:nowrap;_x000D_
    align-items:center;_x000D_
}_x000D_
.kw-dvp-HorizonalButton:before, .kw-dvp-HorizonalButton:after {_x000D_
    background-color: #0078d7;_x000D_
    content: "";_x000D_
    display: inline-block;_x000D_
    float:left;_x000D_
    height:1px;_x000D_
}_x000D_
.kw-dvp-HorizonalButton:before {_x000D_
    order:1;_x000D_
    flex-grow:1;_x000D_
    margin-right:8px;_x000D_
}_x000D_
.kw-dvp-HorizonalButton:after {_x000D_
    order: 3;_x000D_
    flex-grow: 1;_x000D_
    margin-left: 8px;_x000D_
}_x000D_
.kw-dvp-HorizonalButton * {_x000D_
    order: 2;_x000D_
}
_x000D_
    <div class="kw-dvp-HorizonalButton">_x000D_
        <span>hello</span>_x000D_
    </div>
_x000D_
_x000D_
_x000D_

This should always result in a perfectly centered aligned content with a line to the left and right, with an easy to control margin between the line and your content.

It creates a line element before and after your top control and set them to order 1,3 in your flex container while setting your content as order 2 (go in the middle). giving the before/after a grow of 1 will make them consume the most vacant space equally while keeping your content centered.

Hope this helps!


If you are using React with Styled Components. I found that is more easy to just separate elements. Is not the "amazing solution" but it works.

import React from 'react';
import styled from "@emotion/styled";

const Container = styled.div`
  padding-top: 210px;
  padding-left: 50px;  
  display: inline-flex;
`

const Title1 = styled.div`
  position: absolute;
  font-size: 25px;
  left:40px;
  color: white;
  margin-top: -17px;
  padding-left: 40px;
`

const Title2 = styled.div`
  position: absolute;
  font-size: 25px;
  left:1090px;
  color: white;
  margin-top: -17px;
  padding-left: 40px;
`

const Line1 = styled.div`
  width: 20px;
  border: solid darkgray 1px;
  margin-right: 90px;
`
const Line2 = styled.div`
  width: 810px;
  border: solid darkgray 1px;
  margin-right: 126px;
`
const Line3 = styled.div`
  width: 178px;
  border: solid darkgray 1px;
`


const Titulos = () => {
    return (
        <Container>
            <Line1/>
            <Title1>
                FEATURED
            </Title1>
            <Line2/>
            <Line1/>
            <Title2>
                EXCLUSIVE
            </Title2>
            <Line3/>
        </Container>
    );
};

export default Titulos;

Result:

enter image description here


edit (09/2020)

display:flex method seems to be today the most solid and easiest to set in action.


Wrote Mar 17 '15 at 17:06:

for later(nowdays ) browser , display:flex and pseudo-elements makes it easy to draw without extra markup.

border-style, box-shadow and even background helps too for the makeup if you need it fancy or ugly. demo below

_x000D_
_x000D_
h1 {margin-top:50px;
  display:flex;
  background:linear-gradient(to left,gray,lightgray,white,yellow,turquoise);;
}
h1:before, h1:after {
  color:white;
  content:'';
  flex:1;
  border-bottom:groove 2px;
  margin:auto 0.25em;
  box-shadow: 0 -1px ;/* ou 0 1px si border-style:ridge */
}
_x000D_
<h1>side lines via flex</h1>
_x000D_
_x000D_
_x000D_

ressource (added 09/2020):


Solution for IE8 and newer...

Issues worth noting:

Using background-color to mask a border might not be the best solution. If you have a complex (or unknown) background color (or image), masking will ultimately fail. Also, if you resize the text, you'll notice that white background color (or whatever you set) will start covering up the text on the line above (or below).

You also don't want to "guesstimate" how wide the the sections are either, because it makes the styles very inflexible and almost impossible to implement on a responsive site where the width of the content is changing.

Solution:

(View JSFiddle)

Instead of "masking" a border with a background-color, use your display property.

HTML

<div class="group">
    <div class="item line"></div>
    <div class="item text">This is a test</div>
    <div class="item line"></div>
</div>

CSS

.group { display: table; width: 100%; }
.item { display: table-cell; }
.text { white-space: nowrap; width: 1%; padding: 0 10px; }
.line { border-bottom: 1px solid #000; position: relative; top: -.5em; }

Resize your text by placing your font-size property on the .group element.

Limitations:

  • No multi-line text. Single lines only.
  • HTML markup isn't as elegant
  • top property on .line element needs to be half of line-height. So, if you have a line-height of 1.5em, then the top should be -.75em. This is a limitation because it's not automated, and if you are applying these styles on elements with different line-heights, then you might need to reapply your line-height style.

For me, these limitations outweigh the "issues" I noted at the beginning of my answer for most implementations.


People who are using Bootstrap 4 can achieve with this method. classes mentioned in HTML code are from Bootstrap 4.

h1 {
    position: relative;
    flex-grow: 1;
    margin: 0;
}

h1:before {
   content: "";
   display: block;
   border-top: solid 2px blue;
   width: 100%;
   height: 1px;
   position: absolute;
   top: 50%;
   z-index: 1;
 }
 h1 span {
   background: #fff;
   left: 12%;
   padding: 0 15px;
   position: relative;
   z-index: 5;
 }

And write your HTML like this

<div class="d-flex flex-row align-items-center">
  <h1><span> Title </span> </h1>
</div>

This gives you fixed length for the lines, but works great. The lines lengths are controlled by adding or taking '\00a0' (unicode space).

enter image description here

_x000D_
_x000D_
h1:before, h1:after {_x000D_
  content:'\00a0\00a0\00a0\00a0';_x000D_
  text-decoration: line-through;_x000D_
  margin: auto 0.5em;_x000D_
}
_x000D_
<h1>side lines</h1>
_x000D_
_x000D_
_x000D_


Examples related to html

Embed ruby within URL : Middleman Blog Please help me convert this script to a simple image slider Generating a list of pages (not posts) without the index file Why there is this "clear" class before footer? Is it possible to change the content HTML5 alert messages? Getting all files in directory with ajax DevTools failed to load SourceMap: Could not load content for chrome-extension How to set width of mat-table column in angular? How to open a link in new tab using angular? ERROR Error: Uncaught (in promise), Cannot match any routes. URL Segment

Examples related to css

need to add a class to an element Using Lato fonts in my css (@font-face) Please help me convert this script to a simple image slider Why there is this "clear" class before footer? How to set width of mat-table column in angular? Center content vertically on Vuetify bootstrap 4 file input doesn't show the file name Bootstrap 4: responsive sidebar menu to top navbar Stylesheet not loaded because of MIME-type Force flex item to span full row width

Examples related to cross-browser

Show datalist labels but submit the actual value Stupid error: Failed to load resource: net::ERR_CACHE_MISS Click to call html How to Detect Browser Back Button event - Cross Browser How can I make window.showmodaldialog work in chrome 37? Cross-browser custom styling for file upload button Flexbox and Internet Explorer 11 (display:flex in <html>?) browser sessionStorage. share between tabs? How to know whether refresh button or browser back button is clicked in Firefox CSS Custom Dropdown Select that works across all browsers IE7+ FF Webkit