Responsive viewport height workaround for the WordPress Cover Block

I like big images and I cannot lie. I use the WordPress Cover Block a lot on projects and often have to customise it to play well with the sites I build.

There is plenty of criticism levied at WordPress Core developers when site builders run up against problems, but as someone who wrangles sites and the Block Editor for demanding clients1 full-time, I come across edge cases several times per week. I do my best not to curse and just use my own experience and ability to recognise and fix the problem.

A small example came up when I improved the front page of the website you’re reading now, adding a cover block with some nice typography and a big photo of some tulips. This worked perfectly well — I added a WordPress section style as a JSON file for the cover block — but when testing the layout, I found that there was a problem because of my use of viewport units: I wanted the cover block to be 75% of the viewport height.

Pretty new front page for this website, which we’re discussing in this blog post.

The issue was on very small viewport heights, for example on a mobile phone in horizontal orientation. 75% of a short screen is way too small to show all of the content, and so the big top padding wasn’t there to ensure that the content wasn’t overlapped by the fixed top navigation bar.

This is one of the ridiculously-picky situation which core developers are likely to miss, especially as the problem comes about thanks to a highly-specific custom theme. Because the CSS rule which sets the height is placed inline using the style tag, I can’t reliably override it using my own CSS, so I wrote this JavaScript which applies only under the specific conditions I’ve described. The sizing override2 applies automatically when the page is loaded, then removed if the screen size changes. (For example, if the visitor rotates their device.)

const blocks = document.querySelectorAll('.wp-block-cover[style*="min-height"]');

if (blocks.length) {
	blocks.forEach((block) => {
		const minHeight = block.style.minHeight;
		if (minHeight.indexOf('vh') !== -1 || minHeight.indexOf('svh') !== -1) {
			block.dataset.minHeightWas = minHeight;
		}
	});

	const doResize = () => {
		blocks.forEach((block) => {
			if (block.dataset.minHeightWas.indexOf('vh') !== -1 || block.dataset.minHeightWas.indexOf('svh') !== -1) {
				if (window.innerHeight < 650) {
					block.style.minHeight = '460px';
				} else {
					block.style.minHeight = block.dataset.minHeightWas;
				}
			}
		});
	};

	doResize();
	window.addEventListener('resize', doResize);
}

Footnote

  1. I am the most demanding website client I have. You wouldn’t believe the amount of time I’ve spent polishing tiny details on my own website over the past twenty-nine years. ↩︎
  2. Note that the values in this code are arbitrary and apply for use on this specific type of teaser element on my website. You might need to adjust them to suit your own implementation. ↩︎

Leave a Reply

Your email address will not be published. Required fields are marked *