相对于包含div的img宽度

时间:2017-03-14 05:04:38

标签: html css

原始问题

计算相对于css中包含div的图像宽度的最有效方法是什么?

我有以下代码段将#image1.width设置为相对于其父级宽度的百分比。我使用百分比是因为我需要图像在调整屏幕大小时按比例缩放到父级。



div {
  position: relative;
  display: block;
  width: 100%;
}

#image1 {
  position: absolute;
  left: 10%;
  top: 10%;
  width: 29.43%;
  height: auto;
}

#under {
  width: 100%;
}

<div>
  <img id="image1" src="http://placehold.it/206x115">
  <img id="under" src="http://placehold.it/700x300/ff00f0/ffffff">
</div>
&#13;
&#13;
&#13;

它目前按预期工作,但我必须手动计算每个图像的宽度百分比。即。

#image1 dimensions == 206x115
#under dimensions == 700x300
new #image1.width % == #image1.width / #under.width == 206/700 == ~29.43%

我想知道的是,我是否可以实施calc()方法或类似工具来简化/简化此流程?

我打算使用width: calc(100% / 700)但是当屏幕尺寸发生变化时,这显然无效。


目标

要重新迭代,#under图片必须与屏幕尺寸一致,而#image仍然是成比例的。

我希望彼此保留自然图像比率(即,在所有浏览器宽度下,图像的大小仅为另一个图像的四分之一)。

注意:可以通过任何方式重新配置html来实现此目的。

目标浏览器:Chrome,Firefox,Edge。


Post Bounty Review

评论@Obsidian Age的回答(第一笔赏金结束31.03.17):

不幸的是@Obsidian Age的答案是不正确的 - 它很接近但不完全,我只想在这里澄清一下......下面是他回答的片段......请注意,我认为这是一个很好的答案,只是澄清为什么它没有被接受:

:root {
  --width: 90vw; // Must be viewport-driven
}

#image1 {
  width: calc(var(--width) / 3); // The 3 can be replaced with any float
}

设置--width: 90vw如果bodydiv设置了max-width会发生什么?在考虑viewport-scaling时,这对于所有设备来说也很难计算。

#image1 { width:calc(var(--width) / 3); }这相当于calc(90vw / 3) 30vw,相当于图片宽度的30%。但是我们如何计算出除以的数字呢?好吧,它回到了我们开始的地方...... width:calc(var(--width) * calc(206/700*100));这就是为什么我没有接受这个答案。

5 个答案:

答案 0 :(得分:11)

不幸的是,CSS没有父选择器。虽然您无法使用CSS创建相对于父直接的元素,但 对纯CSS执行的操作设置为两个元素都使用的变量:

:root {
--width: 90vw; // Must be viewport-driven
}

现在您可以将此变量用作父元素的(固定)宽度,子项的计算驱动宽度:

#under {
  width: var(--width);
}

#image1 {
  width: calc(var(--width) / 3); // The 3 can be replaced with any float
}

请注意,变量必须是固定单位,或者相对于视口。如果它是基于百分比的,则#under#image1都会将其宽度偏离其各自的父母。为了使这项工作起作用,它必须基于视口。

:root {
--width: 90vw;
}

div {
  position: relative;
  display: block;
  width: 100%;
}

#image1 {
  position: absolute;
  left: 10%;
  top: 10%;
  width: calc(var(--width) / 3);
  height: auto;
}

#image2 {
  position: absolute;
  left: 25%;
  top: 10%;
  width: 10%;
  height: auto;
}

#under {
  width: var(--width);
}
<div>
  <img id="image1" src="http://placehold.it/206x115">
  <img id="under" src="http://placehold.it/700x300/ff00f0/ffffff">
</div>

我还创建了一个这个here的JSFiddle,你可以看到这两个元素在视口调整大小时缩放。

希望这有帮助! :)

答案 1 :(得分:6)

我意识到问题提示了一个纯粹的CSS解决方案,但我自由地将其解释为含义&#34;没有JavaScript&#34;。

在这方面,这是一个使用嵌入式SVG的解决方案:

&#13;
&#13;
<svg xmlns="http://www.w3.org/2000/svg" 
     xmlns:xlink="http://www.w3.org/1999/xlink"
     width="100%" viewBox="0 0 700 300">
     
  <image x="0" y="0"
      xlink:href="http://placehold.it/700x300/ff00f0/ffffff"/>
  <image x="10%" y="10%"
      xlink:href="http://placehold.it/206x115"/>
</svg>
&#13;
&#13;
&#13;

答案 2 :(得分:5)

我认为最好的方法是消除宽度和宽度。使用scale来拟合div,但问题是scale变换不接受任何单位值,例如%或px或vw / vh!

.common_img_class{
    transform: scale(calc(100vw/700)); /* this won't work! */
    /* Idea here is to let image take is original width & then scale with respact to base image scaling. Base image scaling is detenined by *window_width/base_image _width*, here base image width is 700 as per you example */
}

因此,我能想到的第二个最好是消除手动计算百分比。使用calc()功能为您完成此操作。

#firsrt_img{
    width: calc((206/700) * 100%);
}
#second_img{
    width: calc((306/700) * 100%);
}

在这里,你仍然需要为所有人写宽度,但至少要保留百分比或比率计算。

注意:
如果有人可以提供第一种方法,欢迎他们提供意见。

答案 3 :(得分:2)

如果你愿意使用bootstrap(https://getbootstrap.com/examples/grid/),可能会有一些工作:

<!-- parent -->
<div class="row">
  <div class="col-md-6">
    <img src="">
    <!-- this is 50% of the screen for min 992px, a full line otherwise -->
  </div>
  <div class="col-md-3">
    <img src="">
    <!-- this is 25% of the screen for min 992px, a full line otherwise-->
  </div>

  <div class=col-md-3>
    <img src="">
    <!-- this is 25% of the screen for min 992px, a full line otherwise -->
  </div>
</div>

您可以根据需要对这些进行分组,只需记住这些数字必须添加到12(在我的示例中为6 + 3 + 3)。使用col-md-12可以实现100%宽度效果。此外,md中缀只是将所有内容放在同一行和堆叠元素之间的几个截断选项之一。您可以查看http://getbootstrap.com/css/#grid了解更多详情,以及几个示例。

答案 4 :(得分:1)

Inspired by the answer of Robby Cornelissen, here is an approach that works in the targeted browsers currently. Its only drawback is that the dimensions of the images have to be specified in the HTML (well, the SVG really) explicitly.

Here is a demo.

<svg xmlns="http://www.w3.org/2000/svg" 
     xmlns:xlink="http://www.w3.org/1999/xlink"
     width="100%" viewBox="0 0 700 300">
     
  <image x="0" y="0" width="700" height="300"
      xlink:href="http://placehold.it/700x300/ff00f0/ffffff"/>
  <image x="10%" y="10%" width="206" height="115"
      xlink:href="http://placehold.it/206x115"/>
</svg>


The approach, like Robby's answer, uses the SVG image element. That currently defaults to having zero width and height when no dimensions are specified explicitly, but will change in SVG 2. This means that as soon as SVG 2 is supported by browsers, instead of specifying the image dimensions, we could set width="auto" height="auto" and be done.

The value auto for width and height on the ‘image’ element is calculated from the referenced image's intrinsic dimensions and aspect ratio, according to the CSS default sizing algorithm.
SVG 2 Editor's Draft, § 7.8. Sizing properties: the effect of the ‘width’ and ‘height’ properties. Accessed 2017-12-18.