css - 在 CSS Grid 中相互流动的元素
问题描述
有没有更自动的方式让数据围绕元素流动?我觉得我已经非常接近 CSS Grid 了,但是 Grid 中有很多我还没有找到的角落和缝隙,所以也许我只需要添加一些额外的规则。
这是我正在尝试做的事情:
- 在右侧显示一个元素
- 让其他元素围绕它流动
这将非常类似于在 MS Word 或 Google Docs 中,您在右上角有一个图像,所有文本都围绕它流动,但使用元素而不是文本。
我在下面的片段中所拥有的主要是我想要的,但以下情况除外:
当第一个
section
很短时,有足够的空间放置第 4 个部分aside
。使用当前方法要使其正常工作,我需要更改grid-row: 1 / 4
为grid-row: 1 / 5
并添加aside ~ section:nth-of-type(4)
到窄列表中sections
。当第一个
section
很高时,section
它下面的一个 s 远远超过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>
解决方案
看起来这个问题最简单的解决方案是使用 good oldfloat
属性,这会导致其他元素“开箱即用”地围绕给定元素流动。唯一需要添加的是使这些部分建立新的块格式上下文,以防止它们与浮动元素重叠(display: block
默认情况下元素会这样做)。有几种方法可以做到这一点,包括标准(但不幸的是,还不是跨浏览器)解决方案 - 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>
推荐阅读
- android - Android 应用程序 - 内部存储保存未显示
- android - menu.xml 中定义的可绘制矢量图标未显示在 appBar 中?
- ios - backBarButtonItem 显示图片不正确
- vue.js - VUE 观看和道具
- bash - BASH:打印制表符分隔文件中唯一元素的总数
- asp.net - 在 web.config 中插入 URL 重写规则后出现错误 404?
- python - 在 Pandas 中打印 dataFrame 时获取 UserWarning: Boolean Series
- python - 有没有办法从树的转储文件中恢复 AST 树?
- prestashop - 如何创建触发代码添加/编辑/删除产品/类别的 prestashop 模块
- python-3.x - 将列表分成块的更快方法