Tips for ensuring responsive images do not cause blocks to jump down

How can we address the issue of blocks jumping after an image loads while still maintaining responsiveness?

Codesandbox.

Key points to consider:

  • The image should resize when the window is resized.
  • The maximum width of the image is its own width.
  • We do not have prior knowledge of the image size.
  • Javascript can be utilized to solve the problem.

Possible Solution:

If determining the exact image size is not feasible, could we instead base calculations solely on the image's aspect ratio?

By knowing the image’s aspect ratio, we can calculate the block height and embed a responsive image with some additional white space (the amount of which will be minimized on smaller screen sizes).

Image loading: https://i.sstatic.net/2SVx9.png

Image loaded: https://i.sstatic.net/acyA4.png

HTML:

import React from "react";
import "./styles.css";

const img =
  "https://s3.amazonaws.com/images.seroundtable.com/google-css-images-1515761601.jpg";

export default function App() {
  return (
    <div className="app">
      <img alt="" src={img + `?${Date.now()}`} className="img" />
      <h1>I always jump down :(</h1>
    </div>
  );
}

CSS:

.app {
  box-sizing: border-box;
}
.img {
  max-width: 100%;
}
h1 {
  background-color: red;
}

Answer №1

According to @DBS, it appears that the only viable solution is to wrap the image in a div block with a height calculated based on the window width and aspect ratio (in my case I am aware of it). If there are any alternative solutions, please feel free to share.

Check out the sandbox example for a solution.

import React from "react";
import "./styles.css";
import styled from "styled-components";

const aspectRatio = [1, 5];

const img =
  "https://s3.amazonaws.com/images.seroundtable.com/google-css-images-1515761601.jpg";

export default function App() {
  return (
    <div className="app">
      <StyledDiv>
        <img alt="" src={img + `?${Date.now()}`} className="img" />
      </StyledDiv>

      <h1>I always jump down :(</h1>
    </div>
  );
}

const StyledDiv = styled.div`
  height: calc(100vw / ${aspectRatio[1]});
  overflow-y: hidden;
`;

Answer №2

Upon realizing the challenge of determining image width while knowing the aspect ratio, it becomes evident that simply having the aspect ratio is not enough to meet the requirement of

Image max-width is it's own width
.

One potential solution could be implementing a build time method (assuming the image URLs are known during build). There are various server-side rendering options available for React applications that could also address this issue.

Alternatively, a basic DIY approach can be taken:

  1. Develop a Node script to execute on the server. This script will generate a JSON file containing image dimensions, referred to as "buildImageDimensionData.js", which outputs "imageDimensions.json".
var probe = require("probe-image-size");
const fs = require("fs");

const imageUrls = [
  `http://localhost:5000/image1.jpg`,
  `http://localhost:5000/image2.jpg`,
];

async function getImageDimensionsByUrl(urlList) {
  const probePromises = urlList.map(async (imageUrl) => await probe(imageUrl));
  let probedImagesData = [];

  try {
    probedImagesData = await Promise.all(probePromises);
  } catch (error) {
    
  }

  return probedImagesData.reduce((accumulator, imageData) => {
    accumulator[imageData.url] = [imageData.width, imageData.height];
    return accumulator;
  }, {});
}

getImageDimensionsByUrl(imageUrls).then((dimensions) =>
  fs.writeFileSync("imageDimensions.json", JSON.stringify(dimensions))
);
  1. Execute the script before building. For example, in a package.json file with Create React App:
    ...
    "start": "buildImageDimensionData && react-scripts start",
    "build": "buildImageDimensionData && react-scripts build",
    ...
  1. Incorporate the imported imageDimensions.json into your React image component to adjust dimensions based on image URL.

This demonstration serves as a concept illustration, acknowledging the availability of more efficient packages for such tasks.


An alternative, though less optimal approach, would be to delay rendering other content until images have fully loaded to prevent layout shifts.

Answer №3

If you want to prevent the sudden drop, make sure to adjust the margin of the following element to zero:

.container {
  box-sizing: border-box;
}
.image {
  max-width: 100%;
}
.container :nth-child(2) {
margin:0px
}

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

Displaying a preloaded image on the canvas

Once again, I find myself in unfamiliar territory but faced with the task of preloading images and then displaying them on the page once all elements (including xml files etc.) are loaded. The images and references are stored in an array for later retrie ...

Creating a responsive textbox in Bootstrap - tips and tricks!

I am trying to use Bootstrap and I have a Textbox that contains some text. How can I make it responsive, meaning it adjusts to the screen size when I resize the window? When dealing with images, we use the "image-responsive" class, but what about a Textb ...

Alignment of UI Divs with CSS Bootstrap and HTML

I am facing an issue with two divs in my UI. One div has a label, and the other contains a file selector. Currently, they are stacked vertically instead of being side by side. https://i.stack.imgur.com/fIz03.png How can I align these divs horizontally wit ...

"Yakov's slender typefaces are appearing incorrectly on the screen

I recently tried to incorporate Yakov thin fonts using CSS @font-face, but I noticed that the fonts appear quite different from the original ones. Any idea why this might be happening? Below is the code snippet I used: @font-face { font-family:' ...

Implementing Clockwise Padding with React Material-UI

Can Mui Box utilize shorthand properties for padding in a clockwise syntax? Unfortunately, this method does not work and results in a syntax error. <Box padding = {2 1 1 2}/> ...

Positioning divs next to each other in CSS and setting the width of the second

I am attempting to position two divs next to each other. The initial one is 200x200 pixels and the second one should be positioned 10 pixels to the right of the first one. The second div has a height of 200 pixels, and its width needs to extend all the way ...

Problem with CSS animations in IE10

I've encountered a problem with a specific section of a website I created. This section functions perfectly on all browsers and older versions of Internet Explorer, but not on the latest versions. It seems that IE no longer supports [IF] statements in ...

Overlap and cover additional elements within a DIV

I am looking to create a versatile function that can effortlessly overlay various elements such as selects, textfields, inputs, divs, tables, and more with a partially transparent div matching their exact height and width. I have managed to obtain the pos ...

Modify the text inside a div based on the navigation of another div

Hey there, experts! I must confess that I am an absolute beginner when it comes to JavaScript, JQuery, AJAX, and all the technical jargon. Despite my best efforts, I'm struggling to grasp the information I've found so far. What I really need is ...

Attempting to remove an attribute or property in JavaScript will not yield the desired result

When I try to close the menu after opening it, the inline style won't get removed despite trying different methods. The CSS only has text properties for alignment and the class can-transform contains a media query. That's all the information I h ...

Efficiently transferring time values from dynamically created list items to an input box using JavaScript

Is there a way to store a dynamically generated time value from an li element into an input box using JavaScript? I have a basic timer functionality on my website that includes starting, stopping, pausing, taking time snaps, and resetting them. These time ...

Incorporating pre-designed elements into the bottom section of my

I'm currently facing an issue while trying to integrate a footer content from a template into my slideout footer. The problem is that the template footer is currently spanning across the entire width of the page, and I am struggling to contain it with ...

Ways to animate elements while scrolling in React.js?

I am new to using React.JS and currently working on setting up an E-commerce Store. My goal is to have 5 images stack on top of each other and move together as the user scrolls. I used to achieve this effect in Vanilla JavaScript by adding a window.addEven ...

Please indicate the decimal separator for the Number() function

UPDATE : TITLE IS MISLEADING as testing showed that Number() returned a dot-separated number and the HTML <input type="number"/> displayed it as a comma due to locale settings. I changed to using an <input type="text"/> and filtered keydown lik ...

What is the reason behind text underline being disabled when using "hidden: overflow" in CSS?

I have a long text string that I want to auto-shorten using CSS with text-overflow: ellipsis, but it's removing the underline from my link. Here is the code: NORMAL .link { font-weight: bold; cursor: pointer; color: black; text-decorat ...

css: centrally align a collection of items that are spaced evenly throughout the group

I have multiple divs inside a container that I want to evenly distribute horizontally: [container [obj1] [obj2] [obj3] [obj4] ] Additionally, I would like the container to be centered on the page My current CSS (stylus) code for the container is as foll ...

How can you use jQuery to transform a H3 tag into a clickable link?

To transform the h3 tag into a clickable link with jQuery and set the href attribute, while preserving the H3 styling and adding an anchor tag, you can use the following code as an example: Click Here ...

HTML control for adjusting the pan and tilt of a device

I'm looking to develop an interactive input where users can drag a dot within a box and see the 2D coordinates of that dot displayed. The goal is to use this feature to control pan and tilt values. A similar functionality from another application is s ...

Updating tooltip text for checkbox dynamically in Angular 6

Can anyone help me with this code? I am trying to display different text in a tooltip based on whether a checkbox is active or not. For example, I want it to show "active" when the checkbox is active and "disactive" when it's inactive. Any suggestions ...

The browser does not support the display of Spanish special characters

I am working on a website and need to incorporate support for the Spanish language. I have prepared an XML file with both English and Spanish text. The XML file is being read based on the user's selection of language from a dropdown menu. Everything s ...