2014-11-23 47 views
2

我想创建一个日期选择是这样的:如何使用嵌套列表创建水平日历?

| 1 2 3 4 5 6 7 8 9 .. 29 30 31 | 1 2 3 4 .. 
| January      | February 

我觉得我们的最佳结构是:

<div class="outer"> 
    <ol> 
    <li class="month"> 
    January 
     <ol> 
     <li class="day">1</li> 
     <li class="day">2</li> 
     <li class="day">3</li> 
     ... 
     </ol> 
     </li> 
     <li class="month"> 
     February 
     <ol> 
      <li class="day">1</li> 
      <li class="day">2</li> 
      <li class="day">3</li> 
      ... 
     </ol> 
     </li> 
    </ol> 
</div> 

现在我想外的div(.month)扩大到内部div(.day),它们都是相同的宽度。然后在一个大的水平分区(.outer),所以我可以滚动内脏。 我已经有了这个工作只有一个月,但是当我增加更多的月份,它不再工作。

我显然不能设置固定的月份,因为他们没有相同的天数。

我设置了a Fiddle here与一些CSS,但它不工作,我不知道如何去做。

回答

1

这样的问题都只是好玩回答一步一步的。

The basics of the solution is to display all list items as inline-block:

.calendar > ol > li { 
    display: inline-block; 
} 
.calendar > ol > li > ol { 
    padding: 0; 
} 
.calendar > ol > li > ol > li { 
    display: inline-block; 
} 

Give the dates a fixed size, put all months on a single line, and let the container scroll:

.calendar { 
    overflow-x: auto; 
} 
.calendar > ol { 
    padding: 0; 
    margin: 0; 
    white-space: nowrap; 
} 
.calendar > ol > li { 
    display: inline-block; 
} 
.calendar > ol > li > ol { 
    padding: 0; 
} 
.calendar > ol > li > ol > li { 
    display: inline-block; 
    width: 30px; 
} 

And finally, shuffle the months' and the dates' positions,导致这种SNIPPIT:

.calendar { 
 
    overflow-x: auto; 
 
    overflow-y: hidden; 
 
} 
 
.calendar > ol { 
 
    padding: 0; 
 
    margin: 0; 
 
    white-space: nowrap; 
 
    margin-bottom: -1em; 
 
} 
 
.calendar > ol > li { 
 
    display: inline-block; 
 
    margin-top: 1em; 
 
} 
 
.calendar > ol > li > ol { 
 
    padding: 0; 
 
} 
 
.calendar > ol > li > ol > li { 
 
    display: inline-block; 
 
    width: 30px; 
 
    position: relative; 
 
    top: -2.2em; 
 
}
<div class="calendar"> 
 
    <ol> 
 
     <li>January 
 
      <ol> 
 
       <li>1</li> 
 
       <li>2</li> 
 
       <li>3</li> 
 
       <li>4</li> 
 
       <li>5</li> 
 
       <li>6</li> 
 
      </ol> 
 
     </li> 
 
     <li>February 
 
      <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> 
 
      </ol> 
 
     </li> 
 
     <li>March 
 
      <ol> 
 
       <li>1</li> 
 
       <li>2</li> 
 
       <li>3</li> 
 
       <li>4</li> 
 
       <li>5</li> 
 
      </ol> 
 
     </li> 
 
     <li>April 
 
      <ol> 
 
       <li>1</li> 
 
       <li>2</li> 
 
       <li>3</li> 
 
       <li>4</li> 
 
       <li>5</li> 
 
       <li>6</li> 
 
      </ol> 
 
     </li> 
 
    </ol> 
 
</div>

请注意,这是一个严格的CSS2解决方案,即使是最古老的浏览器也是如此,它不使用绝对定位,因此对它周围的内容没有任何影响,只需要一个样式类,与every font size兼容,并且没有影响在标记上。

+0

谢谢。非常干净,易于实施。 – Johanness 2014-11-23 20:48:04

2

我已经完全重写了你的CSS,因为很难确定你想要看什么样子。我选择使用最新的CSS3 flexbox specification - 仅仅是因为它允许我相对于日期重新定位月份,而不使用position,这将非常混乱。您可能需要使用供应商前缀来确保CSS3 flexbox的最大跨浏览器支持。

请参阅验证性小提琴:http://jsfiddle.net/teddyrised/g6u52vhn/4/。我对标记做出的唯一更改是将<span>标记中的月份包裹起来;)

我冒昧添加边框,以便您可以清楚地区分不同的元素。

.dates { 
    display: block; 
    position: absolute; 
    left: 5%; 
    width: 90%; 
    height: 200px; 
    overflow: auto; 
} 

/* General list styles */ 
.dates ol { 
    display: flex; 
    list-style: none; 
    margin: 0; 
    padding: 0; 
    width: 100%; 
    white-space: nowrap; 
} 
.dates li { 
    display: flex; 
    flex-flow: row wrap; 
    flex-shrink: 0; 
    flex-grow: 1; 
} 

/* Specific styles */ 
.dates > ol > li { 
    border: 1px solid #000; 
} 
.dates .month span { 
    border: 1px solid #999; 
    display: block; 
    order: 2; 
    width: 100%; 
} 
.dates .month ol { 
    order: 1; 
} 
.dates .month ol li { 
    border: 1px solid #999; 
} 

不过,如果你需要支持旧的浏览器,你可能要退回到好老<table>元素,我觉得就足够和有效的。

+0

谢谢Terry。与flex非常有趣。我一定会尝试 - 因为我目前的代码库更接近Veens解决方案。 – Johanness 2014-11-23 20:00:07

2

看看这个了JSFiddle链接。 您的CSS部分没有太多变化,但是您的HTML部分有一点变化,我给dates > OL授予了课程,因为dates > OL > LI > OL默认情况下是从父级OL获取CSS。 此外,我已将包含月份名称的LI文本放在span中。

HTML部分:更新

....<div class="dates"> 
    <ol class="datesOL"> 
     <li class="month">.... 

CSS部分:更新

.dates { 
    height: 60px; 
} 

.datesOL { 
    margin: 0; 
    padding: 0px; 
    overflow: scroll; 
} 

.dates ol li { 
    overflow: auto; 
} 

.dates ol li ol { 
    display: block; 
    padding: 0; 
    height: 12px; // removed 
    top: -80px; // removed 
} 

.dates ol li ol li { 
    display: inline-block; 
    width: 20px; 
} 
+0

您应该尽量避免绝对定位,因为它会将日历从内容中拉出。此外,此解决方案与不同的字体大小不兼容,请参阅[您的小提琴的此更新](http://jsfiddle.net/NGLN/g6u52vhn/11/)。 – NGLN 2014-11-23 20:48:54

+0

@NGLN但您不知道其他人的(@Johanness)要求或可能是项目要求。所以我已经用必需/最小的变化来纠正这个问题。 – 2014-11-23 20:49:24

+1

我明白了。我总是试图超越实际的问题。这可能是一个打勾。 ;-) – NGLN 2014-11-23 20:53:46