Alchemy cms

Cropping and responsive images

June 9, 2026 ยท The Alchemy Team

Photo-02

Using Picture ingredients with cropping, srcset and sizes for sharp, fast images.

config/alchemy/elements.yml
- name: post_header
  unique: true
  hint: true
  ingredients:
    - role: headline
      type: Headline
      hint: true
      default: :post_header_headline
      settings:
        levels: [1, 2]
        sizes: [1, 2]
    - role: published_at
      type: Datetime
      hint: true
    - role: author
      type: Text
      hint: true
      default: :post_header_author
    - role: image
      type: Picture
      hint: true
      settings:
        crop: true
        fixed_ratio: true
        size: "800x450"
        srcset:
          - "400x225"
          - "800x450"
          - "1200x675"
        sizes:
          - "(min-width: 768px) 720px"
          - "100vw"
    - role: intro
      type: Richtext
      hint: true
      default: :post_header_intro
      settings:
        tinymce:
          toolbar: "bold italic | alchemy_link unlink"
        sanitizer:
          tags: [p, br, strong, em, a]
          attributes: [href, target, rel, title]

One file, many renderings

A Picture ingredient does not hold a copy of an image. It references a single file in the picture library, and every place that uses it asks for its own rendering.

The header image above is cropped to a fixed 16:9 ratio. The crop lives on the ingredient rather than on the file, so the same picture can be a wide banner here and a taller, differently cropped tile in a gallery without ever being re-uploaded. Editors set it in the admin with a visual cropper.

Responsive delivery is declared next to it in the element definition: a srcset of several widths โ€” 400, 800 and 1200 pixels wide for this header โ€” and a sizes hint describing how wide the image will really be rendered. The browser downloads only the variant it picks.

Alchemy processes each variant on demand and caches the result, so adding another width to the list costs nothing up front. Open โ€œHow this block is builtโ€ on the header above to see the exact settings.

config/alchemy/elements.yml
- name: prose
  hint: true
  ingredients:
    - role: headline
      type: Headline
      hint: true
      default: :prose_headline
      settings:
        levels: [2, 3]
        sizes: [2, 3]
    - role: text
      type: Richtext
      hint: true
      default: :prose_text
      settings:
        tinymce:
          toolbar: "bold italic | bullist numlist | alchemy_link unlink"
        sanitizer:
          tags: [p, br, strong, em, a, ul, ol, li]
          attributes: [href, target, rel, title]