非矩形的CSS网格元素

11

假设我想在CSS网格布局中使用自动密集填充。是否有任何方法引入非矩形区域配置?例如,一个L形区域覆盖一行中的两列,下一行只覆盖一列。我已经尝试过显式命名网格单元格,但这并不起作用。


1
网格区域可以重叠。您应该发布您尝试过的代码。 - Michael Benjamin
3个回答

13

目前不支持非矩形网格项目。根据规范

每个网格项目都与一个网格区域相关联,该区域是相邻网格单元的矩形集,网格项目占据该集合。

并且

注:未来版本的模块可能允许非矩形或不相连的区域。

(这并不意味着已经计划了这样的功能,只是未来可以添加此类功能而已)


13

虽然在网格布局中不能创建 L 形的网格项,但你可以使用 z-index 属性将多个项叠加

进一步来说,如果你想在奇形怪状的项之间留有空隙,你可以使用 grid-gapoutline 的组合,像这样:

.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>

在 Codepen 上打开


2
我的解决方案是创建重叠的网格容器,然后使用浮动来遮挡被覆盖的区域。并且需要一点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


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