首页 > 解决方案 > 在应用包含/覆盖之前调整背景图像的大小

问题描述

一般问题:

我想调整 CSS 背景图像的大小(不保持纵横比),然后将 abackground-size: contain应用于同一图像。反过来做会在一定程度上抵消该contain选项的效果。

这可以用 HTML/CSS 完成还是有必要将 Javascript 引入其中?在我的用例中,事先手动编辑图像是不可行的。

我的用例:

http://jsfiddle.net/h5a2nxfd/68/

我有一些我想以左右或上下改变纵横比显示的图片,具体取决于横向或纵向模式是否处于活动状态。上面的 JSFiddle 缺少大小更改。

我尝试过使用transform来应用缩放,但在当前的解决方案中,宽度/高度div.item是可变的,所以它不是很可行。

我对你的建议持开放态度。我可能试图从错误的角度解决这个问题。但我宁愿不使用 Javascript。

编辑:在 JSFiddle 中使用的示例 SVG 图像中添加了圆圈。

标签: cssflexboxbackground-imagebackground-size

解决方案


如果您可以使用 HTML 和 CSS 解决方案,而不仅仅是纯 CSS 解决方案,则以下通过将图像嵌套在 a中来工作div,让您更有效地拆分弹性项目大小样式和图像大小样式。您可以在 flex 项目上设置样式以确定.image将包含在其中的框的大小,和/或在其自身上设置宽度和高度.image以倾斜图像的纵横比。请注意,为了更灵敏地执行此操作,我没有在容器上设置固定宽度和高度,而是.image. 您可以根据需要更改纵横比。我也用imgs 代替divs 与背景图像,这使您可以对开箱即用的纵横比进行更多控制(即,与div显式宽度不同,并且height: auto;img导致保留纵横比,以及width: auto;显式高度,这可能当您的布局从基于行的 flexbox 布局切换到基于列的布局时很有用)。

img使用标签而不是div带有背景图像的 s 的另一个潜在好处是使用object-fit: contain;属性(或者object-fit: scale-down;如果您希望图像只缩小而不是放大)而不是将图像的宽度和高度设置为容器的 100% 限制为适当的纵横比或background-size: contain;div带有背景图像的情况下使用。有关的参考,请参阅MDNobject-fit,包括浏览器支持信息。

这是一个工作代码片段,其img标签放置在纵横比框中,其纵横比未作为问题请求保留:

document.body.addEventListener("click", function() {
  document.body.classList.toggle("portrait");
});
html,
body {
  height: 100%;
}

.container {
  height: auto;/*you had this as 100%. If you are going to constrain the height of your container, then you need to constrain the height of the items too to make sure they still fit inside, ie put max-height: 50%; on the items inside the container.*/
  width: 100%;
  display: flex;
  flex-flow: row wrap;
  /*align-items: stretch;*//*align-items: stretch; will cause potential problems with your layout if you intend for there to be more than 1 item per row/column*/
}

/*body.portrait .container {
  flex-direction: column;
}*/

.item {
  /*flex-grow: 1;*//*flex-grow: 1; will likewise cause potential problems with your layout if you intend for there to be more than 1 item per row/column*/
  width: 50%;/*can use width auto with images that have an intrinsic width to let image size determine width, or can set an explicit width as I have done here (for 1 image per row 100%, for 2 images per row 50%, etc)*/
}

.aspect-ratio-box-outer {
  position: relative;
  width: 100%;
  height: 0;
  padding: 0 0 75%;
  margin: 0;
}

.aspect-ratio-box-inner {
  position: absolute;
  width: 100%;
  height: 100%;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
}

.item .image {
  background-repeat: no-repeat;
  background-position: center;
  background-size: 100% 100%;
  width: 100%;
  height: 100%;
}

body.portrait .aspect-ratio-box-outer {
  padding: 0 0 133.33333%;
}


/* The images are inline SVG for demonstration purposes only */
/*.item.first {
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='500' height='400'><rect width='100%' height='100%' style='fill: red' /><circle cx='50%' cy='50%' r='150' style='fill: black' /></svg>");
}*/
/*.item.second {
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='500' height='400'><rect width='100%' height='100%' style='fill: blue' /><circle cx='50%' cy='50%' r='150' style='fill: black' /></svg>");
}*/
<!DOCTYPE html>
<html>

<head>
  <meta charset="UTF-8">
  <title>Stackoverflow question</title>
</head>

<body>
  <p>
    Click to toggle between landscape and portrait mode.
  </p>
  <div class="container">
    <div class="item first">
      <div class="aspect-ratio-box-outer">
        <div class="aspect-ratio-box-inner">
          <!--<div class="image"></div>-->
		  <img class="image" src="data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='500' height='400'><rect width='100%' height='100%' style='fill: red' /><circle cx='50%' cy='50%' r='150' style='fill: black' /></svg>" alt="" />
        </div>
      </div>
    </div>
    <div class="item second">
      <div class="aspect-ratio-box-outer">
        <div class="aspect-ratio-box-inner">
          <!--<div class="image"></div>-->
		  <img class="image" src="data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='500' height='400'><rect width='100%' height='100%' style='fill: blue' /><circle cx='50%' cy='50%' r='150' style='fill: black' /></svg>" alt="" />
        </div>
      </div>
    </div>
  </div>
</body>

</html>


推荐阅读