仅使用 CSS 重构响应式设计中的部分

Restructuring sections in responsive design with only CSS

您将如何在移动版和桌面版布局中完全重组网页的各个部分? 我想实现类似下面的布局:

Desktop:
--------
Primary         |   Complementary 1
                |   Complementary 2
Secondary       |

Mobile:
-------
Complementary 1
Primary
Complementary 2
Secondary

注意:Desktop 中的分隔线应该是一条直线,Complementary 有一个固定的宽度和最大宽度,Primary/Secondary 填充页面的其余部分。此外,所有部分的高度都不同。还要注意移动设备中的交错顺序。 所有这些都阻止我使用简单的 flexbox 方法,使用 order 和 row/column 来实现这一点。

他们是我的看法:只有将两列都放在 div 中才能在桌面上实现清晰的水平分隔 - 但这从本质上阻碍了移动布局。 如果有一种方法可以完全忽略 div 到 css 的包装,那是可能的,但我从来没有想过。

任何想法都会受到赞赏 - 使用 Javascript 这当然是可能的,但如果有一个聪明的,或多或少的 CSS-only 解决方案,我会非常喜欢它。

如上面的评论所述,使用 CSS 声明 display: grid 并将其设置为所需大小的媒体查询可以相对轻松地实现这一点。

如果您首先按照希望将其显示为单列的方式构建内容(即 Complementary 1Primary、...),那么您可以简单地创建一个媒体查询a min-width (无论你想要什么最小宽度)然后使用网格相应地设置内容。例如:

/* Set grid layout for screens larger than 700px only */
@media (min-width: 700px) {
  .grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    grid-column-gap: 2em;
  }
  
  /* place sections into relevant columns/rows */
  .grid main {
    grid-column-start: 1;
    grid-row-start: 1;
  }
  
  .grid section {
    grid-column-start: 1;
    grid-row-start: 3;
  }
  
  .grid aside {
    grid-column-start: 2;
    grid-row-start: 1;
  }
  
  .grid main + aside {
    grid-column-start: 2;
    grid-row-start: 2;
  }
  
  /* Add a rule between the aside and the main content */
  aside {
    padding-left: 2em;
    border-left: 1px solid #aaa;
  }
}
<section class="grid">
  <aside>
    <p>Complementary 1</p>
  </aside>
  
  <main>
    <h1>Main content</h1>
    <p>Your main content can go here...</p>
  </main>
  
  <aside>
    <p>Complementary 2</p>
  </aside>
  
  <section>
    <h1>Secondary content</h1>
    <p>Your secondary content can go here...</p>
  </section>
</section>

需要注意的一件事是,在上面的示例中,您的 'secondary content' 似乎是从 'complementary' 内容下方开始的。我不确定这是否只是格式错误 - 如果这不是故意的,您可以适当调整 grid-row-start

编辑:

您可以使用 display: contain 使列与大小无关,但请注意 - pretty terrible 支持!如果可访问性不是特别关心的问题,这就足够了。

如果可访问性 一个问题,您可以使用 JavaScript 相对轻松地实现以下目标,并简单地包装 mainsection div 中的元素和另一个 div 中的 asides 元素,具体取决于屏幕大小。这将解决对 display: contain 的糟糕支持,这只会使有问题的元素 invisible 无论如何(因此使用 JavaScript 删除包装 <div> 将有效地做与设置相同的事情它到 display: contain 无论如何)。

希望这能给你一个前进的方向。

.grid {
  display: flex;
  flex-wrap: wrap;
}

.grid > div {
  display: contents;
}

.grid aside {
  order: 1;
}

.grid aside + aside {
  order: 3;
}

.grid main {
  order: 2;
}

.grid section {
  order: 4;
}

.grid main,
.grid section,
.grid aside {
  width: 100%;
}

/* Set grid layout for screens larger than 700px only */
@media (min-width: 700px) {
  .grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    grid-column-gap: 2em;
  }
  
  .grid > div {
    display: block;
  }
  
  /* Add a rule between the aside and the main content */
  .grid > div + div {
    padding-left: 2em;
    border-left: 1px solid #aaa;
  }
  
  /* Set order back to 0 */
  .grid section,
  .grid main,
  .grid aside {
    order: unset;
  }
}
<section class="grid">
  <div>
    <main>
      <h1>Main content</h1>
      <p>Your main content can go here...</p>
    </main>

    <section>
      <h1>Secondary content</h1>
      <p>Your secondary content can go here...</p>
    </section>
  </div>
  
  <div>
    <aside>
      <p>Complementary 1</p>
      <p>Complementary 1</p>
      <p>Complementary 1</p>
      <p>Complementary 1</p>
      <p>Complementary 1</p>
      <p>Complementary 1</p>
    </aside>

    <aside>
      <p>Complementary 2</p>
    </aside>
  </div>
</section>