Javascript 设置一个元素的长度(高度或宽度)减去另一个元素的可变长度,即calc(x-y),其中y未知

Javascript 设置一个元素的长度(高度或宽度)减去另一个元素的可变长度,即calc(x-y),其中y未知,javascript,jquery,css,flexbox,Javascript,Jquery,Css,Flexbox,我知道我们可以在定义长度时使用: flex-basis: calc(33.33% - 60px); left: calc(50% - 25px); height: calc(100em/5); 但是如果长度是可变的呢 height: calc(100% - <<header with variable height>>); 高度:计算(100%-); 或 宽度:计算(100%-50px-); 在CSS中有没有标准的方法来实现这一点 我知道使用flexbox和表可

我知道我们可以在定义长度时使用:

flex-basis: calc(33.33% - 60px);
left: calc(50% - 25px);
height: calc(100em/5);
但是如果长度是可变的呢

height: calc(100% - <<header with variable height>>);
高度:计算(100%-);

宽度:计算(100%-50px-);

在CSS中有没有标准的方法来实现这一点

我知道使用flexbox和表可以完成整个任务,但我想知道CSS是否提供了一种更简单的方法。Flexbox、表和简单Javascript是可接受的替代方案

Flexbox可以做到这一点

支持IE10及以上

*{
保证金:0;
填充:0;
}
html,
身体{
身高:100%;
}
#容器{
身高:100%;
显示器:flex;
弯曲方向:立柱;
}
#顶{
背景颜色:浅绿色;
}
#底部{
背景颜色:浅蓝色;
弹性:1;
}

绿框可变高度
蓝色框不再溢出浏览器窗口

您可以使用CSS表:

.wrapper{
显示:表格;
宽度:100%;
利润率:15px0;
}
.horizontal.wrapper>div{
显示:表格单元格;
空白:nowrap;/*防止换行*/
边框:1px实心;
}
.左{宽度:100px}/*最小宽度为100px*/
.center{width:0;}/*由内容给定的宽度*/
.vertical.wrapper{高度:200px;}
.vertical.wrapper>div{
显示:表格行;
}
.vertical.wrapper>div>span{
显示:表格单元格;
边框:1px实心;
}
.top{高度:100px;}/*最小高度为100px*/
.medium{height:0;}/*由内容给定的高度*/
.bottom{高度:100%;}/*尽可能高*/

100像素宽
自动宽度,由内容给定
剩余空间
100像素高
自动高度,由内容给定
剩余空间
已更新

正如我前面提到的,除了
flex
,使用
display:table
也可以解决这个问题,下面是我制作的一个示例

如果垂直演示也需要一个固定顶部,下面是我的原始
显示:表的更新版本:

有时我不能(或不想)使用flex或tables,我时不时地考虑使用和

但两者都很短,因为
calc()
只能使用
+-*/
,而
attr()
只能返回字符串值,而
calc()
无法计算该值

我的建议是使用纯javascript,基于这两种方法在某个时候可能会被扩展,以便我们能够更好地使用它们

这就是我希望看到他们工作的方式

width: calc(100% - attr(this.style.left))
但是他们没有,我也不能把它添加到我的css中,因为它不能正确地验证(甚至可能破坏解析,谁知道呢),我在元素上添加了一个变量作为一个属性,有一些怪癖使它更容易计算

在本例中(2个演示),它看起来是这样的:

//height
<div id="bottom" data-calcattr="top,height,calc(100% - toppx)">...</div>

//width 
<div class="box right" data-calcattr="left,width,calc(100% - leftpx)">...</div>
div.flexh {
    display: table; box-sizing: border-box; padding: 0; margin: 0;
}
div.flexh > div { 
    display: table-cell; width: auto; 
    box-sizing: border-box; vertical-align: middle;
}
div.flexh > div:first-child {
    /* Override your custom styling below */
    min-width: 75px; width: 75px; max-width: 75px; 
}
div.flexh > div:last-child { width: 100%; }
//高度
...
//宽度
...
再加上下面的脚本,它绝不是在所有属性组合上完全开发/测试的,它确实调整了div的大小

简而言之,在运行时,它获取属性,将其拆分为一个数组,获取第一个项值作为从哪个属性读取,第二个项值设置为哪个属性,第三个项值插入/替换读取值并分配给要设置的属性(嗯,仍在研究一种更好的表达方式,但希望脚本已经足够清晰了)

这里显示的是高度和宽度演示,集成,使用相同的脚本

function calcattr() {
    var els = document.querySelectorAll('[data-calcattr]');
    for (i = 0; i < els.length; i++) {
        var what = els[i].getAttribute('data-calcattr');
        if (what) {
            what = what.split(',');
            var rect = els[i].getBoundingClientRect();
            var parentrect = els[i].parentNode.getBoundingClientRect();
            var brd = window.getComputedStyle(els[i].parentNode,null).getPropertyValue('border-' + what[0] + '-width');            
            what[2] = what[2].replace(what[0],parseInt(rect[what[0]]-parentrect[what[0]]) - parseInt(brd));
            els[i].setAttribute("style", what[1] + ":" + what[2]);
        }
    }
}
函数calcattr(){
var els=document.querySelectorAll(“[data calcattr]”);
对于(i=0;i
我正在寻找一些简单和可移植的东西。就像CSS一样 属性可以很容易地跨文档应用,我正在寻找 在该功能的易用性方面类似

…首选独立修复程序

水平: 这只能通过CSS实现。由于您不喜欢
flex
布局解决方案,下一个最佳选择是表格布局

您可以将一个简单的CSS片段放入您的项目中(并且可以使用该片段完成),如下所示:

//height
<div id="bottom" data-calcattr="top,height,calc(100% - toppx)">...</div>

//width 
<div class="box right" data-calcattr="left,width,calc(100% - leftpx)">...</div>
div.flexh {
    display: table; box-sizing: border-box; padding: 0; margin: 0;
}
div.flexh > div { 
    display: table-cell; width: auto; 
    box-sizing: border-box; vertical-align: middle;
}
div.flexh > div:first-child {
    /* Override your custom styling below */
    min-width: 75px; width: 75px; max-width: 75px; 
}
div.flexh > div:last-child { width: 100%; }
然后,您可以根据站点要求将特定于站点的样式添加到此基础CSS。例如,
nowrap

此解决方案的两个明显优点是:

  • 您不需要更改标记,也不需要用类装饰所有子级。只需将类
    flex
    应用于父级
    div
    ,即可
  • 所需的最小标记:

    
    75px固定宽度
    可变内容宽度
    柔性剩余宽度
    
    75px固定宽度 柔性剩余宽度
    75px固定宽度 可变文本宽度 可变内容宽度

    柔性剩余宽度
    在CSS中 虽然我从未尝试过,但我相信这会奏效:

    .top {
        height:13px;
    }
    
    .main {
        height:calc(100% - var(height));
    }
    


    盛气凌人

    在这两种情况下,您应该在容器css上放置:

    #container {
        overflow: hidden;
    }
    

    但是,它会隐藏溢出容器的信息。我认为这就是问题所在,因为您放置了
    空白:nowrap;
    ,这意味着您不想更改高度,所以您必须隐藏不适合容器的文本。

    这是一个好问题。对于
    宽度
    ,表格布局可能有效。表格单元格宽度
    #container {
        overflow: hidden;
    }