Tips for maintaining the original size of an image until it is fully loaded to ensure a stable layout

I have always believed that you could define the physical dimensions of an <img/> element using the width and height attributes to inform the browser without requiring a full download. However, it seems that these attributes are considered as CSS properties, which leads to them being overridden when altering with something like width: 50%; height: auto. As a result, the computed height remains at 0 until the image is fully downloaded.
Is there a way to explicitly establish the image's physical dimensions (essentially its aspect ratio) using HTML/CSS?

(...and prevent "flashes of unknown aspect ratios" or constant re-layouting issues when using Masonry - although there might be workarounds, my main concern lies in understanding the fundamental problem. Even if I'm struggling to articulate it succinctly :)

Answer №1

As we enter 2021, a more widely supported and standards-compliant method for achieving this can be found using the CSS aspect-ratio property.

To implement this, you can set the height and width as follows:

.myimage {
  width: 50%;
  height: auto;
  aspect-ratio: 1280 / 720;
}

With this approach, first, the width is calculated as 50% of the parent element's width. Then, by setting the height to auto and defining the aspect ratio, the correct height is determined dynamically.

It's important to note that even after the image has loaded, changes made with the aspect-ratio property persist. This means that if the specified aspect ratio doesn't match the image's actual aspect ratio, the image may appear stretched. To avoid this, it's recommended to include the "auto" value before the aspect ratio values.

aspect-ratio: auto 1280 / 720;

This method ensures that the defined aspect ratio is used until the browser determines the actual intrinsic aspect ratio of the image, at which point it reverts back to automatic sizing.

While this technique is not compatible with non-standard browsers like Internet Explorer and Safari, there is an alternative HTML solution available now. Most modern browsers utilize the height and width attributes of the image element to calculate the aspect ratio before applying CSS styles.

For instance...

<img src='myimage.jpg' class='myimage' width='1280' height='720' />
.myimage {
  width: 50%;
  height: auto;
}

By specifying the width and height attributes directly in the image tag, the appropriate vertical height is reserved, ensuring compatibility across different browsers including Safari. However, please review any browser-specific implementation notes.

In browsers like Chromium and Firefox, the CSS aspect-ratio property is utilized along with a "auto" prefix to maintain the calculated aspect ratio.

aspect-ratio: auto attr(width) / attr(height);

Notably, Safari currently lacks support for the aspect-ratio property. As a result, it requires additional considerations, particularly when implementing lazy loading for images via JavaScript. In such cases, a fallback image should be included to ensure proper spacing allocation.

In conclusion, incorporating height and width attributes within your image tags remains essential for optimal display consistency.

Answer №2

Once we apply the CSS rule height: auto, the browser stops considering the predetermined size specified by the HTML attributes width and height.

Here are some potential workarounds and a possible solution for the future:

  1. Implement the Intrinsic Ratio Box hack
    <div style="height: 0; padding-bottom: 42.857%; position: relative">
      <img style="position: absolute; left: 0; height: 0; width: 100%; height: 100%" … />
    </div>
    
  2. Utilize data URIs and JavaScript to preload a placeholder with the same aspect ratio (beware of rounding errors!)
    <img src="data:image/jpeg;base64,/9j/4AAQSkZJRgABAQIAJQAlAAD/2wBDAFA3PEY8MlBGQUZaVVBfeMiCeG5uePWvuZHI////////////////////////////////////////////////////wAALCAAPACMBAREA/8QAFgABAQEAAAAAAAAAAAAAAAAAAAEE/8QAFBABAAAAAAAAAAAAAAAAAAAAAP/aAAgBAQAAPwDQgoICv//Z"
      onload="this.src='https://via.placeholder.com/3500x1500.jpg'"/>
    
    If opting for the "blurry placeholder" technique, ensure the framework supports it.
  3. Similar to option two, but using an SVG - easier to generate dynamically but lacks a blurry placeholder feature
    <img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg'
      width='350px' height='150px'%3E%3C/svg%3E"
      onload="this.src='https://via.placeholder.com/3500x1500.jpg'"/>
    
  4. If and when intrinsicsize is introduced (WICG, github/Chrome) and widely adopted, a more standardized approach will be available:
    <img intrinsicsize="350x150" width="…
    

All these methods have their drawbacks.
You can test options 2 and 3 in this Pen. While they may require more fine-tuning and testing, I personally anticipate the arrival of option 4, which should rectify a frustrating issue that shouldn't require fixing. Oh, browsers! :)

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

The child div disregarding the usage of Bottom and Top based on its parent div

Take a look at this code snippet on jsfiddle: https://jsfiddle.net/mcgfhL10/ #description{ /*A brief description of the product. */ font-family:"microsoft sans serif"; font-size:22px; position:relative; overflow-y:scroll; bottom:40px; ...

What is the proper way to utilize document.getElementById() within a standalone js file?

As I dive into learning web development for the first time, I've decided to keep my scripts organized in separate files. However, I'm facing a challenge when trying to access elements from these external files. Below is a snippet of the JavaScri ...

Developing a Cutting-Edge 3D Waterwheel Carousel with Bootstrap

I am interested in building a waterwheel carousel design where the middle item is slightly larger than the previous and next items. I have figured out how to create the carousel using cards, but adjusting the size of the middle item is proving to be challe ...

What could be causing my submenu to not display the specified hover effect?

Help needed troubleshooting dropdown menu issue in HTML and CSS. Using :hover to switch from display:none; to display:flex;. Want submenu to appear when hovering over "Unsere Produkte". Grateful for any assistance. Thank you. /* Desktop Navigation Bar ...

Leveraging jQuery for manipulating innerHTML() content

As a complete beginner to jQuery, I am experimenting with updating the content of a span based on user input before clicking a button. $(document).ready(function() { // Replace span inner html with user input value $('button').cl ...

Is there a way to access a comprehensive list of all the font names stored on my personal computer?

I'm currently working on a project that requires using local fonts only. Since I am using a Mac, I have located the fonts in /Library/Fonts. However, I have encountered an issue when trying to use a font named 华文黑体 directly in my CSS property: ...

I'm experiencing some unexpected behavior in JavaScript when I try to apply style changes using JavaScript. Is it possible that transitions are not occurring in both cases as expected?

Everything seems to be working fine with the transition, but when I skip using setTimeout and directly apply the transform, the div instantly reaches the end of the transition. function move(x, y, delay) { let el = document.getElementById('myDiv& ...

Storing all information in a single list and then either revealing them one by one or modifying the HTML content of individual div elements

I'm currently working on an app using "vue.js" that features multiple videos, each with a button, title, and description. When a user clicks on the button, only the selected video's title and description should be displayed while hiding those of ...

Center align `div 1` with CSS and right align `div 2`

Take a look at this code snippet: http://jsfiddle.net/zygnz/1/ <div class="container"> <div class="left"> LEFT </div> <div class="right"> RIGHT </div> </div> Is i ...

Tips for obtaining the dynamically loaded HTML content of a webpage

I am currently attempting to extract content from a website. Despite successfully obtaining the HTML of the main page using nodejs, I have encountered a challenge due to dynamic generation of the page. It seems that resources are being requested from exter ...

Tips for removing a class with ng-class when a value is empty or evaluates to nothing

I'm facing an issue with a class I've created called .lines-hover. My goal is to remove this class when the values in the td elements are empty. For reference, take a look at this example: If you observe closely, on some of the lines, such as M ...

Automatically populate email fields with pre-filled form data

Looking to create an HTML form that utilizes JS/jQuery (no PHP) to capture data from "subject" and "message" fields and send an email. The goal is for the client-side code to open the user's mail client, pre-fill the subject and body with form data, a ...

Ensure that the page is edited before being shown in the iframe

Is it possible to remove a div from an HTML page within an iFrame? The code below fetches an HTML page and displays it in an iframe. Is there a way to remove the specified div from the fetched HTML page? <script type="text/javascript"> (function(){ ...

What is the best way to ensure a textfield remains aligned with its label in ExtJS?

Hey there, I am working on a large window that contains a form with multiple text fields. The default alignment has the labels to the left and the input boxes centered. Is there a way to keep the input boxes aligned next to their respective labels on the ...

Having trouble vertically aligning text? Combining AngularJS, Bootstrap, and Flexbox can help!

I have spent a lot of time trying to understand why I am unable to vertically align the text inside these cells. I have tried multiple solutions: align-items: center; vertical-align: middle; justify-content: center; justify-items: center; Unfortunately, ...

What could be causing the HTML5 video to not function properly on the latest Safari version for Windows?

After conducting tests on multiple installations of Safari 5.1.7 for Windows, I am having trouble getting HTML5 videos to play. I have been using the following link for testing: Basic HTML5 video test The videos appear to work fine on Safari 5.1.7 for Ma ...

What steps can I take to initiate a specific action on a recurring element?

I am trying to trigger a specific action (keyframe animation and text display) on .hover for a particular image, but instead, it is affecting all images when hovered over. The closest solution I found was: $(document).click(function(event){ alert ...

Issue with vertical navigation bar

Currently working on creating a vertical navigation bar without any styling. It's challenging to figure out how to align the items properly side by side. You can check out the basic functionality at . When clicking on 'Android', I want the g ...

Ways to eliminate the default Bootstrap body style within a component's HTML file

I am facing an issue with my angular widget directive where my custom CSS is getting overridden by Bootstrap default styles when I add the widget to another application component. View my Bootstrap CSS here. I am struggling to remove the font-family in m ...

The button contains two span tags, but they are displaying as block elements instead of inline elements

Currently, I am tackling a Reactjs project and utilizing the Bootstrap framework for design purposes. Within a specific div element, there exists a button with two Span tags nested inside. The first Span tag contains an Icon while the second one holds text ...