問題描述
我熟悉標(biāo)準(zhǔn)的基于 colspan 的方法,用于在 HTML 中顯示(多周或月視圖)日歷以及跨越多天的事件.(Google 日歷就是這樣做的,這是眾多示例之一.)
我很好奇是否有人知道實現(xiàn)相同目標(biāo)的無表方法.也許它只是不重要,這是對表格元素的好"使用,但我認(rèn)為它可能在這個響應(yīng)式設(shè)計時代更相關(guān).
這是一個響應(yīng)式、無表格日歷的示例.(不過,沒有多日活動.)https://pittsburghkids.org/calendar 在其小視口版本中,它不再是一個表,語義上.同樣,正如@ThinkingStiff 在下面提到的,如果您在客戶端從月視圖"切換到列表視圖",則表格在語義上也并不真正適合.
日歷 != 表格
日歷是不是語義表.它們感覺就像表格,因為這是我們經(jīng)常看到它們的方式,但是為了使數(shù)據(jù)語義為表格,每一行都必須包含一個唯一的實體,而它們沒有.在日歷中,day 是實體.
混淆之處在于我們還將天分組為幾周.人們很自然地認(rèn)為一個月是幾個星期的集合,但事實并非如此,它是幾天的集合.一個月平均有 4.3 周.表中的一行不能包含一個實體的部分或多個實體.
行 == 實體,列 == 屬性
將其與在線購物車進(jìn)行比較.您購物車中的物品是表格的.每 行 代表您購物車中的一種 item.每個列要么是項目的一個屬性(名稱、股票編號、價格),要么是一個屬性的集合(數(shù)量、總量).您永遠(yuǎn)不會在一行中看到兩種不同的商品類型(因為這沒有意義),而且購物車不能包含 4.3 行.
解決方案
對于這個演示,我使用了 <divs>
,每天一個設(shè)置為 display: inline-block
,但您可能想要使用 >
- .在月/周/日視圖之間更改時,天數(shù)流動良好(表格不可能).對于多日活動,Javascript可以做布局.
演示: http://jsfiddle.net/ThinkingStiff/XXm8y/一個>
輸出:
腳本:
var events = [{ from: 3, to: 9 }, { from: 4, to: 4 }, { from: 9, to: 11 },{從:4,到: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 = firstDay[0].style.top;} 別的 {var eventCount = dayElement.getElementsByClassName('event').length;頂部 = ( 事件計數(shù) * 20 ) + 'px';};var html = '<div'+ 'class="事件事件' + eventIndex + '" '+ 'style="top: ' + top + ';">'+ 事件索引+ '</div>';dayElement.insertAdjacentHTML('beforeEnd', html);};};
CSS:
#calendar {邊框:1px純黑色;高度:400px;寬度:504px;}.日 {顯示:內(nèi)聯(lián)塊;高度:80px;位置:相對;垂直對齊:頂部;寬度:72px;}.day:nth-child(偶數(shù)){背景顏色:粉紅色;}.day:nth-child(奇數(shù)){背景顏色:淺藍(lán)色;}.事件 {背景顏色:淺灰色;高度:20px;位置:絕對;文本對齊:居中;寬度: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>
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.
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:
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>?
這篇關(guān)于多日日歷事件的 HTML 標(biāo)記的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網(wǎng)!