CSS Calc替代


70

我正在尝试使用CSS和jquery动态更改div的宽度。以下代码将在以下浏览器中运行:http : //caniuse.com/calc

/* Firefox */
width: -moz-calc(100% - 500px);
/* WebKit */
width: -webkit-calc(100% - 500px);
/* Opera */
width: -o-calc(100% - 500px);
/* Standard */
width: calc(100% - 500px);

我还希望支持IE 5.5或更高版本,我发现以下内容:表达式。这是正确的用法吗?

/* IE-OLD */
width: expression(100% - 500px);

我还可以支持Opera和Android浏览器吗?


67
哇,IE 5.5?您是将其分发给方舟之类的东西吗?
BenM

1
你怎么知道的!好吧,我至少设法得到它的工作在6或7
H3AP


3
您确定没有XY问题吗?你为什么要这样做?也许诸如边距/填充和/或包装元素之类的简单内容可能会解决您的布局问题?
Jeroen

1
如果我是你,我会重新考虑我对IE5.5的支持。微软正式宣布IE6死亡。我怀疑(希望)IE7也能很快跟进。不想使旧的讨论重新出现,但是您真的想要这个吗?如果答案是肯定的,那么一定要去做。
Marijke Luttekes

Answers:


117

几乎总是box-sizing: border-box可以替换计算规则,例如calc(100% - 500px)用于布局的计算规则。

例如:

如果我有以下标记:

<div class="sideBar">sideBar</div>
<div class="content">content</div>

而不是这样做:(假设边栏为300px宽)

.content {
  width: calc(100% - 300px);
}

做这个:

.sideBar {
     position: absolute; 
     top:0;
     left:0;
     width: 300px;
}
.content {
    padding-left: 300px;
    width: 100%;
    -moz-box-sizing: border-box;
    box-sizing: border-box;
}

PS:我不会在IE 5.5(hahahaha)中工作,但它将在IE8 +,所有移动设备和所有现代浏览器(caniuse)中工作

宽度演示

身高示范

我刚刚从Paul Irish的博客中找到了这篇文章,他还展示了框大小调整作为简单calc()表达式的一种可能选择:(粗体是我的)

边框可以很好地解决我最喜欢的用例之一。我可能想用50%或20%的列划分网格,但想通过px或em添加填充。没有CSS即将发布的calc(),这是不可能的……除非您使用border-box

注意:以上技术的确与相应的calc()语句看起来相同。虽然有区别。当使用calc()规则时,内容div的宽度值实际上是100% - width of fixed div,但是使用上述技术,内容div的实际宽度为全100%宽度,但是看起来像是“填满”剩余宽度。(这可能足以满足大多数人的需求)

就是说,如果内容div的宽度实际上很重要100% - fixed div width 那么可以使用另一种技术-利用块格式化上下文-(请参见此处此处的详细信息):

1)浮动固定宽度div

2)在内容div上设置overflow:hiddenoverflow:auto

演示版


1
为什么需要这两个? -moz-box-sizing: border-box;box-sizing: border-box;。我不能只指定填充和宽度
用户

2
@buffer-否,因为默认的盒模型使用box-sizing-content-box它,这意味着如果添加填充,则元素的宽度会增加。与box-sizing:border-box填充是内填充,并根据你将其设置为所述元件遗体宽度。
Danield

如果高度是px和%的组合,而%应该占用剩余的高度怎么办?
miyalys 2014年

2
如果它是高度而不是宽度,它将如何变化?
路灯

2
知道它,但没想到。旧版android仍然很常见,支持框大小调整但不支持calc。简单的绝对和填充可以节省一天。
Mathijs Segers


17

用这个

    .content
{
    width: 100%;
    -moz-box-sizing: border-box;
    box-sizing: border-box;
    padding-right: 500px;
    margin-right: -500px;
}

4
这是丹尼尔(Danield)在回答中提出的建议吗?
skmasq 2014年

3
不,不是。如果您有500px的图像,并且要显示(100%-500px)的侧翼文本,我发现在IE8中正确显示它们的唯一方法是添加一个负数文字的边距。否则,文本将显示为块。
乔治

1
右边距:-500px使我的文本起作用。不知道它是否覆盖了我错过的东西,我不在乎。救生员。
myol 2014年

0

只是花了3个小时的大部分时间来尝试解决在Andriod设备上的特定情况下的问题,无法使框大小正常工作,所以我将其链接到我的JS中是一种肮脏的解决方法……不过,不需要jQuery!:)

承担了Andriod 2.3上的工作代码。

<div class="sessionDiv" style="width:auto;">
<img> <!-- image to resize -->
</div>
<div class="sessionDiv" style="width:auto;">
<img> <!-- image to resize -->
</div>

带有事件监听器的JS

var orient =
{
    orientation:window.orientation,
    width: window.innerWidth,
    check: function()
    {
        // if orientation does not match stored value, update
        if(window.orientation !== this.orientation)  
        {
            this.orientation = window.orientation; //set new orientation
            this.width = window.innerWidth; //set new width
            this.adjustIrritatingCSS(this.width); //change ui to current value
        }
        //if width does not match stored value, update
        if(window.innerWidth !== this.width)
        {
            this.width = window.innerWidth; //set new width
            this.adjustIrritatingCSS(this.width); //change ui to current value
        }
    },
    adjustIrritatingCSS: function(screenWidth)
    {   
    //disgusting workaround function
        var titleBoxes = document.getElementsByClassName('sessionDiv'); 
        var i = titleBoxes.length;
        var sessWidth = screenWidth - 300; // calc(100% - 300px); -> equivalent
        while(i--)
        {
            titleBoxes[i].style.width = String( sessWidth + "px"); 
            //resize image in auto sized div
        }
        sessWidth = null; //clear width
        titleBoxes = null; //clear nodelist
        i = null; // clear index int
    }
};

window.onload = function()
{
    window.addEventListener('resize', function(){orient.check();}); 
    //on resize, check our values for updates and if theres changes run functions
    window.addEventListener('orientationchange', function(){orient.check();});
    //on rotate, check our values for updates and if theres changes run functions
    setInterval(function(){orient.check();}, 2000);
    //occasionally check our values for updates and if theres changes run functions(just incase!!)
    orient.adjustIrritatingCSS(orient.width); 
    //sets value on first run
};

希望这可以帮助任何无法满足要求的人!PS我遇到了使用此iOS的问题...


看来您需要在Android 2.3上使用-webkit-前缀:caniuse.com/#feat=css3-boxsizing
Kevin Newman

0

用%或px更改#menuLog宽度,您将看到魔术。甚至适用于<2.3的所有设备

*{
	-moz-box-sizing: border-box;
    -webkit-box-sizing: border-box;
    box-sizing: border-box;
}
#menuLog{
  width:30%;
  /*width:300px;*/
	height: 60px;
	padding: 5px;
	background-color: #ddd;
}
#menuLog > div[inline-log="1"]{
	display: inline-block;
	vertical-align: top;
	width: 100%;
	height: 100%;
	margin-right: -60px;
}
#menuLog > div[inline-log="1"] > div[inline-log="1.1"]{
	margin-right: 60px;
	height: 100%;
	background-color: red;
}
#menuLog > div[inline-log="2"]{
	display: inline-block;
	vertical-align: top;
	width: 60px;
	height: 100%;
}
#menuLog > div[inline-log="2"] > div[inline-log="2.1"]{
	display: inline-block;
	vertical-align: top;
	width: 55px;
	height: 100%;
	background-color: yellow;
	margin-left:5px;
}
<div id="menuLog">
  <div inline-log="1">
    <div inline-log="1.1">
      One
    </div>
  </div><div inline-log="2">
     <div inline-log="2.1">
      Two
     </div>
  </div>
</div>


0

我想添加no-calc,no-border-box(即CSS2)替代方案。

正常流块元素最初具有width: auto,这实际上是包含块的宽度减去边距,边框和填充宽度。

上面示例可以在没有边框的情况下完成,只需

.content {
    padding-left: 300px;
}

同样地,

.content {
  margin-left: 1px;
  border-left: 1em solid;
  padding-left: 1rem;
}

有效宽度为100% - 1px - 1em - 1rem

对于绝对定位的元素,height: auto具有相似的属性:

.content {
  position: absolute;
  top: 0;
  bottom: 0;
  margin-bottom: 1px;
  border-bottom: 1em solid;
  padding-bottom: 1rem;
}

这里的有效高度是100% - 1px - 1em - 1rem

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.