Search code examples
cssimagewebp

CSS - Display Alternative Image When Original Not Supported


I'm building a website and I want to use the WebP format for my images. I know than not all browsers support it, so I want to display an alternative JPG image if WebP is not supported. I have a div with this class applied to it:

.my-class{
    background: linear-gradient(to right bottom, rgba(89, 167, 255, 0.5), rgba(0, 31, 62, 0.7)), url('../assets/images/image.webp');
}

I want to add something to this class that displays an alternative image.jpg if the website is used on a browser that doesn't support WebP. How can I achieve this (With pure CSS)?


Solution

  • There is a good guide for what you want to obtain on CSS Tricks:

    https://css-tricks.com/using-webp-images/

    Pure css isn´t the best way to solve this, you´ve to detect if the client supports webp and css won´t do this.

    So you need as example Modenizr to detect if the client supports webp or not.

    https://modernizr.com/download?setclasses

    After you´ve choosen what you need (webp) you will get a small js file. Add it to your page like:

    <!DOCTYPE HTML>
     <html>
     <head>
     <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1" />
      <script src="js/modernizr-custom.js"></script>
      </head>
    

    Now basicly you´ll create your class like this:

     .no-webp .elementWithBackgroundImage {
      background-image: url("image.jpg");
      }
    
     .webp .elementWithBackgroundImage{
      background-image: url("image.webp");
      }
    

    There is even a solution for clients that have deactivated js but this needs a little inline script which can be found in the CSS Tricks article as well.

    Your class would look like this:

    .no-webp-my-class .elementWithBackgroundImage{
    background: linear-gradient(to right bottom, rgba(89, 167, 255, 0.5), rgba(0, 31, 62, 0.7)), url('../assets/images/image.jpg');
     }
    .my-class .elementWithBackgroundImage{
    background: linear-gradient(to right bottom, rgba(89, 167, 255, 0.5), rgba(0, 31, 62, 0.7)), url('../assets/images/image.webp');
     }
    

    Edit

    There is another way but it needs some work and php. Basicly it´s nothing more than a browser switch and you have to spilt up your stylesheet.

    To make things easier create a file named stylesheet.php or whatever and declare the header:

    <?php 
      header("Content-type: text/css;charset=UTF-8"); 
    

    to save some work this soulution will read the existing .css file and give it out as an echo:

    <?php 
      header("Content-type: text/css;charset=UTF-8"); 
      $file_read = fopen("stylesheet.css","r+");
        while(! feof($file_read))  {
        $css= fgets($file_read);
        echo "$css";
        }
    

    Now all classes which use a webp image can be switched by checking if the browser exepts webp.

    if( strpos( $_SERVER['HTTP_ACCEPT'], 'image/webp' ) !== false ) {
    // webp is supported!
     }
     else {
     // webp is not supported!
    }
    

    Which would lead to this:

    <?php 
      header("Content-type: text/css;charset=UTF-8"); 
      $file_read = fopen("stylesheet.css","r+");
        while(! feof($file_read))  {
        $css= fgets($file_read);
        echo "$css";
        }
    if( strpos( $_SERVER['HTTP_ACCEPT'], 'image/webp' ) !== false ) {
     echo "
     .my-class .elementWithBackgroundImage{
      background: linear-gradient(to right bottom, rgba(89, 167, 255, 0.5), rgba(0, 31, 62, 0.7)), url('../assets/images/image.webp');
      }";
    
     }
     else {
     echo "
     .my-class {
      background: linear-gradient(to right bottom, rgba(89, 167, 255, 0.5), rgba(0, 31, 62, 0.7)), url('../assets/images/image.jpg');
      }";
     }
     ?>
    

    Edit

    I´ve forgotten something: You can add the .php file like a normale .css file to your html:

    <link rel="stylesheet" type="text/css" href="stylesheet.php" media="screen"/>