Have you ever wished you could see the HTML source of a web page while on a mobile browser, which generally doesn’t offer that feature? If you have a desktop machine around, there are ways, but what I mean is getting the source without anything but the device itself.
The little View Source tool by Neatnik does the trick.
You enter the URL in the little bar to see the source of that URL. Or add the URL to the the tool’s URL itself to link right to it. Here’s CSS-Tricks (without line wrapping and tidyied up!):
Got a WooCommerce store? It behooves you to offer a variety of payment methods. Just anecdotally, I’m sure both you and me have been annoyed and even abandoned purchases when a merchant, online or otherwise, doesn’t take the payment method we want to pay with. That’s just straight-up lost sales for the merchant. But you don’t have to entirely trust anecdotal evidence, there is data you can pour into, suggesting 7% of abandonment is from missing payment methods.
I’d suggest, at a minimum, you take credit cards and PayPal. There are a variety of payment gateways you can explore (and it’s worth doing so), including a number that take credit cards. The best bet there is WooCommerce Payments — supported in many big countries. It’s Stripe-backed, so it’s a lot like using the Stripe gateway anyway, except way better as it’s loaded with useful features like the fact that you manage all your payments directly in your WordPress dashboard, and Instant Deposits.
The PayPal plugin is free, so that’s kind of a no-brainer, and I’m just talking the basic integration that kicks people over to PayPal.com to pay. Some people like that, as it lets them use their PayPal account online where they may already carry a balance for online purchases and transfers.
The very next step? Apple Pay and Google Pay. Why? Like PayPal, some people strongly prefer it (including me) because of how quick and familiar it makes the checkout process. The Apple Pay and Google Pay functionality in WooCommerce goes so far as to even allow skipping the whole traditional cart and checkout process. That might allow you to make up even more than that 7% based on improved UX.
How does Apple Pay and Google Pay work on WooCommerce? Well if you’re already using WooCommerce Payments, like you should, you’re already almost there.
Enabling Apple Pay and Google Pay on WooCommerce
Apple Pay is supported via the Striple plugin or the Square plugin, but I’d say it’s easiest with WooCommerce Payments. Under Settings > Payments, you’ll see a checkbox for “Enable express checkouts” — flip that on and you’ll be enabling both Apple Pay and Google Pay — and will have an opportunity to pick where you want them to appear.
There are a handful of prerequisites, like having an HTTPS site, but with eCommerce in general, that is not optional and you’ve probably already got it in place.
One thing I experienced when activating it is this warning:
With PayPal, you need a PayPal account for yourself to make it work. That’s not the case with Apple Pay and Google Pay where you don’t have an account and they don’t keep a balance — they just kick that money directly over to WooCommerce Payments and you have access to that money like you would any other WooCommerce Payments transaction.
Example transaction
Here’s an order that came in (I get email notifications for orders):
I can see the order in my dashboard like any other, and have the ability to refund it directly from there and other actions:
I barely even notice it. What payment gateway someone chooses is of little consequence to me once it’s all set up.
The user experience
Apple Pay works on Safari, both on iOS and macOS. If a user both is using one of those browsers and has Apple Pay set up, they’ll see the special buttons show up on your store:
Press that button, and the user sees this immediate checkout step:
The user can change credit cards (that they have set up in Apple Pay), changing shipping address, and then if they approve it, it’s instantly done.
It’s a pretty satisfying user experience, I must say.
Even moreso on a mobile phone, where it feels like things like Apple Pay and Google Pay were really designed to shine. Here’s Apple Pay:
Google Pay works on Android phones nicely, but also works in desktop Chrome.
I did learn one super weird little caveat with Google Pay and desktop Chrome though! Cards that are in your desktop Chrome autofill area in settings that literally say “Google Pay” next to them don’t actually work for the WooCommcere Google Pay buttons. Only credit cards that are kinda manually added in there without that little label work. Just a little thing to be aware of when testing:
This is a rather compelling reason to use WooCommerce for eCommerce. I feel like I got this feature for free. I basically checked a box in settings, and it makes a material positive impact on my business.
Here’s Kilian Valkhof on CSS nesting which isn’t available in browsers yet, but will be soon. There are a few differences he notes between CSS nesting and nesting in Sass or Less though. Take, for example, the following code:
div {
background: #fff;
& p {
color: red;
}
border: 1px solid;
}
When CSS nesting lands, that last line border: 1px solid; won’t be applied to the div like it would be in, say, Sass. That’s because with CSS nesting, any styles you want applied to that div have to be written before any nesting styles are written. I think this makes a ton of sense because I tend to enforce that style in any Sass codebases I work on (it’s just much easier to read), but I can imagine people getting confused about this the first time around.
One of the smaller and, yet for some reason, super exciting things about CSS nesting is how we’ll be able to nest media queries, as Kilian notes, just like this:
It might be the very first thing a lot of people learn in JavaScript:
alert("Hello, World");
One day at CodePen, we woke up to a ton of customer support tickets about their Pens being broken, which ultimately boiled down to a version of Chrome that shipped where they ripped out alert() from functioning in cross-origin iframes. And all other native “JavaScript Dialogs” like confirm(), prompt() and I-don’t-know-what-else (onbeforeunload?, .htpasswd protected assets?).
Cross-origin iframes are essentially the heart of how CodePen works. You write code, and we execute it for you in an iframe that doesn’t share the same domain as CodePen itself, as the very first line of security defense. We didn’t hear any heads up or anything, but I’m sure the plans were on display.
I tweeted out of dismay. I get that there are potential security concerns here. JavaScript dialogs look the same whether they are triggered by an iframe or not, so apparently it’s confusing-at-best when they’re triggered by an iframe, particularly a cross-origin iframe where the parent page likely has little control. Well, outside of, ya know, a website like CodePen. Chrome cite performance concerns as well, as the nature of these JavaScript dialogs is that they block the main thread when open, which essentially halts everything.
There are all sorts of security and UX-annoyance issues that can come from iframes though. That’s why sandboxing is a thing. I can do this:
<iframe sandbox></iframe>
And that sucker is locked down. If some form tried to submit something in there: nope, won’t work. What if it tries to trigger a download? Nope. Ask for device access? No way. It can’t even load any JavaScript at all. That is, unless I let it:
So why not an attribute for JavaScript dialogs? Ironically, there already is one: “allow-modals“. I’m not entirely sure why that isn’t good enough, but as I understand it, nuking JavaScript dialogs in cross-origin iframes is just a stepping stone on the ultimate goal: removing them from the web platform entirely.
Daaaaaang. Entirely? That’s the word. Imagine the number of programming tutorials that will just be outright broken.
For now, even the cross-origin removal is delayed until January 2022, but as far as we know this is going to proceed, and then subsequent steps will happen to remove them entirely. This is spearheaded by Chrome, but the status reports that both Firefox and Safari are on board with the change. Plus, this is a specced change, so I guess we can waggle our fingers literally everywhere here, if you, like me, feel like this wasn’t particularly well-handled.
What we’ve been told so far, the solution is to use postMessage if you really absolutely need to keep this functionality for cross-origin iframes. That sends the string the user uses in window.alert up to the parent page and triggers the alert from there. I’m not the biggest fan here, because:
postMessage is not blocking like JavaScript dialogs are. This changes application flow.
I have to inject code into users code for this. This is new technical debt and it can harm the expectations of expected user output (e.g. an extra in their HTML has weird implications, like changing what :nth-child and friends select).
I’m generally concerned about passing anything user-generated to a parent to execute. I’m sure there are theoretical ways to do it safely, but XSS attack vectors are always surprising in their ingenouity.
Even lower-key suggestions, like window.alert = console.log, have essentially the same issues.
Allow me to hand the mic over to others for their opinions.
Couldn’t the alert be contained to the iframe instead of showing up in the parent window?
I respect the desire to get rid of inelegant parts [of the HTML spec] that can be seen as historical mistakes and that cause implementation complexity, but I can’t shake the feeling that the existing use cases are treated with very little respect or curiosity.
It’s weird to me this is part of the HTML spec, not the JavaScript spec. Right?!
I always thought there was a sort of “prime directive” not to break the web? I’ve literally seen web-based games that used alert as a “pause”, leveraging the blocking nature as a feature. Like: [.] Funny, but true.
A metric was cited that only 0.006% of all page views contain a cross-origin iframe that uses these functions, yet:
Seems like a misleading metric for something like confirm(). E.g. if account deletion flow is using confirm() and breaks because of a change to it, this doesn’t mean account deletion flow wasn’t important. It just means people don’t hit it on every session.
That’s what’s extra concerning to me: alert() is one thing, but confirm() literally returns true or false, meaning it is a logical control structure in a program. Removing that breaks websites, no question. Chris Ferdinandi showed me this little obscure website that uses it:
Speaking of Chris:
The condescending “did you actually read it, it’s so clear” refrain is patronizing AF. It’s the equivalent of “just” or “simply” in developer documentation.
I read it. I didn’t understand it. That’s why I asked someone whose literal job is communicating with developers about changes Chrome makes to the platform.
This is not isolated to one developer at Chrome. The entire message thread where this change was surfaced is filled with folks begging Chrome not to move forward with this proposal because it will break all-the-things.
[…] breaking changes don’t happen often on the web. They are—and should be—rare. If that were to change, the web would suffer massively in terms of predictability.
Secondly, the onus is not on web developers to keep track of older features in danger of being deprecated. That’s on the browser makers. I sincerely hope we’re not expected to consult a site called canistilluse.com.
I’ve painted a pretty bleak picture here. To be fair, there were some tweets with the Yes!! Finally!! vibe, but they didn’t feel like critical assessments to me as much as random Google cheerleading.
Believe it or not, I generally am a fan of Google and think they do a good job of pushing the web forward. I also think it’s appropriate to waggle fingers when I see problems and request they do better. “Better” here means way more developer and user outreach to spell out the situation, way more conversation about the potential implications and transition ideas, and way more openness to bending the course ahead.
We’ve got viewport units (e.g. vw, vh, vmin, vmax), and they are mostly pretty great. It’s cool to always have a unit available that is relative to the entire screen. But when you ask people what they want fixed up in CSS, viewport units are always on the list. The problem is that people use them to do things like position important buttons along the bottom of the screen on mobile devices. Do something like that wrong, it might cost you $8 million dollars.
What’s “wrong”? Well, assuming that 100vh is the visible/usable area in the viewport. Whaaaat? Isn’t that the point of those units? There are tricks like this and this, but that’s why people are unhappy. None of that is intuitive and huge mistakes are all too common. Even though Safari 15 is going to make this a little better, I’d say it’s still not particularly intuitive how you have to handle it.
Bramus Van Damme covers that the spec now includes some new values:
The “Large Viewport”: lvh / lvw / lvmin / lvmax
The “Small Viewport”: svh / svw / svmin / svmax
The “Baby Bear Viewport”
The “Dynamic Viewport”: dvh / dvw / dvmin / dvmax
It seems to me the dynamic ones are the useful ones, because they will be intuitive: the units that represent the currently usable space, be it large or small.
The Dynamic Viewport is the viewport sized with *dynamic consideration of any UA interfaces*. It will automatically adjust itself in response to UA interface elements being shown or not: the value will be anything within the limits of 100vh (maximum) and 100svh (minimum).
It’s almost time for another season of change. Although the temperatures might not reflect it, this is the time of year where most of us start thinking about what’s next.
This collection of tools and resources for designers is just the spark to propel you forward with work as you think ahead. Here’s what’s new for designers this month.
Gradient.Art
Gradient.Art is a CSS-based gradient generator that’s packed with functionality and customization options. It’s more than just a color selector and is an actual gradient editor that allows you to work with a variety of controls to get just the color variations you want for projects. Create illustrations, patterns, icons, and more with this layer-based tool that’s still in beta.
Wicked Backgrounds
Wicked Backgrounds takes some of the headaches out of creating just the right background for website design projects. It’s another easy and customizable generator designed to help create backgrounds with great color, depth, and balance for various project types. The makers promise more features in the future as well.
Typedream
Typedream is not what you might expect from the name; it’s actually a website-building tool. It’s designed to help put the focus on the words of a design with a simple interface that most people can figure out. You can connect your own domain and then optimize for search with built-in SEO tags. It’s a zippy tool for simple sites.
Orbital
Orbital is a zero-friction, super-interactive, customizable place to gather online. Pop in for meetings, quick chats, open-door office hours, or cowork together through the day – all using the same link. This premium tool has super fun backgrounds and meeting spaces.
Access Guide
Access Guide is your one-stop guide to accessibility information for the web. It’s packed with articles and information to help you understand parts and all of the WCAG 2.1 guidelines, the official standard for accessibility online. (Plus, content is sorted into neat cards that make things easy to search and find.)
InLine
InLine is a free JavaScript library built to create a simple text editor for web applications and mobile apps. The tool claims to be the smallest WYSIWYG editor designed to fit into any layout. The plugin allows you to edit and customize text elements practically anywhere.
3D Bay
3D Bay is a collection of free three-dimensional stock images that you can use for various projects. Collections are searchable. Most of the images are actually 3D scene illustrations, a popular design element with many SaaS website designs.
MeisterNote
MeisterNote is a writing tool for teams. (It’s perfect for the new remote working world.) The interface is sleek and intuitive, and you can create customer workspaces for notes and teams to collaborate. One of the best functions might be the search feature, allowing you to find information in notes easily.
Shapecatcher
Shapecatcher solves an interesting problem. Have you ever visualized an element but don’t know what it is called or how to find it? This tool has a “drawbox” where you can sketch the element, and then it visually searches a database of 11,000-plus Unicode characters in multiple languages to find a close match that you can use online.
Batch Image Processing
Batch Image Processing allows you to edit, crop, and style or add watermarks groups of images all at once. It’s a web-based tool that does everything in a flash and allows you to redownloaded processed images for quick use. (It’s great if you need multiple photos with the same crop or size!)
Integrately
Integrately is an integration automation tool designed to help your apps, tools, and web elements talk back and forth. Connect apps to make tasks run on their own in ways that native software might not do alone. (Pro tip: Use it to connect with your email to send notifications or reports automatically.)
Vechai UI
Vechai UI is a set of high-quality, accessible React UI components with built-in dark mode using Tailwind CSS. Components include pre-designed headless UI and Radix UI.
Style Free HTML Bootstrap 4 Template
Style Free HTML Bootstrap 4 Template is a simple and minimally styled website template for a variety of project types. It’s a great website starter if you need to get a site up and running quickly.
Glass UI CSS Generator
Glass UI CSS Generator helps you create trending neumorphism/soft UI/glass UI style elements. The tool is a CSS generator that allows you to add some of your own elements and then pick styling options while outputting CSS and HTML.
Lineicons
Lineicons is a collection of more than 5,000 line icons that you can use for various projects. Every icon comes with free CDN, regular and light variations, an editor, and more to make it browsable and easy to use. The set has high legibility, and the free set of icons includes more than 500 options.
Carrd
Carrd is a simple, free, and responsive one-page website builder that you can do pretty much anything with. It’s perfect for personal profiles, landing pages, or one-page websites. All it takes is a little imagination.
AdonisJS
AdonisJS includes everything you need to create a fully functional web app or an API server. So stop wasting hours in downloading and assembling hundreds of packages and do it all with this framework for Node.js.
Eastman Condensed
Eastman Condensed is a beautiful and functional sans serif that’s easy to read. The demo version is free for personal use, but a commercial license for the full family is available.
Peachy Rose Font
Peachy Rose Font is a fun novelty option that is fun and light. Plus, it is free for any use, even commercial. The set is fairly large for a free option, with 233 characters.
Selga
Selga is an expressive and complex display font with a retro feel. The swashes and tails are especially nice on this typeface, which is free for personal use.
In my previous article, I created a fragmentation effect using CSS mask and custom properties. It was a neat effect but it has one drawback: it uses a lot of CSS code (generated using Sass). This time I am going to redo the same effect but rely on the new Paint API. This drastically reduces the amount of CSS and completely removes the need for Sass.
Here is what we are making. Like in the previous article, only Chrome and Edge support this for now.
CodePen Embed Fallback
See that? No more than five CSS declarations and yet we get a pretty cool hover animation.
What is the Paint API?
The Paint API is part of the Houdini project. Yes, “Houdini” the strange term that everyone is talking about. A lot of articles already cover the theoretical aspect of it, so I won’t bother you with more. If I have to sum it up in a few words, I would simply say : it’s the future of CSS. The Paint API (and the other APIs that fall under the Houdini umbrella) allow us to extend CSS with our own functionalities. We no longer need to wait for the release of new features because we can do it ourselves!
The CSS Paint API is being developed to improve the extensibility of CSS. Specifically this allows developers to write a paint function which allows us to draw directly into an elements [sic] background, border, or content.
I think the idea is pretty clear. We can draw what we want. Let’s start with a very basic demo of background coloration:
CodePen Embed Fallback
We add the paint worklet using CSS.paintWorklet.addModule('your_js_file').
We register a new paint method called draw.
Inside that, we create a paint() function where we do all the work. And guess what? Everything is like working with . That ctx is the 2D context, and I simply used some well-known functions to draw a red rectangle covering the whole area.
This may look unintuitive at first glance, but notice that the main structure is always the same: the three steps above are the “copy/paste” part that you repeat for each project. The real work is the code we write inside the paint() function.
Let’s add a variable:
CodePen Embed Fallback
As you can see, the logic is pretty simple. We define the getter inputProperties with our variables as an array. We add properties as a third parameter to paint() and later we get our variable using properties.get().
That’s it! Now we have everything we need to build our complex fragmentation effect.
Building the mask
You may wonder why the paint API to create a fragmentation effect. We said it’s a tool to draw images so how it will allow us to fragment an image?
In the previous article, I did the effect using different mask layer where each one is a square defined with a gradient (remember that a gradient is an image) so we got a kind of matrix and the trick was to adjust the alpha channel of each one individually.
This time, instead of using many gradients we will define only one custom image for our mask and that custom image will be handled by our paint API.
An example please!
CodePen Embed Fallback
In the above, I have created an image having an opaque color covering the left part and a semi-transparent one covering the right part. Applying this image as a mask gives us the logical result of a half-transparent image.
Now all we need to do is to split our image to more parts. Let’s define two variables and update our code:
CodePen Embed Fallback
The relevant part of the code is the following:
const n = properties.get('--f-n');
const m = properties.get('--f-m');
const w = size.width/n;
const h = size.height/m;
for(var i=0;i<n;i++) {
for(var j=0;j<m;j++) {
ctx.fillStyle = 'rgba(0,0,0,'+(Math.random())+')';
ctx.fillRect(i*w, j*h, w, h);
}
}
N and M define the dimension of our matrix of rectangles. W and H are the size of each rectangle. Then we have a basic FOR loop to fill each rectangle with a random transparent color.
With a little JavaScript, we get a custom mask that we can easily control by adjusting the CSS variables:
CodePen Embed Fallback
Now, we need to control the alpha channel in order to create the fading effect of each rectangle and build the fragmentation effect.
Let’s introduce a third variable that we use for the alpha channel that we also change on hover.
CodePen Embed Fallback
We defined a CSS custom property as a that we transition from 1 to 0, and that same property is used to define the alpha channel of our rectangles. Nothing fancy will happen on hover because all the rectangles will fade the same way.
We need a trick to prevent fading of all the rectangles at the same time, instead creating a delay between them. Here is an illustration to explain the idea I am going to use:
The above is showing the alpha animation for two rectangles. First we define a variable L that should be bigger or equal to 1 then for each rectangle of our matrix (i.e. for each alpha channel) we perform a transition between X and Y where X - Y = L so we have the same overall duration for all the alpha channel. X should be bigger or equal to 1 and Y smaller or equal to 0.
Wait, the alpha value shouldn’t be in the range [1 0], right ?
Yes, it should! And all the tricks that we’re working on rely on that. Above, the alpha is animating from 8 to -2, meaning we have an opaque color in the [8 1] range, a transparent one in the [0 -2] range and an animation within [1 0]. In other words, any value bigger than 1 will have the same effect as 1, and any value smaller than 0 will have the same effect as 0.
Animation within [1 0] will not happen at the same time for both our rectangles. Rectangle 2 will reach [1 0] before Rectangle 1 will. We apply this to all the alpha channels to get our delayed animations.
L is the variable illustrated previously, and O is the value of our CSS variable that transitions from 1 to 0
When O=1, we have (Math.random()*(l-1) + 1). Considering the fact that the random() function gives us a value within the [0 1] range, the final value will be in the [L 1]range.
When O=0, we have (Math.random()*(l-1) + 1 - l) and a value with the [0 1-L] range.
L is our variable to control the delay.
Let’s see this in action:
CodePen Embed Fallback
We are getting closer. We have a cool fragmentation effect but not the one we saw in the beginning of the article. This one isn’t as smooth.
The issue is related the random() function. We said that each alpha channel need to animate between X and Y, so logically those value need to remain the same. But the paint() function is called a bunch during the transition, so each time, the random() function give us different X and Y values for each alpha channel; hence the “random” effect we are getting.
To fix this we need to find a way to store the generated value so they are always the same for each call of the paint() function. Let’s consider a pseudo-random function, a function that always generates the same sequence of values. In other words, we want to control the seed.
Unfortunately, we cannot do this with the JavaScript’s built-in random() function, so like any good developer, let’s pick one up from Stack Overflow:
const mask = 0xffffffff;
const seed = 30; /* update this to change the generated sequence */
let m_w = (123456789 + seed) & mask;
let m_z = (987654321 - seed) & mask;
let random = function() {
m_z = (36969 * (m_z & 65535) + (m_z >>> 16)) & mask;
m_w = (18000 * (m_w & 65535) + (m_w >>> 16)) & mask;
var result = ((m_z << 16) + (m_w & 65535)) >>> 0;
result /= 4294967296;
return result;
}
And the result becomes:
CodePen Embed Fallback
We have our fragmentation effect without complex code:
a basic nested loop to create NxM rectangles
a clever formula for the channel alpha to create the transition delay
a ready random() function taken from the Net
That’s it! All you have to do is to apply the mask property to any element and adjust the CSS variables.
Fighting the gaps!
If you play with the above demos you will notice, in some particular case, strange gaps between the rectangles
To avoid this, we can extend the area of each rectangle with a small offset.
We update this:
ctx.fillRect(i*w, j*h, w, h);
…with this:
ctx.fillRect(i*w-.5, j*h-.5, w+.5, h+.5);
It creates a small overlap between the rectangles that compensates for the gaps between them. There is no particular logic with the value 0.5 I used. You can go bigger or smaller based on your use case.
CodePen Embed Fallback
Want more shapes?
Can the above be extended to consider more than rectangular shape? Sure it can! Let’s not forget that we can use Canvas to draw any kind of shape — unlike pure CSS shapes where we sometimes need some hacky code. Let’s try to build that triangular fragmentation effect.
After searching the web, I found something called Delaunay triangulation. I won’t go into the deep theory behind it, but it’s an algorithm for a set of points to draw connected triangles with specific properties. There are lots of ready-to-use implementations of it, but we’ll go with Delaunator because it’s supposed to be the fastest of the bunch.
We first define a set of points (we will use random() here) then run Delauntor to generate the triangles for us. In this case, we only need one variable that defines the number of points.
const n = properties.get('--f-n');
const o = properties.get('--f-o');
const w = size.width;
const h = size.height;
const l = 7;
var dots = [[0,0],[0,w],[h,0],[w,h]]; /* we always include the corners */
/* we generate N random points within the area of the element */
for (var i = 0; i < n; i++) {
dots.push([random() * w, random() * h]);
}
/**/
/* We call Delaunator to generate the triangles*/
var delaunay = Delaunator.from(dots);
var triangles = delaunay.triangles;
/**/
for (var i = 0; i < triangles.length; i += 3) { /* we loop the triangles points */
/* we draw the path of the triangles */
ctx.beginPath();
ctx.moveTo(dots[triangles[i]][0] , dots[triangles[i]][1]);
ctx.lineTo(dots[triangles[i + 1]][0], dots[triangles[i + 1]][1]);
ctx.lineTo(dots[triangles[i + 2]][0], dots[triangles[i + 2]][1]);
ctx.closePath();
/**/
var alpha = (random()*(l-1) + 1) - (1-o)*l; /* the alpha value */
/* we fill the area of triangle with the semi-transparent color */
ctx.fillStyle = 'rgba(0,0,0,'+alpha+')';
/* we consider stroke to fight the gaps */
ctx.strokeStyle = 'rgba(0,0,0,'+alpha+')';
ctx.stroke();
ctx.fill();
}
I have nothing more to add to the comments in the above code. I simply used some basic JavaScript and Canvas stuff and yet we have a pretty cool effect.
CodePen Embed Fallback
We can make even more shapes! All we have to do is to find an algorithm for it.
I cannot move on without doing the hexagon one!
CodePen Embed Fallback
I took the code from this article written by Izan Pérez Cosano. Our variable is now R that will define the dimension of one hexagon.
What’s next?
Now that we have built our fragmentation effect, let’s focus on the CSS. Notice that the effect is as simple as changing the opacity value (or the value of whichever property you are working with) of an element on it hover state.
This means we can easily integrate this kind of effect to create more complex animations. Here are a bunch of ideas!
Responsive image slider
CodePen Embed Fallback
Another version of the same slider:
CodePen Embed Fallback
Noise effect
CodePen Embed Fallback
Loading screen
CodePen Embed Fallback
Card hover effect
CodePen Embed Fallback
That’s a wrap
And all of this is just the tip of the iceberg of what can be achieved using the Paint API. I’ll end with two important points:
The Paint API is 90% , so the more you know about , the more fancy things you can do. Canvas is widely used, which means there’s a bunch of documentation and writing about it to get you up to speed. Hey, here’s one right here on CSS-Tricks!
The Paint API removes all the complexity from the CSS side of things. There’s no dealing with complex and hacky code to draw cool stuff. This makes CSS code so much easier to maintain, not to mention less prone to error.
Every day design fans submit incredible industry stories to our sister-site, Webdesigner News. Our colleagues sift through it, selecting the very best stories from the design, UX, tech, and development worlds and posting them live on the site.
The best way to keep up with the most important stories for web professionals is to subscribe to Webdesigner News or check out the site regularly. However, in case you missed a day this week, here’s a handy compilation of the top curated stories from the last seven days. Enjoy!
SVG Gobbler is a browser extension that finds the vector content on the page you’re viewing and gives you the option to download, optimize, copy, view the code, or export it as an image.
When a site uses SVG as an , you can right-click/save-as like any other image. But when SVG is inline as (which often makes sense for styling reasons), it’s harder to snag a copy of it. I usually end up opening DevTools, finding the , right clicking that, using Copy > Copy outerHTML, pasting into a text file, and saving out as whatever.svg. A little more toil than I’d like.
With SVG Gobbler, I click the browser extension and it presents me a nice grid of options:
I can quickly download them from here, but notice it will even optimize them for me if I like, or export as a PNG instead. Neat! I’ve made use of this today already, and I’ve only just installed it today.
By way of feedback, I’d say it would be nice to:
Have a way to size the PNG export (might as well allow me to make it huge if I need to).
Export in next-gen formats that might even be better than PNG as far as file size, like WebP or AVIF.
SVG that has a fill of white should be shown on a non-white background so you can see what they are.
Offer, optionally, to let me name the file as I download it rather than always naming it gobbler-original.svg
A stretch goal would be to somehow extract the CSS used on the site into the . I notice some SVGs it finds look very different when exported, because the page was making use of outside-the-SVG styles to style it, which are lost when exported.
I wonder if the changes to Safari extensions will allow Ross to easily port this to Safari (even Mobile Safari?!).
Nuxt offers an incredible developer experience, with a lot of performance and application setup best practices baked in. In recent releases, they’ve been working on taking this developer experience to the next level, with some newer features that speed up and simplify developer processes. Let’s explore some today.
I set up a repo and site for you to explore some of these features! You can check them out here:
You no longer have to pair Nuxt with an external headless CMS and do all of the setup, particularly if you’re not looking for something at a huge scale, but something smaller like a blog. Nuxt content offers a git-based headless CMS where you can write configuration in markdown, CSV, YAML, or XML, based on your preference. There are some out of the box configuration settings available to you, and writing custom configurations is as simple as creating a property.
What this means for development: you can write static Markdown files in a directory, and that can be your blog! We’re using the same dynamic pages API that you would typically use in Nuxt to generate this content.
It also offers full-text search out of the box, which is a lovely feature to add so quickly to a blog without having to integrate a third-party service.
This tutorial by Debbie O’Brien is an incredible guide, it walks you through every piece of setting it up, highly recommended.
Nuxt Components
One thing I noticed I was doing again and again and again was typing import code in all my components. I do have some snippets to make this a bit faster, but adding them each in every file was still interrupting the flow of my work just a bit.
Nuxt component module scans, imports, and registers components, so that we no longer need to do this. The components must be in the components directory, but we can use them in layouts, pages, and components themselves.
The addition of this module is a small change to our nuxt.config.js:
If you use the component repeatedly, Nuxt will do some nice optimizations such as automatically creating a shared chunk for the component. Be mindful when using this on huge projects, though, as it may impact build times.
Nuxt Image
Nuxt Image is a newer module that offers seamless and quick resizes and transforms for optimized responsive images. You can use their built-in optimizer, or work with 10+ ready-to-use popular providers such as Cloudinary or Fastly.
The code output from using their API are standard and tags, so there’s no obfuscation when integrating them into your workflow.
After adding the module, you’ll be able to add configuration to the images via an images property in the nuxt.config.js, and designate breakpoints, providers, and other configurations:
This is just a sampling of some of the options available to you, provided as an example. The full documentation is here.
And then the usage is similar to any Vue component:
<nuxt-img src="/nuxt-icon.png" />
or
<nuxt-picture src="/nuxt-icon.png" />
Further information and all options are documented here. Hat tip to Ben Hong for letting me know this was available. He has a few Nuxt resources out there that are worth exploring, too!
Sample Repo
I’ve created a sample repo for you to explore that uses all of this functionality. It’s a small recipe blog with nuxt-content for the recipe entries, Nuxt components so that I didn’t need to define imports, and nuxt-image for the image transformations.
You can visit it here to see it all in action, fork it, play around with it, and make it your own.
You can see in it how I used the $img API in Nuxt image for background images here, too, which is not yet fully documented.
Nuxt offers incredible developer experience. Nuxt is even coming out with a new version soon with more updates, always expertly implemented. It’s why using Nuxt is continually such a joy, and proves to be a great framework for teams and single developers alike.