Category: Design

The `hidden` Attribute is Visibly Weak

There is an HTML attribute that does exactly what you think it should do:

<div>I'm visible</div> <div hidden>I'm hidden</div>

It even has great browser support. Is it useful? Uhm. Maybe. Not really.

Adam Laki likes the semantics of it:

If we use the hidden attribute, we make our semantic a little better. Anybody will understand what does a “hidden” attribute means on an element.

Monica Dinculescu calls it a lie:

the hidden rule is a User Agent style, which means it’s less specific than a moderate sneeze. This means that your favourite display style will override it:

<style>   div { display: block; } </style> <div hidden>   lol guess who's not hidden anymore   hint: it's this thing </div>

So two related problems…

  1. It’s extremely weak. Literally any change to the display property other than the none value on the element with any strength selector will override it. Much like any other display property, like width or whatever, except the it feels somehow worse to have a hidden attribute actively on an element and have it not actually be hidden.
  2. The display property is sadly overloaded with responsibility. It would be way cool if hidden was a CSS property that could be in charge of the visibility/access of elements rather than the same property that controls the type of block it is. But alas, backward compatibility 4-lyfe of the web stops that (which is a good thing for the health of the web overall).

If you really love the semantics of the attribute, Monica suggests:

[hidden] { display: none !important; }

Seems like a nice addition to any “reset” or base stylesheet.

Otherwise, the classic technique of hiding things with a class is absolutely fine. I typically have a utility class:

.hide, .hidden {   display: none; }

But remember there are always a million ways to do things. I find myself regularly doing one-off hide/show mechanisms. For example, a menu that you need to toggle the visibility of with flair, but remain accessible at all times…

.menu {    opacity: 0;    visibility: hidden;    transition: 0.2s;    transform: translateX(20px);    &[data-open] {      opacity: 1;      visibility: visible;      transform: translateX(0);    } }

The post The `hidden` Attribute is Visibly Weak appeared first on CSS-Tricks.

CSS-Tricks

, , ,

Workflow Considerations for Using an Image Management Service

There are all these sites out there that want to help you with your images. They do things like optimize your images and help you serve them performantly.

Here’s the type of service I mean.

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.

Just me.

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.

The post Workflow Considerations for Using an Image Management Service appeared first on CSS-Tricks.

CSS-Tricks

, , , , ,
[Top]

WordPress Plugin Overload? Give Jetpack a Try!

The WordPress ecosystem has a plentiful supply of plugins that offer everything from AMP to Zapier integration and so, so, so many other things in between. It’s a significant contributor to what makes WordPress great because plugins can account for the needs of nearly any website.

How many plugins are installed on your WordPress site? Five? Fifteen? Fifty? We’ve been up to 31 plugins here at CSS-Tricks and we rely on them for everything from content delivery to performance. Why rebuild the wheel if you don’t have to right? It’s simply too easy and convenient to reach for something someone else has already created (and for free).

Whether you have a handful or a truckload of plugins, you know that each one adds a little bit of complexity to your site, especially when it comes to maintenance and updates. It’s not uncommon to see that little badge at the top of the WordPress admin bar displaying a number of available plugin updates that are ready to install. The problem is that it can happen a lot and staying on top of updates turns almost into a game of Whack-a-Mole that not only eats up time, but risks conflicts on your site that could break things. Plugins are great! But mashing up code from third-party authors is always a (often slight) possibility.

One way to cut down on the number of plugins: Jetpack. It’s a single plugin that provides the features and functionality of dozens. the number of plugins on CSS-Tricks would likely be much higher if we weren’t relying on it for blocking spam comments, security scans, search, social sharing, post subscriptions, and displaying related posts… just to name a few. Jetpack is literally capable of so much that’s hard to contain in a single post. We’ve outlined our favorites, though. And we can’t recommend it enough.

Try Jetpack on your WordPress site to see all the ways it can help you.

The post WordPress Plugin Overload? Give Jetpack a Try! appeared first on CSS-Tricks.

CSS-Tricks

, , , ,
[Top]

Ten-Ton Widgets

At a recent conference talk (sorry, I forget which one), there was a quick example of poor web performance in the form of a third-party widget. The example showed a site that installed the widget in order add a “email us” button fixed to the bottom right of the viewport. Not even a live-chat widget — just an email thing. It weighed in at something like 470KB, which is straight bananas.

Just in case you are someone who feels trapped into using a ten-ton widget because you aren’t yet sure how to replicate the same functionality, I’ve prepared a small chunk of HTML for you.

It’s 602 Bytes, or about 1/10th of 1% of the size of that other widget — with nothing to download, parse or render block.

See the Pen
Mailto Fixed Postion Widget
by Chris Coyier (@chriscoyier)
on CodePen.

Perhaps on your own site, you’d move the styles out to your stylesheet and add in some hover and focus styles.

It’s not that third-party JavaScript has to be bad. It just has a habit of being bad.

My friend Richard showed me a new product he built called Surfacer. It’s like an RSS widget that you can put anywhere.

See the Pen
Surfacer
by Chris Coyier (@chriscoyier)
on CodePen.

That’s a 773 Byte JavaScript file that does a 3.5KB Ajax request for data, and you’d place it at the end of the document to avoid any render-blocking. It would be nice to see more of this kind of thing.

The post Ten-Ton Widgets appeared first on CSS-Tricks.

CSS-Tricks

,
[Top]

Let’s Make a Fancy, but Uncomplicated Page Loader

It’s pretty common to see a loading state on sites these days, particularly as progressive web apps and reactive sites are on the rise. It’s one way to improve “perceived” performance — that is, making it feel as though the site is loading faster than it actually is.

There’s no shortage of ways to make a loader — all it takes is a quick search on CodePen to see oodles of examples, from animated GIFs to complex animations. While it’s tempting to build the fanciest of the fancy loaders, we can actually do a pretty darn good job with only a minimal amount of CSS and JavaScript.

Here’s an example we can make together.

See the Pen
Preloader with JavaScript FadeOut
by Maks Akymenko (@maximakymenko)
on CodePen.

SVG and CSS is all we need for the spinner

I’m going to assume that you’ve already created a project, so we’ll jump right in and start with the spinner — or “pre-loader” as it is also called.

SVG is a great option for a spinner. It’s scalable and implementing it is as easy as an image tag. We could make one from scratch, say in an image editor like Illustrator, Sketch or Figma. For this example, I’m just going to grab this one from loading.io, which is a nice resource to make and customize different loaders.

Now that we have an SVG for the visual, we can drop it into HTML:

<div class="preloader">   <img src="spinner.svg" alt="spinner"> </div>

We’re using .preloader as a wrapper, mostly because it helps us position the image on the page, but also because it will help us hide and reveal the page content while the loader works.

Let’s style it up:

.preloader {   align-items: center;   background: rgb(23, 22, 22);   display: flex;   height: 100vh;   justify-content: center;   left: 0;   position: fixed;   top: 0;   transition: opacity 0.3s linear;   width: 100%;   z-index: 9999; }

This is doing a few things that are more than cosmetic:

  • We’re displaying the loader directly in the center of the screen, using flexbox properties and values.
  • We’ve made the element take up the entire width and height of the screen and given it a black (well, actually a really, really dark gray) background. That means anything behind it (like the page content) is completely hidden. If our page was a different background color (e.g. white), then we would adjust the loader’s background color accordingly.
  • The position is fixed so scrolling won’t affect it’s location on the page. Plus, the z-index is high enough that not other element should stack on top of it and block it from view.

This is what we should see so far when opening it up in the browser:

A circle loader that fades out into a black background.

Some light JavaScript handles the hiding

We’ve got a fancy spinner that covers the entire page, whether we’re viewing this on small or large screens. No we can write some logic to make it fade out after a certain amount of time. That’ll take a small dose of JavaScript.

First, let’s select the .preloader element we just styled up:

const preloader = document.querySelector('.preloader');

It would actually be a lot easier to add a class to the loader that sets its opacity to zero. However, it wouldn’t be as smooth as what we’re doing here, which is using a tiny helping of JavaScript to create a fadeOut function.

const fadeEffect = setInterval(() => {   // if we don't set opacity 1 in CSS, then   // it will be equaled to "" -- that's why   // we check it, and if so, set opacity to 1   if (!preloader.style.opacity) {     preloader.style.opacity = 1;   }   if (preloader.style.opacity > 0) {     preloader.style.opacity -= 0.1;   } else {     clearInterval(fadeEffect);   } }, 100);

💡 jQuery has a function that does this right out of the box. Leverage that if you’re already using jQuery in your project. Otherwise, rolling it with vanilla JavaScript is the way to go.

Let me explain the JavaScript a little bit. As the comment says, if our .preloader element doesn’t have the opacity property set, then it will be equal to empty ("") and we can set it to a value of 1 manually to make sure it displays when the document loads.

Once we know the opacity is set, then we set manipulate it. The whole function is wrapped in setInterval and we check if the opacity property every 100 milliseconds to see if it is greater than zero. As long as it is above zero, we decrease its value in 0.1 increment, which creates a smooth effect that fades the element out over time.

Once we hit zero opacity, we clearInterval to stop the script from running infinitely. Feel free to play around with timing and decreasing points to fit your needs.

The last thing that left to do is to call the function. We’ll call it when the window loads:

window.addEventListener('load', fadeEffect);

We are intentionally using the load event instead of DOMContentLoaded because the DOMContentLoaded event is fired when the document has been completely loaded and parsed. That means it doesn’t *wait for stylesheets, images, and subframes to finish loading* *before it executes*. The load event can be used to detect a fully-loaded page, and that is exactly what we are looking for. Otherwise, the function would start before our CSS and SVG are ready.

Drop some content into the HTML and try things out. Here’s the demo again:

See the Pen
Preloader with JavaScript FadeOut
by Maks Akymenko (@maximakymenko)
on CodePen.


Congratulations! You now know how to build a pretty nice loading effect using nothing but an image and a pinch of CSS and JavaScript. Enjoy!

The post Let’s Make a Fancy, but Uncomplicated Page Loader appeared first on CSS-Tricks.

CSS-Tricks

, , , ,
[Top]

Weaving One Element Over and Under Another Element

In this post, we’re going to use CSS superpowers to create a visual effect where two elements overlap and weave together. The epiphany for this design came during a short burst of spiritual inquisitiveness where I ended up at The Bible Project’s website. They make really cool animations, and I mean, really cool animations.

My attention, however, deviated from spiritualism to web design as I kept spotting these in-and-out border illustrations.

Screenshot form The Bible Project website.

I wondered if a similar could be made from pure CSS… and hallelujah, it’s possible!

See the Pen
Over and under border design using CSS
by Preethi Sam (@rpsthecoder)
on CodePen.

The principal CSS standards we use in this technique are CSS Blend Modes and CSS Grid.

First, we start with an image and a rotated frame in front of that image.

<div class="design">   <img src="bird-photo.jpg">   <div class="rotated-border"></div> </div>
.design {   position: relative;   height: 300px;   width: 300px; }  .design > * {   position: absolute;   height: 100%;   width: 100%; }  .rotated-border {   box-sizing: border-box;   border: 15px #eb311f solid;   transform: rotate(45deg);   box-shadow: 0 0 10px #eb311f, inset 0 0 20px #eb311f; }

The red frame is created using border. Its box-sizing is set to include the border size in the dimensions of the box so that the frame is centered around the picture after being rotated. Otherwise, the frame will be bigger than the image and get pulled towards the bottom-right corner.

Then we pick a pair of opposite corners of the image and overlay their quadrants with their corresponding portion in a copy of the same image as before. This hides the red frame in those corners.

We basically need to make a cut portion of the image that looks like below to go on top of the red frame.

The visible two quadrants will lay on top of the .rotated-border element.

So, how do we alter the image so that only two quadrants of the image are visible? CSS Blend Modes! The multiply value is what we’re going to reach for in this instance. This adds transparency to an element by stripping white from the image to reveal what’s behind the element.

Chris has a nice demo showing how a red background shows through an image with the multiply blend mode.

See the Pen
Background Blending
by Chris Coyier (@chriscoyier)
on CodePen.

OK, nice, but what about those quadrants? We cover the quadrants we want to hide with white grid cells that will cause the image to bleed all the way through in those specific areas with a copy of the bird image right on top of it in the sourcecode.

<div id="design">     <img src="bird-photo.jpg">     <div class="rotated-border"></div>      <div class="blend">       <!-- Copy of the same image -->       <img src="bird-photo.jpg">       <div class="grid">         <!-- Quadrant 1: Top Left -->         <div></div>         <!-- Quadrant 2: Top Right -->         <div data-white></div>         <!-- Quadrant 3: Bottom Left -->         <div data-white></div>         <!-- Quadrant 4: Bottom Right -->         <div></div>       </div>     </div>  </div>
.blend > * {   position: absolute;   height: 100%;   width: 100%; }  /* Establishes our grid */ .grid {   display: grid;   grid: repeat(2, 1fr) / repeat(2, 1fr); }  /* Adds white to quadrants with this attribute */ [data-white]{   background-color: white; }

The result is a two-by-two grid with its top-right and bottom-left quadrants that are filled with white, while being grouped together with the image inside .blend.

To those of you new to CSS Grid, what we’re doing is adding a new .grid element that becomes a “grid” element when we declare display: grid;. Then we use the grid property (which is a shorthand that combines grid-template-columns and grid-template-rows) to create two equally spaced rows and columns. We’re basically saying, “Hey, grid, repeat two equal columns and repeat two equal rows inside of yourself to form four boxes.”

A copy of the image and a grid with white cells on top of the red border.

Now we apply the multiply blend mode to .blend using the mix-blend-mode property.

.blend { mix-blend-mode: multiply; }

The result:

As you can see, the blend mode affects all four quadrants rather than just the two we want to see through. That means we can see through all four quadrants, which reveals all of the red rotated box.

We want to bring back the white we lost in top-left and bottom-right quadrants so that they hide the red rotated box behind them. Let’s add a second grid, this time on top of .blend in the sourcecode.

<div id="design">   <img src="bird-photo.jpg">   <div class="rotated-border"></div>        <!-- A second grid  -->   <!-- This time, we're adding white to the image quandrants where we want to hide the red frame  -->   <div class="grid">     <!-- Quadrant 1: Top Left -->     <div data-white></div>     <!-- Quadrant 2: Top Right -->     <div></div>     <!-- Quadrant 3: Bottom Left -->     <div></div>     <!-- Quadrant 4: Bottom Right -->     <div data-white></div>   </div>    <div class="blend">     <img src="bird-photo.jpg">     <div class="grid">       <!-- Quadrant 1: Top Left -->       <div></div>       <!-- Quadrant 2: Top Right -->       <div data-white></div>       <!-- Quadrant 3: Bottom Left -->       <div data-white></div>       <!-- Quadrant 4: Bottom Right -->       <div></div>     </div>   </div>  </div>

The result!

Summing up, the browser renders the elements in our demo like this:
​​

  1. ​​At bottommost is the bird image (represented by the leftmost grey shape in the diagram below)
  2. ​​Then a rotated red frame
  3. ​​On top of them is a grid with top-left and bottom-right white cells (corners where we don’t want to see the red frame in the final result)
  4. ​​Followed by a copy of the bird image from before and a grid with top-right and bottom-left white cells (corners where we do want to see the red frame) – both grouped together and given the blending mode, multiply​.

You may have some questions about the approach I used in this post. Let me try to tackle those.

What about using CSS Masking instead of CSS Blend Modes?

For those of you familiar with CSS Masking – using either mask-image or clip-path – it can be an alternative to using blend mode.

I prefer blending because it has better browser support than masks and clipping. For instance, WebKit browsers don’t support SVG <mask> reference in the CSS mask-image property and they also provide partial support for clip-path values, especially Safari.

Another reason for choosing blend mode is the convenience of being able to use grid to create a simple white structure instead of needing to create images (whether they are SVG or otherwise).

Then again, I’m fully on board the CSS blend mode train, having used it for knockout text, text fragmentation effect… and now this. I’m pretty much all in on it.

Why did you use grid for the quadrants?

The white boxes needed in the demo can be created by other means, of course, but grid makes things easier for me. For example, we could’ve leaned on flexbox instead. Use what works for you.

Why use a data-attribute on the grid quadrant elements to make them white?

I used it while coding the demo without thinking much about it – I guess it was quicker to type. I later thought of changing it to a class, but left it as it is because the HTML looked neater that way… at least to me. 🙂

Is multiply the only blend mode that works for this example?

Nope. If you already know about blend modes then you probably also know you can use either screen, darken, or lighten to get a similar effect. (Both screen and lighten will need black grid cells instead of white.)

The post Weaving One Element Over and Under Another Element appeared first on CSS-Tricks.

CSS-Tricks

, , , ,
[Top]

Stop Animations During Window Resizing

Say you have page that has a bunch of transitions and animations on all sorts of elements. Some of them get triggered when the window is resized because they have to do with size of the page or position or padding or something. It doesn’t really matter what it is, the fact that the transition or animation runs may contribute to a feeling of jankiness as you resize the window. If those transitions or animations don’t deliver any benefit in those scenarios, you can turn them off!

The trick is to apply a class that universally shuts off all the transitions and animations:

let resizeTimer; window.addEventListener("resize", () => {   document.body.classList.add("resize-animation-stopper");   clearTimeout(resizeTimer);   resizeTimer = setTimeout(() => {     document.body.classList.remove("resize-animation-stopper");   }, 400); });

Now we have a resize-animation-stopper class on the <body> that can force disable any transition or animation while the window is being resized, and goes away after the timeout clears.

.resize-animation-stopper * {   animation: none !important;   transition: none !important; }

There is probably some more performant way of doing this than setTimeout, but that’s the concept. I use this right here on this very site (v17) after noticing some significant resizing jank. It hasn’t entirely eliminated the jank but it’s noticeably better.

Here’s an example:

See the Pen
Turn off animation on resize?
by Chris Coyier (@chriscoyier)
on CodePen.

That demo is mostly just for the working code. There probably isn’t enough going on transitions-wise to notice much resize jank.

The post Stop Animations During Window Resizing appeared first on CSS-Tricks.

CSS-Tricks

, , , ,
[Top]

Design Deals for the Week

[Top]

The Teletype Text Element Lives On… at Least on This Site

It was this: <tt>

I say “was” because it’s deprecated. It may still “work” (like everybody’s favorite <marquee> in some browsers), but it could stop working anytime, they say. The whole purpose of it was to display text in a monospace font, like the way Teletype machines used to.

Dave used it jokingly the other day.

Which got me thinking how much I used to use that element!

Right here on CSS-Tricks. See, in my early days, I learned about that element and how its job is to set text as monospace. I thought, oh! like code! and then for years that’s how I marked up code on this site. I had never heard of the <code> element! When I did, I switched over to that. But I still haven’t updated every single article from <code>

I bring this up just because it's a funny little example of not knowing what you don't know. It's worth having a little sympathy for people early in their journey and just doing things that get the job done because that's all they know. We've all been there... and are always still there to some degree.

The post The Teletype Text Element Lives On… at Least on This Site appeared first on CSS-Tricks.

CSS-Tricks

, , , , , , ,
[Top]

Two Images and an API: Everything We Need for Recoloring Products

I recently found a solution to dynamically update the color of any product image. So with just one <img> of a product, we can colorize it in different ways to show different color options. We don’t even need any fancy SVG or CSS to get it done!

We’ll be using an image editor (e.g. Photoshop or Sketch) and the image transformation service imgix. (This isn’t a sponsored post and there is no affiliation here — it’s just a technique I want to share.)

See the Pen
Dynamic Car color
by Der Dooley (@ddools)
on CodePen.

I work with a travel software company called CarTrawler on the engineering team, and I recently undertook a project a revamp our car images library that we use to display car rental search results. I wanted to take this opportunity to introduce dynamically colored cars.

We may sometimes load up to 200 different cars at the same time, so speed and performance are key requirements. We also have five different products throughout unique code bases, so avoiding over-engineering is vital to success.

I wanted to be able to dynamically change the color of each of these cars without needing additional front-end changes to the code.

Step 1: The Base Layer

I’m using car photos here, but this technique could be applied to any product. First we need a base layer. This is the default layer we would display without any color and it should look good on its own.

Step 2: The Paint Layer

Next we create a paint layer that is the same dimensions as the base layer, but only contains the areas where the colors should change dynamically.

A light color is key for the paint layer. Using white or a light shade of gray gives us a great advantage because we are ultimately “blending” this image with color. Anything darker or in a different hue would make it hard to mix this base color with other colors.

Step 3: Using the imgix API

This is where things get interesting. I’m going to leverage multiple parameters from the imgix API. Let’s apply a black to our paint layer.

(Source URL)

We changed the color by applying a standard black hex value of #000000.

https://ddools.imgix.net/cars/paint.png?w=600&bri=-18&con=26&monochrome=000000

If you noticed the URL of the image above, you might be wondering: What the heck are all those parameters? The imgix API docs have a lot of great information, so no need to go into greater detail here. But I will explain the parameters I used.

  • w. The width I want the image to be
  • bri. Adjusts the brightness level
  • con. Adjusts the amount of contrast
  • monochrome. The dynamic hex color

Because we are going to stack our layers via imgix we will need to encode our paint layer. That means replacing some of the characters in the URL with encoded values — like we’d do if we were using inline SVG as a background image in CSS.

https%3A%2F%2Fddools.imgix.net%2Fcars%2Fpaint.png%3Fw%3D600%26bri%3D-18%26con%3D26%26monochrome%3D000000

Step 4: Stack the Layers

Now we are going to use imgix’s watermark parameter to stack the paint layer on top of our base layer.

https://ddools.imgix.net/cars/base.png?w=600&mark-align=center,middle&mark=[PAINTLAYER]

Let’s look at the parameters being used:

  • w. This is the image width and it must be identical for both layers.
  • mark-align. This centers the paint layer on top of the base layer.
  • mark. This is where the encoded paint layer goes.

In the end, you will get a single URL that will look like something like this:

https://ddools.imgix.net/cars/base.png?w=600&mark-align=center,middle&mark=https%3A%2F%2Fddools.imgix.net%2Fcars%2Fpaint.png%3Fw%3D600%26bri%3D-18%26con%3D26%26monochrome%3D000000

That gives the car in black:

(Source URL)

Now that we have one URL, we can basically swap out the black hex value with any other colors we want. Let’s try blue!

(Source URL)

Or green!

(Source URL)

Why not red?

(Source URL)

That’s it! There are certainly other ways to accomplish the same thing, but this seems so straightforward that it’s worth sharing. There was no need code a bunch of additional functionality. No complex libraries to manage or wrangle. All we need is a couple of images that an online tool will stack and blend for us. Seems like a pretty reasonable solution!

The post Two Images and an API: Everything We Need for Recoloring Products appeared first on CSS-Tricks.

CSS-Tricks

, , , ,
[Top]