通过CSS设置基于高度的元素宽度

时间:2011-05-27 05:00:47

标签: css

我有一组元素,要求它们的最小宽度等于它们的高度,但未明确设置高度。目前,我可以通过jQuery设置css min-width属性来实现这一目的:

$(document).ready
(
    function()
    {
        $('.myClass').each
         (
             function() {$(this).css('min-width', $(this).css('height'));}
         );
    }
);  

是否可以直接在css中指定此行为?

这是一个jsfiddle,展示了我想要实现的目标:http://jsfiddle.net/p8PeW/

10 个答案:

答案 0 :(得分:57)

如果没有JS,这实际上是可能的!

关键是要使用<img> replaced element,因此如果您只设置高度,它的宽度将自动设置以保留图像的内在纵横比。

因此,您可以执行以下操作:

<style>
  .container {
    position: relative;
    display: inline-block; /* shrink wrap */
    height: 50vh; /* arbitrary input height; adjust this */
  }
  .container > img {
    height: 100%; /* make the img's width 100% of the height of .container */
  }
  .contents {
    /* match size of .container, without influencing it */
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    right: 0;
  }
</style>

<div class="container">
  <!-- transparent image with 1:1 intrinsic aspect ratio -->
  <img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7">
  <div class="contents">
    Put contents here.
  </div>
</div>

如果您希望.contents具有4:3的宽高比,那么您应该将img的高度设置为133%,因此img的宽度因此.contents的宽度将是高度为.container的133%。

1:4宽高比的现场演示:https://jsbin.com/juduheq/edit(附加代码注释)。

另一个现场演示,其中容器的高度由兄弟元素中的文本量决定:https://jsbin.com/koyuxuh/edit

如果您想知道,img数据URI适用于1x1 px transparent gif)。如果图像没有1:1的宽高比,则必须相应地调整您设置的高度值。您还可以使用<canvas><svg>元素代替<img>(感谢Simo)。

如果您想要根据 width 设置元素 height ,那么Maintain the aspect ratio of a div with CSS就会有更简单的技巧。

答案 1 :(得分:2)

来自W3C Box Model填充:

  

百分比是根据宽度计算的   生成的框包含块,即使是'padding-top'和   “填充 - 底部”。如果包含块的宽度取决于此   元素,然后在CSS 2.1中未定义结果布局。

所以你可以只使用CSS。请参阅this example this blog post,了解另一个同样有趣的主题。创建比率框的技巧是使用

之类的东西
element::before {
  content: '';
  display: block;
  padding-bottom: 100%;
}

答案 2 :(得分:1)

还有另一种非常简单的css解决方案,但仅针对他在jsfiddle中提出的OP的确切情况:

label {
  background-color: Black;
  color: White;
  padding: 1px;
  font-family: sans-serif;
  text-align: center;
  vertical-align: middle;
  display: inline-block;
  min-width: 1em; /* set width to the glyphs height */
}
<label>A</label><br/>
<label>B</label><br/>
<label>C</label><br/>
<label>D</label><br/>
<label>E</label><br/>
<label>F</label><br/>
<label>R6a</label>

答案 3 :(得分:1)

没有图像,只有具有 100% 可变纵横比的纯 HTML + CSS。技巧是使用提供所需纵横比的内联 SVG。

.width-adjusting-to-height {
  display: inline-block;
  height: 200px; /* change to whatever you like */
  background: tomato;
  position: relative;
}

.width-adjusting-to-height > svg {
  height: 100%;
}

.width-adjusting-to-height .content {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
}
<div class="width-adjusting-to-height">
  <!-- the viewbox will provide the desired aspect ratio -->
  <svg viewBox="0 0 50 100"></svg>
  <div class="content">content goes here</div>
</div>

答案 4 :(得分:1)

现在新的 aspect-ratio 属性可以轻松做到这一点,并且在两种情况下都可以使用:

  1. 高度基于宽度
  2. 宽度基于高度

我们只需设置比例和宽度或高度:

.box {
  height:80vh;
  background:red;
  aspect-ratio:9/6;
}

.box1 {
  width:50vw;
  background:green;
  aspect-ratio:9/6;
}
<div class="box">

</div>

<div class="box1">

</div>

答案 5 :(得分:0)

如果您要制作正方形,则必须考虑这两种情况(W > HW < H):

$('label').each(function() {
    if ($(this).height() > $(this).width()) {
        $(this).css('min-width', $(this).height());
    } else {
        $(this).css('min-height', $(this).width());
    }
});

答案 6 :(得分:0)

我有相同的要求,并且我使用@John Melor解决方案取得了很好的成功……直到在Firefox上无法使用为止。我尝试通过在此处测试不同的jsbin代码示例来重现我的特定问题,但是没有运气。可能是基于我的实际DOM的高度特定的浏览器错误。如果有人遇到该问题,请分享!

我尝试了许多组合,但都失败了:容器不会扩展到图像宽度。 Firefox声明图像具有其高度的宽度,但是无论我尝试了什么,父级的宽度均为1px。

对于在这种情况下发现自己的人,我使用了一个js错误修正,该修正仅保留在image元素的本地。如果未在最初的OP问题中指定容器的高度,那对您也可能会有用。

在JSX / ES6中:

const TRANSPARENT_PIXEL = 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7'
const setWidthToHeight = e => { e.target.style.width = e.target.height }
const force1x1Ratio = <img src={TRANSPARENT_PIXEL} onLoad={setWidthToHeight} />

使用普通的HTML

<img 
    src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" 
    onLoad="javascript:function(e) { e.target.style.width = e.target.height + 'px' }" />

答案 7 :(得分:0)

Safari 用户的坏消息:截至 2021 年 3 月 13 日,此页面上的解决方案将不起作用,至少在 Mac OS Big Sur 中是这样。

出于某种原因,Safari 在这方面出了点问题。

有一个权宜之计,并非在所有情况下都可以选择,但在某些情况下,它比这里的其他解决方案更容易:

  • 宽度使用 vh 单位:

    .container {
        height: 40vh;
        width: 20vh;
    }
    

Suuuuuuper简单,宽度始终与高度成比例。

  • 为了获得更大的灵活性,在某些情况下您甚至可以使用百分比:

    .container {
       height: 40%;
       width: 20vh;
    }
    

这将使容器与其父容器匹配 40%,并始终保持宽度与高度的比例。但这只适用于父元素本身的高度与整个视口的大小始终保持一致的比例。

所以,这不是一个通用的修复方法,但在许多情况下可能是最简单的方法。

答案 8 :(得分:0)

使用 flexboxpadding。使用 @media 查询来确定视口的最小纵横比。然后进行相应调整。

具有 16:9 纵横比的简化解决方案。

html,body {
  height: 100%;
}

.parent {
  height: 100%;
  width: 100%;
  border-style: solid;
  border-width: 2px;
  border-color: black;
  /* to center */
  display: flex;
  align-items: center;
  justify-content: center;
}

.child {
  width: 100%;
  /* 16:9 aspect ratio = 9 / 16 = 0.5625 = padding-bottom*/
  padding-bottom: 56.25%;
  background: blue;
}

@media (min-aspect-ratio: 16/9) {
  .parent>img {
    height: 100%;
    /* make the img's width 100% of the height of .container */
  }
  .child {
    height: 100%;
    /*16:9 aspect ratio = 9 / 16 = 177.77 = width*/
    width: 177.77vh;
    padding: 0;
    margin: 0px;
    background: red;
  }
}
<div class="parent">
  <div class="child">
    content that is not images...
  </div>
</div>

这是一个 fiddle

答案 9 :(得分:-4)

如果没有JS,我不相信这是可能的,但也许有人可以证明我错了?

CSS不允许你使用动态变量,所以如果在页面加载之前没有设置高度,我不知道如何做到这一点。