There’s a design trend I’ve seen popping up all over the place. Maybe you’ve seen it too. It’s this sort of thing where text is repeated over and over. A good example is the price comparison website, GoCompare, who used it in a major multi-channel advertising campaign.
Nike has used it as well, like in this advertisement:
I couldn’t help but wonder how I would implement this sort of design for the web. I mean, we could obviously just repeat the text in markup. We could also export the design as an image using something like Photoshop, but putting text in images is bad for both SEO and accessibility. Then there’s the fact that, even if we did use actual text, it’s not like we’d want a screen reader speak it out.
Versatility Versatility Versatility Versatility
OK, stop already!
These considerations make it seem unrealistic to do something like this on the web. Then I found myself pining for the long-existing, yet badly supported, element() feature in CSS. It enables the use of any HTML element as a background image, whether it be a single button element, or an entire <div> full of content.
The element() function only reproduces the appearance of the referenced element, not the actual content and its structure. Authors should only use this for decorative purposes.
For our purposes, we’d be referencing a text element to get that repeating effect.
Let’s define an ID we can apply to the text element we want to repeat. Let’s call it #thingy. Note that when we use #thingy, we’ve got to prefix the element() value with -moz-. While element() has been supported in Firefox since 2010, it sadly hasn’t landed in any other browser since.
Here’s a somewhat loose recreation of the Nike advertisement we saw earlier. Again, Firefox is required to see the demo as intended.
See how that works conceptually? I placed an element (#versatility) on the page, hid it by giving it zero height, set it as the background-image on the body, then used the background-repeat property to duplicate it vertically down the page.
The element() background is live. That means the background-image appearance on the thing using it will change if the referenced HTML element changes. It’s the same sort of deal when working with custom properties: change the variable and it updates everywhere it’s used.
There are, of course, other use cases for this property. Check out how Preethi used it to make in-page scrolling navigation for an article. You could also use a HTML canvas element as a background if you want to get fancy. One way I’ve used it is to show screenshots of pages in a table of contents. Vincent De Oliveira, has documented some wildly creative examples. Here’s an image-reflection effect, if you’re into retro web design:
Pretty neat, right? Again, I wish I could say this is a production-ready approach to get that neat design effect, but things are what they are at the moment. Actually, that’s a good reminder to make your voice heard for features you’d like to see implemented in browsers. There are open tickets in WebKit and Chromium where you can do that. Hopefully we’ll eventually get this feature in Safari-world and Chrome-world browsers.
Ever wanted to easily convert an image to a grayscale image on your phone? I do sometimes, and that’s why I build a demo using the Web Share Target API to achieve exactly that.
For this I used the Service Worker way to handle the data. Once the data is received on the client, I use drawImage from canvas to draw the image in canvas, use the grayscale filter to convert it to a grayscale image and output the final image.
So you “install” the little microsite like a PWA, then you natively “share” an image to it and it comes back edited. Clever. Android on Chrome only at the moment.
Reminds me of this “Browser Functions” idea in reverse. That was a server that did things a browser can do, this is a browser doing things a server normally does.
Have you ever clicked on an image on a webpage that opens up a larger version of the image with navigation to view other photos?
Some folks call it a pop-up. Others call it a lightbox. Bootstrap calls it a modal. I mention Bootstrap because I want to use it to make the same sort of thing. So, let’s call it a modal from here on out.
Why Bootstrap? you might ask. Well, a few reasons:
I’m already using Bootstrap on the site where I want this effect, so there’s no additional overhead in terms of loading resources.
I want something where I have complete and easy control over aesthetics. Bootstrap is a clean slate compared to most modal plugins I’ve come across.
The functionality I need is fairly simple. There isn’t much to be gained by coding everything from scratch. I consider the time I save using the Bootstrap framework to be more beneficial than any potential drawbacks.
Here’s where we’ll end up:
Let’s go through that, bit by bit.
Step 1: Create the image gallery grid
Let’s start with the markup for a grid layout of images. We can use Bootstrap’s grid system for that.
Now we need data attributes to make those images interactive. Bootstrap looks at data attributes to figure out which elements should be interactive and what they should do. In this case, we’ll be creating interactions that open the modal component and allow scrolling through the images using the carousel component.
About those data attributes:
We’ll add data-toggle="modal" and data-target="#exampleModal" to the parent element (#gallery). This makes it so clicking anything in the gallery opens the modal. We should also add the data-target value (#exampleModal) as the ID of the modal itself, but we’ll do that once we get to the modal markup.
Let’s add data-target="#carouselExample" and a data-slide-to attribute to each image. We could add those to the image wrappers instead, but we’ll go with the images in this post. Later on, we’ll want to use the data-target value (#carouselExample) as the ID for the carousel, so note that for when we get there. The values for data-slide-to are based on the order of the images.
This is a carousel inside a modal, both of which are standard Bootstrap components. We’re just nesting one inside the other here. Pretty much a straight copy-and-paste job from the Bootstrap documentation.
Here’s some important parts to watch for though:
The modal ID should match the data-target of the gallery element.
The carousel ID should match the data-target of the images in the gallery.
The carousel slides should match the gallery images and must be in the same order.
Here’s the markup for the modal with our attributes in place:
You may have noticed that the markup uses the same image files in the gallery as we do in the modal. That doesn’t need to be the case. In fact, it’s a better idea to use smaller, more performant versions of the images for the gallery. We’re going to be blowing up the images to their full size version anyway in the modal, so there’s no need to have the best quality up front.
The good thing about Bootstrap’s approach here is that we can use different images in the gallery than we do in the modal. They’re not mutually exclusive where they have to point to the same file.
So, for that, I’d suggest updating the gallery markup with lower-quality images:
<div class="row" id="gallery" data-toggle="modal" data-target="#exampleModal"> <div class="col-12 col-sm-6 col-lg-3"> <img class="w-100" src="/image-1-small.jpg" data-target="#carouselExample" data-slide-to="0"> <!-- and so on... --> </div>
The site where I’m using this has already themed Bootstrap. That means everything is already styled to spec. That said, even if you haven’t themed Bootstrap you can still easily add custom styles! With this approach (Bootstrap vs. plugins), customization is painless because you have complete control over the markup and Bootstrap styling is relatively sparse.
Jen Simmons explains how to improve image loading by simply using width and height attributes. The issue is that there’s a lot of jank when an image is first loaded because an img will naturally have a height of 0 before the image asset has been successfully downloaded by the browser. Then it needs to repaint the page after that which pushes all the content around. I’ve definitely seen this problem a lot on big news websites.
Anyway, Jen is recommending that we should add height and width attributes to images like so:
This is because Firefox will now take those values into consideration and remove all the jank before the image has loaded. That means content will always stay in the same position, even if the image hasn’t loaded yet. In the past, I’ve worked on a bunch of projects where I’ve placed images lower down the page simply because I want to prevent this sort of jank. I reckon this fixes that problem quite nicely.
On my 13 inch macbook, with Dock positioned on the left, the viewport height in Chrome is 786 pixels so images with loading="lazy" that are more than 4x the viewport down the page are eagerly fetched by Chrome on page load.
In my opinion, that is waaaaay too eager. Why not use a lower threshold value like 1000 pixels? Or even better: base the threshold value on the actual viewport height.
My guess is they chose not to over-engineer the feature by default and will improve it over time. By choosing a fairly high threshold, they ran a lower risk of it annoying users with layout shifts on pages with images that don’t use width/height attributes.
I think this unmerged Pull Request is the closest thing we have to a spec and it uses language like “scrolled into the viewport” which suggests no threshold at all.
Images are the most efficient means to showcase a product or service on a website. They make up for most of the visual content on our website.
But, the more images a webpage has, the more bandwidth it consumes, affecting the page load speed – a raging factor having a significant impact on not just our search ranking, but also on our conversion rates.
Image optimization helps serve the right images and improve the page load time. A faster website has a positive impact on our user experience.
With image optimization becoming a standard practice for websites and apps, finding a service that offers the most competent features with a coherent pricing model, one that integrates seamlessly with the existing infrastructure and business needs, is paramount to any website and its efficiency.
So what are the most common criteria for selecting an image optimization tool?
The importance of image optimization isn’t up for debate, our choice of tool or service for it may just be. And it is a factor we should consider carefully. So where are the challenges?
Inability to integrate with existing infrastructure – Image optimization is very fundamental on modern websites. To implement it, we should not have to make any changes to our existing setup. But unfortunately, a lot of these tools or services can only be used with specific CDNs or are incapable of being integrated with our existing image servers or storage.
Dependency on their image storage – Some tools require us to move our images to their system, making us more dependent on them — an added hassle. And nobody wants to spend their time and effort on a virtually unnecessary step like migrating assets from one platform to another (and may be migrating to some other service in the future, if this one doesn’t work out). Not when it’s not needed. Not if we have hundreds of thousands of images and can never be sure if all the images have been migrated to the new tool or not.
Apart from the above challenges, it is possible that the choice of tool could be expensive or has a complex pricing structure. Or could have only the basic image-related features or not deliver excellent performance across the globe.
ImageKit.io automatically uses the correct output image format based on image content, image quality, browser support, and user device capabilities. Also, the above image will be converted and delivered as a WebP for all browsers supporting the WebP image format.
Just turn it on, and we’re good to go!
And not just simple resizing and cropping, ImageKit.io allows for more advanced transformations like smart crop, image and text overlays, image trimming, blurring, contrast and sharpness correction, and many more. It also comes with advanced delivery features like Brotli compression for SVG images and image security. ImageKit.io is the solution to all our image optimization needs. And more.
It also comes bundled with a stellar infrastructure — AWS CloudFront CDN, multi-region core processing servers, and a media library with automatic global backups.
It isn’t enough to find the most appropriate tool for our website. It should also provide an optimum experience fitting in just right with our existing setup.
With S3 bucket or other web servers
It is usually a tedious task to integrate any image optimization tool into our infrastructure. For example, for images, we would already have a CMS in place to upload the images. And a server or storage to store all of those images. We would not want to make any significant changes to the existing setup that could potentially disrupt all our team’s processes.
But with ImageKit.io, the whole process from integration to image delivery takes just a few minutes. ImageKit.io allows us to plug our S3 bucket or webserver and start delivering optimized and transformed images instantly. No movement or re-upload of images is required. It takes just a few minutes to get the best optimization results.
Such simple integrations with AWS S3 or web servers are not available even with some leading players in the market.
Images fetched through ImageKit.io are automatically optimized and converted to the appropriate format. And we can resize and transform any image by just adding URL parameters.
Image with width 300px and height is adjusted automatically to preserve aspect ratio:
ImageKit.io also provides a media library, a feature missing in many prominent image optimization tools. Media library is a highly available file storage for all ImageKit.io users. It comes with a simple user interface to upload, search, and manage files, images, and folders.
With platforms like Magento and WordPress
Most SMBs use WordPress to build their websites. ImageKit.io proves handy and almost effortless to set up for these websites.
Installing a plugin on WordPress and making some minor changes in the settings from the WP plugin is all we need to do to integrate ImageKit.io with our WordPress website for all essential optimizations. Learn more about it here.
Similarly, we can integrate ImageKit.io with our Magento store. The essential format and quality optimizations do not require any code change and can be set up by making some changes in Settings in the Magento Admin Panel. Learn more about it here.
For advanced use cases like granular image quality control, smart cropping, watermarking, text overlays, and DPR support, ImageKit.io offers a much better solution, with more robust features, more control over the optimizations and more complex transformations, than the ones provided natively by WordPress or Magento. And we can implement them by making some changes in our website’s template files.
With other CDNs
Most businesses use CDNs for their websites, usually under contracts, or running processes other than or in addition to image optimizations on these CDNs, or simply because a particular CDN performs better in a specific region.
Even then, it is possible to use ImageKit.io with our choice of CDN. They support integrations with:
Alibaba Cloud CDN
CloudFlare (if one is on an Enterprise plan in CloudFlare)
To ensure correct optimizations and caching on our CDN, their team works closely with their customer’s team to set up the configuration.
Custom domain names
As image optimization has become a norm, services like LetsEncrypt, which make obtaining and deploying an SSL certificate free, have also become standard practice. In such a scenario, enabling a custom domain name should not be charged heavily.
ImageKit.io helps us out here too.
It offers one custom domain name like images.example.com, SSL and HTTP2 enabled, free of charge, with each paid account. Additional domain names are available at a nominal one-time fee of $ 50. There are no hidden costs after that.
One ImageKit.io account, multiple websites
For image optimization needs for multiple websites or agencies handling hundreds of websites, ImageKit.io would prove to be an ideal solution. We’re free to attach as many “origins” (storages or servers) with ImageKit.io. What that means is each website has its storage or image server, which can be mapped to separate URLs within the same ImageKit.io account.
The added advantage of using ImageKit.io for multiple websites and apps is their pricing model. When one consolidates the usage across their many business accounts, and if it crosses the 1TB mark, they can reach out to ImageKit.io’s team for a special quote. Learn more about it here.
Multiple server regions
ImageKit.io is a global image CDN, It has a distributed infrastructure and processing regions around the world, in North Virginia (US East), North California (US West), Frankfurt (EU), Mumbai (India), Sydney (Australia) and Singapore, aiming to reduce latency between their servers and our image origins.
Additionally, ImageKit.io stores the images (transformed as well as original) in their cache after fetching them from our origins. This intermediate caching is done to avoid processing the images again. Doing so not only reduces the load on our origin servers and storage but also reduces data transfer costs from them.
Custom cache time
There are times when a shorter cache time is required. For cases where one or more images are set to change at intervals, while the others remain the same, ImageKit.io offers the option to set up custom cache times in place of the default 180 days preset in ImageKit.io, giving us more control over how our resources are cached.
This feature is usually not provided by third-party image CDNs or is available to enterprise customers only, but it is available with ImageKit.io on request.
Deliver non-image files through ImageKit.io CDN
ImageKit.io comes integrated with a CDN to store and serve resources. And while the primary use case is to deliver optimized images, it can do the same for the other static assets on our website, like JS, CSS as well as fonts.
There is no point dividing our static resources between two services when one, ImageKit.io, can do the whole job on its own.
It’s worth a mention here that though ImageKit.io provides delivery for non-image assets, it does not process or optimize them.
With ImageKit.io’s pricing model in mind, using their CDN may prove beneficial as it bills only based on one parameter — the total bandwidth consumed.
Most image optimization tools charge us for image storage or bill us based on requests or the number of master images or transformations.
ImageKit.io bills its customers on a single parameter, their output bandwidth. With ImageKit.io, we can optimize and transform to our heart’s content, without worrying about the costs they may incur. With our focus no longer on the billing costs, we can now focus on important tasks, like optimizing our images and website.
Usually, when an ImageKit.io account crosses 1TB total bandwidth consumption, that account becomes eligible for special pricing.
One can contact their team for a quote after crossing that threshold.
Image optimization holds many benefits, but are we doing it right? And are we using the best service in the market for it?
ImageKit.io might prove to be the solution for all image optimization and management needs. But we don’t have to take their word for it. We can know for ourselves by joining the many developers and companies using ImageKit.io to deliver best-in-class image optimizations to their users by signing up for free here.
The Americans with Disabilities Act applies to websites
In the United States, the Americans with Disabilities Act (ADA) applies to websites, which means that people can sue retailers if their websites are not accessible.
Domino’s Pizza’s appeal was recently turned down by the Supreme Court, so the lawsuit against them for failing to make their website accessible to screen reader users will now resume in district court.
Guillermo Robles, who is blind, filed suit in Los Angeles three years ago and complained he had been unable to order a pizza online because the Domino’s website lacked the software that would allow him to communicate. He cited the ADA, which guarantees to people with a disability “full and equal enjoyment of the goods and services … of any place of public accommodations.”
Google announces automatically generated image descriptions for Chrome
When used with the VoiceOver screen reader, Chrome can now automatically generate image descriptions for images that do not have proper alt text (<img alt> attribute). Google has already created more than 10 million image descriptions, but they are not meant to replace alt text written by humans.
Image descriptions automatically generated by a computer aren’t as good as those written by a human who can include additional context, but they can be accurate and helpful.
This new accessibility feature, called “Accessibility Image Descriptions,” may not be enabled by default in your version of Chrome, but you can enable it manually on the chrome://flags page.
That’s a very good thing. By any metric, images are a major slice of the resources on websites, and we’re notoriously bad at optimizing them and doing all the things we could to lower the performance hit from them. I’m sitting at a conference right now and Dave just bet everyone in the audience $ 100 that he could find an unoptimized image on their site. I wasn’t about to take him up on it.
So you use some service to help you deliver images better. Smart. Many of them will make managing and optimizing images a lot easier. But I don’t consider them a no-brainer. There is a lot to think about, like making choices that don’t paint you into a corner.
I should be able to upload images from my own CMS.
I don’t want to go to your site to upload my assets. I want to use the media management in my own CMS. So, the service should have an API at a minimum, and possible even officially maintained CMS plugins.
This site uses WordPress. I can drag and drop images into the media library and posts very easily. I can search my media library for images I’ve uploaded before. I like that, and I want to take advantage of it today, and as it evolves.
The images should be uploaded to my own server.
If it also has to be uploaded to the image service, that’s fine. But it should go to my server first, then to the service. That way, I still maintain ownership of the source file.
Images within content should use functional, semantic markup in my CMS.
I’d prefer that the images within content are stored as totally functional HTML in my database:
<img src="/images/flower.jpg" alt="a blue flower">
It could be fancier than that, like using srcset (but probably not sizes as that will change as the design changes), or be contained within <picture> or <figure> elements… whatever you like that makes sense as semantic HTML. The most important thing being that the content in my database has fully functional HTML with a src on the image that points to a real image on my real server.
The implementation of the image service will involve filtering that HTML to do whatever it needs to do, like replace the URLs to generate fancier responsive image markup and whatnot.
Between having functional HTML and images on my server, that enables me to turn off the image service if I need to. Services have a habit of coming and going, or changing in ways that make them more or less palatable. I don’t want to be locked-in; I want freedom. I want to be able turn off the service and have a perfectly functional site with perfectly functional images, and not be obstructed from moving to a different service — or no service at all.
Even if I didn’t use the service in the past, I want all my images to benefit from it.
I just mentioned filtering the HTML for images in my database. That should happen for all the images on my site, even if they were uploaded and used before I started using the image service.
This probably means the services offers a URL-based “get” API to optimize images on-the-fly pulled from their canonical locations.
I shouldn’t have to think about format or size.
I want to upload whatever I have. Probably some huge un-optimized screenshot I just took. If I think about it at all, I want to upload something much too big and much too high-quality so that I know I have a great original version available. The service will create optimized, sized, and formatted images as needed.
I also want to upload SVG and have it stay SVG (that’s also optimized).
The images will ultimately be served on a CDN.
CDNs are vital for speed. Australians get images from servers hosted in Australia. Canadians get images from servers hosted in Canada. The servers are configured to be fast and cookie-less and all the fancy over-my-head things that make an asset CDN scream.
The images should serve in the right format.
If you serve images in WebP format to browsers that support it, you’ll probably get as much or more performance out of that optimization than serving re-sized images with responsive images syntax. It’s a big deal.
I want the service to know what the best possible format for any particular image for any particular browser and serve the image in that format. This is going to change over time, so I want the service to stay on top of this so I don’t have to.
I know that involved formats like JPEG-XR and JPEG-2000 three years ago. Is that still the case? I have no idea. This is a core value proposition for the service.
It should optimize the images and handle quality.
This is perhaps the most obvious feature and the reason you reach for an image service in the first place. Images need optimization. There are perhaps dozens of image optimization tools/algorithms that aim to squeeze every last byte out of images. The image service probably uses those or even has its own fancy tech for it. Ideally, the default is to optimize an image the most it possibly can be without noticeably hurting the quality, but still allowing me to ratchet it down even more if I want to.
Don’t shame me for using high-pixel density images.
A lot of image services have some sort of tester tool where you drop in a URL and it tells you how bad you’re doing with images. Many of them test the size of the image on the rendered page and compare the dimensions of the original image. If the original image is larger, they tell you could have had savings by sizing it down. That’s obnoxious to me. High-pixel density displays have been around for a long time and it’s no crime to serve them.
It should help me serve the right size for the device it’s on and the perfect responsive syntax if needed.
Not all images benefit from the same responsive breakpoints. Check out the site Responsive Image Breakpoints. It generates versions of the image that are best depending on the image itself. That’s the kind of help I like to see from an image service. Take something hard and automate it for me.
I know I’ll probably need to bring my own sizes attribute because that is very dependant on my own CSS and how the design of the site plays out. It’s still important, and makes me wonder if an image service could step up and help me figure out what my optimal sizes attribute should be for certain images. Like loading my site at different sizes and seeing how large the image renders with my CSS and calculating it from there to use later.
This is just my own list of requirements. I feel like it’s fairly reflective of “normal” sites that have a bunch of images and want to do the right thing to serve them.
I didn’t go into all the fancy features image services offer, like being able to tell you that an image contains a giraffe facing west and hasn’t eaten since Thursday while offering to recolor its retinas. I know those things are vital to some companies. This is more about what seems to me the widest and most common use case of just hosting and delivering images in the best way current technology allows.
In this week’s week roundup of browser news, a trick for loading images conditionally using the picture element, your chance to tell bowser vendors about the web you want, and the styles applied to inline SVG elements are, well, not scoped only to that SVG.
Let’s turn to the headlines…
Preventing image loads with the picture element
You can use the <picture> element to prevent an image from loading if a specific media query matches the user’s environment (e.g., if the viewport width is larger or smaller than a certain length value). [Try out the demo:
The Web We Want (webwewant.fyi) is a new collaboration between browser vendors that aims to collect feedback from web developers about the current state of the web. You can submit a feature request on the website (“What do you want?””) and get a chance to present it at an event (An Event Apart, Smashing Conference, etc.).
Firefox supports a non-standard Boolean parameter for the location.reload method that can be used to hard-reload the page (bypassing the browser’s HTTP cache) [via Wilson Page]
If you use inline <svg> elements that itself have inline CSS code (in <style> elements), be aware that those styles are not scoped to the SVG element but global, so they affect other SVG elements as well [via Sara Soueidan]
XSS Auditor, a Chrome feature that detects cross-site scripting vulnerabilities, has been deemed ineffective and will be removed from Chrome in a future version. You may still want to set the HTTP X-Xss-Protection: 1; mode=block header for legacy browsers [via Scott Helme]
Read more news in my new, weekly Sunday issue. Visit webplatform.news for more information.