【问题标题】:CSS - Calc inaccuracyCSS - 计算不准确
【发布时间】:2017-07-24 09:10:43
【问题描述】:

我有一个 ul 元素和 5 个孩子 <li>

<ul>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
</ul>

&lt;ul&gt; 有一个display: flex 属性。 我尝试使用 &lt;li&gt; 上的 calc 属性来均匀调整列表项的大小:

calc:(100% / 5);

这会给出所需的结果并均匀调整 5 个 &lt;li&gt; 块的大小

现在我在所有的右侧添加了边框,但最后一个子 &lt;li&gt; 元素。所以我从&lt;ul&gt;的总宽度中减少了所有边框的总宽度。

calc:((100% - 8px) / 5);

这也可以正常工作,并均匀地调整带有边框的 &lt;li&gt; 块的大小。

ul {
  width: 600px;
  height: 300px;
  margin: 0;
  padding: 0;
  display: flex;
  background: red;
}

li {
  list-style: none;
  display: block;
  width: calc((100% - 0.8px) / 5);
  height: 100%;
  border-right: 0.2px solid black;
  background: blue;
}

li:last-child {
  border-right: none;
}
<ul>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
</ul>

现在我尝试在视口单元 vw 中设置边框宽度而不是 px,但它给出了不同的结果。

ul {
  width: 600px;
  height: 300px;
  margin: 0;
  padding: 0;
  display: flex;
  background: red;
}

li {
  list-style: none;
  display: block;
  width: calc((100% - 0.8vw) / 5);
  height: 100%;
  border-right: 0.2vw solid black;
  background: blue;
}

li:last-child {
  border-right: none;
}
<ul>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
</ul>

从上面的sn-p可以看出,右边有一点空间。这会随着更宽的视口而变得更大(尝试查看 sn-p 整页)。所以我认为问题在于这里的vw 单位和弹性框。

那么这个错误的原因是什么?

编辑:

从提供的答案和 cmets 中,我看到还有其他更合适的方法来实现我想要做的事情。我很欣赏这些答案,但这些不是我问题的答案。由于calc 在这种情况下显示错误,因此当我尝试在其他情况下(不仅仅是边框)使用calc 和视口单位时,很可能会导致更多问题。所以我需要知道原因和“calc”修复。

【问题讨论】:

  • 我不知道为什么会这样,但如果你不知道,你可以使用box-sizing: border-box;,边框宽度不会影响元素的外部宽度。
  • calc 中使用%vw 有点奇怪,因为%vw 都是基于不同基数的百分比。你没有说ul的父母。假设ul parent 的宽度是 300px,视口宽度即 vw 是 400px,所以 0.8vw 比您预期的要多,并且有空白。
  • @MichaelCoker 是的,我看到了 calc 替代帖子“stackoverflow.com/questions/16034397/css-calc-alternative?rq=1”,并正在考虑尝试 box-sizing。
  • @ata 为什么需要父级 ul?它不会以任何方式影响 li。我猜你误解了这个问题。
  • @AnuragDaolagajao 是的,你是对的,我犯了一个错误,但这个概念是正确的。 ul的宽度是600px,但是viweport的宽度可能超过600px,那么0.8vw大于0.8%就会有一个空白。

标签: html css flexbox viewport-units css-calc


【解决方案1】:

像素 (px):绝对像素。例如,20px 在任何屏幕上实际上都是 20 像素。如果显示器为 1980x1200,并且您将元素的高度设置为 200 像素,则该元素将占用 200 像素。

视口高度/宽度 (vw/vh):相对于视口的大小(基本上是浏览器窗口)。

1px = (100 / document.documentElement.clientWidth)vw 1px = (100 / 500) = 0.2vw

【讨论】:

    【解决方案2】:

    您似乎正在使用flex 将您的lis 分发到您的ul 中。在这种情况下,您不需要calculate 宽度来使它们相等。这就是flex 应该做的事情。

    看这个例子:

    * { box-sizing: border-box; margin: 0; padding: 0; }
    ul, li { list-style: none; }
    ul { width: 600px; height: 300px; background: red; display: flex; }
    li {
      flex: 1 0 auto;
      border-right: 0.8vw solid black;
      background: blue;
    }
    li:last-child { border-right: none; }
    <ul>
      <li></li><li></li><li></li><li></li><li></li>
    </ul>

    在容器上指定flex dsiplay 时,您只需对子项应用flex 属性,以使它们表现为灵活的项目。在您的特定用例中,您需要以下内容:

    1. flex-grow:设置为 1。这将使您的 li 增长到填满整个 ul 宽度。
    2. flex-shrink:设置为 0。您不希望您的 li 缩小。
    3. flex-basis:设置为auto。您希望您的 li 自动增长到均衡宽度。

    所以,你看,你根本不需要calc

    您也无需专门将display: block 应用到您的lis。根据这里的规格:https://www.w3.org/TR/css-flexbox-1/#flex-items

    一个flex项目的显示值被阻塞:如果指定 显示生成弹性容器的元素的流入子项 是一个内联级别的值,它计算到它的块级等价物

    正如 cmets 中的 @BoltClock 所指出的,列表项已经被阻止。

    边界

    现在,来到边界。在您的第一个示例中,您以0.2px 为单位指定了宽度。这是没有意义的。虽然规格允许小数像素,但它会将其四舍五入到显示器上可用的最近像素,通常为 1。

    在第二个示例中,您希望边框随视口缩放。那挺好的。 0.8vw 没问题。

    请看我发布的示例,in this fiddle。调整结果窗口的大小,您将看到边框相对于视口大小发生变化。

    最后,您可能想要也可能不想设置box-sizing。这取决于你的布局。无论您使用什么,都始终如一地使用它。

    【讨论】:

    • "你也不需要专门应用 display: block 到你的 lis。"他只是不需要这样做,因为他已经设置了 list-style: none。您引用的文本不适用于 display: list-item 因为 display: list-item 是块级显示类型,而不是内联级显示类型(即 display: inline-list-item)。
    • 感谢@BoltClock。我错过了。添加到答案。 “他不需要这样做,因为他已经设置了 list-style: none。” - list-style of none 不应该是这里的一个因素,因为它仍然是一个列表项.看到这个:jsfiddle.net/abhitalks/mu4ds20p/1
    • @Anurag,有什么不接受答案的具体理由吗?
    【解决方案3】:

    您无需进行计算即可为您的 li 添加内部内容。如果你给 box-sizing: border-box; 属性,border 和 padding 不会使容器变大。

    ul {
      width: 600px;
      height: 300px;
      margin: 0;
      padding: 0;
      display: flex;
      background: red;
    }
    
    li {
      list-style: none;
      display: block;
      width: calc(100% / 5);
      height: 100%;
      border-right: 2px solid black;
      background: blue;
      box-sizing: border-box;
    }
    
    li:last-child {
      border-right: none;
    }
    <ul>
      <li></li>
      <li></li>
      <li></li>
      <li></li>
      <li></li>
    </ul>

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-06-06
      • 1970-01-01
      • 2020-12-11
      • 2021-05-10
      • 2022-06-10
      • 1970-01-01
      • 2017-06-08
      相关资源
      最近更新 更多