假设我想在CSS网格布局中使用自动密集打包。有没有办法引入非矩形区域配置?例如,L形区域在一行中覆盖两列而在下一行中仅覆盖一列。我已经尝试明确命名网格单元但是这不起作用。
答案 0 :(得分:4)
不支持非矩形网格项。来自spec:
每个网格项都与网格区域相关联,网格区域是网格项占据的一组矩形相邻网格单元格。
And:
注意:在此模块的未来版本中可能允许使用非矩形或断开连接的区域。
(这并不意味着已经计划了这样的功能,只是没有任何停止将来添加这样的功能)
答案 1 :(得分:1)
我的解决方案是创建相互重叠的网格容器,然后使用浮动来掩盖覆盖的区域。以及一些 JavaScript 来调整滚动时这些浮动的位置。
const setStyleProperty = (prop, val) => document.documentElement.style.setProperty(prop, val);
const setScrollbarWidth = () => {
const content = $("#center");
const innerWidth = content.innerWidth();
const width = content.width();
const left = parseFloat(content.css("padding-left"));
const right = parseFloat(content.css("padding-right"));
const scrollbarWidth = innerWidth - width - left - right || 0;
setStyleProperty("--scrollbar-width", scrollbarWidth + "px");
};
const onScroll = (event) => {
const id = event.target.id;
const scrollTop = event.target.scrollTop;
let offset = 0;
if (id.match(/^top/)) { offset = $(`#${id}`).height() / 2; }
setStyleProperty(`--${id}-top`, offset + scrollTop + "px");
};
$(document).ready(function () {
const topLeft = $("#top-left");
const topRight = $("#top-right");
const bottomLeft = $("#bottom-left");
const bottomRight = $("#bottom-right");
const topLeftSpan = topLeft.children("span").eq(0);
const topRightSpan = topRight.children("span").eq(0);
const bottomLeftSpan = bottomLeft.children("span").eq(0);
const bottomRightSpan = bottomRight.children("span").eq(0);
const centerSpan = $("#center>span");
for (i = 1; i < 501; i++) {
topLeftSpan.html(topLeftSpan.html() + `p-shaped grid (${i}) `);
topRightSpan.html(topRightSpan.html() + `q-shaped grid (${i}) `);
bottomLeftSpan.html(bottomLeftSpan.html() + `b-shaped grid (${i}) `);
bottomRightSpan.html(bottomRightSpan.html() + `d-shaped grid (${i}) `);
centerSpan.html(centerSpan.html() + `All work and no play makes Jack a dull boy. `);
}
topLeft.on("scroll", onScroll);
topRight.on("scroll", onScroll);
bottomLeft.on("scroll", onScroll);
bottomRight.on("scroll", onScroll);
$(window).on("resize", function () {
setScrollbarWidth();
topLeft.trigger("scroll");
topRight.trigger("scroll");
bottomLeft.trigger("scroll");
bottomRight.trigger("scroll");
}).trigger("resize");
});
:root {
/* Dynamically adjust border width & content padding to desired values. */
--border-width: 12px;
--padding: 4px;
/* Default scrollbar width. JS code will adjust as necessary. */
--scrollbar-width: 17px;
/* Variables for control height position on outside-shape floats. JS code will adjust as necessary when scrolling */
--top-left-top: 50%;
--top-left-offset: calc(var(--top-left-top) - var(--padding) - (var(--border-width) * 0.25));
--top-right-top: 50%;
--top-right-offset: calc(var(--top-right-top) - var(--padding) - (var(--border-width) * 0.25));
--bottom-right-top: 0px;
--bottom-left-top: 0px;
/* Formulas to properly scale floats to pad L-shaped content around center grid according to dynamic values. */
--void-padding-left-right: calc(var(--padding) + var(--border-width) * 0.25 + (var(--scrollbar-width) * 0.5));
--void-padding-bottom: calc(var(--padding) * 2 + var(--border-width) * 0.25);
}
* {
color: #FFF;
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
font-size: 10pt;
}
body {
margin: 0;
}
.grid-container {
display: grid;
grid-template-columns: 1fr 1fr 1fr 1fr;
grid-template-rows: 1fr 1fr 1fr 1fr;
height: 100vh;
width: 100vw;
}
.grid-container>div {
position: relative;
overflow-x: hidden;
overflow-y: scroll;
border-color: slategrey;
border-style: solid;
border-width: var(--border-width);
padding: var(--padding);
}
.grid-container>div>div {
/* Uncomment background-color to view floats controlling padding. */
/* background-color: rgba(0, 0, 0, 0.5); */
position: relative;
}
#top-left {
grid-area: 1 / 1 / 3 / 3;
background-color: red;
border-width: var(--border-width) calc(var(--border-width) * 0.5) calc(var(--border-width) * 0.5) var(--border-width);
direction: rtl;
text-align: left;
}
#top-left>div {
shape-outside: inset(var(--top-left-offset) 0 0 0);
float: right;
top: var(--top-left-offset);
height: 50%;
width: 50%;
margin-bottom: var(--top-left-offset);
padding: 0 0 var(--void-padding-bottom) var(--void-padding-left-right);
}
#top-right {
grid-area: 1 / 3 / 3 / 5;
background-color: purple;
border-width: var(--border-width) var(--border-width) calc(var(--border-width) * 0.5) calc(var(--border-width) * 0.5);
}
#top-right>div {
shape-outside: inset(var(--top-right-offset) 0 0 0);
float: left;
top: var(--top-right-offset);
height: 50%;
width: 50%;
margin-bottom: var(--top-right-offset);
padding: 0 var(--void-padding-left-right) var(--void-padding-bottom) 0;
}
#bottom-left {
grid-area: 3 / 1 / 5 / 3;
background-color: orange;
border-width: calc(var(--border-width) * 0.5) calc(var(--border-width) * 0.5) var(--border-width) var(--border-width);
direction: rtl;
text-align: left;
}
#bottom-left>div {
shape-outside: inset(var(--bottom-left-top) 0 0 0);
float: right;
height: calc(var(--bottom-left-top) + 50%);
width: 50%;
padding: 0 0 var(--void-padding-bottom) var(--void-padding-left-right);
margin-top: calc(var(--padding) * -1);
}
#bottom-right {
grid-area: 3 / 3 / 5 / 5;
background-color: green;
border-width: calc(var(--border-width) * 0.5) var(--border-width) var(--border-width) calc(var(--border-width) * 0.5);
}
#bottom-right>div {
shape-outside: inset(var(--bottom-right-top) 0 0 0);
float: left;
height: calc(var(--bottom-right-top) + 50%);
width: 50%;
padding: 0 var(--void-padding-left-right) var(--void-padding-bottom) 0;
margin-top: calc(var(--padding) * -1);
}
#center {
grid-area: 2 / 2 / 4 / 4;
background-color: blue;
border-width: var(--border-width);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="grid-container">
<div id="top-left">
<div></div>
<span></span>
</div>
<div id="top-right">
<div></div>
<span></span>
</div>
<div id="bottom-left">
<div></div>
<span></span>
</div>
<div id="bottom-right">
<div></div>
<span></span>
</div>
<div id="center">
<span>I have read multiple times that you cannot have L-shaped grids. That depends on your definition of
‘cannot’… Maybe you cannot do it with the inherit grid controls themselves, but it is possible with a
little additional imagination & creativity!<br>
<br>
Enjoy!<br>
<br>
© 2021 Sassano<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
</span>
</div>
</div>
查看我在 codepen 上的链接: https://codepen.io/sassano/full/dyObGar
答案 2 :(得分:0)
尽管从技术上讲您不能创建L形网格项目。 You can layer items over each other with z-index。
对此进行扩展,如果您想在奇数形状之间留出空隙,可以使用grid-gap
和outline
的组合,如下所示:
.wrapper {
display: grid;
grid-template-columns: repeat(6, 1fr);
grid-template-rows: repeat(4, 1fr);
grid-gap: 10px;
}
.box1 {
grid-column-start: 1;
grid-row-start: 1;
grid-row-end: 3;
}
.box2 {
grid-column-start: 2;
grid-column-end: 4;
grid-row-start: 1;
z-index: 1;
outline: 10px solid white;
}
.box3 {
grid-column-start: 3;
grid-column-end: 7;
grid-row-start: 1;
grid-row-end: 5;
text-align: right;
}
.box4 {
grid-column-start: 2;
grid-row-start: 2;
}
.box5 {
grid-column-start: 3;
grid-column-end: 5;
grid-row-start: 2;
z-index: 1;
outline: 10px solid white;
}
.box6 {
grid-column-start: 1;
grid-column-end: 3;
grid-row-start: 3;
grid-row-end: 5;
}
.wrapper {
background-color: #fff4e6;
}
.box {
background-color: #ffd8a8;
padding: 1em;
color: #d9480f;
}
<div class="wrapper">
<div class="box box1">One</div>
<div class="box box2">Two</div>
<div class="box box3">Three</div>
<div class="box box4">Four</div>
<div class="box box5">Five</div>
<div class="box box6">Six</div>
</div>