根据宽度计算div的高度并保持比例

时间:2019-05-25 15:14:20

标签: javascript html css height responsive

我正在寻找一种纯CSS解决方案,以解决我在这里使用jQuery所提供的帮助。

基本上,我有3个div,它们在容器中的宽度均匀分布。它们保持3/4的比例,高度是根据宽度计算得出的。此外,每个div都有一个与背景保持比例的背景图像以及一些水平和垂直居中的文本。

$(document).ready(function() {
  function setw() {
    var footdivwidth = $('footer div').width();
    var footdivheight = footdivwidth * .75;
    $('footer div').css({
      'height': footdivheight + 'px'
    });
    $('footer div span').html('w: ' + footdivwidth + '<br>h: ' + footdivheight);
  }
  setw();
  $(window).resize(function() {
    setw();
  })
});
FOOTER {
  max-width: 1000px;
  margin: 0 auto;
  background-color: rgba(0, 0, 0, 0.171);
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
}

FOOTER DIV {
  background-image: url('https://learnwebdesign.online/img/bg.jpg');
  background-position: center;
  background-size: cover;
  background-repeat: no-repeat;
  flex: 1;
  text-align: center;
  display: flex;
  align-items: center;
  justify-content: center;
}

FOOTER DIV SPAN {
  display: inline-block;
  text-align: center;
  background-color: rgba(165, 165, 165, 0.282);
  padding: 7px 15px;
  border-radius: 3px;
  color: #FFFFFF;
  text-transform: uppercase;
  font-weight: bold;
  letter-spacing: 2px;
  font-size: 21px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<footer>
  <div><span>left photo</span></div>
  <div><span>center photo</span></div>
  <div><span>right photo and more text</span></div>
</footer>

这是一支笔,显示我的财产。 https://codepen.io/nom3d/pen/arGpBV

这是显示调整大小后效果的gif。请注意背景图像保持比例,文本保持居中。 3 box resize with proportions kept

还想知道如果仅CSS不可能实现,如何使用普通javascript 做到这一点,我是否需要在div中添加ID?

更新:这是一个简单的javaScript函数来处理此任务

function setHeight(el,val){
    var box = document.querySelectorAll(el);
    var i;
    for(i = 0;i < box.length;i++){
        var width = box[i].offsetWidth;
        var height = width * val;
        box[i].style.height = height + 'px';        
    }
}
// set your element to target and the ratio value
setHeight('footer div',.75);
window.onresize = function(event) {
    setHeight('footer div',.75);
};

8 个答案:

答案 0 :(得分:1)

您尝试过

footer div {
    height: 20vw;
}

css的calc属性也可能有帮助

https://developer.mozilla.org/en-US/docs/Web/CSS/calc

答案 1 :(得分:1)

快速的纯CSS解决方案将涉及添加到FOOTER DIV

  max-width: 333px;
  width: calc(100vw/3);
  height: calc(100vw*0.75/3);
  max-height: calc(333px*0.75);

并添加到FOOTER

  width: 100vw;

// Javascript is only used in order to check the width/height ratio in console live.
$(document).ready(function() {

  $(window).resize(function() {
    console.log('width: ' + $('footer div').width() + ', height: ' + $('footer div').height());
  });
  
});
FOOTER {
  max-width: 1000px;
  width: 100vw;
  margin: 0 auto;
  background-color: rgba(0, 0, 0, 0.171);
  display: flex;
  flex-wrap: wrap;
  /*justify-content: space-between;*/
}

FOOTER DIV {
  background-image: url('https://learnwebdesign.online/img/bg.jpg');
  background-position: center;
  background-size: cover;
  background-repeat: no-repeat;
  flex: 1;
  text-align: center;
  display: flex;
  align-items: center;
  justify-content: center;
  max-width: 333px;
  width: calc(100vw/3);
  height: calc(100vw*0.75/3);
  max-height: calc(333px*0.75);
}

FOOTER DIV SPAN {
  display: inline-block;
  text-align: center;
  background-color: rgba(165, 165, 165, 0.282);
  padding: 7px 15px;
  border-radius: 3px;
  color: #FFFFFF;
  text-transform: uppercase;
  font-weight: bold;
  letter-spacing: 2px;
  font-size: 21px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<footer>
  <div><span>left photo</span></div>
  <div><span>center photo</span></div>
  <div><span>right photo and more text</span></div>
</footer>

答案 2 :(得分:0)

您可以简单地考虑获得the aspect ratio using padding.

的基本技巧

在此示例中,我保留了两个示例,以便您可以进行比较,一个使用jQuery,另一个使用纯CSS。

$(document).ready(function() {
  function setw() {
    var footdivwidth = $('footer div').width();
    var footdivheight = footdivwidth * .75;
    $('footer.no-padd div').css({
      'height': footdivheight + 'px'
    });
    $('footer div span').html('w: ' + footdivwidth + '<br>h: ' + footdivheight);
  }
  setw();
  $(window).resize(function() {
    setw();
  })
});
FOOTER {
  max-width: 1000px;
  margin: 0 auto;
  background-color: rgba(0, 0, 0, 0.171);
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
}

FOOTER DIV {
  background-image: url('https://learnwebdesign.online/img/bg.jpg');
  background-position: center;
  background-size: cover;
  background-repeat: no-repeat;
  flex: 1;
  text-align: center;
  display: flex
}
FOOTER:not(.no-padd) DIV:before {
  content:"";
  padding-top: 75%;
}

FOOTER DIV SPAN {
  margin:auto;
  text-align: center;
  background-color: rgba(165, 165, 165, 0.282);
  padding: 7px 15px;
  border-radius: 3px;
  color: #FFFFFF;
  text-transform: uppercase;
  font-weight: bold;
  letter-spacing: 2px;
  font-size: 21px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<footer class="no-padd">
  <div><span>left photo</span></div>
  <div><span>center photo</span></div>
  <div><span>right photo and more text</span></div>
</footer>

<footer >
  <div><span>left photo</span></div>
  <div><span>center photo</span></div>
  <div><span>right photo and more text</span></div>
</footer>

答案 3 :(得分:0)

在CSS中保持特定的高宽比通常是通过利用填充百分比总是 计算based on the element's width的事实来完成的。

例如,假设您有一个包含width: 500pxheight: 300pxpadding: 10%的元素。现在,您可能希望顶部和底部填充为height的10%,而左侧和右侧填充为width的10%。但是,这将导致不相等的垂直和水平填充,这与预期的目的相反-填充率为10%。为了理解这一点,我们需要将填充百分比基于保存维度,并且已选择该维度作为宽度。

因此,我们始终具有一个高度与宽度之比为3:4的元素,我们可以将高度设置为0,底部(或顶部)填充设置为宽度的3/4。

在您的示例中,Flex赋予每个项目33%的宽度。对于3:4的比率,底部填充应为33%* 3/4或24.74%。您的CSS可能看起来像:

width: 33%;
height: 0;
padding-bottom: 24.75%;

请注意,由于高度为0,因此需要相对定位元素,并在其中放置绝对定位的包装器。如果尝试将内容直接放入div中,则会破坏比率。您上面的代码可以这样修改:

footer {
  max-width: 1000px;
  margin: 0 auto;
  background-color: rgba(0, 0, 0, 0.171);
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
}
footer div {
  background-image: url('https://learnwebdesign.online/img/bg.jpg');
  background-position: center;
  background-size: cover;
  background-repeat: no-repeat;
  position: relative;
  width: 33%;
  height: 0;
  padding-bottom: 24.75%;
}
footer div span {
  /* Used as content wrapper, with flex to centre content */
  position: absolute;
  top: 0; bottom: 0;
  left: 0; right: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  background-color: rgba(165, 165, 165, 0.282);
  padding: 7px 15px;
  border-radius: 3px;
  color: #FFFFFF;
  text-transform: uppercase;
  font-weight: bold;
  letter-spacing: 2px;
  font-size: 21px;
}
<footer>
  <div><span>left photo</span></div>
  <div><span>center photo</span></div>
  <div><span>right photo and more text</span></div>
</footer>

答案 4 :(得分:0)

可能要晚一点,但也会添加我的解决方案。

我认为我应该将其保留为一般解决方案,因此我决定不使用您的Footer类。但是我相信你会成功的。

我认为最简单的方法是使用填充计算来获得固定比率和一些div。

  1. 弹性容器
  2. 柔性物品(上面有衬垫):此容器用于保持分辨率。它的填充量取决于项目的宽度。 例如:项目宽度= 100%->填充=(100/4)* 3-> 75%填充
  3. Flex-Item内的内容容器,您可以在其中放置东西
  4. 内容容器内的Background-Div
  5. 将您需要的所有内容都放入background-div

这是一个小玩弄,代码中有一些注释:https://jsfiddle.net/Hoargarth/Lry5gbsq/ 随时询问您是否需要任何东西

快速浏览一下所有这些容器: 您可以仅使用flex-item和另一个容器来完成此操作。但是我认为,如果需要任何悬停事件,动画或其他奇特的东西,有了额外的容器,它会变得更加灵活。 有关简单的解决方案,请参见以下提琴:https://jsfiddle.net/Hoargarth/m57b9jcw/

.container {
  width: 100%;
  display: flex;
  flex-wrap: wrap;
}

/* padding bottom gives the height of the container, 33.33% padding would be a quadratic box. 100% would be the same height as the container's width. Therefore simple trignomometry, (100/4) * 3 = 75%; or for screen width > 500px: (33.33 / 4) * 3 for a 4/3 resolution. You'll find the media query at the end of the css. It's just to demonstrate that it's working with media queries as well. */
.item {
  position: relative;
  width: 100%;
  padding-bottom: 75%;
}

/* Overflow hidden so nothing can overlap to the other items */
.content-wrapper {
  position: absolute;
  overflow: hidden;
  width: 100%;
  height: 100%;
}

.image-holder {
  position: relative;
  height: 100%;
  background-image: url("https://previews.123rf.com/images/happydancing/happydancing1706/happydancing170600014/80282512-flat-lay-photo-of-workspace-desk-with-laptop-smartphone-blank-notebook-and-green-plant-with-copy-spa.jpg");
  background-size: cover;
  background-position: 50%;
  background-repeat: no-repeat;
}

/* Absolute positioned by 50% top, left; To completely center it, you have to translate the holder back by it's own half width and height transform: translate(-50%, -50%) */
.text-holder {
  position: absolute;
  top: 50%;
  left: 50%;
  padding: 10px;
  width: 70%;
  background-color: rgba(255, 255, 255, 0.5);
  transform: translate(-50%, -50%);
  text-align: center;
}

/* Simple media Query to test it. Be aware: If the item's width is changing, the padding has to change as well */
@media (min-width: 500px) {
  .item {
    width: 33.33%;
    padding-bottom: 24.75%;
  }
}
<div class="container">

  <div class="item">
    <div class="content-wrapper">
      <div class="image-holder"></div>
      <div class="text-holder">
        <p>
          Some Centered Text
        </p>
      </div>
    </div>
  </div>
  
  <div class="item">
    <div class="content-wrapper">
      <div class="image-holder"></div>
      <div class="text-holder">
        <p>
          Some Centered Text but larger and longer so we see a difference
        </p>
      </div>
    </div>
  </div>
  
  <div class="item">
    <div class="content-wrapper">
      <div class="image-holder"></div>
      <div class="text-holder">
        <p>
          Groot
        </p>
      </div>
    </div>
  </div>
  
</div>

答案 5 :(得分:0)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style>
        FOOTER {
            max-width: 1000px;
            margin: 0 auto;
            background-color: rgba(0, 0, 0, 0.171);
            display: flex;
            flex-wrap: wrap;
            justify-content: space-between;
        }
        FOOTER DIV {
            position: relative;
            width: calc(100vw / 3);
            height: calc(100vw / 3 * 0.75 );
            max-height: calc(1000px / 3 * 0.75 );
            background-image: url('https://learnwebdesign.online/img/bg.jpg');
            background-position: center;
            background-size: cover;
            background-repeat: no-repeat;
            flex: 1;
            text-align: center;
            display: flex;
            align-items: center;
            justify-content: center;

        }
        FOOTER DIV SPAN {
            position: absolute;
            top:50%;
            left: 50%;
            transform: translate(-50%, -50%);
            display: inline-block;
            text-align: center;
            background-color: rgba(165, 165, 165, 0.282);
            padding: 7px 15px;
            border-radius: 3px;
            color: #FFFFFF;
            text-transform: uppercase;
            font-weight: bold;
            letter-spacing: 2px;
            font-size: 21px;
        }
    </style>
</head>
<body>
    <footer>
        <div><span>left photo</span></div>
        <div><span>center photo</span></div>
        <div><span>right photo and more text</span></div>
    </footer>
</body>
</html>

您可以直接使用给定的代码,为了使宽度的高度成为比例,您有2种不同的方法,下面给出其中一种,您可以将百分比的宽度和高度与calc一起使用,

另一种以宽度为单位的宽度,而不是高度,您可以以百分比为单位填充底部,而所有高度都相同。

答案 6 :(得分:0)

对于那些不想深入了解OP的代码并且只需要使用CSS来响应固定比率元素的解决方案的人,这是一种更通用的解决方案。

基本思想是根据元素的宽度计算padding (百分比)。这意味着padding-bottom: 100% == element.width(在这种情况下为正方形)。我们可以通过计算比率并将其用于填充来劫持该技巧。


图片示例

图像有些奇怪,因为它们已经具有宽高比,因此您只需设置height: auto就可以了。

比率:4:3

img {
  --aspectRatio: calc(3/4 * 100%);
  display:block;
  width: 300px; // this one needs a width to work.
  height:var(--aspectRatio);
}
<img src="https://images.unsplash.com/photo-1559666126-84f389727b9a" />


图片背景

但是,假设您希望容器管理大小而不管原始内容比率如何?只需使用背景图片即可。

这是16:9(典型的宽屏)

.fixedAspect {
  --aspectRatio: calc(9/16 * 100%);
  height: 0;
  padding-bottom: var(--aspectRatio);
  background-size: cover;
  background-position: center center;
}
<div class="fixedAspect" style="background-image: url(https://images.unsplash.com/photo-1559662780-c3bab6f7e00b)"></div>

带有内容的HTML元素

使用height:0和大量填充向元素添加内容可能不是最佳解决方案。但是我们可以通过使用伪类来解决这个问题。强制“最小高度”。

奖金:如果您的内容大于您定义的position: absolute;包装器的长宽比,则不会中断。

.fixedAspect {
  margin: 20px;
  background-color: #f6f3f0;
}

p {
  font-family: Helvetica, Arial, Sans-Serif;
  padding: 10px;
}

.fixedAspect:before {
  --aspectRatio: calc(5/20 * 100%);
  content: "";
  height:0;
  padding-top: var(--aspectRatio);
  
  /* so you can see the element */
  background-color: #F47E20;
  
  /* get this out of the way */
  float: left;
  width: 1px;
  margin-left:-1px;
}

.fixedAspect:after {
  /* we need to clear the float so its container respects height */
  content: "";
  display: table;
  clear: both;
}
<div class="fixedAspect">
  <p>My default size is a ratio of 20:5 but I'll grow if there's too much content.</p>
</div>

答案 7 :(得分:-1)

纯CSS修复

相应地调整宽度和高度

footer {
    display: flex;
    width: 100vw;
    align-items: center;
    justify-content: center;
}

.responsive-box {
    width: 33vw;
    border: 1px solid blue;
    max-width: 333px;
    min-width: 35px;
    flex-flow: row;
    height: 60vh;
  position: relative;
}

.responsive-box span {
   position: absolute;
   top:40%;
   bottom:0;
   left:0;
   right:0;
   text-align: center;
}
<footer>
  <div class="responsive-box left"><span>left photo</span></div>
  <div class="responsive-box center"><span>center photo</span></div>
  <div class="responsive-box right"><span>right photo and more text</span></div>
</footer>