Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Force (rectangular) image to display as square with side length = variable parent div's width

I have a centered flexbox parent div, #con, with % width, which has an image(s)-containing div (.block) sandwiched between two padded text divs (#info and #links). How can I force .block img to be a square with side length equal to #con‘s width with JS or CSS? .block could contain 1×1=1 images, 2×2=4 images, etc; thus, background-image is not an option. Imitating the solution here only seems to work if I replace con.width() in the JS with a specific value (e.g. 300px, as shown here with this placeholder image), which is unideal.

var con = $("#con");
$(".block").css("height", con.width(), "width", con.width());
body {
    font-size:1rem;
    text-align:center;
    margin:0;
    height:100vh;
    display: flex;
    align-items: center;
    justify-content: center;
    overflow:hidden;
}

#con {
    width:50%;
    max-width:300px;
    display:flex;
    flex-flow:row wrap;
    justify-content:center;
    margin:5rem auto;
    border:1px solid black;
}

.block {width:100%; overflow:hidden; background:black;}
.block img {
    position: relative;
    top: 0;
    bottom: 0;
    left: 0;
    right: 0;
    object-fit: cover;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.7/jquery.min.js"></script>
<div id="con">
<div id="info">...</div>
<div class="block"><img src="https://dbdzm869oupei.cloudfront.net/img/vinylrugs/preview/60150.png"></div>
<div id="links">...</div>
</div>

>Solution :

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

You don’t need JS for this: just use aspect-ratio: 1 to force a square aspect ratio. You might want to add display: block to ensure the <img> is not displayed inline (which is the default) as well. See proof-of-concept below:

body {
  font-size: 1rem;
  text-align: center;
  margin: 0;
  height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
}

#con {
  width: 50%;
  max-width: 300px;
  display: flex;
  flex-flow: row wrap;
  justify-content: center;
  margin: 5rem auto;
  border: 1px solid black;
}

.block {
  width: 100%;
  overflow: hidden;
  background: black;
}

.block img {
  display: block;
  object-fit: cover;
  width: 100%;
  aspect-ratio: 1;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.7/jquery.min.js"></script>
<div id="con">
  <div id="info">...</div>
  <div class="block"><img src="https://dbdzm869oupei.cloudfront.net/img/vinylrugs/preview/60150.png"></div>
  <div id="links">...</div>
</div>

If you want to support browsers that do not have aspect-ratio support, you can use a combination of a pseudo-element + padding-bottom hack to set a fixed aspect ratio instead:

body {
  font-size: 1rem;
  text-align: center;
  margin: 0;
  height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
}

#con {
  width: 50%;
  max-width: 300px;
  display: flex;
  flex-flow: row wrap;
  justify-content: center;
  margin: 5rem auto;
  border: 1px solid black;
}

.block {
  width: 100%;
  overflow: hidden;
  background: black;
  position: relative;
}

.block::before {
  width: 100%;
  padding-bottom: 100%;
  content: '';
  display: block;
  
}

.block img {
  display: block;
  object-fit: cover;
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.7/jquery.min.js"></script>
<div id="con">
  <div id="info">...</div>
  <div class="block"><img src="https://dbdzm869oupei.cloudfront.net/img/vinylrugs/preview/60150.png"></div>
  <div id="links">...</div>
</div>
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading