fluxtech-me / frontik

Frontend Development Libraries
https://frontik.js.org
MIT License
10 stars 0 forks source link

Image component #25

Open alexkharatyan opened 1 year ago

alexkharatyan commented 1 year ago

Description

A clear and concise description of what the investigation is.

Additional

Add any other content that might be helpful.

SamoMelkonyan commented 1 year ago

Requirements

  1. Lazy load image
  2. aspect ratio
  3. preview and zoom https://www.primefaces.org/primereact/image/
  4. circular, rounded
alexkharatyan commented 1 year ago

Image Component

Images have an intrinsic size. If an image is wider than the screen, the image will overflow, causing a horizontal scrollbar to appear.

Fortunately, we can take measures in CSS to stop this from happening.

Constrain your images

In your stylesheet, you can declare that images should never be rendered at a size wider than their containing element using max-inline-size.

img {
  max-inline-size: 100%;
  block-size: auto;
}

You can use max-width instead of max-inline-size if you prefer, but remember it's good to get in the habit of thinking in terms of logical properties.

With that rule in place, browsers will automatically scale down images to fit on the screen.

Image

Adding a block-size value of auto means that the aspect-ratio of the images will remain constant.

Sometimes the dimensions of an image might be out of your control—if an image is added through a content management system, for example. If your design calls for a images to have an aspect ratio that's different to the image's real dimensions, use the aspect-ratio property in CSS.

img {
  max-inline-size: 100%;
  block-size: auto;
  aspect-ratio: 2/1;
}

But then the browser might squash or stretch the image to make it fit your preferred aspect ratio.

Image

To prevent that happening, use the object-fit property.

An object-fit value of contain tells the browser to preserve the image's aspect ratio, even if that means leaving empty space above and below.

img {
  max-inline-size: 100%;
  block-size: auto;
  aspect-ratio: 2/1;
  object-fit: contain;
}

An object-fit value of cover tells the browser to preserve the image's aspect ratio, even if that means cropping the image at the top and bottom.

img {
  max-inline-size: 100%;
  block-size: auto;
  aspect-ratio: 2/1;
  object-fit: cover;
}

Image The same image with two different values for object-fit applied. The first has an object-fit value of contain. The second has an object-fit value of cover.

If the cropping at the top and bottom evenly is an issue, use the object-position CSS property to adjust the focus of the crop. You can make sure the most important image content is still visible.

img {
  max-inline-size: 100%;
  block-size: auto;
  aspect-ratio: 2/1;
  object-fit: cover;
  object-position: top center;
}

Image

Deliver your images

Those CSS rules tell the browser how you'd like images to be rendered. You can also provide hints in your HTML about how you the browser should handle those images.

Sizing hints

If you know the dimensions of the image you should include width and height attributes. Even if the image is rendered at a different size (because of your max-inline-size: 100% rule), the browser still knows the width to height ratio and can set aside the right amount of space. This will stop your other content jumping around when the image loads.

<img
 src="image.png"
 alt="A description of the image."
 width="300"
 height="200"
>

https://storage.googleapis.com/web-dev-uploads/video/tcFciHGuF3MxnTr1y5ue01OGLBn2/WOQn6K6OQcoElRw0NCkZ.mp4

https://storage.googleapis.com/web-dev-uploads/video/tcFciHGuF3MxnTr1y5ue01OGLBn2/sFxDb36aEMvTPIyZHz1O.mp4

Loading hints

Use the loading attribute to tell the browser how urgently you want it to load an image. For images below the fold, use a value of lazy. The browser won't load lazy images until the user has scrolled far down enough that the image is about to come into view. If the user never scrolls, the image never loads.

<img
 src="image.png"
 alt="A description of the image."
 width="300"
 height="200"
 loading="lazy"
>

https://storage.googleapis.com/web-dev-uploads/video/KT4TDYaWOHYfN59zz6Rc0X4k4MH3/jazsyaOjXfHS0g8yUijR.mp4

For an important image you can tell the browser to pre-fetch the image in the head of your document.

<link rel="prefetch" href="hero.jpg" as="image">

But remember: when you ask the browser to prioritize downloading one resource—like an image—the browser will have to de-prioritize another resource such as a script or a font file. Only prefetch an image if it is truly vital.

Image decoding

There's also a decoding attribute you can add to img elements. You can tell the browser that the image can be decoded asynchronously. The browser can then prioritize processing other content.

<img
 src="image.png"
 alt="A description of the image."
 width="300"
 height="200"
 loading="lazy"
 decoding="async"
>

You can use the sync value if the image itself is the most important piece of content to prioritize.

<img
 src="hero.jpg"
 alt="A description of the image."
 width="1200"
 height="800"
 loading="eager"
 decoding="sync"
>

Responsive images with srcset

Thanks to that max-inline-size: 100% declaration, your images will never break out of their containers. But even if it looks fine to have a large image that shrinks to fit, it won't feel fine. If someone uses a small screen device on a low bandwidth network, they'll download unnecessarily large images.

If you make multiple versions of the same image at different sizes, you can let the browser know about them using the srcset attribute.

Width descriptor

You can pass in a list of values separated by commas. Each value should be the URL of an image followed by a space followed by some metadata about the image. This metadata is called a descriptor.

In this example, the metadata describes the width of each width using the w unit. One w is one pixel.

<img
 src="small-image.png"
 alt="A description of the image."
 width="300"
 height="200"
 loading="lazy"
 decoding="async"
 srcset="small-image.png 300w,
  medium-image.png 600w,
  large-image.png 1200w"
>

The srcset attribute doesn't replace the src attribute. Instead the srcset attribute complements the src attribute. You still need to have a valid src attribute, but now the browser can replace its value with one of the options listed in the srcset attribute.

The browser won't download the larger images unless they're needed. That saves bandwidth.

Sizes

If you're using the width descriptor, you must also use the sizes attribute to give the browser more information. This tells the browser what size you expect the image to be displayed under different conditions. Those conditions are specified in a media query.

The sizes attribute takes a comma-separated list of media queries and image widths.

<img
 src="small-image.png"
 alt="A description of the image."
 width="300"
 height="200"
 loading="lazy"
 decoding="async"
 srcset="small-image.png 300w,
  medium-image.png 600w,
  large-image.png 1200w"
 sizes="(min-width: 66em) 33vw,
  (min-width: 44em) 50vw,
  100vw"
>

In this example, you're telling the browser that above a viewport width of 66em to display the image no wider than one third of the screen (inside a three column layout, for example).

For viewport widths between 44em and 66em, display the image at half the width of the screen (a two column layout).

For anything below 44em display the image at the full width of the screen.

This means that the biggest image won't necessarily be used for the widest screen. A wide browser window that can display a multi-column layout will use an image that fits in one column. That image might be smaller than an image used for a single-column layout on a narrower screen.

https://storage.googleapis.com/web-dev-uploads/video/KT4TDYaWOHYfN59zz6Rc0X4k4MH3/MkUAq5XQyjlUXLvkT4jL.mp4

Pixel density descriptor

There's another situation where you might want to provide multiple versions of the same image.

Some devices have high-density displays. On a double-density display you can pack two pixels worth of information into the space of one pixel. This keeps images looking sharp on those kinds of displays.

Image

Use the density descriptor to describe the pixel density of the image in relationship to the image in the src attribute. The density descriptor is a number followed by the letter x: 1x, 2x, etc.

<img
 src="small-image.png"
 alt="A description of the image."
 width="300"
 height="200"
 loading="lazy"
 decoding="async"
 srcset="small-image.png 1x,
  medium-image.png 2x,
  large-image.png 3x"
>

If small-image.png is 300 by 200 pixels in size, and medium-image.png is 600 by 400 pixels in size, then medium-image.png can have 2x after it in the srcset list.

Presentational images

Images in HTML are content. That's why you always provide an alt attribute with a description of the image for screen readers and search engines.

If you embed an image that is purely a visual flourish without any meaningful content, use an empty alt attribute.

<img
 src="flourish.png"
 alt=""
 width="400"
 height="50"
>

You must still include the alt attribute. A missing alt attribute is not the same as an empty alt attribute. An empty alt attribute conveys to a screen reader that this image is presentational.

Ideally, your presentational or decorative images shouldn't be in your HTML at all. HTML is for structure. CSS is for presentation.

Background images

Use the background-image property in CSS to load presentational images.

element {
  background-image: url(flourish.png);
}

You can specify multiple image candidates using the [image-set](https://developer.mozilla.org/docs/Web/CSS/image/image-set()) function for background-image.

The image-set function in CSS works a lot like the srcset attribute in HTML. Provide a list of images with a pixel density descriptor for each one.

element {
  background-image: image-set(
    small-image.png 1x,
    medium-image.png 2x,
    large-image.png 3x
  );
}

The browser will choose the most appropriate image for the device's pixel density.

There are many factors to consider when you're adding images to your site:

Reserving the right space for each image. Figuring out how many sizes you need. Deciding whether the image is content or decorative.

It's worth spending the time to get images right. Poor image strategies are responsible for frustration and annoyance for users. A good image strategy makes your site feel snappy and sharp, regardless of the user's device or network connection.

<Picture />

Art direction-based selection

The picture element and the source element, together with the media attribute, can be used to provide multiple images that vary the image content (for instance the smaller image might be a cropped version of the bigger image).

<picture>
  <source media="(min-width: 45em)" srcset="large.jpg">
  <source media="(min-width: 32em)" srcset="med.jpg">
  <img src="small.jpg" alt="The wolf runs through the snow.">
</picture>

The user agent will choose the first source element for which the media query in the media attribute matches, and then choose an appropriate URL from its srcset attribute.

Image format-based selection The type attribute on the source element can be used to provide multiple images in different formats.

<h2>From today's featured article</h2>
<picture>
 <source srcset="/uploads/100-marie-lloyd.webp" type="image/webp">
 <source srcset="/uploads/100-marie-lloyd.jxr" type="image/vnd.ms-photo">
 <img src="/uploads/100-marie-lloyd.jpg" alt="" width="100" height="150">
</picture>
<p><b><a href="/wiki/Marie_Lloyd">Marie Lloyd</a></b> (1870–1922)
was an English <a href="/wiki/Music_hall">music hall</a> singer, ...

In this example, the user agent will choose the first source that has a type attribute with a supported MIME type. If the user agent supports WebP images, the first source element will be chosen. If not, but the user agent does support JPEG XR images, the second source element will be chosen. If neither of those formats are supported, the img element will be chosen.

And if attribute is being ignored entirely by picture-supporting user agents, the src attribute can default to any image, including one that is neither the smallest nor biggest:

(As a side note, if you are creating purely vector graphics, and you can export to SVG, you should do that instead and ignore this entire thing. SVG files are infinitely scalable, look great on all screens regardless of resolution, and are now supported in all current browser versions.)

PictureFill

But even if all the browsers currently supported the responsive images standards, we’d still need a way to help older browsers understand the new syntax. That’s where the PictureFill polyfill comes in.

PictureFill will allow you to use the new responsive images syntax now.

To sum up

Common use cases for :

Values of the srcset Attribute

Value Name Notes
list of sources A list of image source URLs and their respective sizes.

All Attributes of img Element

Attribute name Value Name Notes
height Identifies the intrinsic height of an image file, in CSS pixels.
srcset list of sources Defines multiple sizes of the same image, allowing the browser to select the appropriate image source.
align right left Was previously used to specify the alignment and placement of an image relative to the surrounding text. It has been deprecated and should not be used.
alt text Defines alternate text, which may be presented in place of the image.
border pixels Previously used to define a border on an image element. It has been deprecated and should no longer be used.
controls Toggled media player controls when used in conjunction with the dynsrc attribute. Both attributes are now deprecated.
dynsrc
hspace Previously used to add horizontal space on both side of an image. It is now deprecated.
ismap Identifies an image as a server-side image map. When the containing anchor link is clicked, the coordinates of the mouse will be included in the request.
longdesc Defines a URL at which can be found more information about the image. It was written out of the HTML5 specification, but its status is not quite so clear as other deprecated features.
loop Previously used to specify the number of times a video should play, when used in conjunction with the dynsource attribute. Both attributes have been deprecated.
lowsrc Specified a smaller or lower-quality version of an image.
name Identified the image or provided additional information about it. Deprecated in HTML 4.0 in favor of other attributes.
naturalsizeflag This attribute does nothing. It was once used by a proprietary software system.
nosave Was intended to prevent users from downloading an image. Was never a part of the HTML specification, and not widely implemented.
start fileopen, mouseover
suppress Used by the now-defunct Netscape browser to suppress the display of image prior to image download completion.
usemap Specifies a client-side image map to be used with the image. width Indicates the intrinsic width of the image, in CSS pixels.
src Specifies the URL of an image to be displayed.