CSS Calc 替代方案

Posted

技术标签:

【中文标题】CSS Calc 替代方案【英文标题】:CSS Calc alternative 【发布时间】:2013-04-08 16:50:33 【问题描述】:

我正在尝试使用 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 浏览器吗?

【问题讨论】:

哇,IE 5.5?你是把这个分发到方舟还是什么的? 你怎么知道的!好吧,我至少在尝试让它在 6 或 7 上工作。 IE6-7 快死了,IE8 不支持expression - "Dynamic properties (also called "CSS expressions") are no longer supported in Internet Explorer 8 and later, in IE8 Standards mode and higher. "。 你确定你没有XY-problem吗? 为什么你要这样做?也许像边距/填充和/或包装元素这样简单的东西可以解决您的布局问题? 如果我是你,我会重新考虑我对 IE5.5 的支持。 IE6 被微软正式宣布死亡。我怀疑(希望)IE7 也会很快跟进。不要让旧的讨论回来,但你真的想要这个吗?如果答案是肯定的,那么一定要去做。 【参考方案1】:

在 calc 起作用之前有一个后备。

width: 98%;               /* fallback for browsers without support for calc() */
width: calc(100% - 1em);

在此处查看更多信息https://developer.mozilla.org/en-US/docs/Web/CSS/calc

【讨论】:

【参考方案2】:

几乎总是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;

* 
  margin: 0;
  padding: 0;

html,
body,
div 
  height: 100%;

.sideBar 
  position: absolute;
  top: 0;
  left: 0;
  width: 300px;
  background: orange;

.content 
  padding-left: 300px;
  width: 100%;
  -moz-box-sizing: border-box;
  box-sizing: border-box;
  background: wheat;
<div class="sideBar">sideBar</div>
<div class="content">content</div>

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

Width Demo

Height Demo

我刚刚从 Paul Irish 的博客中找到了 this post,他还展示了 box-sizing 作为简单 calc() 表达式的可能替代方案:(粗体是我的)

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

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

也就是说,如果内容 div 的宽度实际上是 100% - fixed div width很重要,那么可以使用不同的技术——利用块格式化上下文——(参见 here 和 @ 987654326@了解血腥细节):

1) 浮动固定宽度的div

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

Demo

【讨论】:

为什么需要这两个? -moz-box-sizing: border-box; & box-sizing: border-box;。我不能只指定填充和宽度 @buffer - 不,因为默认的盒子模型使用box-sizing-content-box,这意味着如果添加填充 - 元素的宽度会增加。对于box-sizing:border-box,填充是内部填充,元素的宽度根据您设置的内容保持不变。 如果高度是 px 和 % 的组合,而 % 应该占据剩余高度怎么办? 如果它是高度而不是宽度,这将如何改变? 知道,但没想到。旧的 android 仍然很常见,支持 box sizing 但不支持 calc。一个简单的绝对值和填充可以节省时间。【参考方案3】:

使用这个

    .content

    width: 100%;
    -moz-box-sizing: border-box;
    box-sizing: border-box;
    padding-right: 500px;
    margin-right: -500px;

【讨论】:

这不是 Danield 在他的回答中提出的吗? 不,它不是.. 如果你有一个 500px 的图像并且你想显示一个 (100%-500px) 的侧翼文本,我发现显示它们的唯一方法在 IE8 中正确的是为文本添加负边距。否则文本显示为块。 margin-right: -500px 让我的文本工作。不知道它是否覆盖了我错过的东西,我不在乎。救生员。【参考方案4】:

刚刚花了 3 个小时中最好的部分尝试解决这个在 Android 设备上的特定情况,无法让盒子大小工作,所以我将它链接到我的 JS 作为一个肮脏的解决方法......虽然不需要 jQuery! :)

采用 Android 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
;

希望这可以帮助任何无法使用 box-sizing 的人! PS 我在使用 ios 时遇到了问题...

【讨论】:

在 Android 2.3 上您似乎需要 -webkit- 前缀:caniuse.com/#feat=css3-boxsizing【参考方案5】:

用 % 或 px 改变#menuLog 的宽度,你会看到神奇的。适用于所有设备,甚至

*
	-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>

【讨论】:

【参考方案6】:

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

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

example above 可以做到,不用边框,就像

.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

【讨论】:

以上是关于CSS Calc 替代方案的主要内容,如果未能解决你的问题,请参考以下文章

CSS中的媒体片段URI替代方案?

css 这是我对内森萎缩头球的替代方案

normalize.css是一种CSS reset的替代方案

normalize.css是一种CSS reset的替代方案

CSS 媒体查询 - 软键盘打破 css 方向规则 - 替代解决方案?

CSS:不会破坏 3D 变换的“溢出:隐藏”替代方案