使用 CSS 实现弹性日历样式

Avatar of Tim Wright
Tim Wright

DigitalOcean 为您旅程的每个阶段提供云产品。 立即开始使用 价值 200 美元的免费积分!

这篇文章由 CSSKarma 的 Chris Coyier 和 Tim Wright 共同撰写

传统的日历是页面上带编号的方格。 作为一名网页设计师,您可能直接使用表格,我不会责怪您。 但是,表格有时很难塑造成形。 我内心纯粹的 CSS 就会恼火,当我设置表格(或单元格)的宽度时,它决定自己知道得更多,并根据自己的想法增大或缩小。

您可以使用纯 CSS 来处理日历样式,我觉得它在语义上与表格一样有意义。 日历是什么,如果不是一列有序的天数? 通过使用 CSS,我们甚至可以做一些很酷的事情,比如使用 em 来进行所有尺寸调整,这样我们的日历布局就会是弹性的。 也就是说,当浏览器中调整文本大小时,日历的宽度和高度都会随之变化,同时极大地提高可访问性。

我们来看看吧?

查看演示 下载示例

 

三个有序列表

从语义上讲,月历不是单个有序列表,而是三个。 显然,月份的所有日期都是一个有序列表。 但月份并不总是从星期日开始,在星期六结束,因此在网格的开头和结尾,那些“填充”天数更有意义地成为自己的列表。 看一看

<ol class="calendar" start="6">

	<li id="lastmonth">
		<ol start="29">
			<li>29</li>
			<li>30</li>
		</ol>
	</li>
	
	<li id="thismonth">
		<ol>
			<li>1</li>
			<li>2</li>
			<li>3</li>
			<li>4</li>
			<li>5</li>
			<li>6</li>
			<li>7</li>
			<li>8</li>
			<li>9</li>
			<li>10</li>
			<li>11</li>
			<li>12</li>
			<li>13</li>
			<li>14</li>
			<li>15</li>
			<li>16</li>
			<li>17</li>
			<li>18</li>
			<li>19</li>
			<li>20</li>
			<li>21</li>
			<li>22</li>
			<li>23</li>
			<li>24</li>
			<li>25</li>
			<li>26</li>
			<li>27</li>
			<li>28</li>
			<li>29</li>
			<li>30</li>
			<li>31</li>
		</ol>
	</li>
	
	<li id="nextmonth">
		<ol>
			<li>1</li>
			<li>2</li>
		</ol>
	</li>
	
</ol>

以及完全样式化的 CSS

/*
 * CSS Calendar
 * Tim Wright
 * Chris Coyier
 -----------------------------*/

*		{margin:0;padding:0;}
body		{font:1em/1.4 Verdana, Arial, Helvetica, sans-serif; 
			background: url(images/bg.jpg) top center no-repeat #545454;}
body *		{display:inline;}
ol.calendar    {width:52em;margin:0 auto;display:block; min-height: 200px;
			background: url(images/tl.png) top left no-repeat; padding: 12px 0 0 20px;}
li		{list-style:none;}
p.link		{text-align:center;display: block;}
h1		{display: block; width: 200px;height:76px;
			background:url(images/july.png);text-indent:-9999px; margin: 15px auto; }

/*
 * Day styles
 -------------------------*/
li li		{width:6em;height:6em;float:left;margin:.2em; padding:.2em;overflow:auto;
			background: url(images/day-bg.png) bottom right no-repeat; }

/*
 * Day content (UL/OL & P)
 -------------------------*/
li li p	 {font-size:.7em;display:block;}
li li ol	 {width:auto;}
li li ul li,
li li ol li     {font-size:.7em;display:block;height:auto;width:auto; background: none;
			margin:0;padding:.2em 0;float:none;}

/*
 * Holiday class
 -------------------------*/
li li.holiday    {  }

/*
 * Inactive months
 -------------------------*/
li#lastmonth li,
li#nextmonth li    { background: url(images/day-bg-inactive.png);}

这里要注意一些重要事项。

有序列表会生成自己的编号,因此从技术上讲,我们可以利用这一点并使用它来自动对日历进行编号。 但是,以这种方式进行定位会有点棘手,而且无论如何您都需要在每个列表项中添加一些内容(至少要添加一个&nbsp;),以使其在所有浏览器中正确呈现。 因此,最好将列表样式设置为 none,并将日期数字直接放在列表项中。 由于这一点,当 CSS 关闭时,我们会得到以下结果

1. 1
2. 2
3. 3

等等。

这不是世界末日,但因为我们希望即使没有 CSS,我们的日历也尽可能好,所以您可能需要考虑使用无序列表,这样您就可以获得项目符号。

另外,请注意 <ol> 元素中的“start”属性。 这使您的列表可以从除“1”以外的数字开始。 此元素最近已弃用。 这样做是因为列表并不总是基于十进制的,它们可能是字母或罗马数字,或者其他任何有序列表可以表示的东西。 但是,没有 CSS 替代方案,因此只能使用弃用元素。(注意:如果您希望出于验证原因将此 start 属性保留在代码之外,Piotr Petrus 提供了一种使用 javascript 的方法。)

 

跨浏览器问题

也许更有趣的是,我们在这种标记中遇到的跨浏览器问题。 我们在这里的目标是一个直观的网格,所以我们使用的是浮动块。 但列表默认情况下是块级元素,因此为了使所有块都位于同一个网格中,从技术上讲,这些块需要彼此直接叠放在一起才能看起来正确。 当我们创建它时,除了(有趣的是)Firefox 2 之外,所有浏览器都正确地处理了它。 但是 Firefox 3 却正确地处理了它。

Tim 通过将页面上的所有元素设置为内联来欺骗 Firefox 2 服从

body *              {display:inline;}

然后根据需要将元素设置回块。

关于在 body 内的所有元素上显示内联的一个有趣注意事项……Google Analytics 代码位于 body 内的 <script> 标签中(默认情况下设置为 display:none),在 <script> 上显示内联将显示您嵌入的 JavaScript。 这实际上是 Firefox 中的一个不错补充,尤其是在编写教程并希望显示您的 CSS 或 JavaScript 时。 您可以实际显示使页面运行的嵌入式 CSS/JS 代码,非常酷。

在这种情况下(JS 嵌入在 body 中的某个位置),您可能希望将日历包装在一个 <div> 中并使用 div *{display:inline;}。

我们发现的另一个奇怪问题是,display:inline 和 float:left 的组合会将每个有序列表项的计数器重置为零(仍然不知道为什么——而且只在 FF3 中测试),因此您最终会得到一个很长的零列表。 这很奇怪,但由于我们删除了列表样式,所以这不是什么大问题。

当然,任何网页都少不了 IE 的问题。 在 IE 6&7 中,每个日期内的 OL 和 UL 的边距会稍微挤压文本,这没什么大不了的,但需要注意。

 

最后的想法

我们并不建议您抛弃基于表格的日历,转而使用纯 CSS 解决方案。 我们只是想表明这是可以做到的,如果您选择这样做,这种方法甚至还有一些特定的优势。 要了解另一种方法,请查看 Rob 关于 CSS 日历样式的最新文章。 总的来说,这个日历比我们预期的花费的时间要长,但它最终还是做得很好,并且是一个很好的方法,可以证明您可以使用正确的 CSS 和一些语义标记,让任何东西都按照您想要的方式显示。

我们的示例使用背景图像来表示日期。 由于设计的弹性特性,这些背景图像需要比方框大得多。 许多较新的浏览器提供“缩放”功能,这使得这一点变得没有必要,但为了兼容所有人,这是最佳实践。

演示和下载