<figure class="a-image a-image--cover">
    <a class="a-image__link" href="#" tabindex="-1">
        <img src="/img/wheat_ratio.jpg" alt="Some many things on this image" title="This is a linked image" class="a-image__image a-image__image--fp a-image__image--fp-">
    </a>
    <figcaption>
        <span class="a-image__caption">This is the image caption</span>
        <small class="a-image__copy a-image__copy--caption">&copy; Photographer xy</small>
    </figcaption>
</figure>
<figure class="a-image{{#unless no_crop }} a-image--cover{{/unless}}">
	{{#if link-url}}<a class="a-image__link" href="{{link-url}}" tabindex="-1">{{/if}}
	<img src="{{image-src}}" alt="{{alt}}" title="{{title}}" class="a-image__image{{#unless no_crop }} a-image__image--fp a-image__image--fp-{{focal_point}}{{/unless}}">
	{{#if link-url}}</a>{{/if}}
	{{# unless no_caption }}
		<figcaption>
			{{#if caption}}<span class="a-image__caption">{{caption}}</span>{{/if}}
			{{#if copy}}
				<small class="a-image__copy{{#if caption}} a-image__copy--caption{{/if}}">&copy; {{copy}}</small>{{/if}}
		</figcaption>
	{{/unless}}
</figure>
  • Content:
    .a-image {
    	max-width: 100%;
    	position: relative;
    	line-height: 0;
    
    	&__image {
    		transition: transform $transition-mid $transition-ease-image;
    	}
    
    	&__image--no-crop {
    		max-width: 100%;
    	}
    
    	&--cover {
    		width: 100%;
    		height: 100%;
    	}
    
    	&--cover &__image {
    		width: 100%;
    		height: 100%;
    	}
    
    	&--cover &__lazy-wrapper {
    		width: 100%;
    		height: 100%;
    		overflow: hidden;
    	}
    
    	&--cover.object-fit-ie {
    		background-size: cover;
    	}
    
    	&__image--lazy {
    		filter: blur(2vw);
    		transform: scale(1.1);
    	}
    
    	&__image--loaded {
    		animation-name: reveal;
    		animation-duration: $transition-mid;
    		animation-timing-function: $transition-ease-image;
    	}
    
    	&--cover &__image--fp {
    		object-fit: cover;
    
    		&-top {
    			&-left {
    				object-position: 0 0;
    			}
    
    			&-center {
    				object-position: 50% 0;
    			}
    
    			&-right {
    				object-position: 100% 0;
    			}
    		}
    
    		&-middle {
    			&-left {
    				object-position: 0 50%;
    			}
    
    			&-center {
    				object-position: 50% 50%;
    			}
    
    			&-right {
    				object-position: 100% 50%;
    			}
    		}
    
    		&-bottom {
    			&-left {
    				object-position: 0 100%;
    			}
    
    			&-center {
    				object-position: 50% 100%;
    			}
    
    			&-right {
    				object-position: 100% 100%;
    			}
    		}
    
    		&.object-fit-ie {
    			display: none;
    		}
    	}
    
    	// for the IE polyfill
    	&--cover.object-fit-ie.a-image__image-fp {
    		&-top {
    			&-left {
    				background-position: 0 0;
    			}
    
    			&-center {
    				background-position: 50% 0;
    			}
    
    			&-right {
    				background-position: 100% 0;
    			}
    		}
    
    		&-middle {
    			&-left {
    				background-position: 0 50%;
    			}
    
    			&-center {
    				background-position: 50% 50%;
    			}
    
    			&-right {
    				background-position: 100% 50%;
    			}
    		}
    
    		&-bottom {
    			&-left {
    				background-position: 0 100%;
    			}
    
    			&-center {
    				background-position: 50% 100%;
    			}
    
    			&-right {
    				background-position: 100% 100%;
    			}
    		}
    	}
    
    	&__link {
    		@include clean-link;
    
    		display: block;
    		max-width: 100%;
    		overflow: hidden;
    
    		@include hover {
    			.a-image__image {
    				transform: scale(1.01);
    			}
    		}
    	}
    
    	&--cover &__link {
    		width: 100%;
    		height: 100%;
    	}
    
    	&__copy {
    		position: absolute;
    		@include fluid-props(bottom right, $size-tiny, $size-large, 5px, 10px);
    		@include fluid-props(font-size, $size-tiny, $size-large, 5px, 7px);
    		transform: translateX(calc(100% - 1em)) rotate(-90deg);
    		transform-origin: top left;
    
    		color: $color-white;
    		text-transform: uppercase;
    		mix-blend-mode: difference;
    
    		&--caption {
    			transform: none;
    			color: $color-text-light;
    			mix-blend-mode: normal;
    		}
    
    		&--small {
    			bottom: 6px;
    			right: 3px;
    			font-size: 6px;
    		}
    
    		a {
    			box-shadow: none;
    			color: inherit;
    			text-decoration: none;
    
    			@include hover {
    				background: none;
    				box-shadow: none;
    			}
    		}
    	}
    
    	&__caption {
    		line-height: 1.4em;
    		font-size: 0.875rem;
    		color: $color-text-light;
    		padding: 0.5em 1em 1em;
    		background: $color-grey-1;
    		width: 100%;
    		display: block;
    	}
    }
    
    @keyframes reveal {
    	0%   {filter: blur(2vw); transform: scale(1.1);}
    	100% {filter: blur(0); transform: scale(1);}
    };
    
    .no-js .a-image--cover .a-image__lazy-wrapper {
    	display: none;
    }
    
  • URL: /components/raw/a-image/_a-image.scss
  • Filesystem Path: styleguide/src/components/atoms/a-image/_a-image.scss
  • Size: 3.1 KB
  • Content:
    import BaseView from 'base-view';
    
    const COVER_IMAGE_SELECTOR = '.a-image__image--fp';
    
    const LAZY_LOADED = 'a-image__image--loaded';
    const COMPATIBILITY_STATE = 'object-fit-ie';
    
    const LAZY_LOAD_WAIT_MS = 200;
    
    /**
     * Since IE and Edge don't support object-fit, use background: cover css for
     * them
     *
     * @see https://medium.com/@primozcigler/neat-trick-for-css-object-fit-fallback-on-edge-and-other-browsers-afbc53bbb2c3
     */
    export default class AImageCover extends BaseView {
    	initialize() {
    		this.initUrl = this.getUrl();
    	}
    
    	bind() {
    		super.bind();
    
    		this.on( 'afterReplaceImage', () => {
    			this.setSizes();
    			this.objectFit();
    		} );
    	}
    
    	objectFit() {
    		if ('objectFit' in document.documentElement.style !== false) {
    			this.destroy();
    			return;
    		}
    
    		const img = this.getScopedElement(COVER_IMAGE_SELECTOR);
    
    		if (!img) {
    			this.destroy();
    			return;
    		}
    
    		this.polyfill(img);
    	}
    
    	polyfill(img) {
    		const url = this.getUrl();
    
    		// wait for lazy loading to be complete
    		if (img.classList.contains(LAZY_LOADED)) {
    			if (this.initUrl === url) {
    				window.setTimeout(() => this.polyfill(img), LAZY_LOAD_WAIT_MS);
    				return;
    			}
    		}
    
    		let fp = img.className.match(/\ba-image__image--fp-[^\s]+\b/g);
    		if (fp) {
    			this.addClass('a-image__image--fp');
    			this.addClass(fp[0]);
    		}
    
    		this.addClass(COMPATIBILITY_STATE);
    		this.element.style.backgroundImage = "url('"+url+"')";
    
    		this.addClass(img, COMPATIBILITY_STATE);
    	}
    
    	getUrl() {
    		const img = this.getScopedElement( COVER_IMAGE_SELECTOR );
    
    		if (img) {
    			return img.src;
    		}
    
    		return '';
    	}
    
    	setSizes() {
    		const img = this.getScopedElement( COVER_IMAGE_SELECTOR );
    		const cDims = this.element.getBoundingClientRect();
    		const cRatio = cDims.width / cDims.height;
    		const iRatio = img.naturalWidth / img.naturalHeight;
    
    		const zoom = iRatio > cRatio ? iRatio / cRatio : cRatio / iRatio;
    
    		img.sizes = cDims.width * zoom + 'px';
    	}
    }
    
  • URL: /components/raw/a-image/a-image-cover.js
  • Filesystem Path: styleguide/src/components/atoms/a-image/a-image-cover.js
  • Size: 1.9 KB
  • Content:
    import BaseView from 'base-view';
    import inView from '../../../js/service/inview';
    
    const BASE_CONTAINER_SELECTOR = '.a-image';
    
    const LAZY_STATE = 'a-image__image--lazy';
    const LAZY_LOADED = 'a-image__image--loaded';
    const DEBOUNCE_DELAY_MS = 300;
    
    export default class AImageLazy extends BaseView {
    	initialize() {
    		this.loading = false;
    	}
    
    	bind() {
    		super.bind();
    
    		inView(this.element, DEBOUNCE_DELAY_MS).then(() => this.maybeLoadImage());
    	}
    
    	maybeLoadImage() {
    		if (!this.loading){
    			this.loading = true;
    			let img = this.loadFullImage();
    			if (img.complete) {
    				this.replaceImage( img );
    			} else {
    				img.onload = () => this.replaceImage( img );
    			}
    		}
    	}
    
    	loadFullImage() {
    		let img = this.element.cloneNode( true );
    		img.srcset = img.dataset.srcset || '';
    		img.sizes = img.dataset.sizes || '';
    		img.removeAttribute( 'data-srcset' );
    		img.removeAttribute( 'data-sized' );
    
    		// otherwise safari on iOS doesn't load images when
    		// scrolling, even if they are in the viewport
    		img.loading = 'eager';
    
    		return img;
    	}
    
    	replaceImage( img ) {
    		if (this.element.parentNode) {
    			this.element.parentNode.replaceChild( img, this.element );
    		}
    
    		img.classList.add( LAZY_LOADED );
    		img.classList.remove( LAZY_STATE );
    
    		this.triggerAfterReplaceEvent( img.closest( BASE_CONTAINER_SELECTOR ) );
    
    		this.destroy();
    	}
    
    	triggerAfterReplaceEvent(elem) {
    		// use the old fashioned way, cause we need it in IE
    		let event = document.createEvent('Event');
    		event.initEvent('afterReplaceImage', true, true);
    		elem.dispatchEvent(event);
    	}
    }
    
  • URL: /components/raw/a-image/a-image-lazy.js
  • Filesystem Path: styleguide/src/components/atoms/a-image/a-image-lazy.js
  • Size: 1.6 KB
{
  "link-url": "#",
  "image-src": "/img/wheat_ratio.jpg",
  "alt": "Some many things on this image",
  "title": "This is a linked image",
  "copy": "Photographer xy",
  "caption": "This is the image caption"
}

No notes defined.