使用 calc() 时,Flexbox space-between 最后有额外的 1px 间隙

Posted

技术标签:

【中文标题】使用 calc() 时,Flexbox space-between 最后有额外的 1px 间隙【英文标题】:Flexbox space-between has extra 1px gap at the end when using calc() 【发布时间】:2019-11-02 08:50:51 【问题描述】:

我正在使用 flexbox 的 justify-content: space-between; 开发一个网格系统,我注意到在某些屏幕尺寸(大约每隔一个像素)上,某些列的末尾会出现 1 个像素的间隙。

如果您开始使用以下示例调整浏览器大小,您会看到 1 个像素的空间出现和消失。

示例

* 
  margin: 0;
  padding: 0;


.row 
  display: flex;
  flex-wrap: wrap;
  max-width: 550px;
  width: 100%;
  margin: 0 auto;
  border: 2px solid #888;
  justify-content: space-between;


div[class^="col"] 
  border: 2px solid red;


.col-12 
  flex-basis: calc(100% - 4px);


.col-11 
  flex-basis: calc(11/12*100% - (1.167 - 11/12)*24px);


.col-10 
  flex-basis: calc(5/6*100% - (1.167 - 5/6)*24px);


.col-9 
  flex-basis: calc(3/4*100% - (1.167 - 3/4)*24px);


.col-8 
  flex-basis: calc(2/3*100% - (1.167 - 2/3)*24px);


.col-7 
  flex-basis: calc(7/12*100% - (1.167 - 7/12)*24px);


.col-6 
  flex-basis: calc(1/2*100% - (1.167 - 1/2)*24px);


.col-5 
  flex-basis: calc(5/12*100% - (1.167 - 5/12)*24px);


.col-4 
  flex-basis: calc(1/3*100% - (1.167 - 1/3)*24px);


.col-3 
  flex-basis: calc(1/4*100% - (1.167 - 1/4)*24px);


.col-2 
  flex-basis: calc(1/6*100% - (1.167 - 1/6)*24px);


.col-1 
  flex-basis: calc(1/12*100% - (1.167 - 1/12)*24px);
<div class="row">
  <div class="col-12">col-12</div>
  <div class="col-6">col-6</div>
  <div class="col-6">col-6</div>
  <div class="col-4">col-4</div>
  <div class="col-4">col-4</div>
  <div class="col-4">col-4</div>
  <div class="col-3">col-3</div>
  <div class="col-3">col-3</div>
  <div class="col-6">col-6</div>
  <div class="col-3">col-3</div>
  <div class="col-3">col-3</div>
  <div class="col-3">col-3</div>
  <div class="col-3">col-3</div>
  <div class="col-4">col-4</div>
  <div class="col-8">col-8</div>
  <div class="col-7">col-7</div>
  <div class="col-5">col-5</div>
  <div class="col-6">col-6</div>
  <div class="col-4">col-4</div>
  <div class="col-2">col-2</div>
</div>

这是一个可用的 Fiddle,因此您可以更轻松地调整它的大小。

JSFiddle

*注意: 我知道我在用calc() 做一些疯狂的事情,但即使你只是减去5px 而不是(1.167 - 1/12)*24px),问题仍然存在。

这是 flexbox 的错误吗?

我需要做什么才能消除这些列末尾的间隙?

【问题讨论】:

可能是亚像素舍入。 坦率地说,我认为使用 CSS-Grid 可能会更好 这是一个更好的选择@Paulie_D,但我需要支持css-grid 不支持的某些浏览器。 没有确切的方法来避免使用 CSS 进行子像素舍入。要么让它们变成 1px 到宽以适应父级,然后使用 overflow: hidden,或者使用脚本,这样你就可以自己做数学,并确保四舍五入符合你的需要。 【参考方案1】:

你的问题是 col-3 和 col-6

之前:

.col-3 
  flex-basis: calc(1/4*100% - (1.167 - 1/4)*24px);

之后:

.col-3 
  flex-basis: calc(1/4*100% - (1.167 - 1/4)*25px);


试试看:

* 
  margin: 0;
  padding: 0;


.row 
  display: flex;
  flex-wrap: wrap;
  max-width: 700px;
  width: 100%;
  margin: 0 auto;
  border: 2px solid #888;
  justify-content: space-between;


div[class^="col"] 
  border: 2px solid red;


.col-12 
  flex-basis: calc(100% - 4px);


.col-11 
  flex-basis: calc(11/12*100% - (1.167 - 11/12)*24px);


.col-10 
  flex-basis: calc(5/6*100% - (1.167 - 5/6)*24px);


.col-9 
  flex-basis: calc(3/4*100% - (1.167 - 3/4)*24px);


.col-8 
  flex-basis: calc(2/3*100% - (1.167 - 2/3)*24px);


.col-7 
  flex-basis: calc(7/12*100% - (1.167 - 7/12)*24px);


.col-6 
  flex-basis: calc(1/2*100% - (1.167 - 1/2)*25px);


.col-5 
  flex-basis: calc(5/12*100% - (1.167 - 5/12)*24px);


.col-4 
  flex-basis: calc(1/3*100% - (1.167 - 1/3)*24px);


.col-3 
  flex-basis: calc(1/4*100% - (1.167 - 1/4)*25px);


.col-2 
  flex-basis: calc(1/6*100% - (1.167 - 1/6)*24px);


.col-1 
  flex-basis: calc(1/12*100% - (1.167 - 1/12)*24px);

【讨论】:

最好至少突出显示您在代码中所做的更改,以便我们更容易找到 .col-3 和 .col-6 不使用border: 2px solid red;使用背景色边框增加2像素【参考方案2】:

问题

在找到解决方案之前,我稍微解决了这个问题。步骤如下:

首先我将所有内容转换为使用标准格式

calc(a/12 * 100% - (7/6 - a/12) * 24px) 其中a = "col number"

接下来我开始尝试使用数字来查看没有单位的实际输出(当然)

1: -17.6666... 2: -7.3333... 3: 3 4: 13.3333... 5: 23.6666... 6: 34 7: 44.3333... 8: 54.6666... 9: 65 10: 75.3333... 11: 85.6666... 12: 96

形成这个我们可以看到三件事

任何能被3整除的数都是整数 下一个数字以重复x.3333... 结尾 第二个数字以x.6666...结尾

注意: 1 和 2 是特殊情况,因为它们的输出实际上是负数,所以颠倒过来。我们可以假设他们的数字在现实世界中是正数,并且会与其他人一致

之后,查明方程式中的实际问题就很容易了: a/12 * 100%

所以舍入问题是您的问题 - 即当您使用两个或多个以 x.3333... 结尾的数字时

修复

我们希望这些舍入误差不会级联,因此我们有一些选择

    将值相加得到中间数 添加一些半像素以减少错误并希望解决问题(仅在以x.3333... 结尾的数字添加半像素)

例子:

    flex-basis: calc((8/12 - 1/6/100) * 100% - (7/6 - 8/12) * 24px); flex-basis: calc(8/12 * 100% - (7/6 - 8/12) * 24px);

我用第一个例子给我这个重复代码:

* 
  margin: 0;
  padding: 0;


.row 
  display: flex;
  flex-wrap: wrap;
  max-width: 550px;
  width: 100%;
  margin: 0 auto;
  border: 2px solid #888;
  justify-content: space-between;


div[class^="col"] 
  border: 2px solid red;


.col-12 
    flex-basis: calc(12/12 * 100% - (7/6 - 12/12) * 24px);

.col-11 
    flex-basis: calc((11/12 - 1/6/100) * 100% - (7/6 - 11/12) * 24px);

.col-10 
    flex-basis: calc((10/12 + 1/6/100) * 100% - (7/6 - 10/12) * 24px);

.col-9 
    flex-basis: calc(9/12 * 100% - (7/6 - 9/12) * 24px);

.col-8 
    flex-basis: calc((8/12 - 1/6/100) * 100% - (7/6 - 8/12) * 24px);

.col-7 
    flex-basis: calc((7/12 + 1/6/100) * 100% - (7/6 - 7/12) * 24px);

.col-6 
    flex-basis: calc(6/12 * 100% - (7/6 - 6/12) * 24px);

.col-5 
    flex-basis: calc((5/12 - 1/6/100) * 100% - (7/6 - 5/12) * 24px);

.col-4 
    flex-basis: calc((4/12 + 1/6/100) * 100% - (7/6 - 4/12) * 24px);

.col-3 
    flex-basis: calc(3/12 * 100% - (7/6 - 3/12) * 24px);

.col-2 
    flex-basis: calc((2/12 - 1/6/100) * 100% - (7/6 - 2/12) * 24px);

.col-1 
    flex-basis: calc((1/12 + 1/6/100) * 100% - (7/6 - 1/12) * 24px);
<div class="row">
  <div class="col-12">col-12</div>
  <div class="col-6">col-6</div>
  <div class="col-6">col-6</div>
  <div class="col-4">col-4</div>
  <div class="col-4">col-4</div>
  <div class="col-4">col-4</div>
  <div class="col-3">col-3</div>
  <div class="col-3">col-3</div>
  <div class="col-6">col-6</div>
  <div class="col-3">col-3</div>
  <div class="col-3">col-3</div>
  <div class="col-3">col-3</div>
  <div class="col-3">col-3</div>
  <div class="col-4">col-4</div>
  <div class="col-8">col-8</div>
  <div class="col-7">col-7</div>
  <div class="col-5">col-5</div>
  <div class="col-6">col-6</div>
  <div class="col-4">col-4</div>
  <div class="col-2">col-2</div>
</div>

应该在支持非圆角calc的现代甚至大多数旧版浏览器中工作

如果您想查看第二种解决方案,请发表评论,我会发布。

注意:如果可以的话,最好使用类似 sass 或更少的语言来执行这些计算,因为它们是在四舍五入之后进行的,并且还可以将所有这些繁重的工作集中在一个地方。 p>

【讨论】:

以上是关于使用 calc() 时,Flexbox space-between 最后有额外的 1px 间隙的主要内容,如果未能解决你的问题,请参考以下文章

有没有办法在 Less 中为 ~ 运算符使用变量,例如 ~"calc(100% - @spacing)";

尝试在 calc() 中使用 theme() 时解析错误

带边距排水沟的 Flexbox 网格系统

给包装的 flexbox 项目提供垂直间距

在 div 中垂直间隔项目(flexbox space-around 不起作用..)

带有多行文本省略号的 Flexbox