【问题标题】:Why does scrollWidth only include the left padding?为什么 scrollWidth 只包括左边的填充?
【发布时间】:2012-04-20 03:13:38
【问题描述】:

所以,我有一个固定宽度的 DIV #Wrapper。在那个 DIV 里面,我有另一个 DIV #Panel,它也有一个固定的宽度:

<div id="Wrapper">
    <p>...</p>
    <div id="Panel">Panel</div>
    <p>...</p>
</div>  

有时,Panel 的宽度比 Wrapper 的宽度大,在这种情况下,我想通过 JavaScript 加宽 Wrapper,使其完美地包裹 Panel。

现场演示: http://jsfiddle.net/H6rML/

我打算在 Wrapper 上使用.scrollWidth 来确定面板的宽度。但是,问题在于 Wrapper 具有水平填充,而 .scrollWidth 出于某种原因仅包括包装器的左侧填充。所以:

Wrapper.scrollWidth === Wrapper.LeftPadding + Panel.Width

所以,给定:

#Wrapper {
    width: 200px;
    padding: 10px;        
}

#Panel {
    width: 300px;
}

Wrapper.scrollWidth 返回310px,这不是很有用。如果.scrollWidth 不包含任何填充并且只返回面板的宽度,我可以使用它(我会手动将填充添加到该值)。如果两个填充都包括在内,我也可以使用它。但是为什么只包括左边的填充? (顺便说一句,这种行为似乎是跨浏览器的。)

一些补充说明:

  1. 我无法直接在 Wrapper 上设置宽度。在我的实际代码中,我在比 Wrapper 高几级的祖先元素上设置了宽度,并使用自定义 API 来设置宽度。这就是为什么我需要检索完整的 320px 值。

  2. 我想要一个不依赖于 Wrapper 内容的解决方案。在我的演示中,它是一个面板,但在其他情况下,可能会有不同的元素溢出,甚至是多个元素。这就是我在 Wrapper 上选择 .scrollWidth 的原因。

有没有一种方法可以获取值 320px 而无需手动将正确的填充添加到 .scrollWidth 值?


顺便说一句,根据标准,应该包括正确的填充:

scrollWidth 属性必须返回运行这些的结果 步骤:

  1. 如果元素没有任何关联的 CSS 布局框,则返回零并终止这些步骤。

  2. 如果元素是根元素且 Document 不是 quirks 模式,则返回 max(document content width, value of innerWidth)。

  3. 如果元素是 HTML body 元素并且 Document 处于 quirks 模式,则返回 max(document content width, value of innerWidth)。

  4. 返回 'padding-left' 属性的计算值,加上 'padding-right' 的计算值,再加上元素的内容宽度。

来源:http://www.w3.org/TR/cssom-view/

为什么浏览器没有相应的行为?


为了进一步提高我帖子的清晰度,让我总结两个主要问题:

(1) 如果标准规定正确的填充应该包含在.scrollWidth 值中,那么为什么浏览器不采取相应的行为呢?

(2) 是否可以检索正确的值(在我的情况下为320px),而无需手动添加正确的填充?


这个问题已经在另一个帖子中回答了

这个问题的答案在这里:When a child element overflows horizontally, why is the right padding of the parent ignored?

【问题讨论】:

  • @RokoC.Buljan 我无法直接在 Wrapper 上设置宽度。请阅读 Elliot 答案下方的 cmets。我将更新我的问题以澄清这一点。
  • 为什么需要重新计算#Wrapper的宽度?在#Panel 被完美包装之后,我不会再打扰了:)
  • P.S:你真的不能用 jQ 来达到这个目的吗? jsfiddle.net/ytByf/1 使用 .outerWidth(true) 它返回 '320' !希望有帮助! (萨格勒布你好。)
  • @RokoC.Buljan 正如我所说,我确实在 Wrapper 上设置宽度,而是在外部元素(DOM 树更上层的祖先)上设置宽度。我有一个自定义函数可以设置该祖先的宽度,为了正确设置宽度,我必须将值 320 传递给它。 Wrapper.scrollWidth(不正确?)返回值310(它不包括正确的填充),所以我必须弄清楚如何处理这个问题。 (波兹德拉夫:)
  • 有点意思,看起来没有简单的方法来计算两个填充。即使使用 jQuery,我们也必须严格使用“padding-left”(或其他)来获取计算的填充(本机)值。 jsbin.com/onufey/edit#javascript,html,live 但这里实现了:jsbin.com/onufey/2/edit

标签: javascript html css browser cssom


【解决方案1】:

直到今天我还不知道为什么领先的浏览器会分享这个错误,但这里有一个问题的演示和inline-block 解决方法

document.body.innerHTML += 'one.scrollWidth = '+ document.querySelector('.one').scrollWidth 
                          +'<br>two.scrollWidth = '+ document.querySelector('.two').scrollWidth
                          +'<br>three.scrollWidth = '+ document.querySelector('.three').scrollWidth
                          +'&nbsp;&nbsp;&nbsp;(fix applied to grand children)<br>four.scrollWidth = '+ document.querySelector('.four').scrollWidth +'&nbsp;&nbsp;&nbsp;(fix applied to direct child)';
.parent{
  border:1px solid rgba(50,150,220,1);
}
.child{
  background:rgba(100,200,255,0.3);
  padding:10px 20px;
  white-space:nowrap;
}
.scroll-container{
  border:1px solid red;
  display:inline-block;
  overflow:hidden;
}
.two, .three, .four{
  width:60px;
}
.three .child{
  display:inline-block;
}
.four .parent{
  display:inline-block;
}
<div class="scroll-container one">
  <div class="parent">
    <div class="child">Lorem ipsum dolor</div>
    <div class="child">Lorem ipsum dolor sit amet</div>
  </div>
</div>
<br>
<div class="scroll-container two">
  <div class="parent">
    <div class="child">Lorem ipsum dolor</div>
    <div class="child">Lorem ipsum dolor sit amet</div>
  </div>
</div>
<br>
<div class="scroll-container three">
  <div class="parent">
    <div class="child">Lorem ipsum dolor</div>
    <div class="child">Lorem ipsum dolor sit amet</div>
  </div>
</div>
<br>
<div class="scroll-container four">
  <div class="parent">
    <div class="child">Lorem ipsum dolor</div>
    <div class="child">Lorem ipsum dolor sit amet</div>
  </div>
</div>
<br>

【讨论】:

    【解决方案2】:

    我不确定我是否理解正确,但根据我的阅读,我假设您想根据#Panel 更改#Wrapper 的宽度。在这种情况下,也许您可​​以尝试以下方法:

    #Wrapper {
        display: inline-block;
        make sure to remove width from #Wrapper
    }
    

    【讨论】:

      【解决方案3】:

      你可以使用 jQuery 来做到这一点:

      $(function() {
          $("#Wrapper").width($("#Panel").outerWidth());
      });
      

      这会考虑到#Panel 的填充、边距等。

      【讨论】:

      • 不幸的是,我没有设置 Wrapper 本身的宽度。我的答案中的代码是我实际代码的简化版本。在我的代码中,我有几层包装器(其中一层是 iframe),宽度是通过第三方 API(不是 jQuery)设置的。因此,我需要确定正确的值(在上面的示例中为320px)。
      • 把'Wrapper'换成你要设置宽度的元素的ID,对吧?
      • 那行不通,因为您的代码没有考虑 Wrapper 的填充。 $("#Panel").outerWidth() 的值为300,但我需要的值为320。在特殊情况下,当你在 Wrapper 本身上设置宽度时,你可以使用值300,但如果你在外部元素上设置宽度(你需要考虑 Wrapper 的水平填充)。跨度>
      • 也许你想设置$("#Wrapper").innerWidth()
      • .innerWidth() 不能设置;这是一种只读方法。正如我所说,我没有在 Wrapper 上设置宽度,而是在外部元素上设置。这是无法更改的。
      【解决方案4】:

      试试这个:

      #Wrapper {
          min-width: 200px;
          padding: 10px;
          float: left; 
      }
      

      或使用 jQuery

      $(document).ready(function() {
          var width = jQuery("#Panel").width();
          $("#Wrapper").width(width);
      });
      

      【讨论】:

      • 将元素切换为浮动是一个相对较大的变化,这可能会给现有的 CSS/JavaScript 代码带来问题,所以我认为它只是最后的最后手段......
      • 可以用上面的jquery方法吗?为什么浮动它留下了如此巨大的变化?
      • 你能像上面的解决方案那样使用jquery吗?
      • 当一个元素浮动时,它会从页面流中移除。流入元素和流出元素之间存在各种差异:它们的布局不同,不同的 CSS 属性应用不同(使用不同的算法来确定计算值)或根本不应用。
      猜你喜欢
      • 1970-01-01
      • 2022-01-20
      • 2023-03-07
      • 1970-01-01
      • 1970-01-01
      • 2015-02-15
      • 2012-06-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多