javascriptjsonsasscssom

Maintaining Vertical Rhythm on arbitrary images


I would like to be able to maintain vertical rhythm on a page that contains images of unknown heights. I found this but am using vanilla-js rather than jquery so a jquery plugin is out of the question. The other answer requires that the baseline be set in javascript. I already have it set in my SCSS files! I'm a very lazy programmer and don't want to type it twice. Wait, I didn't say that. I meant I'm concerned about the maintainability of duplicating hard-coded values all over the place.

here is another solution that I have to reject because I don't like all that extra markup over style concerns. It reminds me of the days when you had to nest <div> tags four deep just to get rounded corners.

It occurred to me to use generated content to pass JSON to the javascript. I thought I was a genius but then found this example using the exact same method.

Is there a better way of doing this?

All I really want is a way to specify that the height of an element needs to be a multiple of some given value. Is there really no way to do this with just CSS? The answers I've seen say there isn't. I feel like calc could almost do the job but am not smrt enough to figure it out. Is there a better way of getting the value to the javascript?

Thanks in advance.


Solution

  • It occurred to me that it is better to use CSS variables and then read those values from javascript as documented here.

    This has the advantages of

    1. using the cascade to allow multiple regions of the page to each have their own vertical rhythm.
    2. not requiring parsing the content of the ::after psuedo-element as JSON. The browsers are apparently inconsistent regarding how the escape embedding quotes in the content attribute.

    One downside is that custom attributes are not as widely supported as pseudo elements. This way will break on more browsers. Because it's only cosmetic, I find that acceptable.

    const foo = document.getElementsByClassName('foo')[0];
    const bar = document.getElementsByClassName('bar')[0];
    const fooStyles = window.getComputedStyle(foo);
    const barStyles = window.getComputedStyle(bar);
    const fooVR = fooStyles.getPropertyValue('--vertical-rhythm');
    const barVR = barStyles.getPropertyValue('--vertical-rhythm');
    
    foo.innerHTML = '--vertical-rhythm: ' + fooVR;
    bar.innerHTML = '--vertical-rhythm: ' + barVR;
    :root {
      line-height: 1.5rem;
      /* $line-height */
      --vertical-rhythm: 3rem;
      /* 2 * $line-height */
    }
    
    .foo {
      --vertical-rhythm: 6rem;
      /* 4 * $line-height */
    }
    <div class="foo"></div>
    <div class="bar"></div>