使用CSS Grid或Flexbox对一个项目中的一个项目进行居中对齐

时间:2018-03-24 14:20:20

标签: html css css3 flexbox css-grid

是否可以在不调整标记和使用CSS Grid或Flexbox的情况下实现以下布局?

+-------------------------+
||           ||          ||
|+-+         +-----------+|
|                         |
|                         |
|                         |
+-------------------------+

行中有两个项目,第一个对齐左,第二个对齐到页面的中心,并将剩余的宽度填充到右侧。我尝试了各种方法,例如没有宽度的空第3个网格项目,但没有运气。这是我的最后一次尝试并很好地展示了这个问题。

header {
  display: grid;
  grid-template-columns: auto auto;
  justify-items: stretch;
}

ul {
  display: flex;
}

li:last-child {
  margin-left: auto;
}


/* for demo only */

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

li {
  padding: 5px;
  background: #aaa;
}

p {
  text-align: center;
}
<header>
  <span>Title</span>
  <nav>
    <ul>
      <li>Link 1</li>
      <li>Link 2</li>
      <li>Link 3</li>
    </ul>
  </nav>
</header>
<p>| true center |</p>

3 个答案:

答案 0 :(得分:1)

这种布局对于CSS Grid subgrid 功能来说是一个完美的用例场景,它允许子网之外的网格容器的后代识别顶级网格容器线。 / p>

不幸的是,主流浏览器都没有支持此功能。 Technical development has been deferred目前正在考虑CSS Grid Layout Module Level 2

更多信息:Positioning content of grid items in primary container (subgrid feature)

如果没有subgrid,Flex和Grid仍然可以进行布局,但它可能会变得有些复杂,并且在某些情况下可能会中断。例如,使用Flex / Grid,两个外部项目可以固定到边缘,没问题。但是,根据屏幕尺寸和其他因素,两个内部项目可能居中,接近中心或偏离中心。

如果您在某些情况下稍微偏离中心,那么Flex / Grid可能适合您。实际上,您可以通过媒体查询,负边距,translate()属性的transform函数或其组合来解决问题。再次,它变得复杂。

仅使用CSS,最简单的解决方案是使用绝对定位。

(HTML没有变化。)

header, nav {
  position: relative;
}

ul {
  display: flex;
  justify-content: center;
}

li:last-child {
  position: absolute;
  right: 0;
}

span {
  position: absolute;
  left: 0;
}


/* for demo only */
ul {
  padding: 0;
  margin: 0;
  list-style: none;
}
li {
  padding: 5px;
  background: #aaa;
}
p {
  text-align: center;
}
<header>
  <span>Title</span>
  <nav>
    <ul>
      <li>Link 1</li>
      <li>Link 2</li>
      <li>Link 3</li>
    </ul>
  </nav>
</header>
<p>| true center |</p>

顺便说一句,由于您使用的是语义上有价值的nav元素,因此实际上不需要使用无序列表。这是一个更简单的版本:

header, nav {
  position: relative;
}

nav {
  display: flex;
  justify-content: center;
}

nav > div:last-child {
  position: absolute;
  right: 0;
}

header > div {
  position: absolute;
  left: 0;
}


/* for demo only */
nav > div {
  padding: 5px;
  background: #aaa;
}
p {
  text-align: center;
}
<header>
  <div>Title</div>
  <nav>
      <a>Link 1</a>
      <a>Link 2</a>
      <a>Link 3</a>
  </nav>
</header>
<p>| true center |</p>

答案 1 :(得分:0)

我在第二个li上添加了一个类.spacer,以便给它一个flex-grow,让它自动占用所有空白区域,从而将最后一个元素推向右边。

还将标题样式更改为grid-template-columns: 1fr 1fr;,以便两个元素都占据宽度的一半。

&#13;
&#13;
header {
  display: grid;
  grid-template-columns: 0.71fr 1fr;
  justify-items: stretch;
}

ul { display: flex; }
li.spacer{flex-grow: 1;} /* or li:nth-child(2) if you cannot add a class to the html tags */

/* for demo only */
ul { padding: 0; margin: 0; list-style: none; }
li a{ padding: 5px; background: #aaa; }
p  { text-align: center; }
&#13;
<header>
	<span>Title</span>
	<nav>
		<ul>
			<li><a href="#">Link 1</a></li>
			<li class="spacer"><a href="#">Link 2</a></li>
			<li><a href="#">Link 3</a></li>
		</ul>
	</nav>
</header>
<p>| true center |</p>
&#13;
&#13;
&#13;

答案 2 :(得分:0)

这是 hacky 的想法:

&#13;
&#13;
header {
  display: flex;
}
header span {
  min-width:0;
  width:0;
  flex-basis:0%;
  white-space:nowrap;
}
nav {
   margin-left: auto;
   flex-basis:100%;
}
ul {
  display: flex;
}

li:first-child {
  margin-left: auto;
}
li:nth-child(2) {
  margin-right:auto;
}

li:last-child {
  position:absolute;
  right:0;
}

/* for demo only */

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

li {
  padding: 5px;
  background: #aaa;
}

p {
  text-align: center;
}
&#13;
<header>
  <span>Title Title</span>
  <nav>
    <ul>
      <li>Link 1</li>
      <li>Link 2</li>
      <li>Link 3</li>
    </ul>
  </nav>
</header>
<p>| true center |</p>
&#13;
&#13;
&#13;