响应式 ui 模板

by Maciej Nowakowski

通过Maciej Nowakowski

带有即用型模板的响应式图像指南 (A Guide to Responsive Images with Ready-to-Use Templates)

Why generate 12 versions of the same image when just 2 media-queries do the job? The users won’t notice.

为什么只有两个媒体查询才能完成同一图像的12个版本? 用户不会注意到。

But Google will.

但是谷歌会的。

Responsive images that are in the wrong format, images that are not compressed properly, and images that are too big will all decrease the page speed and impact your SEO.

格式错误的响应图像,未正确压缩的图像以及太大的图像都会降低页面速度并影响您的SEO。

According to Google, anything above 2 seconds of download time will put off your users and discourage the crawlers from indexing your website.

根据Google的说法,下载时间超过2秒的任何内容都会推迟用户,并阻止抓取工具将您的网站编入索引。

I learned that the hard way when I was rebuilding my website. My goal was to create a simple website that downloads in the blink of an eye. To do so, I went for Gatsby.js — it’s fast and I know it.

当我重建网站时,我了解到了这一困难的方法。 我的目标是创建一个简单的网站,眨眼间即可下载。 为此,我选择了Gatsby.js-速度很快,我知道。

After a few days of coding, the website was up and running. But, to my disappointment, it scored a modest 78/100 on mobile and a disastrous 57/100 on the desktop on PageSpeed Insights. Not good at all.

经过几天的编码,网站开始运行。 但是,令我失望的是,在PageSpeed Insights上,它在移动设备上的得分仅为78/100,在台式机上的得分仅为57/100。 一点都不好。

PageSpeed Insights suggested an easy fix to the problem. Just download the compressed images the tool has created, and you’ll be fine.

PageSpeed Insights建议对该问题进行简单修复。 只需下载该工具创建的压缩图像,就可以了。

That sparked my curiosity. And the more I thought about sizes, formats, and compression levels, the more I felt overwhelmed with the abundance of choices. PNGs, JPGs, SVGs, inline base64 encoded strings… or maybe WebPs?

那激发了我的好奇心。 而且,我对尺寸,格式和压缩级别的思考越多,我对众多选择的选择就越感到不知所措。 PNG,JPG,SVG,内嵌base64编码的字符串……或者WebP?

To wrap my head around it, I dived into the world of pixels, waded through the muddy waters of random tips on the subject, and came up with a systematic approach.

为了解决这个问题,我进入了像素世界,在泥泞的随机水域中涉水,并提出了系统的方法。

And once I applied what I learned, my PageSpeed rating increased from 78 to 91 on mobile and from 57 to 99 on desktop!

应用我所学的知识后,我的PageSpeed评分在移动设备上从78提高到91,在台式机上从57提高到99!

In this post, I will show you how to quickly generate responsive images that work in all browsers and massively reduce your download speeds.

在本文中,我将向您展示如何快速生成可在所有浏览器中使用的响应式图像,以及如何大幅度降低下载速度。

在你开始前 (Before you start)

If you want to optimize an image, you have to start with a high-quality image that has the right format and the right size:

如果要优化图像,则必须从具有正确格式和正确大小的高质量图像开始:

  • Use JPGs for photos and PNGs for graphics or other images that require transparency
    将JPG用于照片,将PNG用于需要透明的图形或其他图像
  • Use smaller PNG-8 instead of PNG-24 for graphics with a limited number of colors. To decrease the size even further, you can also reduce the number of colors, from 256 to 16
    对于颜色数量有限的图形,请使用较小的PNG-8而不是PNG-24。 要进一步减小尺寸,您还可以将颜色数量从256减少到16
  • Use SVGs (vector graphic images) for icons and logos. They will scale nicely without increasing the size of your file
    将SVG(矢量图形图像)用于图标和徽标。 它们将很好地扩展,而不会增加文件的大小
  • Use inline images below 10KB as 64base encoded strings (sparingly)
    将10KB以下的嵌入式图像用作64base编码的字符串(分别)
  • The actual width of an image shouldn’t exceed the width of the largest container it will be displayed in, multiplied by two (for retina displays)
    图片的实际宽度不应超过将要显示的最大容器的宽度乘以2(用于视网膜显示)

硬件和软件像素 (Hardware and software pixels)

The image that takes the full width of the 15” Macbook Pro screen is 1440 pixels wide but the actual resolution of the retina display is double that, at 2880x1800. Why? Because of its pixel density factor of 2.

整个15英寸Macbook Pro屏幕的图像宽度为1440像素,但视网膜显示屏的实际分辨率是2880x1800的两倍。 为什么? 由于其像素密度因子为2。

Old monitors have a pixel density of 1. But since screen resolutions have increased in recent years, the hardware pixel is no longer equal to the software or CSS pixel.

老式显示器的像素密度为1。但是,由于近年来屏幕分辨率有所提高,因此硬件像素已不再等于软件或CSS像素。

The relationship between hardware and CSS pixels is described by the following formula:

硬件和CSS像素之间的关系由以下公式描述:

CSS Pixels = Hardware Pixels / Pixel density

CSS像素=硬件像素/像素密度

Therefore, hardware resolution of 2880 pixels translates to1440 CSS pixels on the retina display. This also explains why, when you inspect the full-width image in Developer Tools, you will see it as only 1440 pixels wide instead of the original 2880 pixels.

因此,2880像素的硬件分辨率在视网膜显示器上转换为1440 CSS像素。 这也解释了为什么在开发人员工具中检查全角图像时,您会看到它只有1440像素宽而不是原始的2880像素宽。

The retina display was a major breakthrough a few years ago. Today, mobile devices have even “denser” displays of 3 and even 4 for Samsung Galaxy S8+!

视网膜显示是几年前的一项重大突破。 如今,移动设备甚至为三星Galaxy S8 +配备了3甚至4个“密度”显示器!

For the purpose of my experiment, I decided that to be razor-sharp, the full-width image should have the maximum width of 2880 pixels.

出于实验目的,我决定要清晰锐利,全角图像的最大宽度应为2880像素。

With the image height set to 600px and the quality to 75%, Photoshop produced a massive 939KB file. That’s hardly acceptable.

图像高度设置为600px,质量设置为75%,Photoshop生成了一个庞大的939KB文件。 那是很难接受的。

After a few experiments with compression levels, it became clear that compressing JPGs below 60% quality resulted in a visible loss of quality. I set the quality to 60% as a starting point and the image size dropped to 681KB. Still, far from decent.

在进行了一些压缩级别的实验后,很明显压缩JPG的质量低于60%会导致可见的质量损失。 我将画质设为60%作为起点,并将图像大小降至681KB。 尽管如此,还远远不够体面。

WebP格式 (WebP format)

“WebP is a modern image format that provides superior lossless and lossy compression for images on the web,” according to Google.

Google表示:“ WebP是一种现代图像格式,可为网络上的图像提供出色的无损和无损压缩”。

After conversion to the WebP format, my image was not only smaller but alsosharper! WebP shaved another 34% of the compressed JPEG size. “I’m on the right path”, I thought!

转换为WebP格式后,我的图像不仅更小,而且更漂亮! WebP减少了压缩的JPEG大小的34%。 我想:“我走在正确的道路上!”

Unfortunately, the WebP format is supported by Chrome and Opera, just about 60% of all browsers, according to Can I use. So I knew I’d have to think of fallback options.

不幸的是,根据我可以使用的介绍,Chrome和Opera支持WebP格式,仅占所有浏览器的60%。 所以我知道我必须考虑后备选项。

At last, the limits were set:

最后,设置了限制:

  • 60% compression level
    60%压缩等级
  • WebP format where possible
    WebP格式(如果可能)

I also chose to support three breakpoints: 600px and 900px(here is why) and 2-pixel densities — 1x and 2x for retina displays. That meant 6 different images instead of just two. Supporting the WebP format doubled the number.

我还选择支持三个断点:600px和900px( 这就是为什么 )和2像素密度-用于视网膜显示器的1x和2x。 这意味着6张不同的图像,而不是2张。 支持WebP格式的数字增加了一倍。

There are two primary ways to put an image on a website, either by using HTML’s img element or a background-image in CSS.

通过使用HTML的img元素或CSS中的background-image ,有两种主要的方法可以将图像放置在网站上。

HTML中的自适应图像 (Responsive images in HTML)

The basic HTML img element has the src attribute that points to the image URL:

基本HTML img元素具有src属性,该属性指向图像URL:

<img src=“image.jpg” alt=“image description”/>

But you can go a step further and decide which image to serve depending on the screen’s pixel density with the srcset attribute:

但是,您可以更进一步,并使用srcset属性根据屏幕的像素密度来决定要提供哪个图像:

<img srcset=“image_1x.jpg 1x, image_2x.jpg 2x” src=”image_1x.jpg”/>

Here, I’ve used two different screen densities: 1x and 2x. Depending on the actual display density, the browser will choose the right one. The src attribute points to the fallback option.

在这里,我使用了两种不同的屏幕密度: 1x2x 。 根据实际的显示密度,浏览器将选择正确的显示密度。 src属性指向后备选项。

At the moment, most browsers except IE, Edge, and Opera Mini have the srcset attribute implemented.

目前,除IE,Edge和Opera Mini以外的大多数浏览器都实现了srcset属性。

This solution seems like a step in the right direction. Unfortunately, your browser will always select the same image, with the same pixel density, regardless of the display size. And the same image will end up on both the desktop and the mobile device.

该解决方案似乎是朝正确方向迈出的一步。 不幸的是,无论显示大小如何,您的浏览器将始终选择具有相同像素密度的相同图像。 并且同一图像将最终出现在台式机和移动设备上。

We need more control. And we can have it. Apart from pixel densities, the scrset attribute accepts width units w, an equivalent of CSS pixels.

我们需要更多的控制权。 我们可以拥有它。 除了像素密度之外, scrset属性还接受宽度单位w ,它等于CSS像素。

The width unit enables the browser to choose the right image size for the given display capabilities.

宽度单位使浏览器可以为给定的显示功能选择合适的图像尺寸。

With two breakpoints (600px and 900px), we can go with three different image sizes:

使用两个断点(600像素和900像素),我们可以使用三种不同的图像尺寸:

<img srcset=“image-sm.jpg 600w,   image-md.jpg 900w,   image-lg.jpg 1440w” src=”image_1x.jpg”/>

There is a caveat here. When the browser decides which image to fetch, it has no knowledge of our CSS! The CSS file hasn’t been fetched at this point. And it assumes that the image will be displayed at the full width of the window.

这里有一个警告。 当浏览器决定要提取哪个图像时,它不知道我们CSS! 目前尚未提取CSS文件。 并且假定图像将以窗口的整个宽度显示。

If a full-width image is what you want, then fine. But what if you want to place an image in a container that is only 50vw wide? Here comes the sizes attribute into play. Let’s take a look:

如果您想要全角图像,则可以。 但是,如果要将图像放置在仅50vw宽的容器中怎么办? sizes属性发挥作用。 让我们来看看:

<img srcset=“image-sm.jpg 600w,   image-md.jpg 900w,   image-lg.jpg 1440w” sizes=”50vw” src=”image_1x.jpg”/>

By adding the sizes=”50vw” attribute, you are telling the browser that the image will be displayed at 50vw, and based on this information, the browser will decide which image to display.

通过添加sizes=”50vw”属性,您告诉浏览器该图像将以50vw显示,并基于此信息,浏览器将决定显示哪个图像。

But what if you want to display your image at 50vw on a big screen and at the full width of 100vw on a mobile device? The sizes attribute accepts also media queries!

但是,如果你想显示你的形象是什么50vw在全宽在大屏幕上和100vw在移动设备上? sizes属性还接受媒体查询!

You can specify that below the mobile breakpoint of 600px you want the browser to display your image at a full-screen width. And for the width higher than the mobile breakpoint you want the browser to display your image at 50vw.

您可以指定希望移动浏览器在600px以下的断点以全屏宽度显示图像。 对于大于移动断点的宽度,您希望浏览器以50vw显示图像。

You can do this by adding the media query:

您可以通过添加媒体查询来做到这一点:

<img srcset=“image-sm.jpg 600w,   image-md.jpg 900w,   image-lg.jpg 1440w” sizes=”(max-width: 600px) 100vw, 50vw” src=”image_1x.jpg” />

Remember that in the above line of code you are instructing the browser which image to choose because the browser doesn’t know the corresponding CSS. You still have to add the breakpoints in CSS explicitly.

请记住,在上面的代码行中,您正在指示浏览器选择哪个图像,因为浏览器不知道相应CSS。 您仍然必须在CSS中显式添加断点。

This solution works really well but we are missing pixel densities here! If we stopped here, we would be sending the same image both to the displays with 1x pixel density and to the retina screens. Luckily, there is an easy fix to it.

该解决方案确实非常有效,但是这里缺少像素密度! 如果我们在这里停下来,我们将把相同的图像发送到像素密度为1x的显示器和视网膜屏幕。 幸运的是,有一个简单的解决方法。

图片元素 (Picture element)

Meet the HTML5 picture element. It accepts the source and img elements as its children. We can use the source element to list additional image formats that we want to serve to the browser.

符合HTML5 picture元素。 它接受sourceimg元素作为其子元素。 我们可以使用source元素列出要提供给浏览器的其他图像格式。

But before we fix pixel densities, let’s introduce smaller and sharper images in WebP format.

但是在确定像素密度之前,让我们以WebP格式介绍更小,更清晰的图像。

Let’s add the source element as the first option inside the picture element with your image in the WebP format followed by the img pointing at the regular JPG image. Now, when the browser is not WebP-ready, it will gracefully fall back on to the img element (e.g. Safari).

让我们将source元素添加为picture元素内的第一个选项,并以WebP格式添加图像,然后将img指向常规JPG图像。 现在,当浏览器不支持WebP时,它将优雅地返回到img元素(例如Safari)。

<picture> <source   srcset=“image.webp”   type=“image/webp” > <img   src=“image.jpg”   type=“image/jpeg”   alt=”image description”></picture>

The source element opens up a whole new world of possibilities. It accepts media queries!

source元素打开了一个全新的可能性世界。 它接受媒体查询!

First, in the media attribute, we use the media query and then, in the srcsetattribute, we place the appropriate image. And we can use as many sourceelements as we wish:

首先,在media属性中,我们使用media查询,然后在srcset属性中,放置适当的图像。 我们可以根据需要使用任意多个source元素:

<picture> <source   media=”(min-width: 900px)”   srcset=“image-lg.webp”   type=“image/webp” > <source   media=”(min-width: 600px)”   srcset=“image-md.webp”   type=“image/webp” > <source   srcset=“image-sm.webp”   type=“image/webp” > <img   src=“image-lg.jpg”   type=“image/jpeg”   alt=”image description”></picture>

Above, we have prepared three images in the WebP format, depending on the size of the display, and one JPG image as a fallback option.

上面,我们根据显示器的大小准备了三幅WebP格式的图像,以及一幅JPG图像作为后备选项。

The last secret of the srcset attribute is that it also accepts pixel densities. We can decide which image we want to serve on which screen and at which pixel density. The trick is to list image files in the scrset followed by a space and the pixel density factor, for example: 1x, 2x, 3x, or even 4x.

srcset属性的最后一个秘密是它也接受像素密度。 我们可以决定要在哪个屏幕上以哪个像素密度投放的图像。 技巧是在scrset列出图像文件,然后列出一个空格和像素密度因子,例如: 1x2x3x或什至4x

<picture> <source   media=”(min-width: 900px)”   srcset=“image-lg_1x.webp 1x, image-lg_2x.webp 2x”   type=“image/webp” > <source   media=”(min-width: 601px)”   srcset=“image-md_1x.webp 1x, image-md_2x.webp 2x”   type=“image/webp” > <source   media=”(max-width: 600px)”   srcset=“image-sm_1x.webp 1x, image-sm_1x.webp 1x”   type=“image/webp” > <img   src=“image-lg_1x.jpg”   type=“image/jpeg”   alt=”image description”></picture>```

Since we sorted out the screen sizes and pixel densities for the WebP format, let’s have a closer look at the fallback option. In the end, some browsers don’t support the WebP format.

由于我们为WebP格式整理了屏幕尺寸和像素密度,因此让我们仔细研究后备选项。 最后,某些浏览器不支持WebP格式。

Here, we have to decide if we want to use the 1 or 2-pixel-dense images. Below, I went for the first option:

在这里,我们必须决定是否要使用1像素或2像素密集图像。 下面,我选择了第一个选项:

<picture> <source   media=”(min-width: 900px)”   srcset=“image-lg_1x.webp 1x, image-lg_2x.webp 2x”   type=“image/webp” > <source   media=”(min-width: 601px)”   srcset=“image-md_1x.webp 1x, image-md_2x.webp 2x”   type=“image/webp” > <source   srcset=“image-sm_1x.webp 1x, image-sm_2x.webp 2x”   type=“image/webp” > <img    srcset=“image-sm_1x.jpg 600w,   image-md_1x.jpg 900w,   image-lg_1x.jpg 1440w”   src=“image_lg_1x.jpg”   type=“image/jpeg”   alt=”image description”></picture>

We have replaced the img element with the picture element. Where possible, we want to deliver images in the WebP format in three different sizes, depending on the display size, and 2 different pixel densities. If the browser doesn’t support the picture element or the WebP format, it will fall back on to the standard img element with three different sizes of JPGs.

我们已更换img与元素picture元素。 在可能的情况下,我们希望以WebP格式提供三种不同尺寸的图像,具体取决于显示尺寸和2种不同的像素密度。 如果浏览器不支持picture元素或WebP格式,它将使用具有三种不同大小JPG的标准img元素。

Important: Notice that in the img element the srcset attribute should be placed before the src attribute. Otherwise, the browser will download the src image first and then, if it finds a better image in the srcset, it will download this one as well. This way we would end up with two images.

重要:请注意,在img元素中, srcset属性放置在src属性之前。 否则,浏览器将首先下载src映像,然后,如果在srcset找到更好的映像,它将也下载该映像。 这样,我们最终得到两个图像。

We could go one step further and create another 3 source elements for browsers that don’t support the WebP format and deliver JPG files instead.

我们可以再走一步,为不支持WebP格式的浏览器创建另外3个source元素,而是提供JPG文件。

Although it works great for Firefox, I’ve noticed that Safari will download both files: the JPG listed in the source and the JPG from the img element. Again, we would end up with two images instead of one.

虽然Firefox的伟大工程,我注意到,Safari会下载两个文件:JPG格式中所列source ,并从该JPG img元素。 同样,我们将得到两个图像而不是一个图像。

CSS中的响应式图像 (Responsive images in CSS)

If we don’t know the exact height and width of the container we want to cover with an image, we can use generic elements like div with the background-imageproperty pointing to the image URL:

如果我们不知道要覆盖图像的容器的确切高度和宽度,则可以使用div等通用元素,并且background-image属性指向图像URL:

background-image: url(“/images/image.jpg”);

CSS, similarly to HTML, enables image size optimization.

CSS与HTML相似,可以优化图像尺寸。

The image-set in CSS is the equivalent of the srcset in HTML . At the moment, it is implemented in Chrome, Chrome for Android, Safari, iOS Safari, and a few other browsers. You can add polyfills to make the image-setwork on other browsers, but given that Chrome and Safari combined are the browsers of choice for 70% of users today, there is a good chance that most browsers will implement the attribute in the near future.

CSS中的image-set等效于HTML中的srcset 。 目前,它已在Chrome,适用于Android的Chrome,Safari,iOS Safari和其他一些浏览器中实现。 您可以添加polyfill来使image-set在其他浏览器上正常工作,但是鉴于Chrome和Safari结合在一起是当今70%用户的首选浏览器,因此大多数浏览器很有可能在不久的将来实现该属性。

But worry not, the regular background-image as a fallback option will do the trick.

但请放心,将常规background-image作为后备选项可以解决问题。

The structure is very similar to what we’ve just used in a srcset attribute.

该结构与我们刚刚在srcset属性中使用的结构非常相似。

To create a full-width image element with a height of 500px, we have to start with the fallback option — the first background-image in the code example below. Then, using the -webkit-image-set, we need to list the WebP images for different pixel densities. And we have to repeat the process for different breakpoints using media queries.

要创建高度为500px的全宽图像元素,我们必须从后备选项开始-以下代码示例中的第一个background-image 。 然后,使用-webkit-image-set ,我们需要列出不同像素密度的WebP图像。 而且,我们必须使用媒体查询针对不同的断点重复该过程。

One important thing to remember is that both Chrome and Safari use the WebKit layout engine but Safari doesn’t support the WebP format. That’s why we have to add the last set of image-set attributes with JPG images (it will be used by Safari even though it doesn’t start with -webkit).

要记住的一件事是,Chrome和Safari都使用WebKit布局引擎,但是Safari不支持WebP格式。 这就是为什么我们必须在JPG图像中添加最后一组image-set属性(即使它不是以-webkit开头,它也将由Safari使用)。

.bg-image {  width: 100vw;  height: 500px;    background-size: cover;  background-position: center;    background-image: url(/images/image-lg_1x.jpg)    background-image: -webkit-image-set(    url(/images/image-lg_1x.webp) 1x,    url(/images/image-lg_2x.webp) 2x  );  background-image: image-set(    url(/images/image-lg_1x.jpg) 1x,    url(/images/image-lg_2x.jpg) 2x  );
@media(max-width: 900px) {    background-image: url(/images/image-md_2x.jpg);    background-image: -webkit-image-set(      url(/images/image-md_1x.webp) 1x,      url(/images/image-md_2x.webp) 2x    );    background-image: image-set(      url(/images/image-md_1x.jpg) 1x,      url(/images/image-md_2x.jpg) 2x    );  }
@media (max-width: 600px) {    background-image: url(/images/image-sm_2x.jpg);    background-image: -webkit-image-set(      url(/images/image-sm_1x.webp) 1x,      url(/images/image-sm_2x.webp) 2x    );    background-image: image-set(      url(/images/image-sm_1x.jpg) 1x,      url(/images/image-sm_2x.jpg) 2x    );  }}

Here, the background image is centered in the div element and covers its whole area. Using the image-set attribute, we are assigning two different images to two different pixel densities.

在此,背景图像位于div元素的中心并覆盖其整个区域。 使用image-set属性,我们将两个不同的图像分配给两个不同的像素密度。

The fallback option with a standard url takes care of the browsers that don’t support the image-set attribute.

带有标准url的后备选项可用于不支持image-set属性的浏览器。

It’s very important to place the fallback option before the background-imageswith the image-set attribute. If you place it after the image-setattribute, for example, Safari would download both, the image from image-set and the image from the fallback option if it found an image with a different file name.

将后备选项放置在具有image-set属性的background-images 之前非常重要。 例如,如果将其放在image-set属性之后,则Safari会下载image-set的图像和fallback选项中的图像(如果找到的文件名不同)。

The rest of the code follows the same pattern. Above, I have added media queries for 600px and 900px breakpoints and a set of corresponding images in smaller sizes.

其余代码遵循相同的模式。 上面,我添加了600px和900px断点的媒体查询以及一组较小尺寸的对应图像。

The fallback option always has to use the JPG format to avoid the situation where an image cannot be shown at all, that is when the browser doesn’t support the image-set attribute or the WebP format.

后备选项始终必须使用JPG格式来避免根本无法显示图像的情况,即浏览器不支持image-set属性或WebP格式。

如何内嵌小图片 (How to inline small images)

To improve user experience, we should not only compress and serve the smallest possible images, but we should also decrease the number of requests we send to the server.

为了改善用户体验,我们不仅应该压缩并提供尽可能小的图像,而且还应该减少发送到服务器的请求数量。

The browser has to send a separate request for every single image. When sent to the server, the request has to first wait in a queue, which takes time. The more calls the browser makes, the longer the user has to wait.

浏览器必须为每个图像发送单独的请求。 发送到服务器时,请求必须首先在队列中等待,这需要时间。 浏览器拨打的电话越多,用户等待的时间就越长。

That’s especially true when you have to download many small images. If possible, logos and icons should be saved as vector graphics (SVG). Small images can be embedded either in HTML or in CSS directly as base64 encoded strings.

当您必须下载许多小图像时,尤其如此。 如有可能,徽标和图标应另存为矢量图形(SVG)。 小图像可以作为base64编码的字符串直接嵌入HTML或CSS中。

Instead of passing a regular URL to the src attribute in the img element, we can pass the image as a string:

代替将常规URL传递给img元素中的src属性,我们可以将图像作为字符串传递:

<img src=”data:image/png;base64,encoded string” alt=”img description” />

and in CSS:

在CSS中:

.small-image { background-image: url(data:image/png;base64,encoded string);}

In most cases, the generated string will be around 30% bigger than the original image, but you will save time on another round trip to the server.

在大多数情况下,生成的字符串将比原始图像大30%左右,但是您可以节省再次往返服务器的时间。

The most common argument against using base64 encoded images in CSS files is that images are non-blocking resources whereas CSS files are. It means that if you embed too many small images into your CSS, it will increase the size of the CSS file and lengthen the time to the first paint of the website. That, in turn, will make the user wait longer before he or she can see any content.

反对在CSS文件中使用base64编码的图像的最常见论点是,图像是无阻塞资源,而CSS文件是。 这意味着,如果您在CSS中嵌入过多的小图片,则会增加CSS文件的大小,并延长网站首次绘画的时间。 反过来,这将使用户等待更长的时间才能看到任何内容。

Here is a great article on why you may consider dropping the idea of using encoded strings for images entirely.

这是一篇很棒的文章,说明了为什么您可能会考虑完全放弃对图像使用编码字符串的想法。

The truth lays probably somewhere in the middle, and injecting one or two small files as base64 strings into CSS or HTML shouldn’t do any harm.

事实可能在中间,将一两个小文件作为base64字符串注入CSS或HTML不会有任何危害。

At the end of this article, you will learn how to generate them. It can feel strange at first because these strings are thousands of characters long. Your .logo class may look like this, but longer:

在本文的结尾,您将学习如何生成它们。 一开始可能会感到奇怪,因为这些字符串的长度为数千个字符。 您的.logo类可能看起来像这样,但是更长:

.logo { background-image: url(data:image/png;base64,iVBORw0KGgoAAAA NSUhEUgAABqIAAAFvCAMAAAAWmCq0AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZS BJbWFnZVJlYWR5ccllPAAAA3hpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAA Dw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5U Y3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0…);}

如何生成响应图像 (How to generate responsive images)

Let’s assume that you’ve just saved a perfect image and you’d like to create all the variations so you can use it on your website.

假设您刚刚保存了一个完美的图像,并且想要创建所有变体以便可以在您的网站上使用它。

There are many tools that can help. Simple tools include compressjpeg.com, compresspng.com, and tinyjpg.com. More advanced tools include ImageOptim for JPEG, PNGs, and GIFs and ImageAlpha for PNGs.

有很多工具可以提供帮助。 简单的工具包括compressjpeg.com , compresspng.com和tinyjpg.com 。 更高级的工具包括ImageOptim为JPEG,PNG格式,以及GIF和ImageAlpha为PNG格式。

On my quest to take full control of compression levels, formats, and scaling, I needed a tool that would help me automate the whole process. And I didn’t fancy drag-and-dropping dozens of images.

为了完全控制压缩级别,格式和缩放比例,我需要一个可以帮助我自动完成整个过程的工具。 而且我不喜欢拖放数十张图像。

Both ImageMagic and GraphicsMagick are free and powerful pieces of software that painlessly pair with Grunt, the JavaScript task runner.

ImageMagic和GraphicsMagick都是免费且功能强大的软件,可以轻松地与JavaScript任务运行器Grunt配对。

Even better, there are Grunt plugins that simplify the task further. Several quick tests showed that GraphicsMagick generates 20% smaller JPG images than ImageMagic at the same compression level. So the choice was clear.

更好的是,有Grunt插件可以进一步简化任务。 多项快速测试表明,在相同压缩级别下,GraphicsMagick生成的Image图像比ImageMagic少20%。 所以选择很明确。

Before we start to cut our way through the jungle of pixels, we have to prepare our tools and sharpen our axe. Download GraphicsMagick from here or use Homebrew to install it.

在我们开始穿越像素丛林之前,我们必须准备工具并锐化斧头。 从此处下载GraphicsMagick或使用Homebrew进行安装。

brew install graphicsmagick

Next, install Grunt’s CLI globally:

接下来,全局安装Grunt的CLI:

npm install -g grunt-cli

Create a separate folder responsive-images and init the project:

创建一个单独的文件夹responsive-images并初始化项目:

mkdir responsive-imagescd responsive-imagesnpm init

And finally, install the local version of Grunt:

最后,安装本地版本的Grunt:

npm install grunt --save-dev

Create two folders: src/ for original images and dest/ for the responsive images that Grunt and GraphicsMagick will generate:

创建两个文件夹: src/用于原始图像, dest/用于将由Grunt和GraphicsMagick生成的响应图像:

mkdir srcmkdir dest

The original image should be saved at the resolution equal to or greater than the largest image you want to generate in the src/ folder. I saved mine as JPG at 100% quality and 2880 pixels wide. It was around 2.5MB.

原始图像的分辨率应等于或大于您要在src/文件夹中生成的最大图像的分辨率。 我以100%的质量和2880像素的宽度将我的图像另存为JPG。 大约是2.5MB。

First, let’s generate responsive images using the grunt-responsive-imagesplugin. Install it:

首先,让我们使用grunt-sensitive-images插件生成响应式图像 。 安装它:

npm install grunt-responsive-images --save-dev

Now, in the root directory of the project, create an additional file Gruntfile.js:

现在,在项目的根目录中,创建一个附加文件Gruntfile.js

touch Gruntfile.js

This is where we have to configure the plugin.

这是我们必须配置插件的地方。

Copy and paste the code to the Gruntfile.js and let me walk you through the code:

将代码复制并粘贴到Gruntfile.js ,让我Gruntfile.js代码:

module.exports = function(grunt) {  grunt.initConfig({    responsive_images: {      dev: {        options: {          engine: “gm”,          sizes: [            { name: “sm”, suffix: “_1x”, quality: 60, width: 600 },            { name: “sm”, suffix: “_2x”, quality: 60, width: 1200 },            { name: “md”, suffix: “_1x”, quality: 60, width: 900 },            { name: “md”, suffix: “_2x”, quality: 60, width: 1800 },            { name: “lg”, suffix: “_1x”, quality: 60, width: 1440 },            { name: “lg”, suffix: “_2x”, quality: 60, width: 2880 }          ]        },        files: [          {            expand: true,            src: [“**/*.{jpg,png}”],            cwd: “src/”,            dest: “dest/”          }        ]      }    }  });
grunt.loadNpmTasks(“grunt-responsive-images”);  grunt.registerTask(“default”, [“responsive_images”]);};

In options, we set GraphicsMagick as our engine of choice: engine: “gm”. You can also test ImageMagick by changing it to engine: “im”.

options ,我们将GraphicsMagick设置为我们选择的engine: “gm” 。 您还可以通过将ImageMagick更改为engine: “im”来对其进行测试。

Next, in the sizes array, we have to specify the parameters of the images we want to produce, such as a name that will be appended to the original name, a suffix that will be added to the name as well, a quality and a width.

接下来,在sizes数组中,我们必须指定要生成的图像的参数,例如将添加到原始名称的name ,还将添加到名称的suffixqualitywidth

The resulting images will have the following naming structure:

生成的图像将具有以下命名结构:

original-[name]_[suffix}.jpg

For example, using the first sizes object, Grunt will generate from the original my-image.jpg the my-image-sm_1x.jpg image at 60% compression level and 600 pixels wide.

例如,使用第一个sizes对象,Grunt将从原始my-image.jpg生成my-image-sm_1x.jpg图像,其压缩率为60%,宽度为600像素。

Below the options, we need to list source and destination folders as well as patterns of file names that we want to process.

在选项下,我们需要列出源文件夹和目标文件夹以及我们要处理的文件名模式。

To enable the dynamic build of file objects, let’s set the expand attribute to true and define:

要启用文件对象的动态构建,让我们将expand属性设置为true并定义:

  • cwd — source folder

    cwd源文件夹

  • src — an array of patterns to match. In our case, we want to match any folder (**) inside the source folder and all files with extensions jpg or png

    src —要匹配的模式数组。 在本例中,我们要匹配源文件夹中的任何文件夹( ** )和所有扩展名为jpgpng文件

  • dest — destination folder

    dest目标文件夹

The above Grunt task will generate a set of JPG and/or PNG files, depending on the source image file extensions.

上面的Grunt任务将生成一组JPG和/或PNG文件,具体取决于源图像文件扩展名。

We also want to produce a corresponding set of WebP images.

我们还希望产生一组对应的WebP图像。

We need another plugin to do the job: grunt-cwebp. Let’s install it:

我们需要另一个插件来完成这项工作: grunt-cwebp 。 让我们安装它:

npm install grunt-cwebp --save-dev

Append the Gruntfile.js with the following configuration:

用以下配置附加Gruntfile.js:

module.exports = function(grunt) {  grunt.initConfig({    responsive_images: {      …    },    cwebp: {      dynamic: {        options: {          q: 60        },        files: [          {            expand: true,            cwd: “dest/”,            src: [“**/*.{jpg,png}”],            dest: “dest/”          }        ]      }    }  });
grunt.loadNpmTasks(“grunt-responsive-images”);  grunt.loadNpmTasks(“grunt-cwebp”);
grunt.registerTask(“default”, [“responsive_images”, “cwebp”]);};

The grunt-cwebp plugin uses the dest/ folder as the source of images. We want all the newly produced JPGs to have their WebP siblings and we should place them in the same folder.

grunt-cwebp插件使用dest/文件夹作为图像源。 我们希望所有新生成的JPG都具有其WebP兄弟,并将它们放置在同一文件夹中。

Now, we can process the images:

现在,我们可以处理图像了:

grunt

For every image in the src/ folder, Grunt will generate 12 images in all the necessary sizes, pixel densities and in both JPG and WebP format!

对于src/文件夹中的每个图像,Grunt将生成12个具有所有必要大小,像素密度以及JPG和WebP格式的图像!

如何生成base64字符串 (How to generate base64 strings)

If you want to generate base64 strings for inlining your images, here is how to do.

如果要生成用于内联图像的base64字符串,请执行以下操作。

This time, let’s use the Grunt plugin: grunt-base64.

这次,我们使用Grunt插件: grunt-base64

Create a new project in a separate folder base64-images. Init it with npm and install the local version of Grunt:

在单独的文件夹base64-images创建一个新项目。 使用npm初始化它并安装本地版本的Grunt:

mkdir base64-imagescd base64-imagesnpm initnpm install grunt --save-dev

Install the grunt-base64 plugin:

安装grunt-base64插件:

npm install grunt-base64 --save-dev

In the root directory, create a new images/ folder and the Gruntfile.js:

在根目录中,创建一个新的images/文件夹和Gruntfile.js

mkdir imagestouch Gruntfile.js

and copy and paste the code into the Gruntfile.js:

并将代码复制并粘贴到Gruntfile.js

module.exports = function(grunt) {  grunt.initConfig({    base64: {      dev: {        files: {          “images/output.b64”: [“images/*.{jpg,png}”]        }      }    }  });
grunt.loadNpmTasks(“grunt-base64”);  grunt.registerTask(“default”, [“base64”]);};

Place the small original image in the images/ folder and run Grunt:

将小的原始图像放置在images/文件夹中,然后运行Grunt:

grunt

After the task is finished, copy the whole content from the output.b64 file — that’s the base64 string that you can paste into the url of the background-image or into the src attribute of the img element.

任务完成后,复制output.b64文件中的全部内容,这是base64字符串,您可以将其粘贴到background-imageurlimg元素的src属性中。

There is also an easier way (on Mac OS X or Linux):

还有一种更简单的方法(在Mac OS X或Linux上):

uuencode -m image-file-name remotename

The remotename is not used and you can place even xyz to get base64 string printed into the standard output — in most cases into the terminal window.You have to use -m option to get the base64 encoding.

无需使用remotename ,甚至可以将xyz放置成将base64字符串打印到标准输出中-在大多数情况下,将其打印到终端窗口中。您必须使用-m选项来获取base64编码。

结论 (Conclusion)

Responsive images might feel overwhelming at first, but with Grunt and image processing engines on your side, you can create a smooth process and automate most of the repetitive tasks. And I promise it’s worth it. You will not only shine in PageSpeed Insights, but you will also slash the time to the first paint of your website.

响应式图像乍一看可能让人不知所措,但是有了Grunt和图像处理引擎,您就可以创建一个平滑的过程并使大多数重复性任务自动化。 我保证这是值得的。 您不仅可以在PageSpeed Insights中大放异彩,还可以节省时间来制作网站的第一版画。

In my case, the original 939KB image shrank by 60% to 380KB (JPG) and by 77% to 218KB in the WebP format.

以我为例,WebP格式的原始939KB图像缩小了60%,为380KB(JPG),缩小了77%,为218KB。

In the end, my pixel-crusade paid off — the PageSpeed Insight rating for my website turned green.

最后,我的像素之旅获得了回报–我网站的PageSpeed Insight评级变为绿色。

If you liked this article, ? even 50 times — I would really appreciate it and it makes a huge difference to me.

如果您喜欢这篇文章,? 甚至5 0次 -我真的很感激,这对我来说是巨大的改变。

I published recently a free React tutorial for beginners. If you want to learn how to build a web application from scratch it’s a great starting point. You will learn how to build an app to help you find the best movie to watch ? Sweet Pumpkins

我最近为初学者发布了一个免费的React教程。 如果您想学习如何从头开始构建Web应用程序,那么这是一个很好的起点。 您将学习如何构建应用程序以帮助您找到最佳的电影? 甜南瓜

翻译自: https://www.freecodecamp.org/news/a-guide-to-responsive-images-with-ready-to-use-templates-c400bd65c433/

响应式 ui 模板

响应式 ui 模板_带有即用型模板的响应式图像指南相关推荐

  1. 苹果cms10好看的模板_电脑手机自适应超简洁模板

    苹果cms10好看的模板_电脑手机自适应超简洁模板 自适应原创侧边栏系列苹果cmsv10简约模板DIY系列苹果cms模板案例版,经典边框设计风格大图片旋转,原创CSS框架风格库为视频网站设计,无残留代 ...

  2. 基于vue的响应式ui框架_基于Vue.js的响应式和可配置UI框架

    基于vue的响应式ui框架 Framevuerk (Framevuerk) Fast, Responsive, Multi Language, Both Direction Support and C ...

  3. 前端ui框架_跨屏建站发布同名响应式前端ui框架

    跨屏建站发布同名响应式前端ui框架,它是跨屏建站关于前端页面构建上的积累的结晶,现已开源,我们将持续的用开源的方式做好ui框架产品,用心做好建站产品. 关于 跨屏UI框架是基于Bootstrap的扩展 ...

  4. 沉浸式ui设计_有助于沉浸的视频游戏UI —武器轮

    沉浸式ui设计 Many action-adventure games rely on the feeling of thrills via bullets, fire, grenade, more ...

  5. bootstrap后台模板_免费bootstrap后台管理系统模板源码 网站后台模板_后台管理界面...

    Frogetor-响应式管理仪表板模板 Frogetor是一个Bootstrap 4管理仪表板,它具有充分的响应能力,并包括一些很棒的功能,可帮助您快速,轻松地构建Web应用程序.经过精心设计和开发的 ...

  6. javascript 模板_了解JavaScript中的模板文字

    javascript 模板 The author selected the COVID-19 Relief Fund to receive a donation as part of the Writ ...

  7. 制作模板_年会邀请函制作免费模板

    点击上方蓝字关注我们在线制作 作为一年一次鼓舞士气,增强企业凝聚力的年会,可以让员工更好的在心理上和精神上与企业的核心价值观联系起来,也为企业来年带下一个好的基础. 年会是每年一次的重要会议,跟随着时 ...

  8. 电商网站模板_阿里云建站:模板建站与定制建站怎么选(小白参考)

    企业建站不仅是企业形象的重要组成部分,更是将自身展示给客户乃至全球的窗口,因此越来越多的企业会选择建立自己的网站,因此,现在阿里云的建站产品也越来越火了,阿里云建站产品主要分为模板建站和定制建站,模板 ...

  9. 非抢占式优先级调度算法_华为鸿蒙操作系统内核真面目之抢占式和非抢占式内核...

    华为鸿蒙操作系统内核真面目之抢占式和非抢占式内核 众所周知华为鸿蒙操作系统内核是Linux内核.而Linux内核即是抢占式内核也是非抢占式内核.设置软件优先级在优先级在0-99之间是抢占式优先级.设置 ...

最新文章

  1. C#下载远程文件到本地
  2. 报告鼠标和键盘事件的一个程序(转)
  3. Nginx rewrite使用
  4. mnist手写数字识别python_基于tensorflow的MNIST手写数字识别(二)--入门篇
  5. python --- 二分查找算法
  6. Hadoop 2.0.0-alpha尝鲜安装和hello world
  7. 1.1机器学习基础-python深度机器学习
  8. 作为一个程序员,hibernate和jdbc 有什么不一样的点,你知道吗
  9. 小米手机 - Charles无法安装证书 因为无法读取证书
  10. 线上python课程一般多少钱-Python在线培训课程费用是多少?值不值得报名?
  11. 令人魂牵梦绕的香格里拉
  12. Java反射之Method对象详解
  13. 香港地区Airbnb数据可视化分析
  14. 机械战警原型开发 - 仓田机器人
  15. Python数据结构之平衡二叉树
  16. 在 Kubernetes 上运行 GitHub Actions Self-hosted Runner
  17. JS实现多线程--Concurrent.Thread.js
  18. wince 默认输入法_winCE6.0自带中文输入法加载
  19. 2020年中国科技行业最可能发生的38件事
  20. go:linkname must refer to declared function or variable

热门文章

  1. C语言复制文本文件(功能)
  2. 启动未来城市数据中心的设想
  3. C++ assert.h头文件
  4. MySQL 中的 UNION 语句
  5. Linux嵌入式开发常见面试题
  6. python recvfrom函数详解_UDP sendto和recvfrom使用详解
  7. 无人机侦听与反制_使用SWTEventHelper清除SWT侦听器通知
  8. 叹服,阿里自述 SpringCloud 微服务:入门 + 实战 + 案例,一网打尽
  9. kettle提示:ArrayIndexOutOfBoundsException
  10. HttpClient拉取连载小说