使用 CSS 网格创建导航栏

时间:2021-04-19 01:18:55

标签: html css css-grid

我正在创建一个用 CSS 网格制作的导航栏。

我决定使用网格来制作它,这样我就可以重新排列部分(项目)而无需修改 html(只需修改 CSS)。

然后我创建了包含 3 个区域的网格:徽标、菜单、切换器。

而且我添加了一点间隙,这样每个项目就不会粘在一起。

enter image description here

到目前为止一切都很好,直到我尝试删除一个/一些部分,差距仍然存在,即使该部分已经消失。

然后我尝试消除间隙并替换为每个部分的边距。 但是边距不会在网格的开始/结束处崩溃。它的行为与常规块元素不同。

我知道使用 flexbox 比使用网格更实用,但我更喜欢网格,因为可以在不修改 html 的情况下重新排列该部分。可以将徽标移动到顶部或其他位置。使用 flex 做不到的事情。

谁能解决我的网格间隙问题?或者您可能有不同的方法来创建导航栏?

查看我的sandbox

.navbar {
  background: pink;
  display: grid;
  grid-template-rows: auto;
  grid-template-columns: max-content auto max-content;
  grid-template-areas: "logo menus toggler";
  justify-items: stretch;
  align-items: stretch;
  column-gap: 20px;
}

.logo {
  background: green;
  grid-area: logo;
  width: 60px;
}

.menus {
  background: lightsalmon;
  grid-area: menus;
  display: flex;
  flex-direction: row;
  justify-content: start;
}

.menus * {
  padding: 5px;
}

.toggler {
  background: lightskyblue;
  grid-area: toggler;
}
<p>navbar with complete sections:</p>
<nav class="navbar">
  <div class="logo">
    LoGo
  </div>
  <div class="menus">
    <div>menu-1</div>
    <div>menu-2</div>
    <div>menu-3</div>
  </div>
  <div class="toggler">
    X
  </div>
</nav>

<hr>

<p>navbar without logo:</p>
<nav class="navbar">
  <div class="menus">
    <div>menu-1</div>
    <div>menu-2</div>
    <div>menu-3</div>
  </div>
  <div class="toggler">
    X
  </div>
</nav>

<hr>

<p>navbar without toggler:</p>
<nav class="navbar">
  <div class="logo">
    LoGo
  </div>
  <div class="menus">
    <div>menu-1</div>
    <div>menu-2</div>
    <div>menu-3</div>
  </div>
</nav>

4 个答案:

答案 0 :(得分:1)

这绝对可以用 grid 来完成,你完全正确地认为 grid 能够看似重新排列 html 元素的优势。我认为问题在于您的列间隙适用于所有三种情况,因为它是您的导航栏类的一部分

.navbar {
    column-gap: 20px;
}

在下面的示例中,我使用相同的类创建了两个网格区域容器。我将列间隙应用于顶部容器,而不是底部容器。

我也用 justify-self: end 为左边的蓝色 div 向你展示列之间没有间隙,虽然你也可以使用 chrome dev 工具查看顶部网格有间隙,而底部没有。

.container {
  display: grid;
  grid-template-areas: "left center right";
  margin-bottom: 40px;
}
.top {
  column-gap: 20px;
}
.bottom{
  column-gap: 0;
}

.d1 {
  grid-area: left;
  background: red;
}

.d2 {
  grid-area: center;
  background: red;
}

.d3 {
  grid-area: right;
  background: red;
}

.d4 {
  grid-area: left;
  background: blue;
  justify-self: end;
}

.d5 {
  grid-area: center;
  background: blue;
}

.d1,
.d2,
.d3,
.d4,
.d5 {
  width: 200px;
  height: 50px;
}
<div class="container top">
  <div class="d1"></div>
  <div class="d2"></div>
  <div class="d3"></div>
</div>

<div class="container bottom">
  <div class="d4"></div>
  <div class="d5"></div>
</div>

答案 1 :(得分:1)

在这种情况下,您可以试试这个,而不是 column-gap: 20px;

nav > div:not(:first-child){
  margin-left:20px;
}

它为第一级 div 添加边距,并从选择中排除第一个 div。

.navbar {
  background: pink;
  display: grid;
  grid-template-rows: auto;
  grid-template-columns: max-content auto max-content;
  grid-template-areas: "logo menus toggler";
  justify-items: stretch;
  align-items: stretch;
}

nav > div:not(:first-child){
  margin-left:20px;
}

.logo {
  background: green;
  grid-area: logo;
  width: 60px;
}

.menus {
  background: lightsalmon;
  grid-area: menus;
  display: flex;
  flex-direction: row;
  justify-content: start;
}

.menus * {
  padding: 5px;
}

.toggler {
  background: lightskyblue;
  grid-area: toggler;
}
<p>navbar with complete sections:</p>
<nav class="navbar">
  <div class="logo">
    LoGo
  </div>
  <div class="menus">
    <div>menu-1</div>
    <div>menu-2</div>
    <div>menu-3</div>
  </div>
  <div class="toggler">
    X
  </div>
</nav>

<hr>

<p>navbar without logo:</p>
<nav class="navbar">
  <div class="menus">
    <div>menu-1</div>
    <div>menu-2</div>
    <div>menu-3</div>
  </div>
  <div class="toggler">
    X
  </div>
</nav>

<hr>

<p>navbar without toggler:</p>
<nav class="navbar">
  <div class="logo">
    LoGo
  </div>
  <div class="menus">
    <div>menu-1</div>
    <div>menu-2</div>
    <div>menu-3</div>
  </div>
</nav>

答案 2 :(得分:1)

在这种情况下,您可以依赖隐式列。您只定义一个显式列,并且只有在元素存在时才创建新列。您也可以轻松地与问题交换位置

.navbar {
  background: pink;
  display: grid;
  grid-template-rows: auto;
  grid-template-columns: 1fr; /* only column intially */
  grid-auto-flow:dense;
  justify-items: stretch;
  align-items: stretch;
  column-gap: 20px;
}

.logo {
  background: green;
  width: 60px;
  grid-column:-3; /* create an implicit one at the beginning */
}

.menus {
  background: lightsalmon;
  display: flex;
  flex-direction: row;
  justify-content: start;
  grid-column: 1; /* take the explicit one */
}

.menus * {
  padding: 5px;
}

.toggler {
  background: lightskyblue;
  grid-column:2; /* create an implicit one at the end */
}
<p>navbar with complete sections:</p>
<nav class="navbar">
  <div class="logo">
    LoGo
  </div>
  <div class="menus">
    <div>menu-1</div>
    <div>menu-2</div>
    <div>menu-3</div>
  </div>
  <div class="toggler">
    X
  </div>
</nav>

<hr>

<p>navbar without logo:</p>
<nav class="navbar">
  <div class="menus">
    <div>menu-1</div>
    <div>menu-2</div>
    <div>menu-3</div>
  </div>
  <div class="toggler">
    X
  </div>
</nav>

<hr>

<p>navbar without toggler:</p>
<nav class="navbar">
  <div class="logo">
    LoGo
  </div>
  <div class="menus">
    <div>menu-1</div>
    <div>menu-2</div>
    <div>menu-3</div>
  </div>
</nav>

<hr>
<p>navbar without toggler and log at the end </p>
<nav class="navbar">
  <div class="logo" style="grid-column:2">
    LoGo
  </div>
  <div class="menus">
    <div>menu-1</div>
    <div>menu-2</div>
    <div>menu-3</div>
  </div>
</nav>

<hr>

<p>navbar without logo and toogler at the beginning </p>
<nav class="navbar">
  <div class="menus">
    <div>menu-1</div>
    <div>menu-2</div>
    <div>menu-3</div>
  </div>
  <div class="toggler" style="grid-column:-3">
    X
  </div>
</nav>

答案 3 :(得分:0)

您可以只为每个不同的导航创建 css 规则,因为如果您为每个导航类使用相同的类,则网格模板列和网格模板区域在某种程度上是烘焙的。

grid-template-columns: max-content auto max-content;
grid-template-areas: "logo menus toggler";

正在寻找三列之间的差距。

如果您编辑每个导航以匹配每个元素列的内容,它将正确显示而无需任何修改。

.navbar1 {
  background: pink;
  display: grid;
  grid-template-rows: auto;
  grid-template-columns: max-content auto max-content;
  grid-template-areas: "logo menus toggler";
  justify-items: stretch;
  align-items: stretch;
  column-gap: 20px;
}

.navbar2 {
  background: pink;
  display: grid;
  grid-template-rows: auto;
  grid-template-columns: auto max-content ;
  grid-template-areas: "menus toggler";
  justify-items: stretch;
  align-items: stretch;
  column-gap: 20px;
}

.navbar3 {
  background: pink;
  display: grid;
  grid-template-rows: auto;
  grid-template-columns: max-content auto;
  grid-template-areas: "logo menus";
  justify-items: stretch;
  align-items: stretch;
  column-gap: 20px;
}

.logo {
  background: green;
  grid-area: logo;
  width: 60px;
}

.menus {
  background: lightsalmon;
  grid-area: menus;
  display: flex;
  flex-direction: row;
  justify-content: start;
}

.menus * {
  padding: 5px;
}

.toggler {
  background: lightskyblue;
  grid-area: toggler;
}
<p>navbar with complete sections:</p>
<nav class="navbar1">
  <div class="logo">
    LoGo
  </div>
  <div class="menus">
    <div>menu-1</div>
    <div>menu-2</div>
    <div>menu-3</div>
  </div>
  <div class="toggler">
    X
  </div>
</nav>

<hr>

<p>navbar without logo:</p>
<nav class="navbar2">
  <div class="menus">
    <div>menu-1</div>
    <div>menu-2</div>
    <div>menu-3</div>
  </div>
  <div class="toggler">
    X
  </div>
</nav>

<hr>

<p>navbar without toggler:</p>
<nav class="navbar3">
  <div class="logo">
    LoGo
  </div>
  <div class="menus">
    <div>menu-1</div>
    <div>menu-2</div>
    <div>menu-3</div>
  </div>
</nav>