From our sponsor: Ready to show your plugin skills? Enter the Penpot Plugins Contest (Nov 15-Dec 15) to win cash prizes!
Today we want to share a flexible calendar concept with you. Calendars can be a very tricky thing when it comes to their layout and responsiveness. This is an experiment for trying out some grid layouts that can be applied to calendars. We’ve created a jQuery plugin for the calendar itself and you can see some examples of how to use it in the demos. The aim is to provide a suitable layout for both, small and big screens and keeping the calendar structure fluid when possible. On large screens we want to show a grid-based layout while on smaller screens, we want to simply stack the days of the month.
Please note that the demos will only work as intended in browsers that support the new CSS properties used here, especially calc().
The calendar designs are based on these two beauties found on Dribbble:
- Day – the most beautiful calendar app for your iPhone by Toby Negele
- Calendar by Tomas Gajar
For the calendar plugin to work, we simply need a container with the class “fc-calendar-container”:
<div id="calendar" class="fc-calendar-container"></div>
The plugin can be called like this:
$( '#calendar' ).calendario();
The plugin will create a calendar with the following structure:
<div id="calendar" class="fc-calendar-container"> <div class="fc-calendar fc-five-rows"> <div class="fc-head"> <div>Monday</div> <div>Tuesday</div> <div>Wednesday</div> <div>Thursday</div> <div>Friday</div> <div>Saturday</div> <div>Sunday</div> </div> <div class="fc-body"> <div class="fc-row"> <div></div> <div></div> <div></div> <div><span class="fc-date">1</span><span class="fc-weekday">Thu</span></div> <div><span class="fc-date">2</span><span class="fc-weekday">Fri</span></div> <div><span class="fc-date">3</span><span class="fc-weekday">Sat</span></div> <div><span class="fc-date">4</span><span class="fc-weekday">Sun</span></div> </div> <div class="fc-row"> <!-- ... --> </div> <div class="fc-row"> <!-- ... --> </div> <div class="fc-row"> <!-- ... --> </div> <!-- ... --> </div> </div> </div>
The calendar will consist of a head for the listing of the weekdays and a body with rows for the days of the month. Each “cell” will contain the date and weekday (if applicable) and we control the height of the rows by setting the right class to the container (four, five or six rows). The styling for the default calendar is defined in calendar.css.
Note that a cell that contains some content/event will look as follows:
<div class="fc-content"> <span class="fc-date">14</span> <span class="fc-weekday">Wed</span> <div> <!-- Some event/content --> </div> </div>
Note that the weekday of each cell is hidden by default because we have the calendar head with the weekdays. The ones in the cell are especially for the case when we apply media queries to reset the layout of the calendar to be stacked vertically. Here we will want to show the weekdays for each day.
It’s clear that a calendar could/should be represented by a table, but due to some table rendering differences between the browsers (especially IE9), we chose not to use it. You can of course adjust the plugin to output a table, though.
Tiny break: 📬 Want to stay up to date with frontend and trends in web design? Subscribe and get our Collective newsletter twice a tweek.
The important part of making the calendar grid fluid is the styling of the row and the div (or the “cell”):
.fc-four-rows .fc-row { height: 25%; } .fc-five-rows .fc-row { height: 20%; } .fc-six-rows .fc-row { height: 16.66%; height: -moz-calc(100%/6); height: -webkit-calc(100%/6); height: calc(100%/6); } .fc-calendar .fc-row > div, .fc-calendar .fc-head > div { float: left; height: 100%; width: 14.28%; /* 100% / 7 */ width: -moz-calc(100%/7); width: -webkit-calc(100%/7); width: calc(100%/7); position: relative; }
So, we define different heights depending on the amount of rows we’ll have, using calc() where we know that the result is not a round number. For the inner div we will set the width to be 100 divided by 7.
Options
The following (default) options are available:
// initialize calendar with this month (1-12). Default is today month : null, // initialize calendar with this year. Default is today year : null, // initial data/content for the calendar // format: // { // 'MM-DD-YYYY' : 'HTML Content', // 'MM-DD-YYYY' : 'HTML Content', // 'MM-DD-YYYY' : 'HTML Content' // ... // } caldata : null, weeks : [ 'Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday' ], weekabbrs : [ 'Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat' ], months : [ 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December' ], monthabbrs : [ 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec' ], // choose between values in options.weeks or options.weekabbrs displayWeekAbbr : false, // choose between values in options.months or options.monthabbrs displayMonthAbbr : false, // left-most day in the calendar // 0 - Sunday, 1 - Monday, ... , 6 - Saturday startIn : 1, // callback function for when clicking on a day cell in the calendar // $el is the cell // $content is the content division of the cell // dateProperties is an object with the following properties: // day : day number, // month : month number from 1 - 12, // monthname : name from options.months, // year : year number, // weekday : week number from 0 - 6, // weekdayname : name from options.weeks onDayClick : function( $el, $content, dateProperties ) { return false; }
The following public methods are available:
// return the year that is currently being viewed getYear() // return the month that is currently being viewed (1-12) getMonth() // returns the name of the month that is currently being viewed getMonthName() // returns the content division inside the cell associated to day "day" getCell( day ) // sets the data to the calendar. Merges the contents of the passed caldata with the one already set (if any) setData( caldata ) // shows the calendar for today's month and year // month is from 1-12 gotoNow( callback ) // shows the calendar for month "month" and year "year" // month is from 1-12 goto( month, year, callback ) // goes back one month in the calendar gotoPreviousMonth( callback ) // goes back one year in the calendar gotoPreviousYear( callback ) // goes further one month in the calendar gotoNextMonth( callback ) // goes further one year in the calendar gotoNextYear( callback )
You can use setData to add content to the calendar. You can see examples for that in the demo files.
The basic styling is defined in the calendar.css file and you can see examples of how to modify the calendar style and add to it in the custom CSS files.
Demos
Check out the demos: