css - CSS 网格中彼此围绕的流动元素

标签 css css-grid

是否有更自动的方式让数据在元素周围流动?我觉得我已经非常熟悉 CSS Grid,但是 Grid 中有很多我还没有发现的 Angular 落和缝隙,所以也许我只需要添加一些额外的规则。

这就是我正在尝试做的事情:

  1. 在右侧显示元素
  2. 让其他元素围绕它流动

这与 MS Word 或 Google Docs 中的情况非常相似,其中右上角有一个图像,所有文本都围绕它流动,但使用的是元素而不是文本。

下面的代码片段中的大部分内容都是我想要的,但有以下异常(exception):

  1. 当第一个部分很短时,旁边有足够的空间容纳第四部分。使用当前方法,为了使其工作,我需要将 grid-row: 1/4 更改为 grid-row: 1/5,并添加 aside ~section:nth-of-type(4) 到窄部分列表。

  2. 当第一个 section 很高时,其下面的一个 section 会远远超过 aside,因此它应该占据完整的 5 个网格列。

在此片段中,高度是静态的,但在现实世界中它们将是动态的。有没有更自动的方法来使用 CSS Grid 解决这个问题?我能想到的唯一其他方法是使用 javascript 检测大小并根据各种元素的高度添加类或内联 css。

document.querySelector('button').addEventListener('click', () => {
  const aside = document.querySelector('aside');
  if (aside) {
    aside.remove();
  } else {
    document.querySelector('main').prepend(document.createElement('aside'));
  }
});

document.querySelector('a').addEventListener('click', (event) => {
  event.target.parentElement.classList.toggle('tall');
});
main {
  display: grid;
  padding: 5px;
  margin: 5px;
  grid-gap: 5px;
  background-color: gray;
  
  grid-template-columns: repeat(5, 1fr);
}

aside {
  height: 120px;
  background-color: green;
  
  grid-column: 4 / 6;
  grid-row: 1 / 4;
}

section {
  height: 20px;
  background-color: white;
  
  grid-column-end: span 5;
}

section.tall {
  height: 100px;
}

aside ~ section:nth-of-type(1),
aside ~ section:nth-of-type(2),
aside ~ section:nth-of-type(3) {
  grid-column-end: span 3;
}
<button>Toggle Aside</button>
<main>
  <aside></aside>
  <section><a href="javascript://">Toggle Height</a></section>
  <section></section>
  <section></section>
  <section></section>
  <section></section>
  <section></section>
</main>

最佳答案

看起来这个问题最简单的解决方案是使用旧的 float 属性,这会导致其他元素“开箱即用”地围绕给定元素流动。唯一需要添加的是使这些部分建立新的 block 格式上下文,以防止它们与 float 元素重叠(就像 display: block 元素默认情况下所做的那样)。有several ways为此,包括标准(但不幸的是,还不能跨浏览器)解决方案 - display: flow-root

document.querySelector('button').addEventListener('click', () => {
  const aside = document.querySelector('aside');
  if (aside) {
    aside.remove();
  } else {
    document.querySelector('main').prepend(document.createElement('aside'));
  }
});

document.querySelector('a').addEventListener('click', (event) => {
  event.target.parentElement.classList.toggle('tall');
});
main {
  /* the display:flow-root alternative with the best balance
     between browser support and unwanted side effects (IMO).
     Other alternatives live comparison: https://codepen.io/SelenIT/pen/qrORXm */
  column-count: 1;

  padding: 5px 5px 0;
  margin: 5px;
  background-color: gray;
}

aside {
  height: 120px;
  width: calc((100% - 20px) * 0.4); /* 2/5 of (100% - 4 gaps of 5px each) */
  background-color: green;
  margin: 0 0 5px 5px;
  float: right;
}

section {
  column-count: 1;
  height: 20px;
  background-color: white;
  margin-bottom: 5px;
}

section.tall {
  height: 100px;
}
<button>Toggle Aside</button>
<main>
  <aside></aside>
  <section><a href="javascript://">Toggle Height</a></section>
  <section></section>
  <section></section>
  <section></section>
  <section></section>
  <section></section>
</main>

关于css - CSS 网格中彼此围绕的流动元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51331251/

相关文章:

jquery - 响应式导航在响应模式下激活时搞砸了,然后再次调整大小

html - 删除 font awesome 下方的填充(CSS 图标)

javascript - 为类和媒体查询定义暗模式,无需重复 CSS 自定义属性声明,并允许用户在颜色模式之间切换

html - 我可以让内容显示在只有一个 div 的 CSS 网格布局的中间列中吗?

jquery - 在滚动条上隐藏导航栏 - 平板电脑

html - 如何合并重复函数的 Jquery 选择器?

css - 根据 child 的长宽比调整网格列的大小

html - 两列卡片布局,每隔一行使用 css-grid 的双宽度卡片?

CSS 网格元素重叠

css - Flexbox覆盖的区域,很难或不可能通过网格实现