Search This Blog

Saturday, 20 May 2017

CSS3 - Automatically contrast font color according to background image

Requirement statement: For a dynamically changing background, implement a contrasting font

Well, this was something I was trying out, where there was a html container changing images at random with some writing embedded in it.

To make it very simple and scalable, I needed a css that would automatically detect the background shades and adjust the font color of the writing overlayed.

So let me explain this.
I have a <div> in my html that keeps loading random images as its background with each request.
And I have some description embeded inside this <div>.

There are two ways to tackle this scenario

  1. Write javascript to check the background shades and accordingly contrast the font color.
  2. Write a css that does the same.


As everyone, I was more interested in the CSS way of controlling styles.

It is a good practice to keep the behavioral aspects put into javascript / jquery / angular and so on, while the styling aspects to be controlled purely by css or frameworks of the likes.

In CSS, I  found two ways.

1. Use the CSS property: mix-blend-mode

  • This property blends a given element with its backdrop
  • This means, I could have a <span> with some description inside a <div> with a background image, and this property will automatically manage the font color of the <span> according to its background.
  • If the background changes dynamically, this property will dynamically assign font-color to the <span> such that it blends with its background.
  • It can take several values, all of which are available at this link
  • But this property has a drawback with respect to browser compatibility. If you are targetting more than one browsers and IE is one of them, then this property will not show the desired effect.
2. Use the CSS property: filter

  • This property also helps in blending the font with its backdrop. Basically it provides access to effects like blur / sepia / invert colors or anything related to shifting of colors before rendering them to the browser.
  • This property works well with webkits and is also supported by all browsers including IE. The latest version of IE is recommended.
  • Please refer to the details of filter property at this link
So this is what is done

1. In the Html file, we have the following markup

 <!DOCTYPE html>  
 <html>  
  <head>  
   <link rel="stylesheet" href="style.css">    
  </head>  
  <body>  
   <div class='bg'>  
    <span class='bg-contrast-font'>Beautiful Scenary</span>  
   </div>  
  </body>  
 </html>  

2. In style.css, the following css classes are added


 .bg{  
   background: url('https://unsplash.it/350/300/?random') no-repeat;  
   box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19);  
   height: 400px;  
   opacity:0.6;  
   color: white;  
   padding: 10px;  
   font-size: 40px;  
 }  
 .bg-contrast-font{  
  position: relative;  
   background-image: inherit;  
   -webkit-background-clip: text;  
   color: white;  
   -webkit-filter: invert(100%) sepia(100%);  
   filter: invert(100%) sepia(100%);  
   text-align: left;  
 }  

Explanation of the css

  1. The css class .bg is used to 
    • randomly load backgrounds using the background property
    • The div forces the font color to be white (color:white). This is not required. Just shown for demonstration
    • A base height and padding is given so as to view the background image
  2. The css class .bg-contrast-font is used
    • Provide a contrasting font color to the <span> inside the <div>
    • Note, that this has a background-image:inherit, which means we are inheriting the <div> background for the <span> also
    • There are two properties contributing to this.
      • background-clip: In the above sample, the webkit is applied to have browser compatibility. This property does something similar to "crop"  effect in photoshop. It clips a part of the element as specified. It can have the following values
        • background-clip: border-box;
        • background-clip: padding-box;
        • background-clip: content-box;
        • background-clip: text;
      • We are using "text" option to clip the text part of the span element.
      • Try removing background-clip in the plunk and running it in the browser. You will be able to spot the difference.
      • filter: The filter property as specified above, helps us work with color corrections. In this case, the color correction used are
        • invert(): Defines the proportion of inversion of colors. invert(100%) completely invert the colors with respect to its background.
        • sepia(): Converts a given input image to sepia form.
  3.  The output
             

An example of the usage of filter property is given in the following plunk.
https://embed.plnkr.co/hnNhYiOrvoCaov5BYMHs/

Try the following also

  1. Give the color: transparent  in the css class bg-contrast-font
  2. Try removing background-clip in the plunk and running it in the browser. You will be able to find the reason it is used.
Just hope this helps you.



No comments:

Post a Comment