Go to main content

Textpattern CMS support forum

You are not logged in. Register | Login | Help

#13 2021-02-06 17:58:24

giz
Member
From: New Zealand
Registered: 2004-07-26
Posts: 259
Website

Re: How to calculate article image aspect ratio?

Its not very pretty, but works:

<txp:php>
	$h = image_info(array('type' => 'h'));
	$w = image_info(array('type' => 'w'));
	$r = $h/$w;
	global $orientation;
	$orientation = 'square';
	if($r > 1.1) {
		$orientation = 'portrait';
	} else if($r < 0.9) {
		$orientation = 'landscape';
	}
	global $variable;
	$variable['image-orientation'] = $orientation;
</txp:php>
<img src="blah" class="<txp:variable name="image-orientation" />" alt />

Offline

#14 2021-02-08 04:32:55

Kjeld
Member
From: Tokyo, Japan
Registered: 2005-02-05
Posts: 446
Website

Re: How to calculate article image aspect ratio?

giz wrote #328589:

Its not very pretty, but works:

<txp:php>...

Thank you!


Old Photos of Japan – Japan in the 1850s~1960s (100% txp)
MeijiShowa – Stock photos of Japan in the 1850s~1960s (100% txp)
JapaneseStreets.com – Japanese street fashion (mostly txp)

Offline

#15 2021-02-08 11:59:38

nobi-wan
Member
Registered: 2021-02-05
Posts: 23

Re: How to calculate article image aspect ratio?

giz wrote #328589:

Its not very pretty, but works:

<txp:php>...

This looks like it should answer all my prayers, at least from the last 24 hours. However, like the txp hack I am I’ve added it to my article form, not knowing any better, and I get it thrown back at me with a

Tag error: ……. “Warning: Division by zero while parsing form default on page default”.

What’s the proper implementation?

Oh, I also tweaked the code to be tighter on the parsing out of ratios with < or > than 1. Wrong?

if($r > 1) { $orientation = ‘portrait’; } else if($r < 1) { $orientation = ‘landscape’; }

ps: can’t get bc. to work!

Offline

#16 2021-02-08 18:03:18

giz
Member
From: New Zealand
Registered: 2004-07-26
Posts: 259
Website

Re: How to calculate article image aspect ratio?

nobi-wan wrote #328620:

What’s the proper implementation?

The snippet needs to be within a <txp:images /> tag, so it knows which image(s) you’re specifying.

Oh, I also tweaked the code to be tighter on the parsing out of ratios with < or > than 1. Wrong?

No, that should work if you don’t need to allow for square images.

Offline

#17 2021-02-08 18:28:44

nobi-wan
Member
Registered: 2021-02-05
Posts: 23

Re: How to calculate article image aspect ratio?

Thanks!

Offline

#18 2021-02-09 11:16:15

Kjeld
Member
From: Tokyo, Japan
Registered: 2005-02-05
Posts: 446
Website

Re: How to calculate article image aspect ratio?

This became quite a popular thread, I noticed.

Once again, many thanks for all the input and assistance!


Old Photos of Japan – Japan in the 1850s~1960s (100% txp)
MeijiShowa – Stock photos of Japan in the 1850s~1960s (100% txp)
JapaneseStreets.com – Japanese street fashion (mostly txp)

Offline

#19 2021-07-15 06:56:14

Kjeld
Member
From: Tokyo, Japan
Registered: 2005-02-05
Posts: 446
Website

Re: How to calculate article image aspect ratio?

Thanks again for all the suggestions.

I have come up with an alternative solution that solves two problems:

  1. Figuring out if an image is landscape, square or portrait (the original intention of this thread)
  2. Calculating the size of the surrounding div of the responsive image to prevent Cumulative Layout Shift while the image is loading

It is quite a complicated and long explanation. I hope you are able to follow it…

css

To prevent Cumulative Layout Shift, I have created the class .responsive-container for the div holding the image.

Notice var(--img-aspect-ratio). This will be defined in the next paragraph (Variable for list images).

/* Responsive container sets height of image to prevent a jump in the page, which lowers the Google rating */
.responsive-container {
    width: 100%;
    padding-bottom: var(--img-aspect-ratio);
    position: relative;
}
.responsive-container img {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
}

Variable for list images

To prevent Cumulative Layout Shift.

For stylistic reasons, all my list images have the same image aspect ratio.
I add the value for this in a style section in the head using --img-aspect-ratio as defined in the above css.

For example for a site where all list images are square:

<head>
<style>
:root {
--img-aspect-ratio: 100%; /* img height divided by img width */
}
</style>
</head>

For a site where all list images are oblong (the original images are 1500 pixels high by 2400 pixels wide):

<head>
<style>
:root {
--img-aspect-ratio: 62.5%; /* [1500/2400] img height divided by img width */
}
</style>
</head>

Variable for article images

To prevent Cumulative Layout Shift AND enable lay-out changes for different image ratios.

You can use the above variable for list images also for individual article images if they use the exact same image aspect ratio as the list images.

But on one of my sites, the article image on an individual article can be of any image aspect ratio. So, I create a special variable in the head of the page that calculates the image aspect ratio of the article image for an individual article.

For this, two variables are created: a ratio (with %) and a number (without %):

  1. img-aspect-ratio
  2. img-aspect-number
<head>
<txp:if_individual_article>
<txp:images id='<txp:custom_field name="article_image" />'>
<txp:php>
	$h = image_info(array('type' => 'h'));
	$w = image_info(array('type' => 'w'));
	$r = ($h/$w)*100 . '%';
	$v = ($h/$w)*100;
	global $variable;
	$variable['img-aspect-ratio'] = $r;
	$variable['img-aspect-number'] = $v;
</txp:php> 
</txp:images>
</txp:if_individual_article>
</head>

html for list images

Used to prevent Cumulative Layout Shift.

Notice the responsive-container class in the div around the image. It uses the --img-aspect-ratio defined in the <style> declaration in the <head>. The other classes are bootstrap classes.

Because of the responsive-container class, there is no Cumulative Layout Shift. The images load inside a div that already has the appropriate height.

    <!-- START ARTICLE -->
      <article class="col">
        <div class="card h-100 title-upper">
          <txp:if_article_image>
            <div class="responsive-container">
            <img src="<txp:smd_thumbnail type='sq-800' format='url' id='<txp:custom_field name="article_image" />' />" alt="…" class="card-img-top">
            </div>
          </txp:if_article_image>
          <div class="card-body">
            <h2 itemprop="headline"><span><txp:custom_field name="location and date" /></span><br /><txp:title /></h2>
            <p class="lead my-4"><txp:excerpt escape="p" /></p><p><a href="<txp:permlink />" class="stretched-link"><txp:text item="read_more" /></a></p>
          </div>
        </div>
      </article>
    <!-- /END ARTICLE -->

html for individual article images

Figure out if an image is landscape (< 100), square (> 100) or portrait (> 115) and make the column containing the image smaller for square and portrait images:

  • I change the column size of the container div according to the img-aspect-number calculated in Variable for article images. I have a smaller column for square images, and an even smaller column for portrait images: class="<txp:evaluate query='<txp:variable name="img-aspect-number" /> < 100'>col-xl-7<txp:else /><txp:evaluate query='<txp:variable name="img-aspect-number" /> > 115'>col-xl-5<txp:else />col-xl-6</txp:evaluate></txp:evaluate>"

Calculate the size of the surrounding div of the responsive image to prevent Cumulative Layout Shift while the image is loading:

  • If the image aspect ratio of the individual article images are exactly the same as the list images, you only need the responsive-container class for the div around the image.
  • But if the images are of different image aspect ratios, I use the img-aspect-ratio variable by adding style="padding-bottom: <txp:variable name='img-aspect-ratio' />" to the div around the image.
<section class="overflow-hidden article-header"><!-- /START SECTION -->
  <div class="container-fluid g-0"><!-- START CONTAINER -->
    <div class="row align-items-end"><!-- START ROW -->
      <div class="<txp:evaluate query='<txp:variable name="img-aspect-number" /> < 100'>col-xl-7<txp:else /><txp:evaluate query='<txp:variable name="img-aspect-number" /> > 115'>col-xl-5<txp:else />col-xl-6</txp:evaluate></txp:evaluate>">
      <txp:if_article_image>
      <txp:images id='<txp:custom_field name="article_image" />' class="">
      <div class="responsive-container" style="padding-bottom: <txp:variable name='img-aspect-ratio' />">
      <img src="<txp:smd_thumbnail type='ls-1920' format='url' />"
      srcset="<txp:smd_thumbnail type='ls-0640' format='url' /> 640w,
      <txp:smd_thumbnail type='ls-0768' format='url' /> 768w,
      <txp:smd_thumbnail type='ls-1024' format='url' /> 1024w,
      <txp:smd_thumbnail type='ls-1366' format='url' /> 1366w,
      <txp:smd_thumbnail type='ls-1600' format='url' /> 1600w,
      <txp:smd_thumbnail type='ls-1920' format='url' /> 1920w"
      class="d-block w-100" alt="<txp:image_info escape="" type="alt" />"
      />
      </div>
      </txp:images>
      </txp:if_article_image>
      </div>
      <div class="<txp:evaluate query='<txp:variable name="img-aspect-number" /> < 100'>col-xl-5<txp:else /><txp:evaluate query='<txp:variable name="img-aspect-number" /> > 115'>col-xl-7<txp:else />col-xl-6</txp:evaluate></txp:evaluate> px-4">
        <h1 itemprop="headline"><span><txp:custom_field name="location and date" /></span><br /><txp:title /></h1>

      </div>
    </div><!-- END ROW -->
  </div><!-- END CONTAINER -->
</section><!-- /END SECTION -->

Sample Output

Oblong

Square

Portrait

These layouts change according to the size of the screen, the images are fully responsive, and there is no Cumulative Layout Shift.

Suggestions

I think this can probably be simpler and more elegant. Would love to hear your suggestions.

And hopefully, it is helpful to others as well!

Last edited by Kjeld (2021-07-26 14:14:53)


Old Photos of Japan – Japan in the 1850s~1960s (100% txp)
MeijiShowa – Stock photos of Japan in the 1850s~1960s (100% txp)
JapaneseStreets.com – Japanese street fashion (mostly txp)

Offline

Board footer

Powered by FluxBB