如何在CSS多列布局中居中单列

时间:2017-02-02 00:05:25

标签: css css-multicolumn-layout

我有一个使用CSS多列布局的元素来显示项目列表。

<div style="column-width: 300px; column-count: 3; text-align: center;">
    <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>

示例列表正确显示为三列,每列包含两个项目,每个项目都在其列中居中。

但是,当我有一个只包含一个项目的列表时,该项目显示在第一列中,而第二列和第三列的空间仍然保持为空。

有没有办法让单列在父元素中居中?同样,如果我只有两个项目的列表,是否有办法使两个填充列在父元素中居中?

基本上,我想要的是,如果有三个或更多项,则显示三列,但如果只有一个或两个项,则只显示显示这些项所需的列数而不保留未使用的列空间。

修改

问题是我的列表中只有一个项目,例如:

<div style="column-width: 300px; column-count: 3; text-align: center;">
    <div>Item 1</div>
</div>

单个项目位于第一列,而第二列和第三列的空间仍然保留,即使那里没有内容。

2 个答案:

答案 0 :(得分:2)

我创造了一个小提琴:https://jsfiddle.net/Lvtya3qL/

<div class="parent">
    <div class="child">Item 1</div>
    <div class="child">Item 2</div>
    <div class="child">Item 3</div>
    <div class="child">Item 4</div>
    <div class="child">Item 5</div>
    <div class="child">Item 6</div>
    <div class="child">Item 7</div>
</div>

.parent{
  display:flex;
  width: 300px;
  flex-wrap: wrap;
  justify-content: center;
}

.child {
  width: 100px;
}

答案 1 :(得分:0)

我没有打算回答这个问题,因为我面临的问题是不同的。但是后来我注意到,这里唯一的答案是抛弃columns并切换到flexbox,这做了完全不同的事情,从而使这个问题没有得到解决。

我做了一个实现,您可以在下面找到。我还添加了第四列,以便更清楚地了解CSS :nth-child(n):nth-last-child(n)部分的工作。

您会看到有3个奇数选择器,所有选择器都在左侧添加了inset,因此所有子代都居中。您可以继续将这些选择器添加到所需的更多列中。您需要的选择器数量就是列的数量-1。

在进行3列搜索时,您可以删除最后一个看起来奇怪的选择器。
如前所述,我已经添加了第四列,以便您可以看到需要应用的选择器模式才能使它起作用。

.parent {
  --columns: 4;
  --gap:     1em;
  column-count: var(--columns);
  column-gap:   var(--gap);
}

.child {
  position: relative;
  break-inside: avoid;
  break-inside: avoid-column;
}

.child:only-child {
  left: calc((100% + var(--gap)) * (var(--columns) - 1) / 2);
}

.child:nth-child(1):nth-last-child(2),
.child:nth-child(2):nth-last-child(1) {
  left: calc((100% + var(--gap)) * (var(--columns) - 2) / 2);
}

.child:nth-child(1):nth-last-child(3),
.child:nth-child(2):nth-last-child(2),
.child:nth-child(3):nth-last-child(1) {
  left: calc((100% + var(--gap)) * (var(--columns) - 3) / 2);
}

/* Prettifications only */

body {
  margin: 0;
  font-family: sans-serif;
}

.parent {
  margin: var(--gap);
  text-align: center;
}

.child {
  padding: 8px 0;
  background-color: rgba(127,127,127,.1);
  outline: 1px solid black;
  outline-offset: -1px;
}
<div class="parent">
    <div class="child">1</div>
</div>
<div class="parent">
    <div class="child">1</div>
    <div class="child">2</div>
</div>
<div class="parent">
    <div class="child">1</div>
    <div class="child">2</div>
    <div class="child">3</div>
</div>
<div class="parent">
    <div class="child">1</div>
    <div class="child">2</div>
    <div class="child">3</div>
    <div class="child">4</div>
</div>

但是,这有一个很大的缺点。它本身不再响应!

我删除了column-width,这可能会使该实现对您的情况毫无用处,因为column-width属性以前只负责使整个响应过程负责。但是,如果可以手动添加断点可以,那么我认为这是实现居中的多列布局的唯一方法之一。

添加断点最好如下:

@media all and (min-width: 500px) {
  .parent { --columns: 2 }

  .child:only-child {
    left: calc((100% + var(--gap)) * (var(--columns) - 1) / 2);
  }
}

@media all and (min-width: 600px) {
  .parent { --columns: 3 }

  .child:nth-child(1):nth-last-child(2),
  .child:nth-child(2):nth-last-child(1) {
    left: calc((100% + var(--gap)) * (var(--columns) - 2) / 2);
  }
}

@media all and (min-width: 700px) {
  .parent { --columns: 4 }

  .child:nth-child(1):nth-last-child(3),
  .child:nth-child(2):nth-last-child(2),
  .child:nth-child(3):nth-last-child(1) {
    left: calc((100% + var(--gap)) * (var(--columns) - 3) / 2);
  }
}

通过这种方式,仅在需要 时才应用样式。另外:请记住按此顺序进行媒体查询。媒体查询越高,--columns变量的值就越高。