Wednesday, August 20, 2014

Making Some Progress

I just started on a new project recently and one of the things on the page I was working on was displaying progress bars in different colors.  The progress bars need to display an indeterminate state and after talking with a co-worker we thought making it look like KITT from Night Rider was the best (and most awesome) way to display that.


Is that you Mr. Feeny?
Because of a lot of my work being done on the canvas, and to have communication being done with web sockets, I am only supporting modern browsers for this app.  I knew there are a ton of new elements in HTML 5 and one of my personal goals is to become better at writing semantically correct html.  A quick look through the elements, and I found the <progress> tag.  Even better, it comes with an indeterminate state and is supported in the browsers I care about.  My next requirement was just to style the progress elements different colors based on their states.  I thought this is going to be easy.  All I need to do is add some classes to set the color and I'm done!


So after a quick search I find out you pretty much can't do anything to style a progress element.  Which made me think...  how do you expect people to use this element if they can't make it look how they need it to?

I was determined to use CSS only to get this to work and make my page semantically awesome.  I found some sites like this that show you how to clear out the native browser appearance and add your own.  So I started with that and then added my own classes to style them how I needed.  A lot of CSS later, I came up with the following:

.progressContainer{
    position:relative;
    width: 100px;
}

progress{
  height:5px;
  border:0;
  appearance: none;
  -moz-appearance: none;
  -webkit-appearance: none;
  width:100% !important;
 
}

progress.connected::-webkit-progress-value{
  background: green;
} 
progress.connected::-moz-progress-value{
  background: green;
}
progress.connected::progress-value{
  background: green;
}
progress.connected::-webkit-progress-bar{
  background: green;
} 
progress.connected::-moz-progress-bar{
  background: green;
}
progress.connected::progress-bar{
  background: green;
}
progress.connected:not([value])::-webkit-progress-bar{
  background:green;
}
progress.connected:not([value])::-moz-progress-bar{
  background:green;
}
progress.connected:not([value])::progress-bar{
  background:green;
}

With the lower half repeated for each class that I wanted, I was almost done. While verbose, I was able to style the progress as necessary. The only thing left was to get KITT to work. After some quick thinking I figured I would use a ::before pseudo element and animate it.
@-webkit-keyframes knightRider {
   0% {
 left: 0%;
      }
 
  50% {
 left:100%;
        margin-left:-10px;
      }
  100%{
 left:0%;
      }
}
@keyframes knightRider {
   0% {
 left: 0%;
      }
 
  50% {
   left:100%;
        margin-left:-10px;
      }
  100%{
 left:0%;
      }
}

progress.searching::before{
  content:"";
  background-color:blue;
  width:10px;
  height:5px;
  position: absolute;
  animation: knightRider 2s infinite linear;
  -webkit-animation: knightRider 2s infinite linear;
}
A quick refresh of my fiddle and BOOM it was working.  Now I just need to make sure it is working in Firefox which should be just a formality, right?  Wrong!  Only webkit browsers support ::before and ::after on progress for some bizzaro reason.  So I ended up adding a hidden div next to the progress bar that would use the animation from above and only show up when a specific class is added to the progress bar.

See the Pen Progress by Andy (@andyjmeyers) on CodePen.




Finally some progress...

No comments:

Post a Comment