You are looking at archived content. The hot new stuff is happening at Veerle's blog 3.0. You should check it out!

Mar 07

A CSS styled calendar

2005 at 12.54 am posted by Veerle Pieters

Many times I’ve been asked how I created my calendar, or asked me if they could use the code etc. That’s why I thought it might be interesting to write an article on how to create such calendar.

A CSS styled calendar

The table element
If you have already peeked at my code, you've seen that I've used the table element. Well, because I'm describing tabular data in the calendar, it is semantically correct to use the table element. The use of tables as 'a positioning grid ' just to make your site look great is wrong. But it's alright if we use them for the purpose they are designed for, namely to present tabular data. And by tabular data we mean things like calendars, spreadsheets, charts or schedules. Besides think about how things would look without the CSS if you would try to code it by trying to float and position all of the items, it would look chaotic and unordered. Actually, in a crazy fanatic mood I've tried it and believe me, you end up being frustrated because of all the hassle to make it work in all browsers. It is a pure waste of time and I've grown up since then ;-)

Molly Holzschlag wrote a nice enlightening article about 'The Meaning of Semantics'.

Styling the calendar
Everybody has their way of working but I always need to design my stuff in Photoshop. So After I decided on colors and looks I fire up CSSEdit and BBEdit to start coding. Only one gif image is needed to create a calendar like this, the rest is XHTML and CSS code.

#calendar {
 width: 141px;
 padding: 0;
 margin: 0;
 border-left: 1px solid #A2ADBC;
 font: normal 12px/20px "Trebuchet MS", Verdana, Arial, Helvetica, sans-serif;
 color: #616B76;
 text-align: center;
 background-color: #fff;

For the calendar table we use an id selector and give it its necessary properties and values to specify the width, padding... etc. You could also use the table tag element instead if you are sure that this is your only table in your page.

td {
 border-right: 1px solid #A2ADBC;
 border-bottom: 1px solid #A2ADBC;
 width: 20px;
 height: 20px;
 text-align: center;
 background: url(images/bg_calendar.gif) no-repeat right bottom;

We also define the look of the table cells by defining the td tag. As you can see I gave my table a left border and for the cells I defined right and bottom border. There are other ways I'm sure but this is how I did it.

td a:link, td a:visited {
 color: #608194;
 background: url(images/bg_calendar.gif) no-repeat;

td a:hover, td a:active {
 color: #6aa3ae;
 background: url(images/bg_calendar.gif) no-repeat right top;

the backgrounds of the calendarThe only image used contains the 3 different background images of the calendar using background positioning. I've only used classes to style the navigation to go to next and previous month, together with the current date.

Adding more accessible code
There are elements that can be used in a table to help those using a screen reader such as the summary attribute for example. More on this topic can be found in 'Bring on the tables' by Roger Johansson, your number one source on useful CSS info!

For my calendar I've added the abbr attribute to provide screen readers the necessary info on the day names on top 'S', 'M', 'T' etc. But I wonder, abbr is meant to give an abbreviation, and in my case it is the opposite around, so I'm wondering if this done correctly. If anybody knows what's exactly correct please let me know, thanks ;-)

UPDATE: About the last remark. I've changed the XHTML code of the calendar and used the caption attribute for the month and the navigation arrows. Then I've changed the days into headers using the th element and adding the scope attribute to achieve better accessibility. Thanks Michiel ;-)




permalink this comment Vincent Rozenberg Mon Mar 7, 2005 at 01.07 am

Thanks for this! This is certainly appreciated.



permalink this comment Simon Davies Mon Mar 7, 2005 at 02.36 am

Lovely stuff as always. Lets hope I have to create a calendar one day!



permalink this comment Michel Vuijlsteke Mon Mar 7, 2005 at 02.38 am

Nice. Another way of doing it is with spans (or whatever you want to display inline) you clear every Monday (or Sunday of course):

#cal span { width: 20px; float: left; border: 1px solid #A2ADBC; }
#cal span.firstday { clear: left; }

<div id=“cal”>
<span class=“firstday”> </span>
<span> </span><span>1</span>
<span class=“firstday”>6</span>
<span class=“firstday”>13</span>



permalink this comment Michel Vuijlsteke Mon Mar 7, 2005 at 03.00 am

[and to make things work in IE you need to add an explicit width to the containing <div>, something like

#cal { width: 160px; }




permalink this comment Maarten Mon Mar 7, 2005 at 04.21 am


Why would you use spans to create a calendar when it’s so obvious a calendar exists of tabular data?



permalink this comment Michel Vuijlsteke Mon Mar 7, 2005 at 05.03 am

I find them slightly easier to generate dynamically (just add one thing to the first day of the week, no need to bother opening and closing <tr>s). And it’s easy to make a kind of calendar I really like: one line per month, days of the week arranged under each other. Or two-week calendars.

And, erm, because you can? :)

On a slightly more pedantic note: is this type of calendar really tabular? Yes, they are often presented as tables, but my idea of tabular data is stuff that has columns and rows, like an event calendar: rows for the events, columns for date and event.

So I think there’s a semantic reason to it too. Give each weekday a separate class and you could allw the user to override what the first day of the week is, and stuff.

(not that they’d ever, I know :)



permalink this comment Michiel Mon Mar 7, 2005 at 06.34 am

Aren’t the days of the week the real table headers (with scope=“col” of course), and the name of the month the caption for the table?



permalink this comment Veerle Mon Mar 7, 2005 at 06.42 am

@Michel, I’ve once tried to do it with spans but always ended up with some kind of trouble to add the month and navigation buttons on top of it so it matches all perfectly.

The main reason why I use a table is that the calendar will be messed up otherwise as soon as you disable the CSS (like in a text only browser for instance). I think you have to take this in account too. So it’s a matter of choice I believe.



permalink this comment Michel Vuijlsteke Mon Mar 7, 2005 at 06.49 am

Yep, and it’s surprisingly cross-browser  too.



permalink this comment Veerle Mon Mar 7, 2005 at 06.56 am

@Michiel, Ok I get your point. I tried this out, but the thing which makes my calendar ‘nice’ (at least IMHO) is the month on top in the darker background with the navigation on the left and right etc. And now this is gone. Here is the result.



permalink this comment Michiel Mon Mar 7, 2005 at 07.05 am

Then style the caption element?



permalink this comment Veerle Mon Mar 7, 2005 at 07.08 am

Michiel, hmm… aha! :-) I might consider to change my code and choose your solution after all. I’ve managed (I think) to get it reasonably right. Look at the result now.



permalink this comment Michiel Mon Mar 7, 2005 at 07.14 am

Cool, being semantically correct was what it was all about anyway :)

With the scope=“col” a screenreader now knows in every cell which day is the header for that cell!



permalink this comment Thomas Mon Mar 7, 2005 at 07.20 am

I love this article.  First time to the site and must say it has a excellent layout and design.  keep up the excellent work.



permalink this comment Yasuhisa Mon Mar 7, 2005 at 11.09 am

Very Nice;-)

I would put abbr=“Sunday” etc..  in every th tag.
For screen readers, they could have hard time to
understand “S” or “T” represents which day of the



permalink this comment Dustin Diaz Mon Mar 7, 2005 at 11.26 am

I remember the first time I came to your site…I gave you crap about your calendar…
*tsk tsk*
Who am I kidding, you have a lovely little calendar. Perfectly semantic and well styled.
Good job. It’s what tables were meant for.



permalink this comment Veerle Mon Mar 7, 2005 at 11.36 am

@Yasuhisa, you are right, sorry, they were there in my initial code (like I mention in my article) but I forgot to put them back in after I changed the header code etc. (see the update remark), sorry for the confusion. Guess working and blogging the same time isn’t good for me :-S



permalink this comment Tom Mon Mar 7, 2005 at 04.54 pm

The display: block on the A tag is really important and could help you not spend 15 minutes trying to work out why your calendar doesn’t quite look right….



permalink this comment naomi Mon Mar 7, 2005 at 05.09 pm

How timely!  Thank you for this article.  I was just looking at your calendar code last week.  The reason was why your 1px grid table looks good on MAC IE and mine doesn’t.  Now I know the secret is to use borders only on right and bottom of the cells. 

However, I still have problems with MAC IE.  I have a table (yes, it contains tabular data) with a lot of empty data cells, and they look horrible.  I think that’s the reason why you put [nbsp] in your empty cells.  I know my problem will be solved by doing that, but I was wondering if there are any other way to solve this.  Anyone?  Please help.



permalink this comment Mike Purvis Mon Mar 7, 2005 at 06.24 pm

Hi, just thought I’d share the notion of doing a calendar with an ordered list of floating elements. I think it’s probably about on equal footing as a table in the semantics department, but there’s a definite cool factor about using a list that wraps all by itself:

That’s just a quick mockup—I have no need of a calendar on my blog at this time. But you’ve got to admit that it’s pretty spiffy.

(I clicked through to here from css-d)



permalink this comment Michiel Tue Mar 8, 2005 at 02.24 am

@Mike: without the stylesheet, how would you know on which day March 17th is for example? That’s the semantics in the table version!



permalink this comment Veerle Tue Mar 8, 2005 at 02.32 am

@Tom, what is wrong with it? I use the display block to swap the background when hovering a linked date. As far as I know it looks fine to me. Maybe explain a bit more what you mean here would be handy ;-)

@naomi, yes I.E. needs a non breaking space in the empty cells even if you have set a width and height the space is needed. I don’t know any other solution.

@Mike, thanks for sharing, it is cool, it shows how far you can go with CSS. But on the other hand I wonder if it is worth, mine is more graphical and will need even more testing etc. a bit crazy if you ask me (I’ve done it). Also, just disable your styles and everything ends up under each other in a long list, long scrolling etc. I think a table is in this case still a better accessible solution, it still looks like a calendar when you disable the stylesheet. It’s like Michiel says.



permalink this comment pjtr Tue Mar 8, 2005 at 02.35 am

CSS Beauty links to this tutorial, but their comment is just a bit off. ;-)

“Good article by Veerle. He shows us how he created his CSS Styled Calendar.”



permalink this comment Veerle Tue Mar 8, 2005 at 02.52 am

@pjtr, an honest mistake I’m already use to. It is a bit my own fault too since I don’t have an about page and my picture in the header obviously doesn’t help either ... I will have my about page in my new blog I’m sure ;-) Well, no wonder people say ‘Where are the women in css?’ :-))



permalink this comment Danny Tue Mar 8, 2005 at 04.52 am

Hi Veerle,

Very nice article. Guess we need to spread more pictures of you (or pink fluffy stuff ala angie) because your article is mentioned on CSS Beauty and you are referred to as “he”.




permalink this comment Yung Tue Mar 8, 2005 at 06.53 am

Hi Veerle,

Thank you so much for posting this tutorial.  I hope this isn’t asking too much but is there additional coding I have to put in place in order to have the calendar “work”.  For example, I was using javascripts before to gather the date from the user’s PC to display the current date.  How are you doing this with your calendar?  Any help on this would be greatly appreciated.  Thanks a bunch.




permalink this comment Mike Purvis Tue Mar 8, 2005 at 07.10 am

You’re right that it’s no good expanding as a thirty-item list, but if you wanted to implement something such as ‘roll over to see info in a remote div, then it downgrades much more gracefully than a table would. And you could give users rather interesting style-switcher options. (ie, radically different ‘views’ on the same information, rather than just changing the aesthetics of it)

I’ve changed my demo to reflect the rollover-content behaviour. (sorry IE users; no rollovers for you)

(ultimately, however, I concede that it’s not a terribly useful technique, not the least of which because it doesn’t display properly under IE5.)



permalink this comment Alex Giron Tue Mar 8, 2005 at 07.19 am

I said she! I swear! SHE!!!!!

ok ok, It slipped, sorry Veerle! The correction is made…. after I received quite a few emails… hehe.

Great article btw.



permalink this comment annia Tue Mar 8, 2005 at 07.22 am

very nice :) thanks for sharing



permalink this comment Tony Tue Mar 8, 2005 at 11.11 am

Nice tutorial. This is an excellent example of properly mixing CSS and tables.

As for reason *not* to use spans: turn off your style sheet (or simply view the site on a PDA or cell phone that doesn’t understand the style sheet) and see if it makes any sense. (The answer is no…) With a table, you can quickly and easily see a relationship between the days of the week and the numbers. You can tell that March 8 is a tuesday,  and that the 3rd Saturday of this month is the 19th. With spans (and no css), you get this:


Not very meaningful, eh?



permalink this comment Peter G. Tue Mar 8, 2005 at 03.02 pm

Thanks, Veerle. You saved me a ton of time and frustration. Now if I could just figure out how to tie my calendar in with an XML database system I’d be all set. One step at a time.



permalink this comment Nick Valvo Tue Mar 8, 2005 at 10.26 pm

I’m glad you use CSSEdit too. Best thing since CSS?



permalink this comment Eric Wed Mar 9, 2005 at 01.34 am

I’ve used a table to create a calendar for my classes (I teach middle school);

Not as stylish, but very functional.  I apply classes to td tags to gray out non-school days and emphasize important days.  The current day is highlighted through DOM scripting.  One drawback to adding borders through css instead of the border attribute is that the table is rather hard to read if stylesheets are disabled.



permalink this comment Nathan Logan Wed Mar 9, 2005 at 05.00 pm

Very cool, Veerle.

Thanks for the well-written tutorial and associated inspiration!




permalink this comment matisse Thu Mar 10, 2005 at 04.55 am

Nice job!
very inspiring…

one suggestion:
you should try using abbr elements instead of abbr attributes (a better browser support)
<th scope=“col”><abbr title=“Thursday”>T</abbr></th>

i guess this schould make the html code a little bit more semantic

p.s. IE abbr fix



permalink this comment Ali ix Thu Mar 10, 2005 at 01.53 pm

why you dont have any Permalin for posts !?
or i cant see them ?! :?:



permalink this comment Veerle Fri Mar 11, 2005 at 06.36 am

@Ali ix: yes I know but that’s a feature for the next version of blog. So a little bit more patience, it’s coming in a few months if all goes to plan ;-)



permalink this comment Yung Fri Mar 11, 2005 at 09.37 am

Hello everyone,

Does anyone have tips on how to add code to the calendar so that it highlights the current date and also can go back and forward in months?  Any help for a newB would be soooooo appreciated. : ).




permalink this comment Iolaire McFadden Fri Mar 11, 2005 at 10.18 am

Yung, are you looking for something like this?



permalink this comment Ali ix Fri Mar 11, 2005 at 12.15 pm

@ Veerle: as i see u are using pmachin as your blog system and i think it has some built in functions for Permalinks ..isn’t it ?!



permalink this comment Veerle Fri Mar 11, 2005 at 12.30 pm

@Ali ix, as I already said, no it hasn’t. Expression Engine has it but pMachine not I’m afraid. You have to use the URL of this article/comment page.



permalink this comment Marco Sun Mar 13, 2005 at 03.43 am

At first I also always set two td borders to get a ‘grid’ effect but I recently found that you can have the same effect with the border-spacing CSS style. I did that here for example:

I didn’t use a background image on my cells but if I did the effect would be quite similar without having to go and use partial borders. :)



permalink this comment Egor Kloos Mon Mar 14, 2005 at 11.21 am

I’ve done the calendar with CSS only and that seems to work. I did need to do some CSS trickery to get it all pixel perfect. However, normally I’d concider doing a calendar in Table’s first rather than CSS.

ps. I needed to hack pMachine to do this. Transfering it to Expression Engine was pretty easy.



permalink this comment Stef Nighthawk Tue Mar 22, 2005 at 02.18 pm

I have to agree with Veerle that a calendar is best used as tabular data.  When no style is applied the calendar should still be readable.

I am currently trying to work out a calendar that could be made to look like some of the previous posters wanted.  Single line calendars, week column instead of row, ...

The first things I’ve already noticed is that IE won’t let me change anything beyond width and height.  The other thing that I have to add is a <thead> and a <tbody> element to do more complex styling.

I’ll post a link as soon as I’ve finished an example of what I’m trying to say.



permalink this comment Hunox Tue Mar 22, 2005 at 10.09 pm

Looks awesome! I like the little hover red corners. Very neat touch.



permalink this comment Vincent Grouls Mon Mar 28, 2005 at 05.36 am

You can actually use the ‘border-collapse: collapse’ property and then you can simply use full borders for all elements

Great calendar and write-up Veerle. Thanks to Michiel for the some extra semantics lessons—I needed those :D



permalink this comment Matt Wed Apr 6, 2005 at 12.51 pm

“For my calendar I’ve added the abbr attribute to provide screen readers the necessary info on the day names on top ‘S’, ‘M’, ‘T’ etc. But I wonder, abbr is meant to give an abbreviation, and in my case it is the opposite around, so I’m wondering if this done correctly. If anybody knows what’s exactly correct please let me know, thanks ;-)”

You could also use the title attribute of the th tag to add the days like so:

<th title=“Monday”>M</th>
<th title=“Tuesday”>T</th>

A small tooltip will pop up with the value of the title attribute when a user mouses over it. I don’t recall if screen readers see the title attribute, but I know that Mozilla, Firefox, and IE/Windows all do.



permalink this comment Luke Barrow Mon Apr 18, 2005 at 11.21 am


  Thanks for your excellent article. I hope to use your calendar on a website I am doing for my church. Is that alright? If you would rather I not, please email me and I will take it down immediately. Thank you!

The addy is:



permalink this comment Veerle Mon Apr 18, 2005 at 11.43 am

Hi Luke, you have it nicely adjusted to your site’s look, I have no problem with that. Thanks for sharing and for asking, that’s much appreciated :-)



permalink this comment Adam V. Tue Apr 19, 2005 at 12.04 pm

Thank you for presenting this code!



permalink this comment ReneeZara Thu May 5, 2005 at 07.29 am

Hi :) I was wondering if you can help me out with my calendar. I’d like to have the little arrows on both sides of the month - example <<April>>, so that when I click on the arrows the calendar changes and the archive page opens. Would the code be any different if I just wanted the calendar to change without opening the archive page? I’m just trying to understand all this tag business - I’m relatively new to blogging. I use Movable Type, if that makes a difference. I appreciate your help :)



permalink this comment Suchetha Fri May 20, 2005 at 04.36 am

“For my calendar I’ve added the abbr attribute to provide screen readers the necessary info on the day names on top ‘S’, ‘M’, ‘T’ etc. But I wonder, abbr is meant to give an abbreviation, and in my case it is the opposite around, so I’m wondering if this done correctly. If anybody knows what’s exactly correct please let me know, thanks ;-)”

actually the correct tag in this case would be <acronym title=“Monday”>M</acronym> since, strictly speaking, M is an acronym for Monday

but good work




permalink this comment Veerle Tue May 31, 2005 at 04.45 am

@Suchetha,  thanks for the useful information :-) I’ll keep it in mind.



permalink this comment Mr. Sophistication Wed Jun 8, 2005 at 04.35 am

Anyone know how to connect this thing to a database system?



permalink this comment Cody Thu Jun 16, 2005 at 11.20 am

I have a blog over at, and am dieing to know how ot get a calenedar like this for my blog.

I’m not educated in coding of any kind, and woiuld hope I could get someone to help me get an archive calendar for my blog.



permalink this comment oneoo Fri Jul 1, 2005 at 09.24 pm

not use table :)



permalink this comment quentin Mon Jul 4, 2005 at 12.40 pm

Could a calendar like this be populated by a database (such as results for flights available through a search engine?)



permalink this comment sssim Sat Sep 10, 2005 at 03.16 am

Sorry I am so noob but I am learning about css and stuff like this but I did not understand what code I have to use to display my calendar please someone gudies me what I have to do exactly . I am integrating this calendar into a blog like this one.

BTW Thx and great calendar



permalink this comment Johan Fri Oct 21, 2005 at 05.05 am

Sssim did you download the images?

Good article. I am currently building a “week selector calendar” if anyone wants it though I don’t seem to able to add the styles very well in order to get my mouse over working.



permalink this comment lefeno Wed Oct 26, 2005 at 10.01 pm

It’s very good! thanks.



permalink this comment Gil Sun Mar 12, 2006 at 09.04 am

Veerle, I’m sure you have posted this somewhere but I can’t find it. I love you calendar and I would love to use it. I’ll post coments about where to find the origional in my code it its OK with you. I understand the CSS but when I look at the calendar itself the table is built and all the code is gone. Can you let me know how you are dynamically building the code for the table? Thanks so very much in advance.



permalink this comment Srinivasan Raghuraman Wed Mar 15, 2006 at 08.01 am

i had a request. I wanted to display a calendar on my blog site. Searching on google led me to this site. I wanted to ask you if I could use your code. Please do email if you would rather not have me use it. Of course it goes without saying that I would be displaying a message attributing the calendar to you and/or a link to this site (whichever is preferred by you). thanks



permalink this comment wayne Sat Mar 18, 2006 at 01.41 am


great site, great calendar, great discussion!!!!

I’ve built a rough following examples shown here, thank you. Now I want to mouse over the dates to promt text spans to appear in another area on page.

Here is an example of a site I’m working on where I did text spans (mouse over square images) [url=“‘knitting/calendar.html”>Whittington Steel</a>
The page where I want a similar effect but this time off dates in calendar is:
<a ]Zoe Life Church[/url]

I am not the most knowledgable programmer in the world and write all my script from scratch in a text editor being that I do not understand the various applications / tools available out there. i hope to take classes someday so i can automate / speed up / clean up some of my tasks.

Thank you again



permalink this comment SOn Sun Mar 19, 2006 at 07.01 pm

how do i put your calendar on my blogger?



permalink this comment Mohit Mon Apr 3, 2006 at 03.11 am

Nice work



permalink this comment Ben McNelly Wed Apr 5, 2006 at 10.10 am

mmm, thanks for the info!



permalink this comment Vít Dlouhý Thu Apr 27, 2006 at 10.00 pm

Nice work!



permalink this comment slider212 Fri May 12, 2006 at 04.11 am

Great article!!!

Just to let you know the link to download the stylesheet from the calendar demo page points to a different style sheet to the one in the article body.

Sorry if you already know about this.

Thanks again…

Commenting is not available in this weblog entry.


buy something from my Amazon wishlist