PICTURE (Veams Components )

src/app/shared/components/picture/templates

Demo Section

Each variation will be presented in the following section.

Picture with Sizes

Alternative text that describes the image

Picture with Lazyload

Alternative text that describes the image

Readme

Picture

Description

Include responsive (content) images. It supports lazy loading (when provided in your JavaScript) and uses a custom getUrl helper to print out the relative path or URL.


Installation

Installation with Veams

veams install vc picture


Fields

picture.hbs

Settings

Parameter Type Default Description
settings.pictureClasses String '' Modifier classes for component
settings.pictureContextClass String 'default' Context class of component
settings.lazyload Boolean false Use lazyload for images

Content

Parameter Type Description
content.fallback String Path to fallback image, e.g. “https://via.placeholder.com/400x200” - mostly the smallest image defined in srcset
content.alt String An alternative text describing the image if a user for some reason cannot view it
content.items Array An array containing different image sources

The images should differ in type or in picture detail, otherwise there’s no need to add more than one child object. Each item will generate a <source> element

Parameter Type Description
content.items.type String If the browser supports the format described in the type attribute, it uses that source; otherwise, the <source> element is skipped

Example: “image/webp”. Use type attribute only if you provide new file formats like webp, jx2, jp2, apng, etc

Parameter Type Description
content.items.media String If a query in a media attribute evaluates to true, the browser must use that source; otherwise, the <source> element is skipped

Example: “(min-width: 200px)”. Use media attribute only for art direction use case

Parameter Type Description
content.items.srcset Array Use srcset to provide different image sizes. Contains 1-x children
content.items.srcset.src String Path to image, e.g. https://via.placeholder.com/400x200
content.items.srcset.imageWidth String The width in physical pixels (e.g. 400w) of image referenced in src above
Parameter Type Description
content.items.sizes Array Use sizes to define the width of our images at a given screen size

The media queries could reflect the breakpoints in your project, but it’s not mandatory to stick to them. If the width of an image in the srcset attribute is set (= imageWidth), the sizes attribute must be present.

Parameter Type Description
content.items.sizes.screenWidth String Media query (e.g. (min-width: 992px)) defining which image to use
content.items.sizes.imageWidth String Width of image in viewport matching the media query defined in “screenWidth”. Use width in pixel, e.g. 960px or as a dynamic width, e.g. calc(100vw - 50px)

Contributors

Thanks for assistance and contributions:

@chaenu

Templates

picture.hbs

<picture class="c-picture{{#if settings.pictureContextClass}}--{{settings.pictureContextClass}}{{else}}--default{{/if}}
	{{#if settings.pictureClasses}} {{settings.pictureClasses}}{{/if}}{{#if settings.lazyload}} lazyload{{/if}}"
 data-css="c-picture" {{#if settings.pictureJsItem}} data-js-item='{{settings.pictureJsItem}}'{{/if}}>

	<!--[if IE 9]><audio><![endif]-->
	{{#each content.items}}
	<source {{#if ../settings.lazyload}} data-{{/if}}srcset="{{#each srcset}}{{#unless @first}}, {{/unless}}
	 {{getUrl src}} {{#if imageWidth}} {{imageWidth}} {{/if}} {{/each}}"
	        {{#if sizes}} sizes=" {{#each sizes}}
	 {{#unless @first}} , {{/unless}} {{screenWidth}} {{imageWidth}} {{/each}}"{{/if}}
		{{#if media}} media=" {{media}}"{{/if}}
		{{#if type}} type="
	 {{type}}"{{/if}} />
	{{/each}}
	<!--[if IE 9]></audio><![endif]-->

	{{#if content.fallbackSrc}}
		<img class="
	 picture__image{{#if settings.lazyload}} lazyload{{/if}}" src="{{getUrl content.fallbackSrc}}" alt="{{content.alt}}"
	 title="{{content.alt}}" {{#if settings.autoSizes}}  data-sizes="auto" {{/if}} {{#if settings.ariaDescribedBy}} aria-describedby="{{settings.ariaDescribedBy}}"
	 {{/if}} />
	{{else}}
	<h3 style="color: red; font-weight: bold;">Define a fallback picture!</h3>
	{{/if}}
</picture>

Data File

picture-bp.hjson

{
	"title": "Picture",
	"variations": {
		"default": {
			"docs": {
				"variationName": "Picture with Sizes",
				"center": true
			},
			"settings": {
				"pictureContextClass": "default",
				"pictureClasses": false,
				"lazyload": false,
				"autoSizes": true
			},
			"content": {
				"fallbackSrc": "https://via.placeholder.com/400x200",
				"alt": "Alternative text that describes the image",
				"items": [
					{
						"srcset": [
							{
								"src": "https://via.placeholder.com/400x300",
								"imageWidth": "400w"
							},
							{
								"src": "https://via.placeholder.com/800x600",
								"imageWidth": "800w"
							},
							{
								"src": "https://via.placeholder.com/1200x900",
								"imageWidth": "1200w"
							},
							{
								"src": "https://via.placeholder.com/1600x1200",
								"imageWidth": "1600w"
							},
							{
								"src": "https://via.placeholder.com/2000x1500",
								"imageWidth": "2000w"
							},
							{
								"src": "https://via.placeholder.com/2400x1800",
								"imageWidth": "2400w"
							},
							{
								"src": "https://via.placeholder.com/2800x2100",
								"imageWidth": "2800w"
							},
							{
								"src": "https://via.placeholder.com/3200x2400",
								"imageWidth": "3200w"
							}
						],
						"sizes": [
							{
								"screenWidth": "(min-width: 992px)",
								"imageWidth": "1440px"
							},
							{
								"screenWidth": "(min-width: 768px)",
								"imageWidth": "calc( 100vw - 50px )"
							}
						]
					}
				]
			}
		},
		"lazyload": {
			"docs": {
				"variationName": "Picture with Lazyload",
				"center": true
			},
			"settings": {
				"pictureContextClass": "default",
				"pictureClasses": false,
				"lazyload": true,
				"autoSizes": true
			},
			"content": {
				"fallbackSrc": "https://via.placeholder.com/40x10",
				"alt": "Alternative text that describes the image",
				"items": [
					{
						"srcset": [
							{
								"src": "https://via.placeholder.com/400x300",
								"imageWidth": "400w"
							},
							{
								"src": "https://via.placeholder.com/800x600",
								"imageWidth": "800w"
							},
							{
								"src": "https://via.placeholder.com/1200x900",
								"imageWidth": "1200w"
							},
							{
								"src": "https://via.placeholder.com/1600x1200",
								"imageWidth": "1600w"
							},
							{
								"src": "https://via.placeholder.com/2000x1500",
								"imageWidth": "2000w"
							},
							{
								"src": "https://via.placeholder.com/2400x1800",
								"imageWidth": "2400w"
							},
							{
								"src": "https://via.placeholder.com/2800x2100",
								"imageWidth": "2800w"
							},
							{
								"src": "https://via.placeholder.com/3200x2400",
								"imageWidth": "3200w"
							}
						]
					}
				]
			}
		}
	}
}

Styles

styles/_picture.scss

HTML Output

Picture with Sizes

<picture class="c-picture--default
	" data-css="c-picture">
	<!--[if IE 9]><audio><![endif]-->
	<source srcset="
	 https://via.placeholder.com/400x300  400w  , 
	 https://via.placeholder.com/800x600  800w  , 
	 https://via.placeholder.com/1200x900  1200w  , 
	 https://via.placeholder.com/1600x1200  1600w  , 
	 https://via.placeholder.com/2000x1500  2000w  , 
	 https://via.placeholder.com/2400x1800  2400w  , 
	 https://via.placeholder.com/2800x2100  2800w  , 
	 https://via.placeholder.com/3200x2400  3200w  " sizes=" 
	  (min-width: 992px) 1440px 
	  ,  (min-width: 768px) calc( 100vw - 50px ) " />
	<!--[if IE 9]></audio><![endif]-->
	<img class="
	 picture__image" src="https://via.placeholder.com/400x200" alt="Alternative text that describes the image" title="Alternative text that describes the image" data-sizes="auto" />
</picture>

Picture with Lazyload

<picture class="c-picture--default
	 lazyload" data-css="c-picture">
	<!--[if IE 9]><audio><![endif]-->
	<source data-srcset="
	 https://via.placeholder.com/400x300  400w  , 
	 https://via.placeholder.com/800x600  800w  , 
	 https://via.placeholder.com/1200x900  1200w  , 
	 https://via.placeholder.com/1600x1200  1600w  , 
	 https://via.placeholder.com/2000x1500  2000w  , 
	 https://via.placeholder.com/2400x1800  2400w  , 
	 https://via.placeholder.com/2800x2100  2800w  , 
	 https://via.placeholder.com/3200x2400  3200w  " />
	<!--[if IE 9]></audio><![endif]-->
	<img class="
	 picture__image lazyload" src="https://via.placeholder.com/40x10" alt="Alternative text that describes the image" title="Alternative text that describes the image" data-sizes="auto" />
</picture>

Wonach suchst du?