<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Karol P. Kozak - blog]]></title><description><![CDATA[Personal blog & portfolio.]]></description><link>https://kkozak.pl</link><generator>GatsbyJS</generator><lastBuildDate>Sun, 01 Sep 2024 21:12:02 GMT</lastBuildDate><item><title><![CDATA[Images in Optimizely, part 3 - Responsive images in React]]></title><description><![CDATA[Forte.EpiResponsivePicture provides a convenient mechanism to generate responsive images with <picture> tag in Razor Views, but it is also possible to use it while rendeing content with any modern JS framework or library. Here I am showing how to use the package with ReactJS.]]></description><link>https://kkozak.pl/blog/responsive-images-with-react</link><guid isPermaLink="false">https://kkozak.pl/blog/responsive-images-with-react</guid><category><![CDATA[Optimizely CMS]]></category><category><![CDATA[Episerver CMS]]></category><category><![CDATA[Responsive images]]></category><pubDate>Fri, 10 Sep 2021 16:00:00 GMT</pubDate><content:encoded>&lt;blockquote&gt;
&lt;p&gt;Please note that the article was written for EPiServer 11.X. EpiResponsivePicture itself was ported to .Net Core version of EPiServer, but npm package is not updated, so it won’t work with the latest EPiServer/Optimizely CMS. If you need the update of the package, please contact me &lt;a href=&quot;/contact&quot;&gt;here&lt;/a&gt; :)&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;In first part of the series, I’ve shown how to install and configure &lt;code class=&quot;language-text&quot;&gt;Forte.EpiResponsivePicture&lt;/code&gt; package for responsive, adaptive, automatically cropped images in EPiServer CMS. Here I demonstrate how to quickly make it achievable also in EPiServer-based SPA application or pages rendered with React.&lt;/p&gt;
&lt;h3&gt;Images in EPiServer&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://kkozak.pl/blog/responsive-images-in-optimizely&quot;&gt;Part 1: Automatically cropped &amp;#x26; resized responsive images&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://kkozak.pl/blog/picture-profiles&quot;&gt;Part 2: Picture profiles&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Part 3: Responsive images in React&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;p&gt;To demonstrate this in practice, let’s continue on developing the portfolio website we started in previous article. We already have page type that represents a single project page — now it’s time for listing of all the projects on homepage. It’ll be implemented as React component, allowing to filter them by the categories:&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 630px; &quot;
    &gt;
      &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 96.83544303797468%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAATABQDASIAAhEBAxEB/8QAGQABAAMBAQAAAAAAAAAAAAAAAAECBAMF/8QAFAEBAAAAAAAAAAAAAAAAAAAAAP/aAAwDAQACEAMQAAABmm6phe4EB2B//8QAGxAAAwEBAAMAAAAAAAAAAAAAAQIDABIRExT/2gAIAQEAAQUC4bGRO+c55MbrInQHMzJC3rXwoCj/xAAUEQEAAAAAAAAAAAAAAAAAAAAg/9oACAEDAQE/AR//xAAUEQEAAAAAAAAAAAAAAAAAAAAg/9oACAECAQE/AR//xAAfEAACAQMFAQAAAAAAAAAAAAAAARECEjIDEyFhkTH/2gAIAQEABj8Cwq8MKvDBje53EkLVIuu7G2uT4Qj/xAAdEAADAAICAwAAAAAAAAAAAAAAAREhMUFRYXHB/9oACAEBAAE/IcZV08gUfiLCiT5GhA2HmrdRF12xRL7Mul59kQxH/9oADAMBAAIAAwAAABDAADz/xAAUEQEAAAAAAAAAAAAAAAAAAAAg/9oACAEDAQE/EB//xAAUEQEAAAAAAAAAAAAAAAAAAAAg/9oACAECAQE/EB//xAAdEAEAAwEAAgMAAAAAAAAAAAABABEhQTFRYXHR/9oACAEBAAE/EDI2e7Re3FtStYDB/C4uVgbQAODUL7oRau97FYSJZW98bNkgN9Dx2Kyz7P2DwmrRP//Z&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;project list&quot;
        title=&quot;&quot;
        src=&quot;https://kkozak.pl/static/3db213c566bf5d5ffda02fc1f84886a8/828fb/project-list-page.jpg&quot;
        srcset=&quot;https://kkozak.pl/static/3db213c566bf5d5ffda02fc1f84886a8/ff44c/project-list-page.jpg 158w,
https://kkozak.pl/static/3db213c566bf5d5ffda02fc1f84886a8/a6688/project-list-page.jpg 315w,
https://kkozak.pl/static/3db213c566bf5d5ffda02fc1f84886a8/828fb/project-list-page.jpg 630w,
https://kkozak.pl/static/3db213c566bf5d5ffda02fc1f84886a8/0ede0/project-list-page.jpg 945w,
https://kkozak.pl/static/3db213c566bf5d5ffda02fc1f84886a8/fb914/project-list-page.jpg 998w&quot;
        sizes=&quot;(max-width: 630px) 100vw, 630px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Disclaimer: This is just a showcase for responsive images library and should be treated as so. It is not showing any design patterns, good practices in software development etc. Actually, most things are &lt;strong&gt;deliberately trivialized&lt;/strong&gt; to simplify existing setup and minimize amount of boilerplate code needed to run the project and demo capabilities of the package.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;Installation&lt;/h2&gt;
&lt;p&gt;I assume we already have React configured with &lt;a href=&quot;https://reactjs.net/getting-started/aspnet.html&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener&quot;&gt;ReactJS.NET&lt;/a&gt;, as it’s beyond of the scope of this article. For reference, you can look at ReactJS.net website or peek at &lt;a href=&quot;https://github.com/kpkozak/epi-responsive-picture-sample&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener&quot;&gt;full source code&lt;/a&gt; of project in this tutorial available on GitHub.&lt;/p&gt;
&lt;p&gt;Before we start, install &lt;code class=&quot;language-text&quot;&gt;epiresponsivepicture-react&lt;/code&gt; via npm:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;npm&quot;&gt;&lt;pre class=&quot;language-npm&quot;&gt;&lt;code class=&quot;language-npm&quot;&gt;npm install --save epiresponsivepicture-react&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This library contains implementation of &lt;code class=&quot;language-text&quot;&gt;&amp;lt;ResponsivePicture&gt;&lt;/code&gt; component for React, being capable of rendering proper &lt;code class=&quot;language-text&quot;&gt;&amp;lt;picture&gt;&lt;/code&gt; tag, then handled by ImageResizer we’re using for scaling images. It accepts following parameters:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;model&lt;/code&gt;, containing all the properties of an image needed to render it:
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;url&lt;/code&gt; to the image,&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;width&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;height&lt;/code&gt; of original images,&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;focalPoint&lt;/code&gt; chosen by editor for cropping,&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;alt&lt;/code&gt; containing alternate text defined by editor.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;profile&lt;/code&gt;, being a picture profile, ported 1:1 from its C# equivalent. It can simply be serialized instance of &lt;code class=&quot;language-text&quot;&gt;PictureProfile&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;For ReactJS.Net to be able to use &lt;code class=&quot;language-text&quot;&gt;PictureProfile&lt;/code&gt; object directly serialized to props, it is needed to configure it in a way to use camel case property names. In &lt;code class=&quot;language-text&quot;&gt;ReactConfig&lt;/code&gt;, add following code:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;ReactSiteConfiguration.Configuration
    .SetJsonSerializerSettings(
         new JsonSerializerSettings
         { ContractResolver = 
   new CamelCasePropertyNamesContractResolver(),
});&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This article uses the same convention for all view models passed to React components.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;Use of the package&lt;/h2&gt;
&lt;p&gt;First, create a new page type that will become a homepage of portfolio website.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;cs&quot;&gt;&lt;pre class=&quot;language-cs&quot;&gt;&lt;code class=&quot;language-cs&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token attribute&quot;&gt;&lt;span class=&quot;token class-name&quot;&gt;ContentType&lt;/span&gt;&lt;span class=&quot;token attribute-arguments&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;GUID &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;D8BC62BE-64F1-48A9-86D1-E14A7C43FB88&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; DisplayName &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Project list&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    Description &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Page listing all projects, grouped by categories&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token attribute&quot;&gt;&lt;span class=&quot;token class-name&quot;&gt;AvailableContentTypes&lt;/span&gt;&lt;span class=&quot;token attribute-arguments&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Availability&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Specific&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 
    Include &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;typeof&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token type-expression class-name&quot;&gt;ProjectPage&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;ProjectPage&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;ProjectListPage&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token type-list&quot;&gt;&lt;span class=&quot;token class-name&quot;&gt;PageData&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token attribute&quot;&gt;&lt;span class=&quot;token class-name&quot;&gt;Display&lt;/span&gt;&lt;span class=&quot;token attribute-arguments&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Order &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;virtual&lt;/span&gt; &lt;span class=&quot;token return-type class-name&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;string&lt;/span&gt;&lt;/span&gt; Title &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    
    &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token attribute&quot;&gt;&lt;span class=&quot;token class-name&quot;&gt;Display&lt;/span&gt;&lt;span class=&quot;token attribute-arguments&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Order &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;20&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;virtual&lt;/span&gt; &lt;span class=&quot;token return-type class-name&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;string&lt;/span&gt;&lt;/span&gt; Subtitle &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token attribute&quot;&gt;&lt;span class=&quot;token class-name&quot;&gt;Display&lt;/span&gt;&lt;span class=&quot;token attribute-arguments&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Order &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;30&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token attribute&quot;&gt;&lt;span class=&quot;token class-name&quot;&gt;UIHint&lt;/span&gt;&lt;span class=&quot;token attribute-arguments&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;UIHint&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Image&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;virtual&lt;/span&gt; &lt;span class=&quot;token return-type class-name&quot;&gt;ContentReference&lt;/span&gt; MainImage &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;In a controller for this page, we get all its children and iterate over them, building a view model with image, link URL and title, that can be passed directly to picture React component.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;cs&quot;&gt;&lt;pre class=&quot;language-cs&quot;&gt;&lt;code class=&quot;language-cs&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;ProjectListPageController&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token type-list&quot;&gt;&lt;span class=&quot;token class-name&quot;&gt;ContentController&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;ProjectListPage&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;readonly&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;IContentLoader&lt;/span&gt; _contentLoader&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;readonly&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;IUrlResolver&lt;/span&gt; _urlResolver&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;readonly&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;CategoryRepository&lt;/span&gt; _categoryRepository&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token return-type class-name&quot;&gt;ActionResult&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;Index&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;ProjectListPage&lt;/span&gt; currentContent&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
         &lt;span class=&quot;token class-name&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt;&lt;/span&gt; allProjects &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; _contentLoader&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token generic-method&quot;&gt;&lt;span class=&quot;token function&quot;&gt;GetChildren&lt;/span&gt;&lt;span class=&quot;token generic class-name&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;ProjectPage&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;ProjectPage&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;currentContent&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;ContentLink&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
                &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Select&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;x &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token constructor-invocation class-name&quot;&gt;ProjectTeaser&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;x&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Title&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;BuildResponsiveImage&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;x&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;MainImage&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; x&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Category
                    &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Select&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;y &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; _categoryRepository&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;y&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Name&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
                    &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;ToList&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; _urlResolver&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;GetUrl&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;x&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;ContentLink&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;View&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token constructor-invocation class-name&quot;&gt;ProjectListPageViewModel&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;currentContent&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; allProjects&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;ToList&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Model for image is built in &lt;code class=&quot;language-text&quot;&gt;BuildResponsivePicture&lt;/code&gt; method, and it simply creates an object with &lt;code class=&quot;language-text&quot;&gt;Url&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;Width&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;Height&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;FocalPoint&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;Alt&lt;/code&gt; properties from image content, needed by our picture component to be rendered:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;cs&quot;&gt;&lt;pre class=&quot;language-cs&quot;&gt;&lt;code class=&quot;language-cs&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token return-type class-name&quot;&gt;ResponsiveImageViewModel&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;BuildResponsiveImage&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;ContentReference&lt;/span&gt; imageLink&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token class-name&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt;&lt;/span&gt; image &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; _contentLoader&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token generic-method&quot;&gt;&lt;span class=&quot;token function&quot;&gt;Get&lt;/span&gt;&lt;span class=&quot;token generic class-name&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;Image&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Image&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;imageLink&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;image &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token constructor-invocation class-name&quot;&gt;ResponsiveImageViewModel&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;_urlResolver&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;GetUrl&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;imageLink&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 
        image&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;FocalPoint&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; image&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Width&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            image&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Height&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; image&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Description&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;ProjectTeaser&lt;/code&gt; is a view model that represents single project card, and is virtually a simple object with couple of properties:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;cs&quot;&gt;&lt;pre class=&quot;language-cs&quot;&gt;&lt;code class=&quot;language-cs&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;ProjectTeaser&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token comment&quot;&gt;// ctor omited for brevity&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token return-type class-name&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;string&lt;/span&gt;&lt;/span&gt; Name &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token return-type class-name&quot;&gt;ResponsiveImageViewModel&lt;/span&gt; Image &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token return-type class-name&quot;&gt;IEnumerable&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt; Categories &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token return-type class-name&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;string&lt;/span&gt;&lt;/span&gt; Url &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;As we have a view model, now proper React component can be implemented. Each project teaser renders a link, title and image — using component from library&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;tsx&quot;&gt;&lt;pre class=&quot;language-tsx&quot;&gt;&lt;code class=&quot;language-tsx&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;PictureProfile&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; ResponsiveImageViewModel&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; ResponsivePicture&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; 
    &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;epiresponsivepicture-react&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// --&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;renderProjectTeaser&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
        x&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; ProjectTeaser&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 
        profile&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; PictureProfile&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;div&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;className&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;teaser&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;a&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;href&lt;/span&gt;&lt;span class=&quot;token script language-javascript&quot;&gt;&lt;span class=&quot;token script-punctuation punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;x&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;url&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;title&lt;/span&gt;&lt;span class=&quot;token script language-javascript&quot;&gt;&lt;span class=&quot;token script-punctuation punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;x&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;name&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt;
            &lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;div&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;className&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;teaserImage&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt;
                &lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;ResponsivePicture&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;model&lt;/span&gt;&lt;span class=&quot;token script language-javascript&quot;&gt;&lt;span class=&quot;token script-punctuation punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;x&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;image&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;profile&lt;/span&gt;&lt;span class=&quot;token script language-javascript&quot;&gt;&lt;span class=&quot;token script-punctuation punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;profile&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;/&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt;
            &lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;div&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt;
            &lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;h2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;x&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;name&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;h2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;a&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;div&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;And that’s it! Now we only render filter buttons based on data from teasers, and filter visible teasers. Full component looks as following:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;tsx&quot;&gt;&lt;pre class=&quot;language-tsx&quot;&gt;&lt;code class=&quot;language-tsx&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;ProjectList&lt;/span&gt; 
    &lt;span class=&quot;token keyword&quot;&gt;extends&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;React&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Component&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; 
            profile&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; PictureProfile&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; projects&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; ProjectTeaser&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; 
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 
        &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; 
            selectedFilter&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;null&lt;/span&gt; 
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;constructor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;props&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;any&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;super&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;props&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;state &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            selectedFilter&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;null&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;getFilters &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getFilters&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;bind&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token function&quot;&gt;render&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; projects &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;props&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;projects&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; filters &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getFilters&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;projects&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; teasers &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; projects
            &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;filter&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;x &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
                &lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;state&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;selectedFilter&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;||&lt;/span&gt; 
                x&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;categories&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;indexOf&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;state&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;selectedFilter&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;x &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; ProjectList&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;renderProjectTeaser&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;x&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;props&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;profile&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt;
            &lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;filters&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt;
            &lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;div&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;className&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;teasers&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt;   
                &lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;teasers&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt;
            &lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;div&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;renderProjectTeaser&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;x&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; ProjectTeaser&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 
            profile&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; PictureProfile&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;div&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;className&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;teaser&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt;
            &lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;a&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;href&lt;/span&gt;&lt;span class=&quot;token script language-javascript&quot;&gt;&lt;span class=&quot;token script-punctuation punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;x&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;url&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;title&lt;/span&gt;&lt;span class=&quot;token script language-javascript&quot;&gt;&lt;span class=&quot;token script-punctuation punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;x&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;name&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt;
                &lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;div&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;className&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;teaserImage&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt;
                    &lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;ResponsivePicture&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;model&lt;/span&gt;&lt;span class=&quot;token script language-javascript&quot;&gt;&lt;span class=&quot;token script-punctuation punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;x&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;image&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;profile&lt;/span&gt;&lt;span class=&quot;token script language-javascript&quot;&gt;&lt;span class=&quot;token script-punctuation punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;profile&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;/&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt;
                &lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;div&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt;
                &lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;h2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;x&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;name&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;h2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt;
            &lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;a&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;div&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;getFilters&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;projects&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; ProjectTeaser&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; categories &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; projects&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;x &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; x&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;categories&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;reduce&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;x&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; y&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; x&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;concat&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;y&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// flatten&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;filter&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;value&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; index&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; self&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; self&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;indexOf&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;value&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; index&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// distinct&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; filters &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; categories
            &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;x &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
                &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;button&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;className&lt;/span&gt;&lt;span class=&quot;token script language-javascript&quot;&gt;&lt;span class=&quot;token script-punctuation punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;x &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;state&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;selectedFilter &lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;active&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt; 
                        &lt;span class=&quot;token attr-name&quot;&gt;onClick&lt;/span&gt;&lt;span class=&quot;token script language-javascript&quot;&gt;&lt;span class=&quot;token script-punctuation punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;setState&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;selectedFilter&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; x&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt;
                    &lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;x&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt;
                &lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;button&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;div&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;className&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;filters&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;filters&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;div&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The only thing yet left to do is to render created component in .cshtml file of the Project List Page and make sure we call ReactJS &lt;code class=&quot;language-text&quot;&gt;.ReactInitJavaScript()&lt;/code&gt; in view or layout.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;cshtml&quot;&gt;&lt;pre class=&quot;language-cshtml&quot;&gt;&lt;code class=&quot;language-cshtml&quot;&gt;&lt;span class=&quot;token directive&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;@model&lt;/span&gt; &lt;span class=&quot;token csharp language-csharp&quot;&gt;ResponsivePictureSample&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Features&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Pages&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;ProjectListPage&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;ProjectListPageViewModel&lt;/span&gt;&lt;/span&gt;

&lt;span class=&quot;token razor-comment comment&quot;&gt;@* ... *@&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;div&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;content&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;h1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token value variable&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;@&lt;/span&gt;&lt;span class=&quot;token csharp language-csharp&quot;&gt;Html&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;PropertyFor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;m &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; m&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Content&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Title&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;h1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;h2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token value variable&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;@&lt;/span&gt;&lt;span class=&quot;token csharp language-csharp&quot;&gt;Html&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;PropertyFor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;m &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; m&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Content&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Subtitle&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;h2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;div&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;

&lt;span class=&quot;token value variable&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;@&lt;/span&gt;&lt;span class=&quot;token csharp language-csharp&quot;&gt;Html&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;ImagePropertyFor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;m &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; m&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Content&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;MainImage&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; PictureProfiles&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;HeaderImage&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;

&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;div&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;content&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token value variable&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;@&lt;/span&gt;&lt;span class=&quot;token csharp language-csharp&quot;&gt;Html&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;React&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ProjectList&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        profile &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; PictureProfiles&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;ProjectImagesGallery&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        projects &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; Model&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Projects
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;div&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token razor-comment comment&quot;&gt;@* ... *@&lt;/span&gt;
&lt;span class=&quot;token value variable&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;@&lt;/span&gt;&lt;span class=&quot;token csharp language-csharp&quot;&gt;Html&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;ReactInitJavaScript&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;After running application, creating a list page and few project pages as its children, we can see the homepage rendered with React, with images adapting to screen size:
&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 630px; &quot;
    &gt;
      &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 96.83544303797468%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAATABQDASIAAhEBAxEB/8QAGQABAAMBAQAAAAAAAAAAAAAAAAECBAMF/8QAFAEBAAAAAAAAAAAAAAAAAAAAAP/aAAwDAQACEAMQAAABmm6phe4EB2B//8QAGxAAAwEBAAMAAAAAAAAAAAAAAQIDABIRExT/2gAIAQEAAQUC4bGRO+c55MbrInQHMzJC3rXwoCj/xAAUEQEAAAAAAAAAAAAAAAAAAAAg/9oACAEDAQE/AR//xAAUEQEAAAAAAAAAAAAAAAAAAAAg/9oACAECAQE/AR//xAAfEAACAQMFAQAAAAAAAAAAAAAAARECEjIDEyFhkTH/2gAIAQEABj8Cwq8MKvDBje53EkLVIuu7G2uT4Qj/xAAdEAADAAICAwAAAAAAAAAAAAAAAREhMUFRYXHB/9oACAEBAAE/IcZV08gUfiLCiT5GhA2HmrdRF12xRL7Mul59kQxH/9oADAMBAAIAAwAAABDAADz/xAAUEQEAAAAAAAAAAAAAAAAAAAAg/9oACAEDAQE/EB//xAAUEQEAAAAAAAAAAAAAAAAAAAAg/9oACAECAQE/EB//xAAdEAEAAwEAAgMAAAAAAAAAAAABABEhQTFRYXHR/9oACAEBAAE/EDI2e7Re3FtStYDB/C4uVgbQAODUL7oRau97FYSJZW98bNkgN9Dx2Kyz7P2DwmrRP//Z&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;project list&quot;
        title=&quot;&quot;
        src=&quot;https://kkozak.pl/static/3db213c566bf5d5ffda02fc1f84886a8/828fb/project-list-page.jpg&quot;
        srcset=&quot;https://kkozak.pl/static/3db213c566bf5d5ffda02fc1f84886a8/ff44c/project-list-page.jpg 158w,
https://kkozak.pl/static/3db213c566bf5d5ffda02fc1f84886a8/a6688/project-list-page.jpg 315w,
https://kkozak.pl/static/3db213c566bf5d5ffda02fc1f84886a8/828fb/project-list-page.jpg 630w,
https://kkozak.pl/static/3db213c566bf5d5ffda02fc1f84886a8/0ede0/project-list-page.jpg 945w,
https://kkozak.pl/static/3db213c566bf5d5ffda02fc1f84886a8/fb914/project-list-page.jpg 998w&quot;
        sizes=&quot;(max-width: 630px) 100vw, 630px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Example implementation of the component is created for React. However, based on source code of &lt;code class=&quot;language-text&quot;&gt;&amp;lt;ResponsivePicture&gt;&lt;/code&gt; component you should be able to do the same with any JS technology of your choice, by adjusting it to the way you’re rendering actual markup. The most important part of generating URL to the image, taking target width, height, cropping and focal point into consideration, is contained in VanillaJS &lt;code class=&quot;language-text&quot;&gt;getImageUrl&lt;/code&gt; function, so it can be easily used in a framework of your choice.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;&lt;strong&gt;Images&lt;/strong&gt; &lt;br/&gt;
&lt;a href=&quot;https://unsplash.com/photos/NHLS5hOSH0c&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener&quot;&gt;https://unsplash.com/photos/NHLS5hOSH0c&lt;/a&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Responsive images in Optimizely, part 2 - Picture profiles]]></title><description><![CDATA[In the first part of the series, I'm showing how to install and properly configure Forte.EpiResponsivePicture package into Optimizely CMS (formerly EPiServer). Now it's time to take the best of its capabilities, tweaking it with perfect picture profiles.]]></description><link>https://kkozak.pl/blog/picture-profiles</link><guid isPermaLink="false">https://kkozak.pl/blog/picture-profiles</guid><category><![CDATA[Optimizely CMS]]></category><category><![CDATA[Episerver CMS]]></category><category><![CDATA[Responsive images]]></category><pubDate>Sun, 01 Aug 2021 19:30:00 GMT</pubDate><content:encoded>&lt;p&gt;We’re already running Image Resizer with EPiServerBlobReader and Forte.EpiResponsivePicture to render &lt;code class=&quot;language-text&quot;&gt;&amp;lt;picture&gt;&lt;/code&gt; tags in Optimizely CMS (EPiServer), but the picture profiles we’re using are far from being optimal. What are these picture profiles, and how do they affect the images?&lt;/p&gt;
&lt;h3&gt;Responsive images in Optimizely CMS (EPiServer)&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://kkozak.pl/blog/responsive-images-in-optimizely&quot;&gt;Part 1: Automatically cropped &amp;#x26; resized responsive images&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Part 2: Picture profiles&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://kkozak.pl/blog/responsive-images-with-react&quot;&gt;Part 3: Responsive images in React&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2&gt;What is a picture profile&lt;/h2&gt;
&lt;p&gt;Forte.EpiResponsivePicture package is based on &lt;a href=&quot;https://github.com/valdisiljuconoks/ImageResizer.Plugins.EPiServerBlobReader&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener&quot;&gt;EPiServerBlobReader&lt;/a&gt; plugin created by Valdis Iljuconoks, extending its functionalities with focal point base cropping and few other adjustments. The source package introduces the concept of picture profiles. Although its structure is a bit different, the purpose is pretty much the same as in source library.&lt;/p&gt;
&lt;p&gt;A picture profile is an entity describing target size &amp;#x26; quality of the rendered image. It can be perceived as the specific use case for the figure on the web page — for example header, image gallery, product card, article teaser, etc. Having well-defined profiles allow you to use the same image in almost all cases, always fine-tuned and cropped to fit its place.&lt;/p&gt;
&lt;p&gt;An example picture profile looks as follows:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;cs&quot;&gt;&lt;pre class=&quot;language-cs&quot;&gt;&lt;code class=&quot;language-cs&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;readonly&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;PictureProfile&lt;/span&gt; ExampleProfile &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token constructor-invocation class-name&quot;&gt;PictureProfile&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    Format &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; ResizedImageFormat&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Jpg&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    DefaultWidth &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;800&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    Sources &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token constructor-invocation class-name&quot;&gt;PictureSource&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            AllowedWidths &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;360&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;  &lt;span class=&quot;token number&quot;&gt;768&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1024&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1920&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            Mode &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; ScaleMode&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Default&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            TargetAspectRatio &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; AspectRatio&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Original&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            Sizes &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;token string&quot;&gt;&quot;(min-width: 1024px) 50vw&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;token string&quot;&gt;&quot;1000px&quot;&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Each picture profile should define a set of sources, as well as the default width for an image. The default width is used when the browser doesn’t support picture spec, or no sources match their media condition). It can also optionally set the target image format.&lt;/p&gt;
&lt;p&gt;The source has numerous properties to customize rendering:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;Mode&lt;/code&gt; — One of &lt;code class=&quot;language-text&quot;&gt;Max&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;Pad&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;Crop&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;Stretch&lt;/code&gt;. Defines behavior when target dimensions don’t match original. &lt;code class=&quot;language-text&quot;&gt;Default&lt;/code&gt; is equal to &lt;code class=&quot;language-text&quot;&gt;Pad&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;TargetAspectRatio&lt;/code&gt; — width to height ratio of output image. The most interesting when used with &lt;code class=&quot;language-text&quot;&gt;Crop&lt;/code&gt; mode, it then causes cropping image according to the focal point. When no cropping is desired, use &lt;code class=&quot;language-text&quot;&gt;AspectRatio.Original&lt;/code&gt; — original aspect ratio will be maintained.&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;Sizes&lt;/code&gt; — a list used to constraint image size with media condition. If you’re familiar with &lt;code class=&quot;language-text&quot;&gt;&amp;lt;picture&gt;&lt;/code&gt; spec, this is virtually the same. Each size contains media condition followed by the desired size of image, in CSS units. &lt;code class=&quot;language-text&quot;&gt;px&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;vw&lt;/code&gt;/&lt;code class=&quot;language-text&quot;&gt;vh&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;em&lt;/code&gt;/&lt;code class=&quot;language-text&quot;&gt;rem&lt;/code&gt; supported. However, you cannot use &lt;code class=&quot;language-text&quot;&gt;%&lt;/code&gt;. Sizes are matching from the top, so the first matching condition will be applied. The last size may omit the condition — it will then be used as a fallback when no matching condition is found.&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;AllowedWidths&lt;/code&gt; — defines in which dimensions images should be available. It is used to generate &lt;code class=&quot;language-text&quot;&gt;srcset&lt;/code&gt; in resulting &lt;code class=&quot;language-text&quot;&gt;&amp;lt;picture&gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;Quality&lt;/code&gt; — for JPEGs, compression quality of output image.&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;MediaCondition&lt;/code&gt; optional media condition that constraints use of the source. When multiple conditions are met in different sources, first matching is taken.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;How to write profiles?&lt;/h2&gt;
&lt;p&gt;Generally, a single source is capable of serving images in various sizes. You should use a separate source when different aspect ratios and/or mode used. For images with the same aspect ratio, it is better to have additional allowed width and handle it with sizes — for performance and bandwidth optimization reasons.&lt;/p&gt;
&lt;p&gt;This is because browsers are optimizing loads. For example, when reducing the size of the browser window, there is no point in loading a smaller image, if the bigger one is already in cache. When having a bigger image, the browser won’t load a smaller one.&lt;/p&gt;
&lt;p&gt;However, different &lt;code class=&quot;language-text&quot;&gt;&amp;lt;source&gt;&lt;/code&gt; instructs the browser that images between sources are different — either differently cropped, or even totally different media. So resizing the browser window in a way that another &lt;code class=&quot;language-text&quot;&gt;&amp;lt;source&gt;&lt;/code&gt; matches, will always trigger loading another image. Thanks to that, after switching you won’t have badly aligned, improper images shown in your mobile layout.&lt;/p&gt;
&lt;h3&gt;Handling Retina&lt;/h3&gt;
&lt;p&gt;Before &lt;code class=&quot;language-text&quot;&gt;&amp;lt;picture&gt;&lt;/code&gt; spec being widely adopted, Retina screens used to be a headache — developer needed to write additional media query for 2x. If that’s too little, there are devices with the device pixel ratio greater than 2 (now even more than 3) and being fractional. For example, it is quite common that small laptops have enabled scaling on OS level, which in browser is seen as DPR like 1.25.&lt;/p&gt;
&lt;p&gt;As in &lt;code class=&quot;language-text&quot;&gt;sizes&lt;/code&gt; we specify sizes of space that image occupies in CSS units, not the screen pixels, Retina displays are automatically handled. You just need to add image twice as wide to &lt;code class=&quot;language-text&quot;&gt;AllowedWidths&lt;/code&gt; (or whatever DPR you want to support best). Simple as that, the browser will do the rest.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/3ff9bad46ee256d6f82fc2ded0443315/jobdone.gif&quot; alt=&quot;Job done&quot;&gt;&lt;/p&gt;
&lt;h2&gt;Examples — sample portfolio project&lt;/h2&gt;
&lt;p&gt;To show all of this by example, let’s go back to the project we started implementing in the previous part and finally adjust its picture profiles. On the project page, there are three ways of displaying the image: header, inside the article, and bottom image gallery.&lt;/p&gt;
&lt;h3&gt;Header image&lt;/h3&gt;
&lt;p&gt;At first, let’s take the background header image. The header is styled to occupy 60% of viewport height and extend to full screen on mobile. Typically desktop wide screens are 16:9, so our resulting target aspect ratio will be&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;16:(9x0.6) = 16:5.4&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Most typical screen sizes are 1920x1080, 1440x900, 1280x960(or 800). Desktop layout range ends at screens 1024px wide. Thus we can model source for desktop screens as follows:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;cs&quot;&gt;&lt;pre class=&quot;language-cs&quot;&gt;&lt;code class=&quot;language-cs&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token constructor-invocation class-name&quot;&gt;PictureSource&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    MediaCondition &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;(min-width: 1024px)&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    AllowedWidths &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1920&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1440&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1280&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1024&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    Mode &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; ScaleMode&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Crop&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    TargetAspectRatio &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; AspectRatio&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Create&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;16&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;5.4&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// 60vh for 16:9 screens&lt;/span&gt;
    Sizes &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token string&quot;&gt;&quot;100vw&quot;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    Quality &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;80&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;As on mobile we typically have a different screen aspect ratio, we’re covering this with another source. Dimensions of mobile screens differ, but the most “standard” would be vertically placed, panoramic screen (9:16). There is no way to cover each mobile device, so let’s go by choosing the most standard widths: 360px, 375px, 420px. DPR is usually 2x or 3x, so we add additional widths of 750, 1050 and 1125px — 375x2, 350x3 and 375x3 respectively. I think there is no point in loading overlayed background wider than 1125px on smartphones that fit into the pocket, so we stop at this size.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;cs&quot;&gt;&lt;pre class=&quot;language-cs&quot;&gt;&lt;code class=&quot;language-cs&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token constructor-invocation class-name&quot;&gt;PictureSource&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    AllowedWidths &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;360&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;375&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;425&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;750&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1050&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1125&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    Mode &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; ScaleMode&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Crop&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    TargetAspectRatio &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; AspectRatio&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Create&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;9&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;16&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    Sizes &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token string&quot;&gt;&quot;100vw&quot;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;As the second source is our last one, we can skip having media condition for it. In both cases, the image always occupies the whole space, so the size is set to &lt;code class=&quot;language-text&quot;&gt;100vw&lt;/code&gt;. We can also lower quality a bit, as image is being shown in the background, overlayed.&lt;/p&gt;
&lt;p&gt;Finally, our new header image profile looks as follows:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;cs&quot;&gt;&lt;pre class=&quot;language-cs&quot;&gt;&lt;code class=&quot;language-cs&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;readonly&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;PictureProfile&lt;/span&gt; HeaderImage &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token constructor-invocation class-name&quot;&gt;PictureProfile&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    Format &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; ResizedImageFormat&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Jpg&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    DefaultWidth &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1920&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    Sources &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token constructor-invocation class-name&quot;&gt;PictureSource&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            MediaCondition &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;(min-width: 1024px)&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            AllowedWidths &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1920&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1440&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1280&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1024&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            Mode &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; ScaleMode&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Crop&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            TargetAspectRatio &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; AspectRatio&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Create&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;16&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;5.4&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// 60vh for 16:9 screens&lt;/span&gt;
            Sizes &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;token string&quot;&gt;&quot;100vw&quot;&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            Quality &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;60&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token constructor-invocation class-name&quot;&gt;PictureSource&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            AllowedWidths &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;360&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;375&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;425&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;750&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1050&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1125&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            Mode &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; ScaleMode&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Crop&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            TargetAspectRatio &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; AspectRatio&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Create&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;9&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;16&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            Sizes &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;token string&quot;&gt;&quot;100vw&quot;&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            Quality &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;60&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;Article content&lt;/h3&gt;
&lt;p&gt;For the purpose of the article, we assume that we never want to crop the images.  and always show them as an editor uploaded them. We can cover it with just one source. Maximum width of article content is 1140px.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;cs&quot;&gt;&lt;pre class=&quot;language-cs&quot;&gt;&lt;code class=&quot;language-cs&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;readonly&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;PictureProfile&lt;/span&gt; XHtmlString &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token constructor-invocation class-name&quot;&gt;PictureProfile&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    Format &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; ResizedImageFormat&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Jpg&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    DefaultWidth &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;800&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    Sources &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token constructor-invocation class-name&quot;&gt;PictureSource&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            AllowedWidths &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;360&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;480&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;768&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1024&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1280&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1440&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            Mode &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; ScaleMode&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Default&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            TargetAspectRatio &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; AspectRatio&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Original&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            Sizes &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;token string&quot;&gt;&quot;(max-width: 1480px) 100vw&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;token string&quot;&gt;&quot;1440px&quot;&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            Quality &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;80&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;Project images gallery&lt;/h3&gt;
&lt;p&gt;Project images gallery seems most sophisticated. Desktop gallery shows 4:3 pictures in a three-column layout, while on mobile we want to generate square images in 2 columns. As you may see, it isn’t overcomplicated:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;cs&quot;&gt;&lt;pre class=&quot;language-cs&quot;&gt;&lt;code class=&quot;language-cs&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;readonly&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;PictureProfile&lt;/span&gt; ProjectImagesGallery 
    &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token constructor-invocation class-name&quot;&gt;PictureProfile&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    Format &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; ResizedImageFormat&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Jpg&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    DefaultWidth &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;800&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    Sources &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token constructor-invocation class-name&quot;&gt;PictureSource&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            MediaCondition &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;(min-width: 1024px)&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            AllowedWidths &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;960&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;640&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;480&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;430&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;345&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            Mode &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; ScaleMode&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Crop&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            TargetAspectRatio &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; AspectRatio&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Create&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            Sizes &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;token string&quot;&gt;&quot;30vw&quot;&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            Quality &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;80&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token constructor-invocation class-name&quot;&gt;PictureSource&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            AllowedWidths &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;215&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;375&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;525&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;640&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;960&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            Mode &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; ScaleMode&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Crop&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            TargetAspectRatio &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; AspectRatio&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Create&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            Sizes &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;token string&quot;&gt;&quot;50vw&quot;&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            Quality &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;80&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;That’s it! Now images are quite fairly optimized, and — when cropped — cut according to the focal point set by editors, looking pretty good in every scenario:&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 630px; &quot;
    &gt;
      &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 43.67088607594937%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAJABQDASIAAhEBAxEB/8QAFwABAQEBAAAAAAAAAAAAAAAAAAYCBP/EABUBAQEAAAAAAAAAAAAAAAAAAAAB/9oADAMBAAIQAxAAAAHlUeUmVcX/xAAYEAADAQEAAAAAAAAAAAAAAAAAAxQCEP/aAAgBAQABBQKRhK0keb7/AP/EABQRAQAAAAAAAAAAAAAAAAAAABD/2gAIAQMBAT8BP//EABQRAQAAAAAAAAAAAAAAAAAAABD/2gAIAQIBAT8BP//EABgQAAIDAAAAAAAAAAAAAAAAAAAyASAz/9oACAEBAAY/AkkQzp//xAAbEAEAAgIDAAAAAAAAAAAAAAABADERkRAhQf/aAAgBAQABPyEG95HH0tkcttksQ84//9oADAMBAAIAAwAAABB0D//EABURAQEAAAAAAAAAAAAAAAAAABAR/9oACAEDAQE/EIf/xAAWEQADAAAAAAAAAAAAAAAAAAABECH/2gAIAQIBAT8QNX//xAAdEAACAQQDAAAAAAAAAAAAAAAAATEQQXHwEaHh/9oACAEBAAE/EFUrW4g/Odl6DLPfydIlkqf/2Q==&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;EPiServer responsive image on desktop&quot;
        title=&quot;&quot;
        src=&quot;https://kkozak.pl/static/e0677a4e386a1f848f0c31f7a04034d5/828fb/cropped-wide.jpg&quot;
        srcset=&quot;https://kkozak.pl/static/e0677a4e386a1f848f0c31f7a04034d5/ff44c/cropped-wide.jpg 158w,
https://kkozak.pl/static/e0677a4e386a1f848f0c31f7a04034d5/a6688/cropped-wide.jpg 315w,
https://kkozak.pl/static/e0677a4e386a1f848f0c31f7a04034d5/828fb/cropped-wide.jpg 630w,
https://kkozak.pl/static/e0677a4e386a1f848f0c31f7a04034d5/0ede0/cropped-wide.jpg 945w,
https://kkozak.pl/static/e0677a4e386a1f848f0c31f7a04034d5/3ac88/cropped-wide.jpg 1260w,
https://kkozak.pl/static/e0677a4e386a1f848f0c31f7a04034d5/82dae/cropped-wide.jpg 3788w&quot;
        sizes=&quot;(max-width: 630px) 100vw, 630px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 630px; &quot;
    &gt;
      &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 69.62025316455697%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAOABQDASIAAhEBAxEB/8QAFQABAQAAAAAAAAAAAAAAAAAABQD/xAAUAQEAAAAAAAAAAAAAAAAAAAAA/9oADAMBAAIQAxAAAAFcN4cdqP/EABsQAAEEAwAAAAAAAAAAAAAAAAMAAgQRARMz/9oACAEBAAEFAjcYF70XFihje0y//8QAFBEBAAAAAAAAAAAAAAAAAAAAEP/aAAgBAwEBPwE//8QAFBEBAAAAAAAAAAAAAAAAAAAAEP/aAAgBAgEBPwE//8QAHBAAAAYDAAAAAAAAAAAAAAAAAAECEBEhUWFx/9oACAEBAAY/Al8F4ZZaEqOab//EABkQAQADAQEAAAAAAAAAAAAAAAEAETEQIf/aAAgBAQABPyG/nt4C7O+MZq45KL8//9oADAMBAAIAAwAAABDTz//EABQRAQAAAAAAAAAAAAAAAAAAABD/2gAIAQMBAT8QP//EABQRAQAAAAAAAAAAAAAAAAAAABD/2gAIAQIBAT8QP//EABsQAQABBQEAAAAAAAAAAAAAAAERABAhMXFh/9oACAEBAAE/EGJqYacqf8JQ9LKmAguhiiOwoFXKeW//2Q==&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;Responsive image cropped for mobile phone&quot;
        title=&quot;&quot;
        src=&quot;https://kkozak.pl/static/c15c14fd7ebe29cf546ea43dcf2239ec/828fb/cropped-mobile.jpg&quot;
        srcset=&quot;https://kkozak.pl/static/c15c14fd7ebe29cf546ea43dcf2239ec/ff44c/cropped-mobile.jpg 158w,
https://kkozak.pl/static/c15c14fd7ebe29cf546ea43dcf2239ec/a6688/cropped-mobile.jpg 315w,
https://kkozak.pl/static/c15c14fd7ebe29cf546ea43dcf2239ec/828fb/cropped-mobile.jpg 630w,
https://kkozak.pl/static/c15c14fd7ebe29cf546ea43dcf2239ec/0ede0/cropped-mobile.jpg 945w,
https://kkozak.pl/static/c15c14fd7ebe29cf546ea43dcf2239ec/3ac88/cropped-mobile.jpg 1260w,
https://kkozak.pl/static/c15c14fd7ebe29cf546ea43dcf2239ec/903c8/cropped-mobile.jpg 2340w&quot;
        sizes=&quot;(max-width: 630px) 100vw, 630px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;In the next part of the tutorial I’ll demonstrate how to combine &lt;code class=&quot;language-text&quot;&gt;Forte.EpiResponsivePicture&lt;/code&gt; with React by creating projects listing page.&lt;/p&gt;
&lt;p&gt;The full source code of the sample project is available on &lt;a href=&quot;https://github.com/kpkozak/epi-responsive-picture-sample&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener&quot;&gt;GitHub&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 630px; &quot;
    &gt;
      &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 64.55696202531645%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAANABQDASIAAhEBAxEB/8QAFwAAAwEAAAAAAAAAAAAAAAAAAAIDBP/EABQBAQAAAAAAAAAAAAAAAAAAAAD/2gAMAwEAAhADEAAAAarZzMaw/8QAGxABAAICAwAAAAAAAAAAAAAAAQAEFCEDEiL/2gAIAQEAAQUC6beHRXmJ6xgCoE//xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAEDAQE/AT//xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAECAQE/AT//xAAeEAABAwQDAAAAAAAAAAAAAAAAAjKREiExQQEDEf/aAAgBAQAGPwJ/XI5EmUSVVb9aZtzoso//xAAcEAACAgIDAAAAAAAAAAAAAAABEQAhMUFhcYH/2gAIAQEAAT8h1WSyyeZaK84DmmqIB4jqMQWWWXif/9oADAMBAAIAAwAAABCzz//EABQRAQAAAAAAAAAAAAAAAAAAABD/2gAIAQMBAT8QP//EABQRAQAAAAAAAAAAAAAAAAAAABD/2gAIAQIBAT8QP//EAB8QAQEAAgIBBQAAAAAAAAAAAAERACExYZFBcYGhsf/aAAgBAQABPxBfK1Im/mJub9jr0ylVGO2PjAiwiAF51b3ju6DBmxx4+8PBmhBv4z//2Q==&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;cropped&quot;
        title=&quot;&quot;
        src=&quot;https://kkozak.pl/static/8a23d0866163407407efcd1b9e432845/828fb/cropped-homepage.jpg&quot;
        srcset=&quot;https://kkozak.pl/static/8a23d0866163407407efcd1b9e432845/ff44c/cropped-homepage.jpg 158w,
https://kkozak.pl/static/8a23d0866163407407efcd1b9e432845/a6688/cropped-homepage.jpg 315w,
https://kkozak.pl/static/8a23d0866163407407efcd1b9e432845/828fb/cropped-homepage.jpg 630w,
https://kkozak.pl/static/8a23d0866163407407efcd1b9e432845/0ede0/cropped-homepage.jpg 945w,
https://kkozak.pl/static/8a23d0866163407407efcd1b9e432845/3ac88/cropped-homepage.jpg 1260w,
https://kkozak.pl/static/8a23d0866163407407efcd1b9e432845/ccd6b/cropped-homepage.jpg 2108w&quot;
        sizes=&quot;(max-width: 630px) 100vw, 630px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
    &lt;/span&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Responsive images in Optimizely CMS - automatically resized & cropped picture]]></title><description><![CDATA[Today it is impossible to have one image that fits all devices and scenarios for web. Responsive websites must not only serve good quality content, but also be loaded quickly for both visitors' convenience and SEO purposes. That's why &lt;picture&gt; tag was introduced in HTML5. Here I show how to use its advantage in Optimizely CMS (formerly EPiServer).]]></description><link>https://kkozak.pl/blog/responsive-images-in-optimizely</link><guid isPermaLink="false">https://kkozak.pl/blog/responsive-images-in-optimizely</guid><category><![CDATA[Optimizely CMS]]></category><category><![CDATA[Episerver CMS]]></category><category><![CDATA[Responsive images]]></category><pubDate>Thu, 01 Jul 2021 17:30:00 GMT</pubDate><content:encoded>&lt;h3&gt;Responsive images in Optimizely CMS (EPiServer)&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Part 1: Automatically cropped &amp;#x26; resized responsive images&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://kkozak.pl/blog/picture-profiles&quot;&gt;Part 2: Picture profiles&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://kkozak.pl/blog/responsive-images-with-react&quot;&gt;Part 3: Responsive images in React&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;p&gt;As responsive websites must load quickly and offer good quality on all devices at the same time, it is almost obligatory to use &lt;a href=&quot;https://kkozak.pl/blog/picture-html5-tag/&quot;&gt;HTML5 &amp;#x3C;picture&gt; tag&lt;/a&gt; that allows providing different sets of images targeting a whole variety of screen sizes and pixel densities. In this series I’m showing how to make automatic, responsive pictures in &lt;strong&gt;Optimizely CMS (formerly EPiServer)&lt;/strong&gt;, which gets automatically scaled, compressed, or even cropped perfectly for the use case.&lt;/p&gt;
&lt;p&gt;The &lt;code class=&quot;language-text&quot;&gt;&amp;lt;picture&gt;&lt;/code&gt; tag is handy, but preparing each image in at least a few sizes is not the most attractive action that content creators can do. Additionally, computers are times better and faster in image processing (additionally, they don’t get bored at the same time) — so there is no reason to do that by ourselves.&lt;/p&gt;
&lt;h2&gt;What is Forte.EpiResponsivePicture&lt;/h2&gt;
&lt;p&gt;Valdis Iljuconoks had created great &lt;a href=&quot;https://github.com/valdisiljuconoks/ImageResizer.Plugins.EPiServerBlobReader&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener&quot;&gt;EPiServer plugin&lt;/a&gt; that allows automatic resizing of the images. It enables ImageResizer support for the content uploaded to the CMS. I also liked focal point-based cropping shown in &lt;a href=&quot;https://github.com/defsteph/EPiFocalPoint&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener&quot;&gt;the project developed by defsteph&lt;/a&gt; (currently archived), but neither of these two projects allowed fully adjusting image size or cropping based on visitor’s screen size.&lt;/p&gt;
&lt;p&gt;Leveraging concept of &lt;em&gt;picture profiles&lt;/em&gt; from Valdis’ package by mixing it with focal point cropping and &lt;a href=&quot;https://github.com/ErikHen/ImagePointEditor&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener&quot;&gt;ImagePointEditor by ErikHen&lt;/a&gt; had allowed to squeeze from the &amp;#x3C;picture&gt; spec as much as possible!&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 630px; &quot;
    &gt;
      &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 66.45569620253164%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAANABQDASIAAhEBAxEB/8QAGQAAAgMBAAAAAAAAAAAAAAAAAAYCAwQF/8QAFQEBAQAAAAAAAAAAAAAAAAAAAQD/2gAMAwEAAhADEAAAAcs2KseCMBP/xAAbEAABBAMAAAAAAAAAAAAAAAACAAEREwMQMf/aAAgBAQABBQIAysj5UWqgmF//xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAEDAQE/AT//xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAECAQE/AT//xAAaEAACAgMAAAAAAAAAAAAAAAAAARAyERIh/9oACAEBAAY/AqsSTKuM69j/xAAbEAEAAwADAQAAAAAAAAAAAAABABEhEDGBkf/aAAgBAQABPyFjH8mrC1oHUAN+HGmq2rKT/9oADAMBAAIAAwAAABAE3//EABcRAAMBAAAAAAAAAAAAAAAAAAABESH/2gAIAQMBAT8QWFZ//8QAFhEBAQEAAAAAAAAAAAAAAAAAAAEh/9oACAECAQE/ELWP/8QAGxABAQEAAgMAAAAAAAAAAAAAAREAITFBUdH/2gAIAQEAAT8QHpJwlF1LCUwV6V7fmIVqWlYK5G9ejy5pv//Z&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;Focus&quot;
        title=&quot;&quot;
        src=&quot;https://kkozak.pl/static/ee5c793850ce766eb16553b6b7870959/828fb/pexels-splitshire-1421.jpg&quot;
        srcset=&quot;https://kkozak.pl/static/ee5c793850ce766eb16553b6b7870959/ff44c/pexels-splitshire-1421.jpg 158w,
https://kkozak.pl/static/ee5c793850ce766eb16553b6b7870959/a6688/pexels-splitshire-1421.jpg 315w,
https://kkozak.pl/static/ee5c793850ce766eb16553b6b7870959/828fb/pexels-splitshire-1421.jpg 630w,
https://kkozak.pl/static/ee5c793850ce766eb16553b6b7870959/0ede0/pexels-splitshire-1421.jpg 945w,
https://kkozak.pl/static/ee5c793850ce766eb16553b6b7870959/3ac88/pexels-splitshire-1421.jpg 1260w,
https://kkozak.pl/static/ee5c793850ce766eb16553b6b7870959/0f98f/pexels-splitshire-1421.jpg 1920w&quot;
        sizes=&quot;(max-width: 630px) 100vw, 630px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;h2&gt;Focal point&lt;/h2&gt;
&lt;p&gt;On one hand, we could allow editors to upload different images for all variants of layouts, but in reality, we usually don’t need completely different images for desktop and phone/tablet screens. In the vast majority of cases, all we want to do is just make the image cropped in a way that the most important part of the image is still shown. This part of the image is called its &lt;strong&gt;focal point&lt;/strong&gt;. By allowing editors to choose that place on the image, we will be able to use the same image in very different scenarios, automatically cropped, and looking good at the same time on every device and use case on your page. No one likes boring, repetitive tasks, so if you take them off the editors, they’ll be really grateful!&lt;/p&gt;
&lt;p&gt;Let’s take an example project to illustrate the idea
— a site presenting the portfolio of fictional architects. We’re starting with a simple page that describes a project:&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 630px; &quot;
    &gt;
      &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 90.50632911392405%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAASABQDASIAAhEBAxEB/8QAGAABAQEBAQAAAAAAAAAAAAAAAAYBBQT/xAAVAQEBAAAAAAAAAAAAAAAAAAAAAf/aAAwDAQACEAMQAAAB5O1WJILgTHuLeyI//8QAHhAAAgEDBQAAAAAAAAAAAAAAAAIBAxIxERMhMjT/2gAIAQEAAQUCukuOR6kK25qLiv6IyvX/xAAWEQADAAAAAAAAAAAAAAAAAAAAEBH/2gAIAQMBAT8BI//EABQRAQAAAAAAAAAAAAAAAAAAACD/2gAIAQIBAT8BH//EABwQAAICAgMAAAAAAAAAAAAAAAABETECcRBBUf/aAAgBAQAGPwKmUURLb8RPXGezHQj/xAAcEAADAAEFAAAAAAAAAAAAAAAAARExIWFxofD/2gAIAQEAAT8hIvNXgbrIbFBFBJawarFTuPXsdQ//2gAMAwEAAgADAAAAEDfgAP/EABgRAAIDAAAAAAAAAAAAAAAAAAABEBFh/9oACAEDAQE/EFhQUf/EABkRAAIDAQAAAAAAAAAAAAAAAAABEBFBUf/aAAgBAgEBPxBrpY8j/8QAIBAAAgIBAwUAAAAAAAAAAAAAAREAITFBgZFRYXGhsf/aAAgBAQABPxCunLJFfIjRAs+YURzdjMmDrDG5QHMEQmJk73CqEQE2esUYG+R4lUUo+kn/2Q==&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;Architectural portfolio website&quot;
        title=&quot;&quot;
        src=&quot;https://kkozak.pl/static/86500cf3ca315da7c3c697f1c0d5fd9d/828fb/portfolio-item.jpg&quot;
        srcset=&quot;https://kkozak.pl/static/86500cf3ca315da7c3c697f1c0d5fd9d/ff44c/portfolio-item.jpg 158w,
https://kkozak.pl/static/86500cf3ca315da7c3c697f1c0d5fd9d/a6688/portfolio-item.jpg 315w,
https://kkozak.pl/static/86500cf3ca315da7c3c697f1c0d5fd9d/828fb/portfolio-item.jpg 630w,
https://kkozak.pl/static/86500cf3ca315da7c3c697f1c0d5fd9d/0ede0/portfolio-item.jpg 945w,
https://kkozak.pl/static/86500cf3ca315da7c3c697f1c0d5fd9d/d8d7f/portfolio-item.jpg 1032w&quot;
        sizes=&quot;(max-width: 630px) 100vw, 630px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;h2&gt;How to use&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;Disclaimer: The code shown in this article is meant to illustrate the idea and usage of the &lt;code class=&quot;language-text&quot;&gt;Forte.EpiResponsivePicture&lt;/code&gt; package and &lt;strong&gt;is not&lt;/strong&gt; showing good practices of writing code. For the simplicity of this tutorial, some things are deliberately trivialized.&lt;/p&gt;
&lt;p&gt;Full code of the project developed in this tutorial can be found on &lt;a href=&quot;https://github.com/kpkozak/epi-responsive-picture-sample&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener&quot;&gt;GitHub&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;Installation&lt;/h3&gt;
&lt;p&gt;First, let’s install the package from NuGet feed from your IDE, or by running the command:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;Install-Package Forte.EpiResponsivePicture&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;Warning: When installing via JetBrains Rider, make sure that static resources of peer dependency, ImagePointEditor, located in &lt;code class=&quot;language-text&quot;&gt;modules/_protected/ImagePointEditor&lt;/code&gt;, were added to the project correctly as &lt;code class=&quot;language-text&quot;&gt;&amp;lt;Content&gt;&lt;/code&gt;, not &lt;code class=&quot;language-text&quot;&gt;&amp;lt;None&gt;&lt;/code&gt; (see picture below).&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 630px; &quot;
    &gt;
      &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 59.49367088607595%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAMCAYAAABiDJ37AAAACXBIWXMAAA7DAAAOwwHHb6hkAAABsUlEQVR42pVTW3KcMBDkQK4sDyFACPRAAm9sV+UKuf8h2j1iscspfzgfjVSjUU9Pj6jc6rHtB1zM8NuOaV6glELbtmjapkD2P0XVdh1C9Mh5xzCOJPg87NoOPcmlQMc89di3jP9LJOeCSvGTg8UW45eEpmkwKo3NRzjvEUJASgmB+5GFtdYYBl1WgcSkeCWXwzJiTxvm2ZLsa4ueBI6kW74j73dE2rK6BB8S49sJ7u3iSTychJubqDCg73u2+alQ97oQTsZQATHNhIExM2MCe66Mz/R+4lklF6ehx5ECxmHE7XYrg6jruvgVIxW4tbQkSPmguo2KHBYO9MK6PhQqqtKF0GE/npE2yrcW3WMAojDnTOLIS2shEwsMFYlSQ/WGVgnKUAq783h7fcXb8x0vJEzurCotiK/LIu1MHMLwMWmlOHVtocYA1Q9FvVK9tFwjeYN1mdnm2arYIKtUlERZxV/BNdW+V9DrH5jjLwbjqDyUrqquaxHTTm92+rKUZCG8BnMV+Bb1L9S3J4ioK68Sgph/Y0l3jHb9IPsZ+MC766Gfj70yJLH2HLkh/uc3++7XeweK6IxUNNivcQAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;ImagePointEditor.zip should be added as &amp;quot;Content&amp;quot; element in .csproj file&quot;
        title=&quot;&quot;
        src=&quot;https://kkozak.pl/static/1d1f35bdea9c271bcf3dec4d6b27500d/f058b/ImagePointEditor.png&quot;
        srcset=&quot;https://kkozak.pl/static/1d1f35bdea9c271bcf3dec4d6b27500d/c26ae/ImagePointEditor.png 158w,
https://kkozak.pl/static/1d1f35bdea9c271bcf3dec4d6b27500d/6bdcf/ImagePointEditor.png 315w,
https://kkozak.pl/static/1d1f35bdea9c271bcf3dec4d6b27500d/f058b/ImagePointEditor.png 630w,
https://kkozak.pl/static/1d1f35bdea9c271bcf3dec4d6b27500d/5a6dd/ImagePointEditor.png 802w&quot;
        sizes=&quot;(max-width: 630px) 100vw, 630px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;h3&gt;Image content type &amp;#x26; properties&lt;/h3&gt;
&lt;p&gt;Then, let’s create content type for an image, deriving from base image type in &lt;code class=&quot;language-text&quot;&gt;Forte.EpiResponsivePicture&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;cs&quot;&gt;&lt;pre class=&quot;language-cs&quot;&gt;&lt;code class=&quot;language-cs&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token attribute&quot;&gt;&lt;span class=&quot;token class-name&quot;&gt;ContentType&lt;/span&gt;&lt;span class=&quot;token attribute-arguments&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;GUID &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;FD23C075-1DCD-4EF9-9E60-505ACD34C211&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token attribute&quot;&gt;&lt;span class=&quot;token class-name&quot;&gt;MediaDescriptor&lt;/span&gt;&lt;span class=&quot;token attribute-arguments&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;ExtensionString &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;jpg,jpeg,gif,png&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Image&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token type-list&quot;&gt;&lt;span class=&quot;token class-name&quot;&gt;Forte&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;EpiResponsivePicture&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;ResizedImage&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;ImageBase&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;When introducing responsive pictures to an existing project and you can’t, or simply don’t want to derive from the base class, alternatively you can implement &lt;code class=&quot;language-text&quot;&gt;IImage&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;IResponsiveImage&lt;/code&gt; interfaces, for automatic &lt;code class=&quot;language-text&quot;&gt;alt&lt;/code&gt; loading from image metadata, and focal point based cropping, respectively. &lt;code class=&quot;language-text&quot;&gt;Width&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;Height&lt;/code&gt; properties are automatically set when publishing content, so they shouldn’t be editable. Although, base class has also the additional quality of being culture-specific, so you can prepare versions of &lt;code class=&quot;language-text&quot;&gt;alt&lt;/code&gt; for different language branches easily (this is greatly explained by &lt;a href=&quot;https://gregwiechec.com/2015/07/localizable-media-assets/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener&quot;&gt;Greg Wiecheć on his blog&lt;/a&gt;).&lt;/p&gt;
&lt;h3&gt;Responsive image as property on page&lt;/h3&gt;
&lt;p&gt;Our first page type will represent single project in portfolio of our architects:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;cs&quot;&gt;&lt;pre class=&quot;language-cs&quot;&gt;&lt;code class=&quot;language-cs&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token attribute&quot;&gt;&lt;span class=&quot;token class-name&quot;&gt;ContentType&lt;/span&gt;&lt;span class=&quot;token attribute-arguments&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;GUID &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;4CCD0094-450D-449F-8B51-D7FF7A5A249F&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 
             DisplayName &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Project Page&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        Description &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Single project article&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token attribute&quot;&gt;&lt;span class=&quot;token class-name&quot;&gt;AvailableContentTypes&lt;/span&gt;&lt;span class=&quot;token attribute-arguments&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Availability&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;None&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;ProjectPage&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token type-list&quot;&gt;&lt;span class=&quot;token class-name&quot;&gt;PageData&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token attribute&quot;&gt;&lt;span class=&quot;token class-name&quot;&gt;Display&lt;/span&gt;&lt;span class=&quot;token attribute-arguments&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Order &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;virtual&lt;/span&gt; &lt;span class=&quot;token return-type class-name&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;string&lt;/span&gt;&lt;/span&gt; Title &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    
    &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token attribute&quot;&gt;&lt;span class=&quot;token class-name&quot;&gt;Display&lt;/span&gt;&lt;span class=&quot;token attribute-arguments&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Order &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token attribute&quot;&gt;&lt;span class=&quot;token class-name&quot;&gt;UIHint&lt;/span&gt;&lt;span class=&quot;token attribute-arguments&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;UIHint&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Image&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;virtual&lt;/span&gt; &lt;span class=&quot;token return-type class-name&quot;&gt;ContentReference&lt;/span&gt; MainImage &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token attribute&quot;&gt;&lt;span class=&quot;token class-name&quot;&gt;Display&lt;/span&gt;&lt;span class=&quot;token attribute-arguments&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Order &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;20&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;virtual&lt;/span&gt; &lt;span class=&quot;token return-type class-name&quot;&gt;XhtmlString&lt;/span&gt; Description &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    
    &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token attribute&quot;&gt;&lt;span class=&quot;token class-name&quot;&gt;Display&lt;/span&gt;&lt;span class=&quot;token attribute-arguments&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Order &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;30&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token attribute&quot;&gt;&lt;span class=&quot;token class-name&quot;&gt;AllowedTypes&lt;/span&gt;&lt;span class=&quot;token attribute-arguments&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;typeof&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token type-expression class-name&quot;&gt;Image&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Image&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;virtual&lt;/span&gt; &lt;span class=&quot;token return-type class-name&quot;&gt;ContentArea&lt;/span&gt; Images &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This page allows adding images in three different ways&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;as a &lt;code class=&quot;language-text&quot;&gt;ContentReference&lt;/code&gt; in MainImage,&lt;/li&gt;
&lt;li&gt;as elements of &lt;code class=&quot;language-text&quot;&gt;ContentArea&lt;/code&gt;, for &lt;code class=&quot;language-text&quot;&gt;Images&lt;/code&gt; gallery,&lt;/li&gt;
&lt;li&gt;in Description, added to &lt;code class=&quot;language-text&quot;&gt;XhtmlString&lt;/code&gt; via TinyMCE.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;To render &lt;code class=&quot;language-text&quot;&gt;&amp;lt;picture&gt;&lt;/code&gt; from content reference, we call &lt;code class=&quot;language-text&quot;&gt;ResizedPicture(ContentReference, PictureProfile)&lt;/code&gt; extension method of &lt;code class=&quot;language-text&quot;&gt;HtmlHelper&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;html&quot;&gt;&lt;pre class=&quot;language-html&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;article&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;div&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;header&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;div&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;content&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
            &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;h1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
                @Html.PropertyFor(m =&gt; m.Title)
            &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;h1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;div&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
        @Html.ResizedPicture(Model.MainImage, 
            PictureProfiles.HeaderImage) &lt;span class=&quot;token comment&quot;&gt;&amp;lt;!-- rendering of the image --&gt;&lt;/span&gt;
    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;div&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;div&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;content description&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
        @Html.PropertyFor(m=&gt;m.Description)
    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;div&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;article&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The second parameter of the &lt;code class=&quot;language-text&quot;&gt;ResizedPicture&lt;/code&gt; method is an instance of Picture Profile. &lt;code class=&quot;language-text&quot;&gt;PictureProfile&lt;/code&gt; is a class that represents single use case of an image, describing image dimensions, cropping, quality, etc. needed for that place, allowing to instruct the browser how the images should look like. These data are not related to the images themselves, rather describing a concrete place on a website for it. I’ll explain this concept, as well as how to create picture profiles, later. For now, let’s go with some placeholder:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;cs&quot;&gt;&lt;pre class=&quot;language-cs&quot;&gt;&lt;code class=&quot;language-cs&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;PictureProfiles&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;readonly&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;PictureProfile&lt;/span&gt; HeaderImage &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token constructor-invocation class-name&quot;&gt;PictureProfile&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        Format &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; ResizedImageFormat&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Jpg&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        DefaultWidth &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;800&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        Sources &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token constructor-invocation class-name&quot;&gt;PictureSource&lt;/span&gt;
                &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                    AllowedWidths &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1920&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1440&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1280&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1024&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
                    Mode &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; ScaleMode&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Crop&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
                    &lt;span class=&quot;token comment&quot;&gt;// 60vh for 16:9&lt;/span&gt;
                    TargetAspectRatio &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; AspectRatio&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Create&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;16&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;5.4&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 
                    Sizes &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
                    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                        &lt;span class=&quot;token string&quot;&gt;&quot;100vw&quot;&lt;/span&gt;
                    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
                    Quality &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;60&lt;/span&gt;
                &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; 
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now we can run the application, go to CMS edit mode, and create a new page for the project. Upload an image, remembering about filling alternate text and setting focal point, being the most important thing the photo is showing. Then, if we set the image as &lt;code class=&quot;language-text&quot;&gt;HeaderImage&lt;/code&gt; of our hero page, we can see that our image was rendered nicely as a &lt;code class=&quot;language-text&quot;&gt;&amp;lt;picture&gt;&lt;/code&gt; element, and is adapting to screen dimensions changes. Also, alternate text was loaded from image properties in the proper language.&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 630px; &quot;
    &gt;
      &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 82.27848101265823%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAQABQDASIAAhEBAxEB/8QAGQAAAQUAAAAAAAAAAAAAAAAAAAECAwQF/8QAFQEBAQAAAAAAAAAAAAAAAAAAAAH/2gAMAwEAAhADEAAAAdlY2RYAP//EABcQAAMBAAAAAAAAAAAAAAAAAAECAxD/2gAIAQEAAQUC2lAhnQvn/8QAFBEBAAAAAAAAAAAAAAAAAAAAEP/aAAgBAwEBPwE//8QAFhEBAQEAAAAAAAAAAAAAAAAAAAER/9oACAECAQE/AWx//8QAGRAAAgMBAAAAAAAAAAAAAAAAAAERITEQ/9oACAEBAAY/Aq6lY5yTT//EABsQAQADAQADAAAAAAAAAAAAAAEAESFRMXGR/9oACAEBAAE/ITS/CU+pvY7BKXkWdAY+Szif/9oADAMBAAIAAwAAABDLz//EABQRAQAAAAAAAAAAAAAAAAAAABD/2gAIAQMBAT8QP//EABcRAQADAAAAAAAAAAAAAAAAAAABIWH/2gAIAQIBAT8QqGz/xAAeEAABBAEFAAAAAAAAAAAAAAABABEhMUFRYcHR8f/aAAgBAQABPxCMRyyMoxNTZN5o/rQAIhsmE0wwVpxvV0CjkHa//9k=&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;Editing uploaded image properties&quot;
        title=&quot;&quot;
        src=&quot;https://kkozak.pl/static/7c787677cdf6808562ac66f1ba08487d/828fb/image-properties-edited.jpg&quot;
        srcset=&quot;https://kkozak.pl/static/7c787677cdf6808562ac66f1ba08487d/ff44c/image-properties-edited.jpg 158w,
https://kkozak.pl/static/7c787677cdf6808562ac66f1ba08487d/a6688/image-properties-edited.jpg 315w,
https://kkozak.pl/static/7c787677cdf6808562ac66f1ba08487d/828fb/image-properties-edited.jpg 630w,
https://kkozak.pl/static/7c787677cdf6808562ac66f1ba08487d/da104/image-properties-edited.jpg 809w&quot;
        sizes=&quot;(max-width: 630px) 100vw, 630px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 630px; &quot;
    &gt;
      &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 63.291139240506325%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAANABQDASIAAhEBAxEB/8QAFwAAAwEAAAAAAAAAAAAAAAAAAAIFA//EABUBAQEAAAAAAAAAAAAAAAAAAAAB/9oADAMBAAIQAxAAAAHJaqxFLpX/xAAcEAABBAMBAAAAAAAAAAAAAAAAAQIDFAQREhP/2gAIAQEAAQUC7HPTXqU4xMGNCnEf/8QAFBEBAAAAAAAAAAAAAAAAAAAAEP/aAAgBAwEBPwE//8QAFBEBAAAAAAAAAAAAAAAAAAAAEP/aAAgBAgEBPwE//8QAGBAAAgMAAAAAAAAAAAAAAAAAAEECEDH/2gAIAQEABj8CtmyGf//EABwQAAMAAQUAAAAAAAAAAAAAAAABESExYYGh8P/aAAgBAQABPyFolZ2hK8kQb7nPc0vnZ6Q//9oADAMBAAIAAwAAABD8D//EABQRAQAAAAAAAAAAAAAAAAAAABD/2gAIAQMBAT8QP//EABURAQEAAAAAAAAAAAAAAAAAAAAh/9oACAECAQE/EFf/xAAcEAEAAgIDAQAAAAAAAAAAAAABABEh0UFRYcH/2gAIAQEAAT8QQW0dbJW4r4qAAAwckED3sNRVXqU0vyLtt310n//Z&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;Character page adapting to screen changes&quot;
        title=&quot;&quot;
        src=&quot;https://kkozak.pl/static/fb72ad117316f32e9019272aa6f176ed/828fb/page-view-adapting-to-screens.jpg&quot;
        srcset=&quot;https://kkozak.pl/static/fb72ad117316f32e9019272aa6f176ed/ff44c/page-view-adapting-to-screens.jpg 158w,
https://kkozak.pl/static/fb72ad117316f32e9019272aa6f176ed/a6688/page-view-adapting-to-screens.jpg 315w,
https://kkozak.pl/static/fb72ad117316f32e9019272aa6f176ed/828fb/page-view-adapting-to-screens.jpg 630w,
https://kkozak.pl/static/fb72ad117316f32e9019272aa6f176ed/0ede0/page-view-adapting-to-screens.jpg 945w,
https://kkozak.pl/static/fb72ad117316f32e9019272aa6f176ed/193c9/page-view-adapting-to-screens.jpg 1093w&quot;
        sizes=&quot;(max-width: 630px) 100vw, 630px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;However, as we didn’t use &lt;code class=&quot;language-text&quot;&gt;@Html.PropertyFor&lt;/code&gt;, On-Page Editing doesn’t work for this property. To address that issue, we need to define a display template for properties marked with Image UiHint (for more info, Allan Thraen wrote a great post explaining &lt;a href=&quot;https://www.codeart.dk/blog/2018/9/how-are-images-rendered/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener&quot;&gt;how images are rendered in EPiServer (now Optimizely)&lt;/a&gt;). Let’s create a partial view in &lt;code class=&quot;language-text&quot;&gt;Views/Shared/DisplayTemplates&lt;/code&gt;, named &lt;code class=&quot;language-text&quot;&gt;Image.cshtml&lt;/code&gt; with model matching to our property type, that additionally tries to extract Picture Profile from &lt;code class=&quot;language-text&quot;&gt;ViewData&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;cs&quot;&gt;&lt;pre class=&quot;language-cs&quot;&gt;&lt;code class=&quot;language-cs&quot;&gt;@model EPiServer&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Core&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;ContentReference
@&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token class-name&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt;&lt;/span&gt; pictureProfile &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;ViewData&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;PictureProfile&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;PictureProfile&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; 
        &lt;span class=&quot;token operator&quot;&gt;??&lt;/span&gt; PictureProfiles&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;XHtmlString&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

@&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;ContentReference&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;IsNullOrEmpty&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Model&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    @Html&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;ResizedPicture&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Model&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; pictureProfile&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now we can render the image with &lt;code class=&quot;language-text&quot;&gt;.PropertyFor&lt;/code&gt; passing picture profile as additional view data. Let’s wrap this call with a handy extension method:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;cs&quot;&gt;&lt;pre class=&quot;language-cs&quot;&gt;&lt;code class=&quot;language-cs&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;HtmlHelperExtensions&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;token return-type class-name&quot;&gt;MvcHtmlString&lt;/span&gt; &lt;span class=&quot;token generic-method&quot;&gt;&lt;span class=&quot;token function&quot;&gt;ImagePropertyFor&lt;/span&gt;&lt;span class=&quot;token generic class-name&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;T&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; TValue&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;HtmlHelper&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;T&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt; html&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token class-name&quot;&gt;Expression&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;Func&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;T&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; TValue&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt; propExpr&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token class-name&quot;&gt;PictureProfile&lt;/span&gt; pictureProfile&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; html&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;PropertyFor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;propExpr&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;PictureProfile &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; pictureProfile&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now, after rendering the image with the following line, On-Page Editing works properly:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;cs&quot;&gt;&lt;pre class=&quot;language-cs&quot;&gt;&lt;code class=&quot;language-cs&quot;&gt;@Html&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;ImagePropertyFor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;m&lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt;m&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;MainImage&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; PictureProfiles&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;HeaderImage&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;Rendering &lt;code class=&quot;language-text&quot;&gt;&amp;lt;picture&gt;&lt;/code&gt; for Image in Content Area&lt;/h3&gt;
&lt;p&gt;Our project page looks great already. However, after adding some pictures in TinyMCE to the &lt;code class=&quot;language-text&quot;&gt;XHtml&lt;/code&gt; description field, it is still rendered as a regular &lt;code class=&quot;language-text&quot;&gt;&amp;lt;img&gt;&lt;/code&gt; tag. Moreover, after adding some nice pictures to the &lt;code class=&quot;language-text&quot;&gt;Images&lt;/code&gt; Content Area, the page breaks completely, not knowing how to render the images! Let’s address the second issue first.&lt;/p&gt;
&lt;p&gt;Let’s create a partial controller for our image type to make Optimizely (EPiServer) know how to render this type of content — exactly the same as we’d do with any content that can be rendered in the Content Area. The controller attempts to extract picture profile from &lt;code class=&quot;language-text&quot;&gt;ViewData&lt;/code&gt; of parent context. When profile is not present, it falls back to default &lt;code class=&quot;language-text&quot;&gt;XHtmlString&lt;/code&gt; profile — passing the data to &lt;code class=&quot;language-text&quot;&gt;Image.cshtml&lt;/code&gt; view defined in the previous step:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;cs&quot;&gt;&lt;pre class=&quot;language-cs&quot;&gt;&lt;code class=&quot;language-cs&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token attribute&quot;&gt;&lt;span class=&quot;token class-name&quot;&gt;TemplateDescriptor&lt;/span&gt;&lt;span class=&quot;token attribute-arguments&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    Inherited &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 
    Default &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    AvailableWithoutTag &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;ImageController&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token type-list&quot;&gt;&lt;span class=&quot;token class-name&quot;&gt;PartialContentController&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;Image&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;override&lt;/span&gt; &lt;span class=&quot;token return-type class-name&quot;&gt;ActionResult&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;Index&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Image&lt;/span&gt; currentContent&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token class-name&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt;&lt;/span&gt; profile &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; ControllerContext&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;ParentActionViewContext
                         &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;ViewData&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;PictureProfile&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;PictureProfile
                        &lt;span class=&quot;token punctuation&quot;&gt;?&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;?&lt;/span&gt; PictureProfiles&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;XHtmlString&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        ViewData&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;PictureProfile&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; profile&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;PartialView&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;~/Features/Image/Image.cshtml&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; currentContent&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;ContentLink&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;We still need to define &lt;code class=&quot;language-text&quot;&gt;XHtmlString&lt;/code&gt; picture profile:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;cs&quot;&gt;&lt;pre class=&quot;language-cs&quot;&gt;&lt;code class=&quot;language-cs&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;readonly&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;PictureProfile&lt;/span&gt; XHtmlString &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token constructor-invocation class-name&quot;&gt;PictureProfile&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    Format &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; ResizedImageFormat&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Jpg&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    DefaultWidth &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;800&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    Sources &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token constructor-invocation class-name&quot;&gt;PictureSource&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            MediaCondition &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;max-width: 768px&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            AllowedWidths &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;360&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;480&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;768&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            Mode &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; ScaleMode&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Crop&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            TargetAspectRatio &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; AspectRatio&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Create&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            Sizes &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;token string&quot;&gt;&quot;95vw&quot;&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now in &lt;code class=&quot;language-text&quot;&gt;ProjectPage.cshtml&lt;/code&gt; we can finally render the content area containing images, passing specific profile in the &lt;code class=&quot;language-text&quot;&gt;additionalViewData&lt;/code&gt; parameter (let’s not bother the picture profile for now, we can use any of the existing as well):&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;html&quot;&gt;&lt;pre class=&quot;language-html&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;@Html.PropertyFor(m=&gt;m.Images, 
    new
    {
        PictureProfile = PictureProfiles.HeaderImage
    })&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 630px; &quot;
    &gt;
      &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 90.50632911392405%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAASABQDASIAAhEBAxEB/8QAGAABAQEBAQAAAAAAAAAAAAAAAAYBBQT/xAAVAQEBAAAAAAAAAAAAAAAAAAAAAf/aAAwDAQACEAMQAAAB5O1WJILgTHuLeyI//8QAHhAAAgEDBQAAAAAAAAAAAAAAAAIBAxIxERMhMjT/2gAIAQEAAQUCukuOR6kK25qLiv6IyvX/xAAWEQADAAAAAAAAAAAAAAAAAAAAEBH/2gAIAQMBAT8BI//EABQRAQAAAAAAAAAAAAAAAAAAACD/2gAIAQIBAT8BH//EABwQAAICAgMAAAAAAAAAAAAAAAABETECcRBBUf/aAAgBAQAGPwKmUURLb8RPXGezHQj/xAAcEAADAAEFAAAAAAAAAAAAAAAAARExIWFxofD/2gAIAQEAAT8hIvNXgbrIbFBFBJawarFTuPXsdQ//2gAMAwEAAgADAAAAEDfgAP/EABgRAAIDAAAAAAAAAAAAAAAAAAABEBFh/9oACAEDAQE/EFhQUf/EABkRAAIDAQAAAAAAAAAAAAAAAAABEBFBUf/aAAgBAgEBPxBrpY8j/8QAIBAAAgIBAwUAAAAAAAAAAAAAAREAITFBgZFRYXGhsf/aAAgBAQABPxCunLJFfIjRAs+YURzdjMmDrDG5QHMEQmJk73CqEQE2esUYG+R4lUUo+kn/2Q==&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;Rendered images in Content Area&quot;
        title=&quot;&quot;
        src=&quot;https://kkozak.pl/static/86500cf3ca315da7c3c697f1c0d5fd9d/828fb/portfolio-item.jpg&quot;
        srcset=&quot;https://kkozak.pl/static/86500cf3ca315da7c3c697f1c0d5fd9d/ff44c/portfolio-item.jpg 158w,
https://kkozak.pl/static/86500cf3ca315da7c3c697f1c0d5fd9d/a6688/portfolio-item.jpg 315w,
https://kkozak.pl/static/86500cf3ca315da7c3c697f1c0d5fd9d/828fb/portfolio-item.jpg 630w,
https://kkozak.pl/static/86500cf3ca315da7c3c697f1c0d5fd9d/0ede0/portfolio-item.jpg 945w,
https://kkozak.pl/static/86500cf3ca315da7c3c697f1c0d5fd9d/d8d7f/portfolio-item.jpg 1032w&quot;
        sizes=&quot;(max-width: 630px) 100vw, 630px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;h3&gt;Picture in XHtmlString&lt;/h3&gt;
&lt;p&gt;The next thing that we still need to have worked out is rendering images dropped to the XHtmlField, edited via TinyMCE. By default, TinyMCE adds image dragged in the editor as &lt;code class=&quot;language-text&quot;&gt;&amp;lt;img&gt;&lt;/code&gt;, allowing an editor to add custom classes and customize rendering. There are generally two ways of coping with that:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;customize TinyMCE to add an image as a content block,&lt;/li&gt;
&lt;li&gt;alter rendering process of XHtml fields and replace &lt;code class=&quot;language-text&quot;&gt;&amp;lt;img&gt;&lt;/code&gt; tags with responsive &lt;code class=&quot;language-text&quot;&gt;&amp;lt;picture&gt;&lt;/code&gt; element.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;As the first solution is neat and simple, we’ll go with that one. We only need to add a custom UI Descriptor, altering drop behavior for &lt;code class=&quot;language-text&quot;&gt;Image&lt;/code&gt; content type:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;cs&quot;&gt;&lt;pre class=&quot;language-cs&quot;&gt;&lt;code class=&quot;language-cs&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token attribute&quot;&gt;&lt;span class=&quot;token class-name&quot;&gt;UIDescriptorRegistration&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;ImageUIDescriptor&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token type-list&quot;&gt;&lt;span class=&quot;token class-name&quot;&gt;UIDescriptor&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;Image&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;IEditorDropBehavior&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token return-type class-name&quot;&gt;EditorDropBehavior&lt;/span&gt; EditorDropBehaviour &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;ImageUIDescriptor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        EditorDropBehaviour &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; EditorDropBehavior&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;CreateContentBlock&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;When dropped, the image will be now rendered with partial controller and the view defined for Content Area. It is worth knowing that using “Insert/edit image” won’t result in the same, so we have to &lt;a href=&quot;https://world.episerver.com/documentation/developer-guides/CMS/add-ons/customizing-the-tinymce-editor-v2/default-settings/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener&quot;&gt;remove this button from toolbar&lt;/a&gt; to prevent users from something we don’t expect.
&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 630px; &quot;
    &gt;
      &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 82.27848101265823%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAQABQDASIAAhEBAxEB/8QAFwABAQEBAAAAAAAAAAAAAAAAAAIBBf/EABQBAQAAAAAAAAAAAAAAAAAAAAD/2gAMAwEAAhADEAAAAe4rCgf/xAAYEAACAwAAAAAAAAAAAAAAAAABEAIRMf/aAAgBAQABBQKWWi//xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAEDAQE/AT//xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAECAQE/AT//xAAWEAADAAAAAAAAAAAAAAAAAAARIDH/2gAIAQEABj8Cob//xAAcEAEBAAAHAAAAAAAAAAAAAAABABARIUFRYXH/2gAIAQEAAT8h2j0I08w5l2gHD//aAAwDAQACAAMAAAAQUM//xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAEDAQE/ED//xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAECAQE/ED//xAAaEAEAAwEBAQAAAAAAAAAAAAABABEhMWGh/9oACAEBAAE/ECoQ14C/YNAGh2aEA1RagGGewKJ//9k=&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;TinyMce image editor&quot;
        title=&quot;&quot;
        src=&quot;https://kkozak.pl/static/2975bf55456809c46d0f1050f6e31e1d/828fb/insert-image-tinymce.jpg&quot;
        srcset=&quot;https://kkozak.pl/static/2975bf55456809c46d0f1050f6e31e1d/ff44c/insert-image-tinymce.jpg 158w,
https://kkozak.pl/static/2975bf55456809c46d0f1050f6e31e1d/a6688/insert-image-tinymce.jpg 315w,
https://kkozak.pl/static/2975bf55456809c46d0f1050f6e31e1d/828fb/insert-image-tinymce.jpg 630w,
https://kkozak.pl/static/2975bf55456809c46d0f1050f6e31e1d/70dea/insert-image-tinymce.jpg 861w&quot;
        sizes=&quot;(max-width: 630px) 100vw, 630px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;That’s it! We have made our responsive images work with the Optimizely CMS. The next part will show how to replace current placeholder picture profiles with the actual ones.&lt;/p&gt;
&lt;p&gt;The whole source code of this tutorial can be found on &lt;a href=&quot;https://github.com/kpkozak/epi-responsive-picture-sample&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener&quot;&gt;GitHub&lt;/a&gt;.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;Images: &lt;br /&gt;
1: &lt;a href=&quot;https://www.pexels.com/photo/person-using-chainsaw-4206120/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener&quot;&gt;Karolina Grabowska&lt;/a&gt; &lt;br /&gt;
2: &lt;a href=&quot;https://www.pexels.com/photo/binocular-country-lane-filter-focus-1421/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener&quot;&gt;SplitShire&lt;/a&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[How does the <picture> work?]]></title><description><![CDATA[Almost every web developer already heard about all-image-problems-fixing HTML5 &lt;picture&gt; tag. But do you know how does that actually work?]]></description><link>https://kkozak.pl/blog/picture-html5-tag</link><guid isPermaLink="false">https://kkozak.pl/blog/picture-html5-tag</guid><category><![CDATA[Responsive images]]></category><pubDate>Sat, 27 Mar 2021 10:30:00 GMT</pubDate><content:encoded>&lt;p&gt;HTML5 is knocking around for some time already. Actually, most of it was widely adopted, fairly quickly became a part of good practices, and later — almost mandatory for semantic and structured Web content. In general, it allows to specify more than one version of the image to be shown, and let the browser choose option that fits most.
Almost every conscious web developer is aware of &lt;code class=&quot;language-text&quot;&gt;&amp;lt;picture&gt;&lt;/code&gt; tag and knows that it &lt;em&gt;solves a problem with responsive, optimized images in Web&lt;/em&gt;. While it may seem no-brainer, knowing exactly how that works and how browsers handle that is sometimes being treated as kinda’ &lt;em&gt;witchcraft&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;In good ol’ days of the Internet, everyone was browsing the Web with Internet Explorer (or earlier, Netscape Navigator), using desktop with screen having more-or-less the same resolution. However, starting from 1990s, more and more different resolutions appeared, and another types of devices got connected to the Internet, having now almost everything online. PCs. Smartphones. Tablets. Game consoles. TVs. Smartwatches. Even light bulbs (OK, I know — even if connected to the Internet, one &lt;em&gt;can not&lt;/em&gt; browse the Web with light bulb. Yet.) All these devices coming with dozens of different models, combinations, screen sizes and resolutions. To make this hell worse, Apple introduced Retina displays a while ago. There is no longer possibility to have one-picture-to-rule-them-all. Kinda dark times for people trying to publish content in the Internet, right? Well, not really.&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 630px; &quot;
    &gt;
      &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 56.9620253164557%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAALABQDASIAAhEBAxEB/8QAGAAAAwEBAAAAAAAAAAAAAAAAAAQFAgP/xAAWAQEBAQAAAAAAAAAAAAAAAAABAAL/2gAMAwEAAhADEAAAAdtyuWV8gk//xAAaEAADAQADAAAAAAAAAAAAAAABAhIAAyEy/9oACAEBAAEFAr5ctwz9nxbOCxO//8QAFBEBAAAAAAAAAAAAAAAAAAAAEP/aAAgBAwEBPwE//8QAFBEBAAAAAAAAAAAAAAAAAAAAEP/aAAgBAgEBPwE//8QAHRAAAgIBBQAAAAAAAAAAAAAAABEBEnECMUFRkf/aAAgBAQAGPwJRFsD1J5OPR9E2lo3P/8QAHBAAAgICAwAAAAAAAAAAAAAAAREAITFRQWHR/9oACAEBAAE/IVlFsaQgQ6vUIXQRka7A6gPToocQkyU//9oADAMBAAIAAwAAABDMD//EABURAQEAAAAAAAAAAAAAAAAAABAR/9oACAEDAQE/EIf/xAAVEQEBAAAAAAAAAAAAAAAAAAAAEf/aAAgBAgEBPxCo/8QAHRABAQABBAMAAAAAAAAAAAAAAREAITFRcUGhsf/aAAgBAQABPxB1EOwBHa/TEQYq2APF2XHERNDV7MS0AomK5HIolU2M42cZqPef/9k=&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;A lot of different devices, each one having different screen size&quot;
        title=&quot;&quot;
        src=&quot;https://kkozak.pl/static/977bf9df7eb3facb365a9447a0cdb62e/828fb/pexels-pixabay-207589.jpg&quot;
        srcset=&quot;https://kkozak.pl/static/977bf9df7eb3facb365a9447a0cdb62e/ff44c/pexels-pixabay-207589.jpg 158w,
https://kkozak.pl/static/977bf9df7eb3facb365a9447a0cdb62e/a6688/pexels-pixabay-207589.jpg 315w,
https://kkozak.pl/static/977bf9df7eb3facb365a9447a0cdb62e/828fb/pexels-pixabay-207589.jpg 630w,
https://kkozak.pl/static/977bf9df7eb3facb365a9447a0cdb62e/0ede0/pexels-pixabay-207589.jpg 945w,
https://kkozak.pl/static/977bf9df7eb3facb365a9447a0cdb62e/3ac88/pexels-pixabay-207589.jpg 1260w,
https://kkozak.pl/static/977bf9df7eb3facb365a9447a0cdb62e/c42e5/pexels-pixabay-207589.jpg 4928w&quot;
        sizes=&quot;(max-width: 630px) 100vw, 630px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;h2&gt;Controlling image dimensions: &lt;code class=&quot;language-text&quot;&gt;srcSet&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 630px; &quot;
    &gt;
      &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 57.59493670886076%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAMCAYAAABiDJ37AAAACXBIWXMAAA7DAAAOwwHHb6hkAAAC+ElEQVR42k2S2W8TVxSH/R9VKioFKh5opRJCS+CxqA8VqloJ8QASq9QXqkKLRKiStCQUSlaQspklqpM4jeM4iWOP7cT22ONJPJ7xkrETx3ZWm6WoX68nKOrDp/M7R3fO/O49xzbr6ME//QKfa0gwzNz0IAvzL4lJYxbxwBiy5CDq20P2jxL0vCA085LFeQcLvkmUyBweZz8nPzuAraS4KGRjmKkAhVSQvBFkNR1iPRummAmzZoTYWo3zupKkVlq24kZeFsR4VU6yW1xip7xEbtlH0/GPsckzQyRCe06SUTeaYCk8JWpOEsFR62A5F2F7NcZWYY9t8YM6Vi6a19ZVMolZTn3+ETZv/w/IT79F83RgavOsqG4KhkTG30v02XXhdIGq+GBnTXlP/H9aYVtQE66zqpfTDcKhEXOTT0kUtCC1wjK7psJWTqacXaRqRgVx8sviCTIRy+mGKWMmJVKxGetMUQ9SEbHu8MyJw9h0ZYbNlSQeaZSf7Lf5efgmvePt4qoSPROtdDruoUdDpBQ/muojl4uTViWMsIeyKt5d1OrvvN8wJbtZiP9F88hNjjZ/yid3j9HQepLzPd/x5e+nLX2u8xvOPjrLpe7vMUY6CXieMB54ypj0hICrh/xkP/Wbnmk8IhoK4Qj08qP9Ol/8dorHE820Om7RKBo1tDTy9cOv6Jtqo8vVwsBEC0ZXM3+PtNA13Ua3wGW/hznQjh6ZpKnhEDZNnoI3ZZzBfj785Si6Psc/JY2k5qFt7A73nXdhI82/FYN3GwbV3TRvNw2o6AKDN5s6r2tZskvevSknIy6qxQRx1cXQ7GMy+rxYh7ioqeyuJtgRurQS2aeSC1vDsXIxtLreKSgYSn1tDmJTvX0UlWdUtGmqaS/rSRepxREUv511bQozMU5RxKKomwknpZSbNaFXRL22tsirUox3mwmxJbM01R12/3qB54+uMfjgCgMdlxl6cFVwhcH2ywz/cXWfem1fv8/tD68xLHj+5w36Wi/SeOwD/gNpHAh5jnDi+gAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;Picture tag is supported by all Internet browsers&quot;
        title=&quot;&quot;
        src=&quot;https://kkozak.pl/static/fccebf4739aef728ec1c3bd357bd0e73/f058b/caniuse-picture.png&quot;
        srcset=&quot;https://kkozak.pl/static/fccebf4739aef728ec1c3bd357bd0e73/c26ae/caniuse-picture.png 158w,
https://kkozak.pl/static/fccebf4739aef728ec1c3bd357bd0e73/6bdcf/caniuse-picture.png 315w,
https://kkozak.pl/static/fccebf4739aef728ec1c3bd357bd0e73/f058b/caniuse-picture.png 630w,
https://kkozak.pl/static/fccebf4739aef728ec1c3bd357bd0e73/40601/caniuse-picture.png 945w,
https://kkozak.pl/static/fccebf4739aef728ec1c3bd357bd0e73/58fee/caniuse-picture.png 1051w&quot;
        sizes=&quot;(max-width: 630px) 100vw, 630px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;It’s been some time when the &lt;code class=&quot;language-text&quot;&gt;&amp;lt;picture&gt;&lt;/code&gt; was introduced, and as you see above, it is supported by all &lt;em&gt;Internet browsers (&lt;a href=&quot;https://www.zdnet.com/article/microsoft-security-chief-ie-is-not-a-browser-so-stop-using-it-as-your-default/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener&quot;&gt;I mean, browsers&lt;/a&gt;)&lt;/em&gt;. Internet Explorer has some polyfills available, so if you still have to support this
ancient artifact, there is an option. At worst, without polyfill, it would be fallbacked to what was defined in &lt;code class=&quot;language-text&quot;&gt;&amp;lt;img&gt;&lt;/code&gt; tag.&lt;/p&gt;
&lt;p&gt;First, let’s assume that we have image that takes full width of the article pane, up to 1000px. Wanting them to be shown good on Retina screens, we might do something like the following:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;&amp;lt;picture&gt;
    &amp;lt;source srcset=&quot;1000px.jpg 1x, 2000px.jpg 2x, 3000px 3x&quot; /&gt;
    &amp;lt;img src=&quot;1000px.jpg&quot; alt=&quot;Our beautiful image&quot; /&gt;
&amp;lt;/picture&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Adding a &lt;code class=&quot;language-text&quot;&gt;&amp;lt;source&gt;&lt;/code&gt; element with &lt;code class=&quot;language-text&quot;&gt;srcset&lt;/code&gt; attribute, containing comma-separated list of URLs to different versions of the image, will instruct the browser to choose the one that fits best. In this case, for devices with device pixel ratio equal to 2, bigger image could be loaded. For device pixel ratio at 3, the biggest one will be loaded, making everything look fine on different screens.&lt;/p&gt;
&lt;p&gt;However, this takes into consideration only pixel density — so, even browsing with the small Retina-like device will trigger loading bigger image unnecesarily. For example, with iPhone 6/7/8, working at CSS resolution of &lt;code class=&quot;language-text&quot;&gt;375x667&lt;/code&gt; and pixel density &lt;code class=&quot;language-text&quot;&gt;2.0&lt;/code&gt;, we can take advantage of image being at most 750 pixels wide. The smallest one provided is sufficient, while device pixel ratio suggest to load image with dimensions multiplied by 2. Definitely not the best way to save bandwith. If we would want to do it better, we need to make calculations based on image placeholder size &amp;#x26; breakpoints, and use media querying to adjust &lt;code class=&quot;language-text&quot;&gt;&amp;lt;source&gt;&lt;/code&gt; elements accordingly. Additionally, we’re not optimally covering devices with pixel density values not being integer, or bigger than three (there are already some devices).&lt;/p&gt;
&lt;p&gt;That’s why second option of providing image size alternatives — width descriptor — is much more fancy. Instead of constraining images to pixel density, let’s just describe the images we’re providing:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;&amp;lt;source srcset=&quot;1000px.jpg 1000w, 2000px.jpg 2000w, 3000px.jpg 3000w&quot; /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The above literally instructs browser that &lt;code class=&quot;language-text&quot;&gt;1000px.jpg&lt;/code&gt; is 1000 pixels wide, &lt;code class=&quot;language-text&quot;&gt;2000px.jpg&lt;/code&gt; — 2000 pixels, and &lt;code class=&quot;language-text&quot;&gt;3000px.jpg&lt;/code&gt; — 3000 pixels.&lt;/p&gt;
&lt;p&gt;Why is that better? We didn’t instruct the browser directly when certain images should be picked, but just let it to browser. We still need to give browser directions on how to choose it, but we won’t need to tie image sizes with media conditions, doing all the calculations and constraining loading proper images. Just imagine the scenario of &lt;em&gt;whole-width-images-but-2-columns-on-tablet-and-4-on-desktop&lt;/em&gt;, and try to include all variety of pixel density. Yup. May by &lt;em&gt;a bit&lt;/em&gt; messy. And let the one of you that won’t make a mistake during the calculations be the first to cast a stone.&lt;/p&gt;
&lt;p&gt;OK, we did first part — told the browser what images we have. Now let’s add &lt;code class=&quot;language-text&quot;&gt;sizes&lt;/code&gt; to that. To make things more fun, let’s use that simple layout mentioned earlier:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;on mobile, image is displayed full width&lt;/li&gt;
&lt;li&gt;on tablets, show items in two column layout&lt;/li&gt;
&lt;li&gt;4 columns for desktop,&lt;/li&gt;
&lt;li&gt;whole content pane is growing up to 1400px at screen width of 1440px, then leaving margins on both sides.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;/444c84f3814b707b4111493dfa432965/4-columns.gif&quot; alt=&quot;4 columns layout, changing with screen size&quot;&gt;&lt;/p&gt;
&lt;p&gt;While it might seem tough, actual markup is pretty straightforward:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;&amp;lt;source srcset=&quot;340px.jpg 340w, 
                480px.jpg 480w,
                700px.jpg 700w, 
                1024px.jpg 1024w&quot; 
        sizes=&quot;(min-width: 1440px) 340px,
               (min-width: 1024px) 22vw,
               (min-width: 768px) 45vw,
               92vw&quot;
                /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;We can see already known &lt;code class=&quot;language-text&quot;&gt;srcset&lt;/code&gt;, and a new attribute — &lt;code class=&quot;language-text&quot;&gt;sizes&lt;/code&gt;. &lt;code class=&quot;language-text&quot;&gt;Sizes&lt;/code&gt; describe widths of space held for the image, in CSS units. Note that &lt;code class=&quot;language-text&quot;&gt;w&lt;/code&gt; in &lt;code class=&quot;language-text&quot;&gt;srcset&lt;/code&gt; mean “pixels of image”, while &lt;code class=&quot;language-text&quot;&gt;px&lt;/code&gt; in &lt;code class=&quot;language-text&quot;&gt;sizes&lt;/code&gt; — “CSS pixels” (which not necessarily mean screen pixel).&lt;/p&gt;
&lt;p&gt;Why is that better? Well, what we did was describing images we have (in &lt;strong&gt;image units&lt;/strong&gt;), as well as space which these image should occupy (&lt;strong&gt;in CSS units&lt;/strong&gt;), leaving all the calculations to browser. We don’t have to bother device pixel ratio, counting what should the image size be and so on. Additionally, we described both images and space for them &lt;strong&gt;in their natural units&lt;/strong&gt; — image in pixels (of bitmap), sizes — with CSS &lt;code class=&quot;language-text&quot;&gt;px&lt;/code&gt; or &lt;code class=&quot;language-text&quot;&gt;vw&lt;/code&gt;, the units we use in CSS to same exact thing. So now, viewing the page with Retina iPhone with resolution (in CSS pixels) &lt;code class=&quot;language-text&quot;&gt;375x667&lt;/code&gt;, with device pixel ratio equal to two, browser will look for image 690 pixels wide (&lt;code class=&quot;language-text&quot;&gt;375 * 0.92 * 2&lt;/code&gt;). The closest one is 700, so this one will be chosen.&lt;/p&gt;
&lt;p&gt;What’s also worth noting:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;if multiple media conditions are met, &lt;strong&gt;first (top) matching size is taken&lt;/strong&gt; — this might be a bit counterintuitive, as with CSS, selectors weighted equally are applied sequentially&lt;/li&gt;
&lt;li&gt;despite above example uses &lt;code class=&quot;language-text&quot;&gt;px&lt;/code&gt; or &lt;code class=&quot;language-text&quot;&gt;vw&lt;/code&gt;, you can use any CSS unit (&lt;code class=&quot;language-text&quot;&gt;vh&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;em&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;rem&lt;/code&gt;), or even &lt;code class=&quot;language-text&quot;&gt;calc&lt;/code&gt;. I prefer to simplify things so usually go with simple approximation that is fair enough, but value accurately calculated with &lt;code class=&quot;language-text&quot;&gt;calc&lt;/code&gt; will also do the job. However, &lt;strong&gt;percents cannot be used&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Alternative images for different views (aka &lt;em&gt;art direction-based selection&lt;/em&gt;): &lt;code class=&quot;language-text&quot;&gt;&amp;lt;source&gt;&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;media&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;While &lt;code class=&quot;language-text&quot;&gt;srcset&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;sizes&lt;/code&gt; address our needs for different image quality across screens, it doesn’t help when our layout changes significantly across devices. Let’s suppose we have nice, beautifully composed, horizontal product photo, that shows your product with great surrounding on desktop. However, with the same photo on vertical, 4-inch smartphone screen, customer will barely see the product. We need to show something more accurate.&lt;/p&gt;
&lt;p&gt;To achieve this, just create separate &lt;code class=&quot;language-text&quot;&gt;&amp;lt;source&gt;&lt;/code&gt; element with &lt;code class=&quot;language-text&quot;&gt;media&lt;/code&gt; attribute describing when to use each image:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;html&quot;&gt;&lt;pre class=&quot;language-html&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;picture&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;source&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;media&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;(min-width: 1024px)&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; 
            &lt;span class=&quot;token attr-name&quot;&gt;srcset&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;nicely-composed-medium.jpg 1024w, 
                    nicely-composed-large.jpg 1440w&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
            &lt;span class=&quot;token attr-name&quot;&gt;sizes&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;100vw&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;/&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;source&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;srcset&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;bare-product.jpg 375w, 
                    bare-product-retina.jpg 750w&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
            &lt;span class=&quot;token attr-name&quot;&gt;sizes&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;100vw&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;/&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;img&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;src&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;default.jpg&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;alt&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;My beautiful product&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;/&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;picture&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;img src=&quot;/abd93e961462f642eb24845ce9af609e/animation-sources.gif&quot; alt=&quot;Different &lt;source&gt; elements allow to show totally different images depending on screen size&quot;&gt;&lt;/p&gt;
&lt;p&gt;While this might seem a bit similar to use of &lt;code class=&quot;language-text&quot;&gt;srcset&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;sizes&lt;/code&gt;, the main difference is that by using different &lt;code class=&quot;language-text&quot;&gt;&amp;lt;source&gt;&lt;/code&gt; you instruct the browser that &lt;strong&gt;another image is used&lt;/strong&gt;, and it’s not only another sizing of the same — so, for example, resizing the screen down &lt;strong&gt;will force loading the new image&lt;/strong&gt; if another &lt;code class=&quot;language-text&quot;&gt;&amp;lt;source&gt;&lt;/code&gt; meets its criteria. This wouldn’t happen with &lt;code class=&quot;language-text&quot;&gt;srcset&lt;/code&gt;, as browser won’t load smaller image already having bigger version of the same pic.&lt;/p&gt;
&lt;h2&gt;Different image formats&lt;/h2&gt;
&lt;p&gt;Another nice feature of &lt;code class=&quot;language-text&quot;&gt;&amp;lt;source&gt;&lt;/code&gt; is possibility to serve images in different formats. For example, if we want to allow using &lt;code class=&quot;language-text&quot;&gt;webp&lt;/code&gt; images for browsers supporting it, just add &lt;code class=&quot;language-text&quot;&gt;type=webp&lt;/code&gt; attribute:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;html&quot;&gt;&lt;pre class=&quot;language-html&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;picture&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;source&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;srcset&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;image.webp&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;webp&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;/&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;source&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;srcset&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;image.jpg&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;jpeg&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;/&gt;&lt;/span&gt;&lt;/span&gt;

    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;img&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;src&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;default.jpg&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;alt&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;Alternate text&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;/&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;picture&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Guess that’s rather self-explanatory, so no need to explain.&lt;/p&gt;
&lt;h2&gt;That’s it!&lt;/h2&gt;
&lt;p&gt;With &lt;code class=&quot;language-text&quot;&gt;&amp;lt;picture&gt;&lt;/code&gt; tag, responsive, adaptive images are becoming ridiculously simple, especially combined with solutions that can do the job of resizing and/or cropping automatic. It is supported virtually everywhere, and it’s worth to be used in nearly every web page.&lt;/p&gt;
&lt;p&gt;Using Optimizely CMS (formerly EPiServer)? &lt;a href=&quot;https://kkozak.pl/blog/responsive-images-in-optimizely/&quot;&gt;The solution already exists&lt;/a&gt;.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;Images: &lt;br /&gt;&lt;/p&gt;
&lt;p&gt;1: &lt;a href=&quot;https://unsplash.com/photos/3_Xwxya43hE&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener&quot;&gt;Pine Watt&lt;/a&gt;
&lt;br /&gt;
2: &lt;a href=&quot;https://www.pexels.com/photo/macbook-and-ipad-on-desk-207589/?utm_source=attribution_note&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener&quot;&gt;Pixabay&lt;/a&gt;
&lt;br /&gt;
3: &lt;a href=&quot;https://www.pexels.com/photo/red-apples-on-tree-574919/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener&quot;&gt;Tom Swinnen&lt;/a&gt;
&lt;br /&gt;
3: &lt;a href=&quot;https://www.pexels.com/photo/healthy-apple-fruits-natural-102104/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener&quot;&gt;Mali Maeder&lt;/a&gt;
&lt;br /&gt;
5: &lt;a href=&quot;https://caniuse.com/picture&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener&quot;&gt;caniuse.com&lt;/a&gt;&lt;/p&gt;</content:encoded></item></channel></rss>