+1  A: 

You could:

  • Find a grey which suits
  • Use JavaScript to change the colour between white and black dynamically, depending on where it is
  • Make the middle colour of the background gradient closer to white, and always use dark text
  • Put the progress outisde the box:
[#########              ] 50 % 
Lucas Jones
Thank you. I'm considering those suggestions as a "fallback" options if I'll fail to implement what I exactly want. Still, if it's possible, I'd really like to implement it the way it's shown on the picture in my question.
drdaeman
+7  A: 

What about putting a second copy of the progress bar text inside the div, and set the div's overflow to hidden, so it reveals with it?

--

Update: I am also not a javascript expert, but I am sure that you can find out the width of an object and then set the offset based upon that if the width is flexible as you say.

Meep3D
This is what you want to do. Have two versions of the bar over top each other and progressively reveal one of them.
Nosredna
Sounds like a good idea. Thank you, I'll try!
drdaeman
I've got the overall idea — it seems to be a right way to go, but the progress has no fixed width and automatically stretches to all available space, so putting a copy in inner (filled area) div with example `width: 50%` don't work.
drdaeman
+1  A: 

You could use a text shadow for your "percentage" text. The only downside to this is that it would only work in the latest browsers. Only Firefox 3.5, Safari (all versions), and Chrome 2+ support it.

Here is a demo of using text-shadow in a way that would make your progress readable.
http://www.w3.org/Style/Examples/007/text-shadow#white

If you're willing to use more JavaScript, you could try this jQuery plugin:

http://kilianvalkhof.com/2008/javascript/text-shadow-in-ie-with-jquery/

The article says it works in IE only, however it works in Chrome 3 (what I'm using), Firefox 3.5, Internet Explorer, and Safari. It may work in older browsers but I haven't tested it.

Dan Herbert
+1  A: 

Meep3D has the correct answer. Two versions of the box. Reveal n% of the top one.

More options:

  • Put a translucent box under the number that either darkens the area for a white number or lightens the area for a black number.
  • Use red and white as backgrounds and a black number. (Problem here is red is associated with error, so you can play with other combinations of three colors that are all high contrast against each other.)
Nosredna
+1  A: 

As per Meep3D's suggestion, take 2 copies of the text.

Wrap each in a div of the same width as the container. The "upper" div is wrapped with another div which clips at the desired percentage.

Update: removed the fixed widths.
The "upper" div is sized to the inverse percentage of its wrapper.

<html>
<head>
  <style type="text/css">
    #container {
        position: relative;
        border: 1px solid;
        text-align: center;
        width: 400px;
        height: 32px;
    }
    .black-on-white {
        height: 32px;
        color: #000;
    }
    .white-on-black {
        height: 32px;
        color: #fff;
        background-color: #44a;
    }
    .wrapper {
        width: 53%;
        overflow: hidden;
        position: absolute;
        top: 0; left: 0;
    }
    .black-on-white {
        width: 100%;
    }
    .white-on-black {
        width: 188.7%;
    }
  </style>
</head>
<body>
  <div id="container">
    <div class="wrapper">
        <div class="white-on-black">
             <span>This is a test</span>
        </div>
    </div>
    <div class="black-on-white">
        <span>This is a test</span>
    </div>
  </div>
</body>
</html>
Lachlan Roche
Thank you, this is what I tried yesterday too. One problem — in my case progress bar should have no fixed width and take all horizontally available space. But without `width: 400px` rule everything breaks. And I'd like to avoid using JavaScript, if possible.
drdaeman
Awesome! Thank you very much, it works great. Didn't thought about (1/percent) width.
drdaeman