Calculate height of div based off width & maintain

2019-06-15 05:19发布

This question already has an answer here:

I am looking for a pure CSS solution to what I have here done using jQuery to help.

Basically I have 3 divs that spread evenly in width in a container. They maintain a 3/4 ration with the height being calculated off of the width. Furthermore, each div has a background image that stays proportional and some text that is centered horizontally and vertically.

$(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>

Here is a pen showing what I have. https://codepen.io/nom3d/pen/arGpBV

Here is a gif showing the effect when resized. Note the background image staying proportional and text staying centered. 3 box resize with proportions kept

Also wondering if it's not possible with just CSS, how to do this with plain javascript, would I need to add id's to my divs?

Update: here is a plain javaScript function to handle this task

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条回答
何必那么认真
2楼-- · 2019-06-15 05:46

Have you tried with

footer div {
    height: 20vw;
}

there is also calc property for css which could be helpful

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

查看更多
Viruses.
3楼-- · 2019-06-15 05:49

Probably a bit late, but will add my solution as well.

I thought I should keep it a general solution, so I decided to not use your Footer classes. But I'm sure you'll get the trick.

In my opinion the easiest way is to use the padding calculation to get a fixed ratio and some divs.

  1. Flex container
  2. Flex items (with the padding on it): This container is used to maintain the resolution. The amount of padding for it depends on the width of the item. For example: Item width = 100% --> Padding = (100/4)*3 --> 75% padding
  3. Content container inside Flex-Item where you can put your stuff
  4. Background-Div inside the content container
  5. put everything you need as sibling to the background-div

Here's a fiddle to play around, some comments are in the code: https://jsfiddle.net/Hoargarth/Lry5gbsq/ Feel free to ask if you need anything

Just a quick note on all of those containers: You could do it with just the flex-item and one other container. But in my opinion, with the extra container it get's more flexible if you need any hover-events, animations or som other exotic stuff. For the simple solution see this fiddle: 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>

查看更多
登录 后发表回答