Dynamic CSS – Creating Time Sensitive Sites

January 7, 2010
Written by

Create subtle CSS changes to your site based on time and date

Oasis Overland uses time sensitive stylesheets

In todays modern web design environment it takes more and more to attract visitors visually, and even more to make them keep coming back. Of course this mostly depends on content as there has to be a purpose to the visit, however small subtle details to the site can make any visitor become excited.

In this tutorial, you will create a site that changes it’s background based on the time a person visits the site, afterwards you should have the knowledge to adapt the script to be based on any other data you want to use.

All server-side examples in this tutorial will be based on PHP, so make sure you have a working test environment with PHP5 enabled. If you are using any other server-side scripting tool it is likely there will be a guide to accomplish a similar effect online; however reading through this guide you will likely recognise similar syntax and functions allowing you to convert it to the language you’re using.

Opening the Folders

Included in this download is a folder called dynamic_css which contains all of the base files needed to complete this project. Move the folder into your testing servers root directory. Open the folder in your preferred IDE and then view index.php in a browser. If you’ve got PHP enabled and everything was copied successfully then you should see a basic white page with a header, navigation on the left and lorem ipsum on the right; it’s now time to start the dynamic styles.

PHP Sunsets and Sunrises

Using PHP to retrieve and make decisions based on time has it’s advantages and disadvantages. The largest disadvantage is the fact that PHP can’t access the users computer time and can only get the time of the server, the advantage however is that PHP has a large set of functions that make dealing with time that little less painfull. If you open up index.php, before the start <html> tag type the following PHP. Afterwards I will explain the key parts of the script.

<?php
 $time = date('G');
 $sunrise = date_sunrise(time(), SUNFUNCS_RET_DOUBLE);
 $sunset = date_sunset(time(), SUNFUNCS_RET_DOUBLE) + 1;
 if($time >= $sunrise && $time < $sunrise + 2) $style = 'sunrise';
 elseif($time >= $sunrise + 2 && $time < $sunset) $style = 'day';
 elseif($time >= $sunset && $time < $sunset + 2) $style = 'sunset';
 else $style = 'night';
?>

Lines 2 – 4 set three variables; $time is set to the current hour, $sunrise is set to the sunrise time for today and $sunset is set to one hour later than the sunset time (from my experience, official sunset times start an hour or two before what most people would call sunset starts).

Lines 5 – 8 runs a set of standard if statement to determine which style to show; sunrise, day, sunset or night, this is then set to the variable $style. This can now be used whenever a reference to the time of day is needed, as you will be shown below.

Dynamic CSS Techniques; One, Two and Three

There are three main ways of achieving dynamic CSS – which one you use depends on several factors; the amount of styles that change per data, amount of style sheets that get loaded into the page and the amount of customisation you have on your server.

Setting a body id/class

The most popular method of using dynamic CSS is to set the body id or class of the page depending on the styles needed. The advantages of this is that no server changes need to be made, you can use the same id/class across style sheets with no extra code and it’s easy to quickly prototype and debug. The disadvantage of this is that you can only use pre-defined constants, because of this you can’t have random colour pallates using this method.

Including style sheets

The second most popular method is to include extra style sheets depending on which styles you need, this can be beneficial when a lot of styles change depending on what is needed; this stops the stylesheet having to include styles for all other posible states of the site together. The disadvantages is that you have to create a stylesheet per state, this can be a large hassle if you are going to have a lot of different styles, it also inherits the flaw of not being able to access the data in the style sheet.

PHP in the style sheet

This approach can be done in several ways, when used successfully and appropiately this can create the largest amount of freedom with data being able to be directly accessed in the style sheet meaning there is no limit to the amount of states possible. The disadvantages is that if you want your style sheets to still have the .css file extension you need to customise the server, this also means you lose the portability of the style sheet. The other option is to use .php as the CSS extension. Another disadvantage is that you are limited to having all the rules in one file without having to duplicate and re-process the PHP.

Setting a body ID

In our example there are only a few things changing per state and there are only 4 states, based on the advantages and disadvantages outlined above, setting a body id is probably the best way of achieving the effect.

Change the <body> tag to be the following:

<body id="<?=$style?>">

Then open base.css and add the following to the end of the file.

/********** TIME SENSITIVE CSS **********/
#sunset {
background: url('../images/sunset.jpg') repeat-x #BE7001;
}
#sunrise {
background: url('../images/sunrise.jpg') repeat-x #EFC501;
}
#day {
background: url('../images/day.jpg') repeat-x #0A6FBF;
}
#night {
background: url('../images/night.jpg') repeat-x #00123A;
}

Open your page in a browser now and admire the scenery depending on what time of day it is.

Including style sheets

Including style sheets is another simple yet effect method, the practice involves having a separate style sheet for each state. To adapt the current site to use this method create 4 style sheets called, sunset.css, sunrise.css, day.css and night.css. Place the appropriate code for each state in it’s file, then remove the id on the body tag and instead place the below code in the <head> tag.

<link rel="stylesheet" href="css/<?=$style?>.css" type="text/css" media="screen" charset="utf-8" />

PHP in the style sheet

Out of the three methods outlined this one is by far the most flexible and powerful however also requires the most work so if a stage doesn’t work for you go back and repeat again; if it still isn’t working as it should then a quick search online will normally end up in a solution to the same problem someone else had.

Setting .css to be run as php

This is a matter of personal opinion however, I feel that having a .css extension helps define what an external asset is doing; this stage isn’t required so if you don’t mind having css with the .php ending or your server doesn’t allow you to make the following changes then skip this step.

Create a .htaccess file in the root of your site, place the following line in it:

AddHandler application/x-httpd-php .css

This sets PHP to handle all files with a .css extension, allowing you to place php in a .css file as if it were exactly the same as a .php file. If it fails to do anything at first, restart apache and see if that solves the problem.

Setting the Content-Type and Using the PHP

The most important thing to do when using dynamic CSS is to stop PHP setting the content-type header as text/html, you need your css files to be sent to the browser with the content-type text/css. To do this place the following line at the top of base.css (or base.php if you didn’t complete the previous step).

<?php header('Content-Type: text/css'); ?>

To get the background to change now place this just below the line you just wrote at the top (you can remove all the PHP from the index.php):

<?php
 $time = date('G');
 $sunrise = date_sunrise(time(), SUNFUNCS_RET_DOUBLE);
 $sunset = date_sunset(time(), SUNFUNCS_RET_DOUBLE) + 1;
 if($time >= $sunrise && $time < $sunrise + 2) $style = 'url(../images/sunrise_bg.jpeg) repeat-x orange';
 elseif($time >= $sunrise + 2 && $time < $sunset) $style = 'url(../images/day_bg.jpeg) repeat-x blue';
 elseif($time >= $sunset && $time < $sunset + 2) $style = 'url(../images/sunset_bg.jpeg) repeat-x black';
 else $style = 'url(../images/night_bg.jpeg) repeat-x black';
?>
body {
 background: <?=$style?>;
}

Opening the page in a browser should now show you a background simulating the great outdoors.

The equivalent in javascript

PHP isn’t the only way to add dynamic elements in your sites, javascript has been the raw base to site dynamics for years. Of the three methods above the first two will work fine in javascript with adaptations. Javascript has a few disadvantages; there’s a delay between page load and the new styles, javascript is also notorious for browser differences and it of course requires javascript

Javascript doesn’t have the same resources as PHP and so can’t provide sunrise and sunset times so in the examples below the state will be statically set to ‘day’.

Setting a body id

var state = 'day';
document.getElementsByTagName('body')[0].id = state;

A general breakdown of the code above is that it assigns the variable state a value of ‘day’, the second line then starts by selecting the document, finds all the elements with the tag name body (should always be just one) and then gives the first ( 0 nth element) the id of state.

Including extra style sheets

var state = 'day';
var cssFile = 'css/' + state + '.css';
var link = document.createElement('link');
link.setAttribute('href', cssFile);
document.getElementsByTagName('head')[0].appendChild(link);

Enjoy and Explore

Based on the three PHP methods demoed here there are a llimitless amount of different ways you can make your CSS dynamic, if you need some ideas though just see the taking it further boxout for more info.

Taking it Further

Dynamic CSS isn’t restricted to simple time and date manipulations. Any data that your server or the clients browser can access can be used. Whether it’s pre-determined states such as seasons or  based on data hosted elsewhere, a few extra ideas are below.

1) Location – Retrieving the visitors location is a tricky thing although there are several popular libraries and snippets readily available to make things easier. Mozilla is also pioneering the methods in which a server and site can detect a users location. Having the background change to compliment your location could be an easy way to make your site more localised.

2) Weather – Having your sites background change depending on the weather could add function as well as design to a site, visitors to a local harbour could quickly determine the current weather or water height before even getting to the page.
RSS Feeds – Easily accessible and retrievable RSS feeds now span the spectrum of content on the web, colour palettes, political data, surveys and pretty much anything you could want is probably already in RSS format.

3) Local site data - If your site has dynamic content why not compliment it with some dynamic styles. If you have a blog then you could have the background represent the category which was last blogged about.

You may also like to read:

Banner ads not to be ignored
SEO summary: Some of the biggest changes to come from Google in 2014
Game-changing smart tennis racket set to make an entrance at Wimbledon
LEGO comes to life with augmented reality

Comments

  1. John Parker says:

    A bit pedantic, but all date related PHP calls since version 5.1 will throw a E_NOTICE error if you don’t set the timezone via either a call to the date_default_timezone_set function or use of the date.timezone INI setting.

  2. Neil says:

    @john – good point and thanks for highlighting!

  3. [...] See the original post: Dynamic CSS – Creating Time Sensitive Sites | Strawberrysoup Blog … [...]

  4. Tommy says:

    Tried to download your example file but the link is broken. I did see a script at php.net with which you can get the users time zone, function.date-default-timezone-set. It works well in the body on my test page but I could not get it to run properly with your code above. Would be a great idea if it is possible to do.

  5. This is an innovative idea. But probably we need to use CSS gradients rather than img gradients. Else, we’ll just end by increasing our HTTP Requests.