CSS定位填充容器:宽度 vs 左/右?

22

考虑到:

  • 元素绝对定位在相对定位的容器内。
  • 如果您希望元素填充容器的宽度。
  • 该元素也底部对齐。

enter image description here

在考虑浏览器兼容性的情况下,是将元素的宽度设置为像素还是仅使用leftright最好呢?

这两种方法都有哪些常见的bug需要注意?

显然,在图像宽度或填充发生变化的情况下,使用left: 0;right: 0;会使代码更易于管理,但是否存在width: 300px更有利的缺点呢?


4
除了IE6(和没有正确文档类型的IE7),在每个浏览器中都可以使用“left:0”和“right:0”。我建议使用“left”和“right”,因为从长远来看更容易维护代码(例如更改容器大小)。 - BenM
2
我不会再担心IE6的支持了... - Xarcell
很多人在工作中仍被迫使用IE6,因此这真的取决于实现和目标受众。 - Baumr
4个回答

16

历史上,我们学习使用width而不是left & right,因为IE6不支持同时使用同一轴线的两个属性。

<div style="top:0;bottom:0;position:absolute;">modern browsers</div>

<div style="top:0;height:100%;position:absolute;">MSIE6</div>

<div style="left:0;right:0;position:absolute;">modern browsers</div>

<div style="left:0;width:100%;position:absolute;">MSIE6</div>

<div style="left:0;right:0;top:0;bottom:0;position:absolute;">modern browsers</div>

<div style="left:0;top:0;height:100%;width:100%;position:absolute;">MSIE6</div>

另外,该技术在某些元素上不起作用(包括规范中的现代浏览器)。

<!-- these will not work -->
<!-- edit: on some browsers they may work,
but it's not standard, so don't rely on this -->

<iframe src="" style="position:absolute;top:0;bottom:0;left:0;right:0;"></iframe>

<textarea style="position:absolute;top:0;bottom:0;left:0;right:0;"></textarea>

<input type="text" style="position:absolute;left:0;right:0;">

<button ... ></button>

and possibly others... (some of these can't even be display:block)

然而,使用 width:auto 属性分析正常静态流程时发生了什么。

<div style="width:auto;padding:20px;margin:20px;background:lime;">a</div>

你会发现它非常类似于...

<div style="width:auto;padding:20px;margin:20px;background:lime;
    position:absolute;top:0;left:0;bottom:0;right:0;">b</div>

所有元素的属性和属性值都相同!这真的很好!否则会看起来像:

<div style="width:100%;height:100%;
    position:absolute;top:0;left:0;">
    <div style="padding:20px;margin:20px;
        background:lime;">c</div>
</div>

这里有一个不同点,因为内部div无法填满y轴。 为了解决这个问题,我们需要使用css calc()box-sizing,尽管这会带来一些不必要的麻烦。


我的答案是,left + right | top + bottom非常棒,因为它们最接近静态定位的width:auto,并且没有理由不使用它们。与替代方案相比,它们更易于使用,并且提供了更多功能(例如,在一个单独的元素中同时使用margin-leftpadding-leftleft)。

与替代方案width:100% + box-sizing | calc()相比,left + right | top + bottom得到了更好的浏览器支持,而且更容易使用!

当然,如果您不需要(就像您的示例一样)在y轴上扩展元素,那么使用width:100%并为填充使用一些嵌套元素,这是实现对MSIE6支持的唯一解决方案。

所以,这取决于您的需求。如果您想支持MSIE6(这是唯一的实际原因),您应该使用width:100%,否则使用left + right

希望对您有所帮助。


1
您介意解释一下规范的哪个部分提供了关于这些元素的信息,这些元素仅使用绝对坐标指定时不会填充父级容器吗?我很难理解链接的句子如何导致您列出的元素列表。 - davidtheclark

0

这两种方法都可以,但如果你想让你的设计具有响应性或手机兼容性-我建议在容器没有包含在<div>中时使用Left:Bottom:

如果它包含在一个<div>中,那么在我的意见中,使用width: 100%或者max-width: 200px是引起最少显示问题的一种方式。

如果您希望您的主题具有响应性,请避免在CSS中使用固定宽度。


在这种情况下,它并不适用于响应式设计(请参见演示)。 - Baumr

-1

我还没有在所有浏览器(和模式)上测试过,但对于IE怪异模式(例如在未定义DOCTYPE的.HTA中),我创建了一个子例程,用于纠正设置了LEFT / RIGHT样式或TOP / BOTTOM样式(不是“auto”)的元素的WIDTH或HEIGHT。为避免进入各种单位转换,该例程暂时删除LEFT(或TOP)样式,并将WIDTH(或HEIGHT)设置为100%以确定像素中的RIGHT(或BOTTOM)偏移量。

脚本是用VBScript编写的,但将其想法翻译成JavaScript应该不难。

<html>
<head>
    <script language="VBScript">

Option Explicit

Sub Justify(ByVal hElement)

    Dim sStyleTop, iTop, iBottom, sStyleLeft, iLeft, iRight

    With hElement
        If .currentStyle.top <> "auto" And .currentStyle.height = "auto" And .currentStyle.bottom <> "auto" Then
            iTop = .offsetTop
            sStyleTop = .currentStyle.top
            .style.top = "auto"
            .style.height = "100%"
            iBottom = -.offsetTop 
            .style.height = .offsetHeight - iTop - iBottom & "px"
            .style.top = sStyleTop
        End If
        If .currentStyle.left <> "auto" And .currentStyle.width = "auto" And .currentStyle.right <> "auto" Then
            iLeft = .offsetLeft
            sStyleLeft = .currentStyle.left
            .style.left = "auto"
            .style.width = "100%"
            iRight = -.offsetLeft 
            .style.width = .offsetWidth - iLeft - iRight & "px"
            .style.left = sStyleLeft
        End If
        For Each hElement In .Children
            Justify hElement
        Next
    End With

End Sub

Sub window_onload

    Justify Document.body

End Sub

    </script>
    <style type="text/css">
    body {
        position:absolute;
        width:100%;
        height:100%;
    }
    #outer{
        background:blue;
        position:absolute;
        top:10px;
        right:20px;
        bottom:30px;
        left:40px;
    }
    #inner{
        background:green;
        position:absolute;
        top:40px;
        right:30px;
        bottom:20px;
        left:10px;
    }
    </style>
</head>
<body>
    <div id="outer">
        <div id="inner">
        </div>
    </div>
</body>
</html>

文档中使所有元素对齐的命令是:
Justify Document.body

我正在从onload事件中调用它,因为它涉及到我的情况下的固定大小.HTA,但我希望该例程也能在可调整大小的窗口(或父元素)的onsize事件上工作。


1
欢迎来到SO!您是否错误地将答案发布在了错误的问题上? - Baumr
为什么呢?我认为这回答了当您在CSS中预定义左边和右边(或上边和下边)时,应该由浏览器计算宽度(或高度)的期望。 - iRon
我没有给你的回答点踩,但请参考我的问题和 Stack Overflow 的指南 — 希望能帮到你? - Baumr
它间接回答了“在哪些情况下,宽度为300像素会更有利?”的问题:是的,在您无法预测窗口或父元素的宽度并且想要左右两侧都“固定”对齐时。实际上,这是针对那些“将使代码更易于管理”的情况的答案。 - iRon
请参考SO指南,回答应该直接针对问题。此外,值得注意的是,在CSS问题中添加VBScript或JavaScript以实现简单布局是过度的。我不会说这会使代码更易管理;尽管我感谢你的尝试 - 谢谢。 - Baumr

-1

这两种解决方案在任何浏览器中都能正常工作,没有任何问题。在这些情况下,我喜欢为元素添加 width: 100%; left: 0; bottom: 0;,但如果你更喜欢 left:0;right:0; bottom:0;,那么你也可以使用它。


2
如果没有指定盒模型的方法,仅仅设置width: 100%会导致元素在添加内边距时变得更大。 - BenM
我认为那不是问题的一部分。 - Seer
1
显然,在图像的宽度或填充发生变化的情况下,使用left: 0;和right: 0;会使代码更易于管理。 - BenM
1
@Seer,我不想卷入争论,但你不能绝对排除IE6/7——这取决于每个网站的流量。 - Baumr
@Baumr,正确。每个人都可以决定在IE6的使用率为0.2%而IE7为0.8%时是否值得再努力工作,或者更加努力。我认为这些数字的一半只是开发人员,他们检查旧浏览器中的网站是否正常工作 :) 无论如何,我认为我们有点跑题了。我同意你在评论Khanh To时所写的内容。 - Seer
显示剩余2条评论

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