Tag Archives: CSS

Setting CSS Background Colors via Javascript – RGB triplet vs Hex

10 Oct 2012

We’ve all had to do it – change the color of text or visible html elements like Div backgrounds or borders, etc. One thing I’ve noticed is that when I request the background color of a Div I get the RGB triplet, not a hexadecimal value. Observe this example:

(Please use a modern browser, I’ve made no effort to make the examples work in old browsers)





Click here to get the color of the box

The box color is:

 

Notice that the color obtained is not the hexadecimal value that you saw in the sample source provided above but the RGB equivalent even though its Hexadecimal to begin with.

Next, if I were to attempt to change the color by setting the css background-color value to an RGB value nothing will happen. See this example:





Click here to change the box color with an RGB value: rgb(122, 122, 122);

The box color is:

 

As you can see… nothing happens…. so in order to change the background color you must use a hexidecimal value.

If we get a hex value from an element it will be RGB so in order to make it useful elsewhere in our code we would need to convert the RGB back to hexadecimal. Below is a function I wrote that will do that for us.

...
function convertToHex(str){
  var raw = str.match(/(\d+)/g);
  var hexr = parseInt(raw[0]).toString(16);
  var hexg = parseInt(raw[1]).toString(16);
  var hexb = parseInt(raw[2]).toString(16);
      hexr = hexr.value == 1 ? '0' + hexr: hexr;
      hexg = hexg.length == 1 ? '0' + hexg: hexg;
      hexb = hexb.length == 1 ? '0' + hexb: hexb;
  var hex = '#' + hexr + hexg + hexb;
  return hex;
}
...

This function takes an RGB of the following format: rgb(x, x, x) where “x” is any number within the RGB number range. The short description of what is happening would be to say that hexadecimal is base 16, thus the toString(16) which gives us the hex equivalent of each individual RGB value.

The long description would to say that the basic usage of toString() is to convert a number to a string, but we can also pass an argument to the toString() method to tell it what base to convert the number to. A few different bases are available. If we wanted to convert a number to binary we would use toString(2) (pronounced to string base 2), to octal, we would use toString(8) and finally to convert to hexadecimal we use toString(16). Using a base of 10 as in toString(10) is the same as using nothing at all – base 10 is decimal which is what numbers are to begin with.

An interesting thing to note is that hexadecimal is a numbering system from 0 to 9 and then continuing from A to F which totals 16 characters. 15 in hex is “f” which is just one character in length. 16 is two characters – ’10’. So any RGB value lower than 16 in hexadecimal will be a single character in length. Such values need to be left-padded by a zero since a hexadecimal color is always a total of 6 characters (2 characters per R, G, and B). To use our example, 15 = f in hex, we need to left zero pad it to be “0f”. If your RGB value is rgb(15, 15, 15) the proper hexadecimal value would be “0f0f0f” and not “fff” (which is a completely different color, see below). You can see the zero-padding happening in the ternary operators on lines 7, 8, and 9.

The caveat to all of this are the “shortcode” hex values that you see from time to time. Such as “fff” for white which in its full form is “ffffff”, or “ccc” for a light grey which is really “cccccc”. How about this shortened hex: “7de” – that would be “77ddee”. See the pattern? If a browser sees a 3 character hex value then each individual character must represent R, G, and B. In the absence of any other data the rest of the hex values are implied by the existing data, so “7” = “77, “d” = “dd” and “e” = “ee”. It is then necessary to give a browser a full hexadecimal value where necessary to get the actual colors, not implied colors. Left zero-padding where needed achieves this.

So here now is my last example using a color palette toolbar to change the color of a Div element, where I take the background color of the clicked Div element, which is revealed as RGB, convert it back to hexadecimal and apply it to the color box:







Select a color to change the box's background color.

 

An interesting thing to note is that the hexedecimal is not inserted as hexadecimal – its inserted as RGB! Yeah… I don’t know why either… if someone knows, please enlighten me in the comments below….

Mobile-Specific Style Sheets

28 Aug 2012

Here’s a brief snippet of code that I just wrote to handle serving up style sheets for a mobile project – it detects iOS, Android, iPhone and iPad allowing you to write in platform/device-specific style sheets into your HTML documents. This is a self-invoking function, simply paste into the head of your document and you are done – of course, change the CSS paths to your liking.


This simply writes in a style tag to the appropriate style sheet and is easily adapted to whatever your needs might be.

Another method of using platform/device-specific styles is to write them in when you’re doing your DOM manipulation – i.e., whenever you add content to the page. Doing so give you the ability to insert the proper id and class selectors using your framework’s ability to detect the given platform/device. If you take this route you will need to load up a style sheet that contains all of your css so that all of your styling is available to be used whenever its applied to your layout.

Mobile Safari Debug Console Breaks @Media Query

03 Jul 2012

Spent a lot of time spinning my wheels on this – in these cases you always think about whats changed since the last time your layout did what you wanted…and I backed up all the way to settings I enabled/disabled on the iPhone, and found the issue!

If you’re using an @media query like the following:

...
@media screen and (max-width:320px) and (orientation: portrait){
    /* your css here */
}
...

You will notice that it **breaks** when Mobile Safari’s debug console is enabled.

We can look into this a little further by using JavaScript to get the device’s reported width and we can infer the orientation from the number of degrees of rotation. To discover this information:

...
alert('width: ' + window.innerWidth + '\n orientation: ' + window. orientation);
...

Holding the iPhone in a portrait orientation with the debug console on we see the following values when reloading the test page:

  • width: 320
  • orientation: 0

The same test with the debug console off… is the same as with it on – there’s no smoking gun here as to why this is happening. The above @media query for unknown reasons is just plain broken with the debug console enabled!

Scaling Fixed Background Images

08 Jun 2012

I recently built a page template for a friend that required a static background image that scaled with the browser window while keeping the image’s aspect ratio intact. The challenge was more about getting it to display properly in IE 7 and 8. In the end there are a combination of approaches here – one for browsers that support “background-size:cover” and the other only for IE browsers below IE 9.

To begin, here’s the CSS-compliant bit – works in FF 3.6+, Safari 5+, IE 9+, and Chrome 5+.

First create two divs inside a blank HTML document. The first div will be the one responsible for the static back-ground image on our page, the second will be the wrapper for all of the page’s content. As you can see I’ve assigned ID’s to the two divs: “page-background” and “contentWrapper”.



  
    
    
  
  
    

Next we want to start adding some CSS, lets start with the background. As the ID for the background is “pageBackground” lets add a STYLE tag to the page and define the DIV’s styling:



  
    
    
    
  
  
    

Breaking down the above CSS – “position:fixed” affixes the DIV to the viewing area outside of the document flow. The DIV will remain in its position regardless of page scrolling. “top” and “left” simply places the div to the upper left corner of the window and the “width” and “height” values of 100% ensure that the DIV stretches to fit the rest of the window.

Once the DIV is setup simply add the proper CSS for the image, including position (50% 50% places it in the center of the DIV), turn image repeating off and setting the “background-size” property to “cover” – this last item is what results in stretching the image to fill the page while maintaining the image’s aspect ratio. Some clipping may occur while the browser does this but it should be minor and is something to expect.

Finally, the “-moz-background-size” enables FireFox 3.6 support.

In order to appreciate the effect we should add a bit of content. The most important thing to realize here is that we will have to float our content-wrapping DIV over the background image so we will have to give it a higher z-index than the background.

Also you’ll see in the following code snippet that I’ve added some content to the “contentWrapper” and gave it a transparent background for extra effect.



  
    
    
    
  
  
    

top

middle

bottom

Cool, almost done – now for IE 7 and 8.

The “background-size” CSS property doesn’t exist in those browsers, so, the best that we can do is to use an image that is stretched to fill the page. Image scaling/stretching is an unfortunate consequence of this technique but is all that we have available to us.

So what we want to do is to use the above code/CSS for all capable browsers and then have a mechanism where we fall back to the stretched image approach for older IE browsers. My approach is to use conditional comments that only IE recognizes – all other browsers will ignore them.

The code is really pretty simple – we just add the conditional comment wrapping an image tag that we’ll add within the “pageBackground” DIV:



  
    
    
    
  
  
    

top

middle

bottom

That’s it, pretty simple – I’m really not concerned with trying to get the same CSS effect in IE 7 or 8 and the above for my purposes is “good enough”. What we have is the image appearing only in IE versions less than 9 and its height and width stretch to fill the screen by virtue of the height and width of the image being set to 100%.

Vertical Text Align Issue In Chrome

24 May 2012

(UPDATE: The good people at chromium have pointed out that Safari 5 fails on this too, and so this is a WebKit error not unique to Chrome).

Stumbled upon this one today in Chrome (submitted to the Chrome bug list on 7/3/12) – given the right set of circumstances vertical text alignment of italicized text will drop below the baseline. The complete list of circumstances that must be present to see this are:

  • At the time of this writing you must be using Chrome build 19.0.1084.46 m on Windows. I’m using Vista64.
  • Text must exist in a table cell
  • The text must not be wrapped by any other element
  • A portion of text must be italicized via the EM element
  • A portion of text must be superscripted via the SUP element
  • The wrapping TD element must have its VALIGN attribute set to “top”

Obviously this is pretty obscure. The key to producing this is the td/valign and the EM and SUP elements. The EM’d and SUP’d text must be on the same line and not be wrapped by anything at all within the TD. By either removing the SUP element or the TD VALIGN the issue goes away. Here are the test cases:

...
  // view this code in chrome and the emphasized "Motor Trend" will appear below the baseline
  
  </tr></table>
  
  // Next, lets remove the TD valign - and everything appears normal in Chrome
  
2012 Motor Trend Car of the Year®
2012 Motor Trend Car of the Year®
// Next, lets remove the SUP element and return the TD valign - and everything appears normal in Chrome
2012 Motor Trend Car of the Year®
// this is the "control" - outside of a table everything is on the baseline.

2012 Motor Trend Car of the Year®

...

And a screen shot of the above (or view it here):

This behavior only happens in Chrome. IE 7, 8, 9 and FireFox don’t exhibit this behavior. My fix to this problem was to set the vertical alignment of the EM element like so:

...

  (function fixChrome(){
     if (navigator.userAgent.toLowerCase().indexOf('chrome') != -1){
       document.write('');
     }
  })();

  
2012 Motor Trend Car of the Year®
...

And with that, the above scenario displays as desired within Chrome.