CSS中的条件多列

时间:2015-09-25 14:46:54

标签: css

我有一个包含一些子菜单的菜单,比如这个



.menu {
  position: absolute;
  background: yellow;
  margin-top: 2em;
}
header {
  font-size: 20px;
}
ul {
  -moz-column-count: 2;
  -moz-column-gap: 10px;
  -webkit-column-count: 2;
  -webkit-column-gap: 20px;
  column-count: 2;
  column-gap: 10px;
  list-style: none;
  padding: 0;
}
li:nth-child(odd) {background: lightblue; }
li:nth-child(even) {background: lightyellow; }
div:not(.main) {
  display: inline-block;
  position: relative;
}

<div>menu one
  <div class="menu">
    <header>menu one header</header>
    <ul>
      <li>Item one</li>
      <li>Item two 2</li>
      <li>Item tree</li>
      <li>Item four</li>
      <li>Item five</li>
      <li>six</li>
      <li>Item 7</li>
    </ul>
  </div>
</div>
<div>menu two</div>
&#13;
&#13;
&#13;

如果.menu>ul列表中有超过4个条目,我只需要显示2列。

是否可以使用纯CSS?

5 个答案:

答案 0 :(得分:1)

我们可以处理数量查询,只有订单问题。如果您对该订单妥协,我们可以使用数量查询。

ul {
    margin:0; padding:0; list-style:none;
}

li {
    width:40%;
    border:1px solid red;
    margin:2px;
}


ul li:nth-last-child(n+5), 
ul li:nth-last-child(n+5) ~ li { 
    float:left;
}

demo

答案 1 :(得分:1)

你可以利用这里描述的技巧 - http://alistapart.com/article/quantity-queries-for-css,这是@Jesse Kernaghan in the comments above建议的。

然而,为了能够做到这一点,你需要做一些硬连线的事情:

  1. 修复容器public class ProjectDeletionListenerManager implements IResourceChangeListener { public interface ProjectDeletionListener { void projectAboutToBeDeleted(IProject project); } private IWorkspace workspace; private ProjectDeletionListener listener; public ProjectDeletionListenerManager(ProjectDeletionListener listener) { this.workspace = ResourcesPlugin.getWorkspace(); this.listener = listener; this.workspace.addResourceChangeListener(this, IResourceChangeEvent.PRE_DELETE); } @Override public void resourceChanged(IResourceChangeEvent event) { IResource rsrc = event.getResource(); if (rsrc instanceof IProject) { listener.projectAboutToBeDeleted((IProject) rsrc); } } public void dispose() { if (listener!=null) { workspace.removeResourceChangeListener(this); listener = null; } } } 的高度和宽度,以及
  2. 修正ul的高度,并确保此宽度乘以li等于容器n的高度。 ul是您的幻数,在您的情况下n
  3. 这是必需的,因此CSS 4不会重排内容,并且columns会以可预测的方式排列到列中。

    如果您的标记和用例可以使用上述两个约束,那么您可以使用以下CSS选择器:

    li

    第一个选择器将从末尾选择li:nth-last-child(4):first-child, li:nth-last-child(4):first-child ~ li { width: 160px; } 4 th ,并且恰好是第一个,有效地仅选择一组中的第一个li恰好四个li s,其中li是你的神奇数字。

    第二个选择器(通用兄弟组合器)将选择第一个选择器之后存在的所有4

    对这些li应用固定宽度,以提供一列的虚假外观。

    示例代码段

    li
    div.menu {
      display: inline-block; vertical-align: top;
      background: yellow; margin: 2em 1em;
    }
    header { font-size: 20px; }
    ul {
      width: 160px; -moz-columns: 2 auto; -moz-column-fill: auto;
      -webkit-columns: 2 auto; columns: 2 auto;
      list-style: none; padding: 0; height: 8em;
    }
    li { height: 2em; }
    li:nth-child(odd) {background: lightblue; }
    li:nth-child(even) {background: lightyellow; }
    
    li:nth-last-child(4):first-child, li:nth-last-child(4):first-child ~ li {
      width: 160px;
    }

答案 2 :(得分:1)

这是一种方法,使用Chrome,FF,IE11和Edge进行测试,但仍有一些固定值,如果超过8项则需要进行调整。

li高度需要修正,然后负margin-top将是该高度的4倍,以便将正确的项目推到顶部。

这里的技巧是当2&#34;列&#34;时,每个项目的宽度超过可用宽度的50%。需要,所以漂浮物保持侧面然后推动右侧&#34;列#34;因此它与左边对齐。

&#13;
&#13;
.menu {
  position: absolute;
  background: yellow;
  margin-top: 2em;
}
header {
  font-size: 20px;
}
ul {
  list-style: none;
  padding: 0;
}
li:nth-child(odd) {background: lightblue; }
li:nth-child(even) {background: lightyellow; }

li { position: relative; height: 20px; }
li:nth-child(-n+4) { float: left; width: 48%; margin-right: 3%; }
li:nth-child(n+5) { float: right; width: 48%; margin-left: 3%; top: -80px }

li:nth-last-child(4):first-child, li:nth-last-child(4):first-child ~ li {
  width: 94%; margin-right: 6%
}

div:not(.main) {
  display: inline-block;
  position: relative;
}
&#13;
<div>menu one
  <div class="menu">
    <header>menu one header</header>
    <ul>
      <li>Item one</li>
      <li>Item two 2</li>
      <li>Item tree</li>
      <li>Item four</li>
      <li>Item five</li>
      <li>six</li>
      <li>Item 7</li>
    </ul>
  </div>
</div>
<div>menu two
  <div class="menu">
    <header>menu two header</header>
    <ul>
      <li>Item one</li>
      <li>Item two 2</li>
      <li>Item tree</li>
      <li>Item four</li>
    </ul>
  </div>
</div>
&#13;
&#13;
&#13;

更新这是另一种方式,使用flex。

基于li高度和ul高度n项适合每列。

&#13;
&#13;
.menu {
  position: absolute;
  background: yellow;
  margin-top: 2em;
}
header {
  font-size: 20px;
}
ul {
  list-style: none;
  padding: 0;
  display: flex;
  flex-direction: column;
  flex-wrap: wrap;
  height: 100px;
}

li {
  height: 22px;
}

li:nth-child(odd) {background: lightblue; }
li:nth-child(even) {background: lightyellow; }

div:not(.main) {
  display: inline-block;
  position: relative;
}
&#13;
<div>menu one
  <div class="menu">
    <header>menu one header</header>
    <ul>
      <li>Item one</li>
      <li>Item two 2</li>
      <li>Item tree</li>
      <li>Item four</li>
      <li>Item five</li>
      <li>six</li>
      <li>Item 7</li>
    </ul>
  </div>
</div>
<div>menu two
  <div class="menu">
    <header>menu two header</header>
    <ul>
      <li>Item one</li>
      <li>Item two 2</li>
      <li>Item tree</li>
      <li>Item four</li>
    </ul>
  </div>
</div>
<div>menu three
  <div class="menu">
    <header>menu three header</header>
    <ul>
      <li>Item one</li>
      <li>Item two 2</li>
      <li>Item tree</li>
      <li>Item four</li>
      <li>Item five</li>
      <li>Item six</li>
      <li>Item seven</li>
      <li>Item eight</li>
      <li>Item nine</li>
      <li>Item ten</li>
    </ul>
  </div>
</div>
&#13;
&#13;
&#13;

答案 3 :(得分:0)

嗯,会有一个&#34;干净&#34;方式(不依赖于任何硬编码的数字),但当然有一个问题......

您可以使用ul总是两列,而是使用column-span: all使所有li元素跨越所有列,并且&#34;撤消&#34;通过制作所有li元素,如果所有列中有超过四个(nth-last-child(n + 5)),的范围。
Buuut ...... Firefox doesn't support this (撰写本文时)。

&#13;
&#13;
.menu {
  position: absolute;
  background: yellow;
  margin-top: 2em;
}
header {
  font-size: 20px;
}
ul {
  -webkit-column-count: 2;
  -webkit-column-gap: 20px;
  column-count: 2;
  column-gap: 10px;
  list-style: none;
  padding: 0;
}
li:nth-child(odd) {background: lightblue; }
li:nth-child(even) {background: lightyellow; }
div:not(.main) {
  display: inline-block;
  position: relative;
}
li {
  -webkit-column-span: all;
  column-span: all;
}
li:nth-last-child(n + 5), li:nth-last-child(n + 5) ~ li {
  -webkit-column-span: none;
  column-span: none;
}
&#13;
<div>menu one
  <div class="menu">
    <header>menu one header</header>
    <ul>
      <li>Item one</li>
      <li>Item two 2</li>
      <li>Item t(h)ree</li>
      <li>Item four</li>
    </ul>
  </div>
</div><div>menu two
  <div class="menu">
    <header>menu two header</header>
    <ul>
      <li>Item one</li>
      <li>Item two 2</li>
      <li>Item t(h)ree</li>
      <li>Item four</li>
      <li>Item five</li>
    </ul>
  </div>
</div>
&#13;
&#13;
&#13;

我希望有一天这对未来的读者有用。

也许有一种方法可以使用包装的双列flexbox来实现这一点,但是我的尝试失败了。

答案 4 :(得分:0)

我在这里使用此技巧,通过允许CSS知道有多少子级来“帮助” CSS何时中断以及达到多少列。

用CSS不可能做到这一点,因为CSS不了解元素的子代计数,因此它无法决定样式在树中应该向上。

但是,通过最少的javascript代码,只能通过以下方式在具有孩子数量的父对象上设置 smart 属性:“ 1 2 3 4 ...”,这样开发人员就可以充分使用能否根据容器的样式来设置容器的样式。

例如,如果存在6个以上的子代,则下面的代码分为2列:

.list > * {
  background: lightyellow;
  border-bottom: thin dotted;
  break-inside: avoid;
  
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* CSS decides to how many columns to break, depending on nodes count */
.list[data-count*=' 6'] {
    columns: 2;
}
<div class="list" data-count="1 2 3 4 5 6 7 8 9 10">
  <div>item 1</div>
  <div>item 2</div>
  <div>item 3</div>
  <div>item 4</div>
  <div>item 5</div>
  <div>item 6</div>
  <div>item 7</div>
  <div>item 8</div>
  <div>item item which is very long and needs trimming is quite common</div>
  <div>item 10</div>
</div>