Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
511 views
in Technique[技术] by (71.8m points)

css - HTML markup for multi-day calendar events

I'm familiar with the standard colspan-based approach for displaying (multiweek or month view) calendars in HTML with events that span multiple days. (Google Calendar does this, as one of many examples.)

I'm curious if anyone knows of a table-less approach to achieve the same thing. Maybe it's just not important, and this is a "good" use of the table element, but I think it might be more relevant in this era of responsive design.

Here's an example of a responsive, table-less calendar. (No multi-day events, though.) https://pittsburghkids.org/calendar In its small-viewport version, it's no longer a table, semantically. Similarly, as @ThinkingStiff mentions below, if you're switching from "month view" to "list view" on the client side, a table doesn't really fit semantically either.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Calendars != Tables

Calendars are not semantically tables. They feel like tables because that is how we always see them, but for the data to be semantically tabular, each row would have to contain a unique entity, and they don't. In calendars the day is the entity.

The confusion lies in the fact that we also group days into weeks. People naturally think a month is a collection of weeks, but it is not, it's a collection of days. A month has, on average, 4.3 weeks. A row in a table can't contain part of an entity or multiple entities.

Row == Entity, Column == Property

Compare it to, say, a shopping cart online. The items in your cart are tabular. Each row represents one type of item in your cart. Each column is either a property of the item (name, stock number, price) or an aggregate (quantity, total amount) of a property. You never see two different item types in a single row (because it wouldn't make sense) and a cart can't contain 4.3 rows.

A Solution

For this demo I used <divs>, one for each day set to display: inline-block, but you'll probably want to use an <ol>. Days flow well when changing between month/week/day views (not possible with tables). For multi-day events, Javascript can do the layout.

Demo: http://jsfiddle.net/ThinkingStiff/XXm8y/

Output:

enter image description here

Script:

var events = [{ from: 3, to: 9 }, { from: 4, to: 4 }, { from: 9, to: 11 },{ from: 4, to: 12 }];

for( var eventIndex = 0, event; event = events[eventIndex], eventIndex < events.length; eventIndex++ ) {
    for( var dayIndex = event.from; dayIndex <= event.to; dayIndex++ ) {
        var dayElement = document.getElementById( 'day' + dayIndex ),
            firstDay = document.getElementsByClassName( 'event' + eventIndex ),
            top;
        if( firstDay.length ) {
            top = firstDay[0].style.top;
        } else {
            var eventCount = dayElement.getElementsByClassName( 'event' ).length;
            top = ( eventCount * 20 ) + 'px';
        };
        var html = '<div '
            + 'class="event event' + eventIndex + '" '
            + 'style="top: ' + top + ';">' 
            + eventIndex
            + '</div>';
        dayElement.insertAdjacentHTML( 'beforeEnd', html );
    };        
};
?

CSS:

#calendar {
    border: 1px solid black;
    height: 400px;
    width: 504px;    
}
.day {
    display: inline-block;
    height: 80px;
    position: relative;
    vertical-align: top;
    width: 72px;   
}
.day:nth-child( even ) {
    background-color: pink;
}
.day:nth-child( odd ) {
    background-color: lightblue;
}
.event {
    background-color: lightgrey;
    height: 20px;   
    position: absolute;
    text-align: center;
    width: 100%;
}

?

HTML:

<div id="calendar">
    <div id="day1" class="day"></div><div id="day2" class="day"></div><div id="day3" class="day"></div><div id="day4" class="day"></div><div id="day5" class="day"></div><div id="day6" class="day"></div><div id="day7" class="day"></div><div id="day8" class="day"></div><div id="day9" class="day"></div><div id="day10" class="day"></div><div id="day11" class="day"></div><div id="day12" class="day"></div><div id="day13" class="day"></div><div id="day14" class="day"></div><div id="day15" class="day"></div><div id="day16" class="day"></div><div id="day17" class="day"></div><div id="day18" class="day"></div><div id="day19" class="day"></div><div id="day20" class="day"></div><div id="day21" class="day"></div><div id="day22" class="day"></div><div id="day23" class="day"></div><div id="day24" class="day"></div><div id="day25" class="day"></div><div id="day26" class="day"></div><div id="day27" class="day"></div><div id="day28" class="day"></div><div id="day29" class="day"></div><div id="day30" class="day"></div><div id="day31" class="day"></div>
</div>?

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...