CSS Grid:在WebKit浏览器中,使用span,calc()和CSS变量的grid-column无法工作

8

我正在使用一个简单的网格系统,其中列数可以通过CSS变量进行配置/覆盖。

.grid {
  display: grid;
  grid-template-columns: repeat(var(--grid-columns, 1), 1fr);
}

// Mixin for tablet media query
@include tablet {
  .grid {
    --grid-columns: 2;
  }
}

// Mixin for tablet media query
@include desktop {
  .grid {
    --grid-columns: 4;
  }
}

上面是一个简化的示例。
我还有一个可以用于“单元格”的类,用于标注它是否是全宽或两个单元格宽(跨一半)。
@include desktop {
  .span {
    &-full {
      grid-column: 1 / -1;
    }

    &-half {
      grid-column: span calc(var(--grid-columns) / 2);
      // or grid-column: auto / span calc(var(--grid-columns) / 2);
    }
  }
}

我使用 .span-half 来创建一个单元格,该单元格跨越了由 --grid-columns 变量设置的一半列大小。
然而,在 Chrome 或 Safari 中,这个计算不起作用。Firefox 正确地呈现了 .span-half(例如,在桌面上跨越 2 列的单元格)。在 Dev Tools 中没有看到“无效值属性”。
这是一个 Codepen:https://codepen.io/Bregt/pen/oNbWvzx 我不知道发生了什么。我错过了什么?

1
你是否在媒体查询之外定义 --grid-columns?媒体查询是自定义变量的作用域容器。 - Bryce Howitson
我没有这样做,但当我将它添加到根目录时似乎无法解决问题。 - Bregt
我可能需要看更多的代码。一个可工作的示例将非常有帮助。 - Bryce Howitson
你说得对,这是一个 Codepen。https://codepen.io/Bregt/pen/oNbWvzx - Bregt
似乎calcgrid-column存在一个错误。即使没有变量,它也无法正常工作。有趣的是,这个可以正常工作:grid-column: span calc(2);,而这个却不行:grid-column: span calc(4 / 2); - Aedan
3个回答

5

https://developer.mozilla.org/zh-CN/docs/Web/CSS/calc 上找到了这个内容。

注意:目前 Chrome 浏览器不接受 calc() 返回的某些值,即使期望返回一个整数,也包括任何除法,即使它得到一个整数。

以下是我在 Chrome 中通过 grid-column 进行的一些测试:

grid-column: calc(4 / 2); = 无效的属性值

grid-column: calc(1 * 2); = 正常工作

grid-column: calc(4 * 0.5); = 无效的属性值

grid-column: calc(1 + 1.5); = 无效的属性值

grid-column: calc(1 + 2); = 正常工作

grid-column: calc(1 - 2); = 正常工作

结论:除法在 grid-column(可能还有行)中不起作用。只要不使用浮点数,乘法、加法和减法就能正常工作。这也适用于其他需要整数作为值且没有单位的 CSS 属性,例如 z-index

接受浮点数的属性,如 line-height,不会有此问题。


是的,行也一样。 - certainlyakey
1
请注意,这已经不再是Chrome 97的情况了。 - Luke Taylor

1
媒体查询不是你所询问的问题,但它们会导致问题。基本上,当您将变量包装在类中时,您正在限定变量的范围,因此无法对其进行任何计算。(.grid {--grid-columns: 4})相反,您应该在根元素中设置基础,然后在媒体查询中更改基础值。
:root {
 --grid-columns: 4;
}

@media (args) {
  :root {
     --grid-columns: 8;
  }
}

这会改变你代码中的所有变量,所以你不需要去处理除了变量以外的任何东西。

至于其他部分,似乎是与calc()有关的问题,与自定义属性无关。

这个可以正常工作:

grid-column: span 2;

这不是(webkit)

grid-column: span calc(4 / 2);

我认为这与calc不喜欢无单位值有关,但我在任何官方文档或Chromium错误中都找不到相关信息。

编辑: 这似乎是一个Chromium错误,因为Chrome、Edge和Safari都遇到了这个问题。 此外,如评论中Aedan所述,calc()可使用+、-、*。 我添加了一个Chromium bug for this issue。 如果您会使用此功能,请随意标记该错误以帮助团队了解情况。

这里有一个Codepen,其中包含完整示例


Span是无单位的,我认为我无法避免这一点。 - Bregt
关于媒体查询和:root。你说得对,我确实不应该再次编写选择器。可能是试图找出问题所在的剩余部分。谢谢。 - Bregt
我同意你不能避免无单位部分。我认为这可能是calc()实际输出的一个错误(可能是无效的)。我正在尝试确定这是grid实现中的错误还是calc实现中的错误。 - Bryce Howitson
我也进行了一些测试。它似乎只与 calc 内的除法运算符和 grid-column 相关。乘法运算正常工作。这让我想到只使用 calc(4*0.5),但是在 webkit 中似乎存在另一个 bug,不允许在 calcgrid-column 中使用浮点数。在 grid-column 之外,calc 中的浮点数工作正常。哦,天啊... 真是糟糕的一天。 - Aedan
哇,谢谢大家。跟进这个过程很有趣。 - Bregt
显示剩余3条评论

0

我已经多种方式测试了您的问题。这是一个calc错误。使用var是完全没问题的。但是,即使我将calc放在单独的var中,也不起作用。

更新

我只想演示简单的JavaScript解决方案。无论如何,您都不应该编辑代码,可以像往常一样使用CSS。此JS仅获取--grid-columns并返回--grid-span。基本上,这就是CSS中calc()的功能,但更加稳定。

setDimensions(); 
window.addEventListener('resize', () => {
 setDimensions(); 
});
function setDimensions(){
  let gridColumns = getComputedStyle(document.documentElement).getPropertyValue('--grid-columns');
  document.documentElement.style.setProperty('--grid-span', gridColumns / 2);
}
:root {
    --grid-columns: 1;    
  }
.grid {
  display: grid;
  grid-template-columns: repeat(var(--grid-columns, 1), 1fr);
  grid-gap: 10px 10px
}

@media (min-width: 500px) {
  :root {
    --grid-columns: 4;
  }
}

.span-full {
  grid-column: 1 / -1;
}

.span-half {
  grid-column: span var(--grid-span);
}

.cell {
  background: #77dd77;
  height: 50px;
  line-height: 50px;
  text-align: center;
  font-family: arial;
  text-transform: uppercase;
  color: #fff;
  font-weight: bold;
}
<div class="grid">
  <div class="cell span-full">full</div>
  <div class="cell span-half">half</div>
  <div class="cell span-half">half</div>
  <div class="cell span-half">half</div>
  <div class="cell">single</div>
  <div class="cell">single</div>
  <div class="cell">single</div>
  <div class="cell">single</div>
  <div class="cell span-half">half</div>
</div>


谢谢。那我需要在某个地方记录这个吗?因为我的例子是简化的。我希望span-half只计算一次。例如,我有8列的网格。 - Bregt
我认为你应该在JS上进行计算。如果您可以使用JS的话 - 我可以写一个简单的脚本。 - focus.style
JS真的不是一个选择。 - Bregt
更新了一个带有JS的答案,只需查看,您可以直接使用,无需编辑。唯一需要的是CSS中的--grid-columns才能正常工作。 - focus.style
为什么不尝试使用JS呢?它非常简单,而且可以100%稳定地在多个浏览器上运行。 - focus.style
在我的情况下,我无法访问JavaScript。 - Bregt

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