Is there any way to resize css elements in increments / multiples of a particular number?

Viewed 206

I'd like any div element to resize when the viewport size changes, so generally I could use e.g. flex or 10em or % - but actually I'd like it only to resize in increments of 30 pixels, so it'd always align with a background.

Is this possible?

The only way I could think of is defunct - it might have been possible with the mod operator back in the day but not now?

Using modulus in css calc function

Also I could achieve this with media queries but to set that up for increments of only 30 pixels would be a nightmare.

The snippet below has a max-width of 210px and a min-width of 30px. As the browser resizes from wide to thin, it should jump in increments of 30px only.

.Mlt{
   background-color:grey;
   min-width:60px;
   max-width:210px;
}
<div class="Mlt">
    <p>Hello</p>
    <p>Content</p>
</div>

2 Answers

CSS grid can do this but you will need an extra container. The trick is to create columns having 30px of width using auto-fit then you simply span all the created columns:

The use of jquery is only for demo purpose to show the width on resize. I also removed the max-width to easily test

console.log($('.Mlt > div').width());
$(window).resize(function() {
  console.log($('.Mlt > div').width());
})
.Mlt {
  min-width: 60px;
  display:grid;
  grid-template-columns:repeat(auto-fit,30px);
  /* justify-content: center; <-- use this if you want to center the div */
}

.Mlt > div {
  grid-column:1/-1; /* take all the columns */
  background-color: grey;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="Mlt">
  <div >
    <p>Hello</p>
    <p>Content</p>
  </div>
</div>

It's not what I'd call easy on the eyes, but, this is the best solution I could come up with:

const div = document.querySelector('.Mlt');

window.addEventListener('resize', () => {
  if (div.clientWidth >= window.innerWidth - 20) {
    div.style.width = div.clientWidth - 30 + "px";
  } else if (div.clientWidth < window.innerWidth - 20) {
    div.style.width = div.clientWidth + 30 + "px";
  }

  // Display div width
  document.getElementById('div-width').innerHTML = div.style.width;
})
.Mlt {
  background-color: grey;
  min-width: 60px;
  max-width: 510px;
}
<div class="Mlt">
  <p>Hello</p>
  <p>Content</p>
</div>

<!-- Display div width -->
<div id="div-width"></div>

Relies on JS if that's what you're after. With CSS I don't see any other way than setting an unreasonable number of media queries, like you said.

The divs width increases and decreases by multiples of 30 when it hits the edge of the viewport. I've set minus 30 on window.innerWidth as that's what it needed in JSFiddle's preview window, you might need to tweak it a bit.

You can test it here: https://jsfiddle.net/L61sq3fd/1/

Related