CSS网格布局中,针对某些列使用固定宽度

5
我正在尝试使用CSS网格布局来实现这种布局。
图片:

enter image description here

这是我目前为止的内容:

#wrapper {
    display: grid;
    gap: 20px;
    grid-template-columns: auto 300px 1fr 1fr 180px auto;
    grid-template-rows: auto;
    grid-template-areas: 
    "logo nav-primary nav-primary nav-primary nav-primary search"
    "nav-secondary nav-secondary nav-secondary nav-secondary nav-secondary nav-secondary"
    "aside-1 aside-1 article article aside-2 aside-2"
    "footer footer footer footer footer footer";
}

/* Article: use up remaining width */
#article{
    grid-area: article;
}

/* Logo: use up a little width as possible */
#logo{
    grid-area: logo;
}

/* Nav Primary: use up remaining width */
#nav-primary{
    grid-area: nav-primary;
}

/* Nav Secondary: use full width */
#nav-secondary{
    grid-area: nav-secondary;
}

/* Search: use up a little width as possible */
#search{
    grid-area: search;
}

/* Aside 1: fixed with of 300px */
#aside-1{
    grid-area: aside-1;
}

/* Aside 2: fixed with of 180px */
#aside-2{
    grid-area: aside-2;
}

/* Footer: use full width */
#footer{
    grid-area: footer;
}

/* Demo style */
#wrapper > * {
    background: #C4C4C4;
    padding: 10px;
}
<div id="wrapper">
    <article id="article">Article (use up remaining space)</article>
    <header id="logo">Logo</header>
    <nav id="nav-primary">Nav Primary</nav>
    <nav id="nav-secondary">Nav Secondary</nav>
    <form id="search">Search Form</form>
    <aside id="aside-1">Aside 1 (fixed width: 300px)</aside>
    <aside id="aside-2">Aside 2 (fixed width: 180px)</aside>
    <footer id="footer">Footer</footer>
</div>

Codepen: https://codepen.io/aobrien/pen/YzwNZpy

问题在于 Aside1 的宽度不是 300px, 而是 300px 加上 logo 栏目的宽度。Aside2 同理,它的宽度是 180px 加上搜索栏目的宽度。 我似乎不能为 Aside1 和 Aside2 设置固定宽度,同时使 logo 和搜索的宽度动态适应其内容且尽可能小。

logo 方框必须始终尽可能小地适应其内容。搜索也同样要求尽可能小。

Aside1 需要有一个固定的宽度为 300px,而 Aside2 需要有一个固定的宽度为 180px

我的唯一规定是,不能更改当前 HTML 结构,因此不能嵌套这些项。但是,我可以添加新的 HTML 元素到当前元素中,其中可能包含一个固定的宽度(如果有帮助的话?)。

我不必依赖于grid-template-areas,它可以是显式或隐式网格。如果有帮助的话,它也可以包含更多列。欢迎对CSS进行任何更改。
到目前为止,我似乎唯一的解决方案(这不是我想要的解决方案)是给标志和搜索分配固定宽度,然后计算剩余宽度以实现Aside1和Aside2的宽度。然而,这真的不是我想要的,因为我希望尽可能保持动态性,而不需要在整个布局中手动设置多个固定宽度。
我尝试的另一个解决方案是,而不是通过grid-template-columns定义Aside1的固定宽度,我可以在Aside1内部创建一个新的div,并将其宽度设置为width: 300px,并为该列设置grid-template-columnsauto。这确实有效,除非标志变得比300像素宽,否则Aside1也会变得比300像素宽。
有人有什么解决方案或指针可以帮助我吗?
1个回答

7

首先,您有6个列,但是我们可以为这项任务只保留5个。其次,如果我们将使用单元格合并,则不需要在grid-template-columns中设置固定宽度。对于特定的列来说,设置固定宽度更容易。就这样。

#wrapper {
  display: grid;
  gap: 15px;
  grid-template-columns: auto auto 1fr auto auto;
  grid-template-rows: auto;
 grid-template-areas: 
    "logo nav-primary nav-primary nav-primary search"
    "nav-secondary nav-secondary nav-secondary nav-secondary nav-secondary"
    "aside-1 aside-1 article aside-2 aside-2"
    "footer footer footer footer footer";
}


/* Article: use up remaining width */

#article {
  grid-area: article;
}


/* Logo: use up a little width as possible */

#logo {
  grid-area: logo;
  max-width: 300px;
}


/* Nav Primary: use up remaining width */

#nav-primary {
  grid-area: nav-primary;
}


/* Nav Secondary: use full width */

#nav-secondary {
  grid-area: nav-secondary;
}


/* Search: use up a little width as possible */

#search {
  grid-area: search;
  max-width: 180px;
}


/* Aside 1: fixed with of 300px */

#aside-1 {
  grid-area: aside-1;
  width: 300px;
}


/* Aside 2: fixed with of 180px */

#aside-2 {
  grid-area: aside-2;
  width: 180px;
}


/* Footer: use full width */

#footer {
  grid-area: footer;
}


/* Demo style */

#wrapper>* {
  background: #C4C4C4;
  padding: 10px;
  box-sizing: border-box;
}
<div id="wrapper">
  <article id="article">Article (use up remaining space)</article>
  <header id="logo">Logo</header>
  <nav id="nav-primary">Nav Primary</nav>
  <nav id="nav-secondary">Nav Secondary</nav>
  <form id="search">Search Form</form>
  <aside id="aside-1">Aside 1 (fixed width: 300px)</aside>
  <aside id="aside-2">Aside 2 (fixed width: 180px)</aside>
  <footer id="footer">Footer</footer>
</div>

请注意,此情况下您的 Logo 宽度应小于 300 像素。搜索框应小于 180 像素宽度。如果您希望搜索框宽度大于 180 像素,我们需要稍微编辑一下代码。

#wrapper {
  display: grid;
  gap: 15px;
  grid-template-columns: auto auto 1fr auto auto auto;
  grid-template-rows: auto;
 grid-template-areas: 
    "logo nav-primary nav-primary search search search"
    "nav-secondary nav-secondary nav-secondary nav-secondary nav-secondary nav-secondary"
    "aside-1 aside-1 article article aside-2 aside-2"
    "footer footer footer footer footer footer";
}


/* Article: use up remaining width */

#article {
  grid-area: article;
}


/* Logo: use up a little width as possible */

#logo {
  grid-area: logo;
  max-width: 300px;
}


/* Nav Primary: use up remaining width */

#nav-primary {
  grid-area: nav-primary;
}


/* Nav Secondary: use full width */

#nav-secondary {
  grid-area: nav-secondary;
}


/* Search: use up a little width as possible */

#search {
  grid-area: search;
}


/* Aside 1: fixed with of 300px */

#aside-1 {
  grid-area: aside-1;
  width: 300px;
}


/* Aside 2: fixed with of 180px */

#aside-2 {
  grid-area: aside-2;
  width: 180px;
}


/* Footer: use full width */

#footer {
  grid-area: footer;
}


/* Demo style */

#wrapper>* {
  background: #C4C4C4;
  padding: 10px;
  box-sizing: border-box;
}
<div id="wrapper">
  <article id="article">Article (use up remaining space)</article>
  <header id="logo">Logo</header>
  <nav id="nav-primary">Nav Primary</nav>
  <nav id="nav-secondary">Nav Secondary</nav>
  <form id="search">Search Form</form>
  <aside id="aside-1">Aside 1 (fixed width: 300px)</aside>
  <aside id="aside-2">Aside 2 (fixed width: 180px)</aside>
  <footer id="footer">Footer</footer>
</div>


好的答案。请注意,您可以将logo的最大宽度设置为300像素。 - vals
是的,非常感谢!已将其添加到答案中。搜索也是同样的道理。 - focus.style
太棒了,谢谢。但是,如果徽标比300像素宽怎么办?有简单的解决方案吗?我能想到的唯一解决方案是让徽标跨越2列,而aside1跨越1列(基本上颠倒它们)。我想不出更简单(动态)的解决方案,当徽标的宽度超过aside1的宽度时,不需要改变列数。 - Aedan
你可以添加 #logo {max-width: 300px;}#logo img {width: 100%;} 来控制标志的宽度不超过300像素。使用grid没有这样灵活的选项。你的标志应该是小于300像素或大于300像素的宽度,而不是两者都有。但我不认为标志会那么宽。在我过去12年的所有项目中,没有一个标题标志超过290像素宽。你说没有可能重写HTML。但是,它是否可以通过JS在浏览器中重写?如果可以,我可以为您编写最灵活的JS解决方案。 - focus.style
谢谢。我不能将标志限制在300像素内。有些网站将网站标题作为文本包含在内,这可能超过300像素。我无法在此项目中使用JS,我的目标是仅使用CSS网格并具有简化的HTML结构,而不进行嵌套。我试图创建一个HTML结构,通过只进行CSS更改即可创建所有可能的网站布局。我想唯一现实的解决方案是制作一个不同的HTML结构,但我真的想避免这样做。我最终可能会将aside1、aside2和article包装在单独的网格中。这样列就不会互相影响了。 - Aedan
好的,这将是最正确的方式-将页眉与侧边栏的文章分开。如果您需要,我可以为此编写代码。 - focus.style

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接