Grow your CSS skills. Land your dream job.

Using Weather Data to Change Your Website’s Appearance through PHP and CSS

Published by Guest Author

This article is co-authored by David Walsh of
The David Walsh Blog :: PHP, CSS, MooTools, and Everything Else

UPDATE: This post was updated on April 30th, 2008 to account for a minor change in how Yahoo! was serving up data UPDATED DOWNLOAD

Inspiration for this idea came from a comment by Andreas.

Using a little magic and trickery (read: PHP and CSS), we can change the appearance of a website automatically based on the weather outside, in real time! In the example site we have created, the header graphic will change to one of four different styles based on Sunny, Rain, Snow, and Cloudy.

Step 1: Designing your weather graphics

Our example site changes header graphics as as well as an icon in the sidebar to describe the weather. For the sake of example, we only created four different weather scenarios, defaulting to sunny.

headerexample-partlycloudy.jpg

headerexample-rain.jpg

headerexample-snow.jpg

headerexample-sunny.jpg

Step 2: Retrieving the weather information

Yahoo! has an API for weather information. We can tap into this very easily using an URL formatted like so:

http://weather.yahooapis.com/forecastrss?p=97211&u=f

The 5-digit number is your Zip Code and the "f" stands for "Fahrenheit" (change to "c" for "Celsius"). The information comes in XML format and it's up to you how you want to parse the data. Since the only bit of information we care about is the "yweather:condition" element's "text" attribute, We're going to avoid creating an XML parsing object and use a short regular expression.

Once the regular expression returns the yweather element's text, we'll use str_replace() and strtolower to format the string into a representative CSS class.

Step 3: Turning the weather information into an CSS class

Here is the PHP code:

<?php
	
	/* get xml, find match */
	
	/* get the weather from Yahoo */
	$data = get_data("http://weather.yahooapis.com/forecastrss?p=97211&u=f");
	
	$weather_class = format_result(get_match('/<yweather:condition  text="(.*)"/isU',$data));
	
	/* debug to see what we got back */
	//echo '<pre style="background:#fff;font-size:12px;">['; print_r($weather); echo ']</pre>';
	
	/* format the result */
	function format_result($input)
	{
		return strtolower(str_replace(array(' ', '(', ')'), array('-', '-', ''), $input));
	}
	
	/* helper:  does regex */  
	function get_match($regex,$content)  
	{  
		preg_match($regex,$content,$matches);  
		return $matches[1];  
	}
	
	/* gets the xml data from Alexa */
	function get_data($url)
	{
		$ch = curl_init();
		$timeout = 5;
		curl_setopt($ch,CURLOPT_URL,$url);
		curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);
		curl_setopt($ch,CURLOPT_CONNECTTIMEOUT,$timeout);
		$xml = curl_exec($ch);
		curl_close($ch);
		return $xml;
	}
	
?>

Now we have a variable we can echo out that is representative of the current weather at the zip code we provided:

<div class="header header-<?php echo $weather_class; ?>">
	<!-- Change the class above to change the header graphic -->
</div>

Step 4: Code your CSS for each of the classes

.header {
	width: 782px; height: 150px;
	/* DEFAULTS TO SUNNY */
	background: url(images/header-sunny.png) no-repeat center center black;
	}
	.header-rain {
		background: url(images/header-rain.png) no-repeat center center black;
	}
	header-snow {
		background: url(images/header-snow.png) no-repeat center center black;
	}
	.header-sunny, .header-fair {
		background: url(images/header-sunny.png) no-repeat center center black;
	}
	.header-partly-cloudy, .header-cloudy, .header-mostly-cloudy {
		background: url(images/header-partlycloudy.png) no-repeat center center black;
}

Step 5: Extending the idea

Notice that we use the "partlycloudy" graphic for the weather conditions of "partly-cloudy", "cloudy", and "mostly-cloudy". It's up to you how specific you want to get. Here is a full list of the possible weather conditions from Yahoo!:

0  	tornado
1 	tropical storm
2 	hurricane
3 	severe thunderstorms
4 	thunderstorms
5 	mixed rain and snow
6 	mixed rain and sleet
7 	mixed snow and sleet
8 	freezing drizzle
9 	drizzle
10 	freezing rain
11 	showers
12 	showers
13 	snow flurries
14 	light snow showers
15 	blowing snow
16 	snow
17 	hail
18 	sleet
19 	dust
20 	foggy
21 	haze
22 	smoky
23 	blustery
24 	windy
25 	cold
26 	cloudy
27 	mostly cloudy (night)
28 	mostly cloudy (day)
29 	partly cloudy (night)
30 	partly cloudy (day)
31 	clear (night)
32 	sunny
33 	fair (night)
34 	fair (day)
35 	mixed rain and hail
36 	hot
37 	isolated thunderstorms
38 	scattered thunderstorms
39 	scattered thunderstorms
40 	scattered showers
41 	heavy snow
42 	scattered snow showers
43 	heavy snow
44 	partly cloudy
45 	thundershowers
46 	snow showers
47 	isolated thundershowers

For this example, you'll notice we also used a hard-coded zip code that must be changed in the PHP in order to change where the website will be basing it's weather appearance on. But wouldn't it be cool if the website knew the zip code of your visitors and would change the appearance of the site based on their weather instead of your weather? That kind of coding requires services and expertise beyond the scope of this tutorial, but a quick Google search brings up some services that could probably make this happen like IP2Location.

Have fun! - and let me know if anyone actually uses this, I'd love to see what you did with it.

weather-switcher.jpg

Comments

  1. Wow, thanks for this! I tried doing this last two months but got pretty lazy somehow…
    Just visited your site and subscribed. :D

  2. Permalink to comment#

    Nice little tutorial.

    I’ve fancied the header/weather images Dunstan Orchard had on his blog for a long time but outside of sharing the graphics he never gave any sort tutorial on it. I don’t blame him though, I’m sure he put a great bit of work into it. (Click the tab that says “Panorama information” on the right side under the header to lean a little more.)

  3. Permalink to comment#

    very very funny, ha :)

  4. Permalink to comment#

    This is pretty cool!
    Donno where, but I sure wanna use it!

    Oli

    P.S.: You can easily fetch (e.g.) german feeds by checking out weather.yahoo.com. Just fetch your weather and use firefox’s built in rss feature to capture the rss-url.

  5. Permalink to comment#

    Cool trick thanks.

    You have a small mistake in your debug line in the php code, you need to say print_r($weather_class) instead of print_r($weather).

  6. Permalink to comment#

    Wow! I wonder if I have the patience to create a graphic for every state… Though to be honest if we start getting tropical storms in the UK, the asthetics of my website will be the last thing on my mind!!! Hmmm… That’s a point will this work in the UK?

  7. great post. i liked it… Like the Paranaque Scandal…

  8. Kim
    Permalink to comment#

    Cool… but what about the rest of the world? Do you have a script or location that everyone else can use?

  9. Permalink to comment#

    Cool tutorial, I think i’ll try this out on my wordpress blog.

    Thanx a lot !

  10. Permalink to comment#

    Also very cool are those gravatars used in the comments, also a nice feature i’ll be looking into :)

  11. Permalink to comment#

    what a great idea! thanks

  12. Permalink to comment#

    I saw almost this exact same thing on IBM’s site months ago – nice grab!

  13. Joe
    Permalink to comment#

    Check out this site: http://www.sky-catcher.nl
    Over two hundres thousand images of the sky, available under a creative commons license.

  14. Permalink to comment#

    Rather than applying the class to the element that is going to receive the styling I would suggest (and did) adding the class to the body-element instead.

    That way you have control over the entire site, not just one particular element (and it’s children):

    <body class=’rainy’>

    body.rainy #header {rainy-bg.gif} body.sunny #header {sunny-bg.gif} etc..

  15. wow, what an idea! this could be linked to the ip address.

    cheers,
    praveen.

  16. If you’re looking for weather for a place outside of the States, do a search at http://weather.yahoo.com/. The result URL will be something like http://weather.yahoo.com/forecast/KSXX0037.html. Just take that part after forecast/ and before .html and use that for the location:

    http://weather.yahooapis.com/forecastrss?p=CAXX0212&u=c would get me the weather for my location.

  17. You beat me to it Snook — thank you for pointing that out.

    Initially, I was going to take this to the next level where I’d grab the user’s IP, find their location, and cater the weather to them. The problem was that I didn’t want to endorse any service, especially a pay service, to turn the IP into a Zip.

    Hopefully what I’ve provided is a great starting point for everyone.

  18. I might have to use this one on my blog as well. This is a very cool trick and I bet this will become more popular than you might think. Well done, David and Chris!

  19. Permalink to comment#

    Thanks a ton! I’ve been wondering how to sync with the weather for over a year now. Figured out how to change the CSS based on the time of day using JavaScript, but this is a heck of alot bolder. Thanks again, hopefully you see some great examples come out of this.

  20. Permalink to comment#

    That’s exactly what I went through Walsh when I saw that IBM article months ago.

  21. Very, very nice. I always looked to do something like that, maybe also using the time of day (and the sunrise/sunset times) to push some sunrise/sunset or some night shots.
    Thank you.

    P.S.: Yahoo has big servers, but a little local file cache to save results for a couple of minutes or more would help a lot.

  22. Caching the result on the hour would be a great idea. I tried to keep the script basic but that would be a nice and easy addition.

  23. Permalink to comment#

    This is freaking sweet, thanks for the post! I will need to give this a try one of these days!

  24. Permalink to comment#

    I used to have a weather forecast on my page too – well a few years ago though…
    I had a pulldown to choose from some capitals in europe. I don’t know if anybody ever checked the weather, but I thought it was a nice feature and when I was on my website I always knew that the actual weather in Paris is really as described on my site;-)

    Nowadays you could of course combine the feature with the IP2location service…

    Léonie.
    paranoiaparadise

  25. Permalink to comment#

    I have tried it out on my site and it seems to be working fine. Again thanx for this post !

  26. Permalink to comment#

    amazing, ill post my url with this one soon!

  27. Graphixboy
    Permalink to comment#

    Somewhat similar idea was done a while ago with a music video set to display different imagery based on the local viewers weather. This one’s flash based, but it provides some food for thought on whats possible. theunseenvideo.com

    I should also point out that the above tutorial could easily be changed to swap the entire css file based on the weather making for a very dynamic user experience. (I’m having visions of all my site’s content piled at the bottom of the screen when its snowing…)

  28. This looks awesome. I have a blog site, that deals with the weather and snow conditions for Whistler, Canada. I am not very good at coding and stuff, but am going to have to study this a lot more and see if I can incorporate it into my blog somehow. It would be awesome if I can set up a header that uses real pictures of the mountains while changing depending on the weather.
    Thanks for the info here, hope I can work out a good way of using it.

  29. Permalink to comment#

    Really neat, once I switched to a web hotel that allowed curl. thx a 1*10E6

  30. mark
    Permalink to comment#

    Nice tute. shame I cannot get it to work. Using the exact code you give it simply will not return the weather at all.

    do you have a zip of your example that I can work with at all.

    apart from this, it is a damn fine idea and could come in extremely handy

    thank you

  31. Hey Mark, I think I intended all along to make this a downloadable example, but I forgot to put a link in there! Here it is:

    DOWNLOAD WEATHER SWITCHER

  32. Osmar
    Permalink to comment#

    Hello!, thank you for this tutorial…
    I am searching for a tutorial that parse the Yahoo Weather RSS in php, and this tutorial help me…
    I want to show in my page, the full weather info, any ideas to do this?
    I have implemented this in the php code, and it works fine, but suddenly a week ago, it stops workin, and i dont know why…

    Can you help me?

    • Tommaso
      Permalink to comment#

      I’m looking for the same thing… have you found anything yet?

  33. Permalink to comment#

    Hi there,

    great tutorial. Thanks for that :). I´ve modified your idea a bit, so on my Website not change the header, but it changes my little Southpark avatar with different cloth expect the weather.

    My problem is, that the option “sunny, rain, wind, cloudy” isnt inserted in the tag on my page. Are there any restrictions to change the chmod on the file or folder to include the xml file?

    What i´ve done is, that i create a file called weather.php, created different avatars als png file, call the variable in my theme on the location i want it and insert the css code in my stylesheet.

    Kind regards
    Frank

    Sorry for my bad english

  34. For anyone having trouble outside the U.S. – Make sure to read Jonathan Snook’s comment above.

  35. kyuuki
    Permalink to comment#

    I have been trying and trying but cant seem to get this working on safari.

    Does anyone have any ideas? I think the problem lies somewhere in the default header.

  36. Anyone that has been having problems with this… Please note that Yahoo changed something and we had to updated a line in the PHP to make it work again.

    $weather_class = format_result(get_match(‘/

    Make sure to change this in your own files to make it work again! Article, example, and download are updated.

  37. Is it possible to change the png according to a specific parameter like the wind?

    And if yes how?

  38. Thank you for the article David. I used it to implement a background-image rotation according to the temperature on my location.

  39. Thanks for the article and coding examples.

    I’m currently trying to figure out a way to achieve the 7-day forecast in the same fashion. This is beginning to be a pain. hehe

    R.

  40. Eray Alakese
    Permalink to comment#

    Hello, thanks for the article. But i have a problem. I am from Istanbul, Turkey. Istanbul's general zip code is 34000 and my neighbourhood's zip code is 34330. But this zip codes is invalid in Yahoo Weather API.

    When I tried to reach weather data ,
    (http://weather.yahooapis.com/forecastrss?p=34000&u=c and

    http://weather.yahooapis.com/forecastrss?p=34330&u=c)

    i have hot this error:
    Sorry, your location ‘34000’ was not found. Please try again.
    Sorry, your location ‘34330’ was not found. Please try again.

    Can you help me?

  41. @Eray Alakese- See Snook’s comment above (#16) about finding the appropriate “zip” to use for international locations.

    Chris- Great tut and I might be putting it into action in my next redesign.

    Thanks!
    -Rob

  42. Eray Alakese
    Permalink to comment#

    Thank you very much Rob :)

  43. Permalink to comment#

    @David Walsh Try this site, they let you download the database that they use, which means you could use it locally. http://software77.net/cgi-bin/ip-country/geo-ip.pl

  44. Eray Alakese
    Permalink to comment#

    PS: There is a RSS button in top right :)

  45. Permalink to comment#

    Hi there,

    Just wanted to let you know that reading your article inspired me to use the yahoo weather feed on my site.

    My site has the option for users to choose their city (UK only at the mo) and displays the weather in the form of the page background.

    I also added a little php to detect the users current time and alter the site accordingly. Admitadly this is only based on the users computer time. In the future i will have it relating to the users ip or the location they choose.

    So thanks!

    If you want to check it out you can see it at http://www.jealousdesigns.co.uk.
    (Use FireFox for the full site…..IE doesn’t like big drop downs so have to scale it down….)

    Cheers.

    Andy

  46. Permalink to comment#

    Thank you very much Rob :)

    My pleasure Eray.

    As I mentioned previously, and although a pain, I had to go another route, and this Weather MOD is what I came up with.

    The zip code functionality is generally U.S. based, but if the weather conditions are not found, you can type in the city name, for example, if you type in Hyderabad, it will display a drop down combo box and display all instances of Hyderabad that exist, ala:

    Hyderabad, India

    Hyderabad, Pakistan

    and you can choose from there.

    A million ‘Thanks’ for the inspiration!!!

    Kind Regards,

    Rob.

  47. TechnoCat
    Permalink to comment#

    After reading this tutorial, I was inspired to make a small website that would show the current time and weather data.

    http://web.ics.purdue.edu/~dcfritz/files/Sandbox/TODAW/timeofdayandweather.html

    The sun and moon rotate around the center reflecting the time. The background also reflects the time with the brightness. Dark for night and bright blue for day. The moon shows the current lunar phase (full moon and such). And weather data is displayed in the center.

    When i aggregated my weather and lunar phase information, I did not use regular expressions like used in this tutorial. Instead i switched to converting the xml to a php array using built in php functions. Then i just echoed select php arrays to html elements so they could be passed to the javascript.
    I have all the source code posted if anyone wants a look-see.

  48. Thanks for that tutorial. It was very useful for me…

  49. Permalink to comment#

    Really thanks for this article .
    I think this is a good technique in SMO .
    This style can bring a lot of visitors .

  50. Permalink to comment#

    Can add more function for this script like hour time fuction.

    Thanks

  51. mezzarino
    Permalink to comment#

    Very nice, how would I go about coding this in .NET?

  52. Alysson
    Permalink to comment#

    Hi,
    i just loved this tutorial.
    i have one question! is it possible to display the temperature also?
    thanks.

This comment thread is closed. If you have important information to share, you can always contact me.

*May or may not contain any actual "CSS" or "Tricks".