Using Weather Data to Change Your Website’s Appearance through PHP and CSS
This article is co-authored by David Walsh
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.




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; ?>">
</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.










1
Wow, thanks for this! I tried doing this last two months but got pretty lazy somehow…
Just visited your site and subscribed.
Comment by Lim Chee Aun — February 16, 2008 @ 8:30 pm
2
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.)
Comment by chipgrafx — February 16, 2008 @ 10:30 pm
3
very very funny, ha
Comment by awflasher — February 16, 2008 @ 11:41 pm
4
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.
Comment by Oli — February 17, 2008 @ 2:29 am
5
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).
Comment by Philippe — February 17, 2008 @ 4:44 am
6
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?
Comment by Alex — February 18, 2008 @ 1:27 am
7
great post. i liked it… Like the Paranaque Scandal…
Comment by Paranaque Scandal — February 18, 2008 @ 2:20 am
8
Cool… but what about the rest of the world? Do you have a script or location that everyone else can use?
Comment by Kim — February 18, 2008 @ 3:16 am
9
Cool tutorial, I think i’ll try this out on my wordpress blog.
Thanx a lot !
Comment by Tjeerdoo — February 18, 2008 @ 3:48 am
10
Also very cool are those gravatars used in the comments, also a nice feature i’ll be looking into
Comment by Tjeerdoo — February 18, 2008 @ 5:48 am
11
what a great idea! thanks
Comment by Dito — February 18, 2008 @ 8:16 am
12
I saw almost this exact same thing on IBM’s site months ago - nice grab!
Comment by BillyG — February 18, 2008 @ 8:55 am
13
Check out this site: http://www.sky-catcher.nl
Over two hundres thousand images of the sky, available under a creative commons license.
Comment by Joe — February 18, 2008 @ 9:25 am
14
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..
Comment by Andreas — February 18, 2008 @ 9:53 am
15
wow, what an idea! this could be linked to the ip address.
cheers,
praveen.
Comment by OracleTube.com — February 18, 2008 @ 10:03 am
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.
Comment by Jonathan Snook — February 18, 2008 @ 11:02 am
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.
Comment by David Walsh — February 18, 2008 @ 11:56 am
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!
Comment by Eric Wendelin — February 18, 2008 @ 12:20 pm
19
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.
Comment by panther — February 18, 2008 @ 12:45 pm
20
That’s exactly what I went through Walsh when I saw that IBM article months ago.
Comment by BillyG — February 18, 2008 @ 3:23 pm
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.
Comment by Paolo Gabrielli — February 18, 2008 @ 5:01 pm
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.
Comment by David Walsh — February 19, 2008 @ 7:44 am
23
This is freaking sweet, thanks for the post! I will need to give this a try one of these days!
Comment by JONxBLAZE — February 19, 2008 @ 10:41 am
24
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
Comment by Léonie — February 20, 2008 @ 3:05 pm
25
I have tried it out on my site and it seems to be working fine. Again thanx for this post !
Comment by tjeerdoo — February 22, 2008 @ 8:21 am
26
amazing, ill post my url with this one soon!
Comment by jong — February 26, 2008 @ 7:34 pm
27
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…)
Comment by Graphixboy — March 6, 2008 @ 12:42 pm
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.
Comment by Whistler Weather and Snow Conditions — March 11, 2008 @ 12:10 pm
29
Really neat, once I switched to a web hotel that allowed curl. thx a 1*10E6
Comment by PO — March 31, 2008 @ 1:28 am
30
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
Comment by mark — April 8, 2008 @ 1:30 pm
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
Comment by Chris Coyier — April 8, 2008 @ 6:18 pm
32
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?
Comment by Osmar — April 21, 2008 @ 4:59 pm
33
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
Comment by Franky — April 21, 2008 @ 6:23 pm
34
For anyone having trouble outside the U.S. - Make sure to read Jonathan Snook’s comment above.
Comment by Chris Coyier — April 22, 2008 @ 7:19 am
35
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.
Comment by kyuuki — April 25, 2008 @ 4:29 am
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.
Comment by Chris Coyier — April 30, 2008 @ 6:03 pm