Skip to main content

Responsive Images for Media Entities in Drupal 8

Image Styles Breadcrumb

Images on websites can be a huge pain when you are optimizing a site. We want our images to render as crisp as possible but we also want our sites to load as fast as possible. Content creators will often ask "what size image should I upload" and with the thought of some tiny image being rendered at full-screen width pixelated out of control we'll answer "as large as you've got". The content creator will then upload a 2mb jpeg and the load time/network request size will increase dramatically.

by nick.fletcher /

Responsive images can be a decent solution for this. A front end developer can achieve this in many ways. A popular way would be to use a <picture> element with the contents of multiple <source>'s using srcset and `media` attributes and a default <img> tag.

I'll explain how we can do that in Drupal 8. 
The scenario I'm trying to set up in this example is a paragraph that references a media entity with an image field.

Tutorial

Enable the responsive images module from Drupal core.

  1. To enable the responsive image module, go to Admin > Configuration.
  2. Click the checkbox next to Responsive Image.
  3. Click Install.

This module may already be installed on your project so just head to Admin > Config and ensure that the Responsive image styles module is enabled.

Responsive Image Styles Config

Add / Confirm breakpoints

The default theme will already have a breakpoints YAML file. If you're using a custom theme you'll need to make sure you have a breakpoints YAML file for it. This should exist at themes/{theme-name}/{theme-name}.breakpoints.yml, where {theme-name}, is the name of your theme.
Create or open the file and configure your breakpoints. There should be a few breakpoints in there and they'll look something like this

custom_theme.small:
  label: small
  mediaQuery: "(min-width: 0px)"
  weight: 1
  multipliers:
    - 1x
    - 2x
custom_theme.medium:
  label: medium
  mediaQuery: "(min-width: 768px)"
  weight: 2
  multipliers:
    - 1x
    - 2x
custom_theme.large:
  label: large
  mediaQuery: "(min-width: 1024px)"
  weight: 3
  multipliers:
    - 1x
    - 2x

You can add as many breakpoints as you need to suit your requirements. The weight should go from 0 for the smallest breakpoint to the highest number for the largest breakpoint. The multipliers are used to provide crisper images for HD and retina displays.

Configure Image Styles (sizes)

Head to Admin > Config > Media > Image Styles and create a size for each breakpoint.

Configuring Image Styles UI
  1. Click Add image style.
  2. Give it an Image style name and click Create new style (e.g. Desktop 1x, Desktop 2x, Tablet 1x etc...).
    Create Image Style UI
  3. Select an effect e.g. Scale or Scale and crop.
    Edit Image Style UI
    Edit Image Style Effect Options
  4. Set a width (height is calculated automatically) or width and height when cropping.
    Image Style Effect UI
  5. When creating multiple styles just use the breadcrumbs to get back to Configure Image Styles
    Image Styles Breadcrumb Item

When you have created all the sizes for your responsive format you can move on to the next step.

Create a responsive Image Style

Head to Admin > Config > Media > Responsive Image Styles

  1. Click Add responsive image style to create a new one.
  2. Give it a label (for example if it's for a paragraph type called profile_image then use that as the name)
    Add responsive image style UI
  3. Select your theme name from the Breakpoint Group
    Breakpoint Group Selection
  4. The breakpoints will load, open the breakpoints that this image style will use and check the radio next to Select a single image style or use multiple.
    Configuring the breakpoint image style
  5. Select the image style from the Image style dropdown (these are the styles we created in the previous step).
    Image style selection UI
  6. Set the Fallback Image style (this will be used where the browser doesn't understand the <source> tags inside the picture element. It should be the most appropriate size to use if you could only pick one across all screen sizes)
    Fallback image style

Add a new view mode for media entities

Head to Admin > Structure > Display Modes > View Modes, click 'Add new view mode' and add your display mode. In this instance, we'll use 'Profile image' again.

Adding a view mode

Update the display of the image for the entity type

Head to Admin > Structure > Media Types > Image > Manage display

  1. On the default tab click on Custom display settings at the bottom and check the new 'Profile Image' view mode and then Click Save
    Custom display settings
  2. Click on the tab that matches your new display type (in my example it's Profile image)
  3. On the Image fields row change the Label to Hidden and the Format to Responsive Image.
    Configuring the image format
  4. Click on the cog at the end of the row.
    Row configuration cog
  5. Under Responsive image style select your style.
    Format Configuration
  6. Select where the file should link to (or Nothing), Click update
  7. Click Save

Update your Paragraph type to use the new display format

Go to Structure > Paragraph Types > {type} > Manage Display

  1. Find the row with the field displaying your media entity and change the format to Rendered Entity
  2. Click the gear icon to configure the view mode by selecting your view mode from the list (in this instance profile image)
    Paragraph type display format
  3. Click Save

Testing Our Work

At this point you should be all set.

  1. Create an example page
  2. Select your paragraph to insert into the page
  3. Add an image
  4. Save the page and view it on the front end
  5. Inspect the image element and ensure that a <picture> element is rendered with <source>'s, a default, and when you resize the browser you see what you expect.
    <picture>
      <source srcset="/sites/default/files/styles/profile_image/public/2019-11/image.jpeg 1x" media="(min-width: 1024px)" type="image/jpeg">
      <source srcset="/sites/default/files/styles/profile_image_1024x1024_/public/2019-11/image.jpeg 1x" media="(min-width: 768px)" type="image/jpeg">
      <source srcset="/sites/default/files/styles/profile_image_512x512_/public/2019-11/image.jpeg 1x" media="(min-width: 320px)" type="image/jpeg">
      <img src="/sites/default/files/styles/profile_image_256x256/public/2019-11/image.jpeg" alt="A profile Image" typeof="foaf:Image">
    </picture>
  6. To inspect further select the Network tab in your developer tools and filter by images. Resize the browser window and watch as new image sizes are loaded at your defined breakpoints.