10

我有一个显示在多列上的列表。每个列表项都是块元素(display:block),并附有一些样式(底部有 1px 边框)。它目前看起来像这样:

List item    List item    List item
---------    ---------    ---------
List item    List item    List item
---------    ---------    ---------
List item    List item
---------    ---------

我想在每列的第一个项目的顶部添加一个相同的边框,例如

---------    ---------    ---------    
List item    List item    List item
---------    ---------    ---------
List item    List item    List item
---------    ---------    ---------
List item    List item
---------    ---------

我尝试过 :first-line 和 ::first-line,在这种情况下它们似乎都没有(可能是因为它不适用于块元素?)

该列表的长度可能会有所不同,因此我无法确定每列中有多少项目,因此我也无法使用 :nth-of-type() 。

有谁知道这是否可以做到(或者相反,如果它绝对不能做到?)

我的 HTML

<ul>
  <li><a href="">List item</a></li>
  <li><a href="">List item</a></li>
  <li><a href="">List item</a></li>
  ...
</ul>

我的 CSS

  ul {
    list-style: none;
    padding: 21px;
    -moz-column-count: 4;
    -webkit-column-count: 4;
    column-count: 4;
    -moz-column-gap: 21px;
    -webkit-column-gap: 21px;
    column-gap: 21px;
  }
  li {
    display: block;
    -moz-column-break-inside: avoid;
    -webkit-column-break-inside: avoid;
    -mx-column-break-inside: avoid;
    column-break-inside: avoid;
    padding: 1em 0;
    border-bottom: 1px dotted #000;
  }
4

4 回答 4

6

看到代码和 1 小时后编辑:完成!使用纯 CSS!

因为我不想使用javascript,所以我花了很长时间。这是幕后真实情况的演示http://jsfiddle.net/mEtF6/1/,这是工作版本:http: //jsfiddle.net/mEtF6/2/。如果您不明白任何内容,请随时询问,因为它没有很好的文档记录。我实际上必须添加一个包装“ul”的 div,因为overflow: hiddenonul不会像border-top在元素之外那样表现。这是工作代码:

<div>
  <ul>
    <li><a href="">List item 1</a></li>
    <li><a href="">List item 2</a></li>
    <li><a href="">List item 3</a></li>
    <li><a href="">List item 4</a></li>
    <li><a href="">List item 5</a></li>
    <li><a href="">List item 6</a></li>
    <li><a href="">List item 7</a></li>
    <li><a href="">List item 8</a></li>
    <li><a href="">List item 9</a></li>
  </ul>
</div>

和CSS:

div {
  /* This will hide the white space at the right (blue in the explanation) */
  overflow: hidden;
  }

ul {
  position: relative; /* Needed to place the :before pseudo element in the proper position */
  list-style: none;
  border-top: 1px dotted #000;
  padding: 0;
  margin: 0;
  -moz-column-count: 4;
  -webkit-column-count: 4;
  column-count: 4;
  -moz-column-gap: 20px;
  -webkit-column-gap: 20px;
  column-gap: 20px;
  }

/* This 'cuts' the top margin of ul so it's displayed in the same way as the other */
ul:before {
  content: " ";
  position: absolute;
  display: block;
  width: 100%;
  height: 1px;

  /* Put the gaps on the <ul> top margin */
  top: -1px;

  /* Background-size = 1/4 of the width + 1/4 of the space between columns */
  background-size: calc(25% + 5px) 1px;

  /* Or it will hide the border-top of the ul */
  background-color: transparent;

  /* The actual white gaps at the top */
  background-image: linear-gradient(
    90deg,
    transparent calc(100% - 20px), /* All the <li> width minus the gap is transparent */
    red 20px);  /* Those 20px are white */
  }

li {
  -moz-column-break-inside: avoid;
  -webkit-column-break-inside: avoid;
  -mx-column-break-inside: avoid;
  column-break-inside: avoid;
  padding: 0;
  border-bottom: 1px dotted #000;
  }

/* This will hide the top margin of the last columns without elements */
li:last-child:before {
  position: absolute;
  /* You want to place the top  */
  margin-left: calc(25% + 5px);
  content: " ";
  display: block;
  background-color: blue;
  width: 10px;
  height: 1px;
  top: -1px;
  width: 100%;
  }

/* Make the <a> fill the whole space of the <li> */
li a {
  display: block;
  padding: 1em 0;
  }

注意:我添加了对标签的适当支持<a>,使整个块可点击,而不仅仅是其中的文本。你可以逆转它。

注 2:仅使用FIREFOX进行测试。您可能需要添加一些其他 -webkit 渐变以使其跨浏览器。抱歉,我会把这个肮脏的工作留给你(;我发现了一个明显的错误,并在 SO 中提出了一个关于它的问题

同样,工作演示:http: //jsfiddle.net/mEtF6/2/

于 2013-10-10T15:33:18.730 回答
5

添加border-top: 1px dotted #000; margin-bottom: -1px;到你的李风格

小提琴

于 2013-10-10T15:56:15.837 回答
2

如果ul跨多个列的相同,并且列中的项目数可能会有所不同。然后我看不到这样做的方法。至少不使用 CSS。

我会将列设置为固定数量的项目并使用 a:nth* pseudo selector或将列拆分为不同的ul标签并设置第一个li.

如果你想使用 jQuery 或类似的,你可以定位第一个li,找到top它的位置并遍历其他的,如果top位置匹配添加边框。

编辑

这个 JSFiddle 是一种解决方案,但它确实使用了 jQuery:

http://jsfiddle.net/8ZRkG/

有四列: 在此处输入图像描述

三列: 在此处输入图像描述

于 2013-10-10T15:32:25.380 回答
1

CSS3 多列模型的工作方式是在content-boxcontent之间创建一种新型容器,称为column box

不幸的是,当前的规范明确指出:

无法在列框上设置属性/值。例如,不能设置某个列框的背景,列框没有内边距、边距或边框的概念。

因此,目前,没有用于列框或其中的元素的选择器,尽管同一页面打开了将来可能包含这样一个东西的可能性(为什么他们没有想到将它包含在目前的规格,超出了我的范围)。

由于您声明无法编辑服务器端输出,因此您需要使用 Javascript。我看到一个解决方案已经提出了这一点,尽管我不同意计算li:first-child. 相反,我建议:

var liNum  = $('ul.columns li').length; // This computes the number of list items
var colNum = 4;                        // This is the number of columns you want

$('ul.columns li').each(function(i) {
    if ( i % Math.ceil(liNum/colNum) === 0 ) {
        $(this).addClass('top');
    }
});

Working demo

当然,它有点长,但不依赖于计算的顶部位置(这是一个视觉属性)或li存在:first-child。相反,它依赖于列表中元素的数量,我认为这是重要的数字。

当然,这是假设您知道您有多少列(正如您所说的那样)。如果您不想依赖该信息,则可以只计算该 CSS:

var colNum = $('ul.columns').css('column-count')

另外,如果您只想将边框添加到顶部,并且不想设置其他任何样式,我可能会直接通过.css()方法编辑 css 而不是添加类。如果您需要将顶部元素定位为更多样式或其他目的(例如进一步的 JS),那么我将添加该类。但这确实是一个偏好问题。

于 2013-10-10T16:31:30.043 回答