Developer News

Looking at WCAG 2.5.5 for Better Target Sizes

Css Tricks - Tue, 06/08/2021 - 8:31am

Have you ever experienced the frustration of trying to tap a button on a mobile device only to have it do nothing because the target size is just not large enough **and it’s not picking up on your press? Maybe you have larger fingers, like I do, or maybe it’s due to limited dexterity. This is because the sadly ever-decreasing target area of elements we, the users, have to interact with.

Let’s talk about target size and how to make it large enough for users to easily interact with an element. This is an especially big deal if a user is accessing content on a small hand-held touch screen device where real estate is much tighter.

Success criterion revisited

I touched (no pun intended) on Success Criterion in a previous article covering the WCAG 2.1 criterion, Label in Name. In short, the WCAG criteria is the baseline from which we determine whether our work is “accessible.”

If you’re wondering whether there’s a criterion for target size, the answers is yes. It’s WCAG 2.5.5. Pulling straight from the guidelines. passing WCAG 2.5.5 with a AAA grade requires “the size of the target for pointer inputs is at least 44 by 44 CSS pixels except when:

  • Equivalent: The target is available through an equivalent link or control on the same page that is at least 44×44 CSS pixels;
  • Inline: The target is in a sentence or block of text;
  • User Agent Control: The size of the target is determined by the user agent and is not modified by the author;
  • Essential: A particular presentation of the target is essential to the information being conveyed.”
What could possibly go wrong?

It’s just a size, right? Easy peasy. Nothing can possibly go awry.

Or can it?

Small target sizes can cause accessibility hurdles for many people. Have you ever been traveling in a vehicle on a bumpy road and you’re trying to interact with an app on your mobile can not press on an element? That is an accessibility hurdle. Those with motor skill or cognitive impairments will have a much harder time because it is much harder for them if the target size is too small and does not meet WCAG requirements.

I don’t mean to pick on Twitter here, but it’s the first notable example I found while hunting for examples of small targets.

There are some good examples of small targets in here, from the tiny contextual menu to the actions in the footer of a tweet, and even the small icons to add topics to a timeline. And notice that even with a properly sized target, like the floating button to compose a tweet, it overlaps with another target, obstructing access to it.

Imagine the hurdles someone with neuromuscular disorders, such as Multiple Sclerosis, Cerebral Palsy, arthritis, tremors, or Alzheimer’s Disease or any other motor impairment would have to overcome to activate a target in any of those cases.

Another favorite example I see quite often? Ads. Have you ever struggled to click the minuscule “X” button to close them?

You’re not alone if you’ve ever struggled to click, let alone even locate, the close button.

Having no motor skill or cognitive disabilities personally, I find myself fumbling around and taking multiple times to hit some target areas. The fact that someone who needs to use something like a pen or stylus on a target size that is not a minimum of 44×44 pixels can be a difficult task. These targets shouldn’t need multiple attempts to activate when the target size doesn’t meet recommended guidelines.

Target size considerations

WCAG 2.5.5 goes into specific detail to help us account for these things by defining the four types of controls we just saw: equivalent, inline, User Agent, and essential.

We’re going to look at different considerations for determining target sizes and hold them up next to the WCAG guidelines to help steer us toward making good, accessible design decisions.

Consider the difference between “click” and “tap”

This success criteria ensures that target sizes are large enough for users to easily activate targets, even if the user is accessing these targets on handheld devices. We typically associate small screens with “taps” instead of “clicks” when it comes to activating targets. And that’s something we need to consider in our target sizing.

Mice and similar input devices use a pointer on the screen, which is considered “fine” precision because it allows a user to access an element on the screen with exact precision. Fine precision makes it easier to access smaller target sizes in theory. The trouble is, that sort of input device can be tough for some users, whether it’s with gripping the device, or some other cognitive or motor skill. So, even with fine precision, having a clear target is still a benefit.

A Tale of Two Targets: Combining padding and color can help increase the size of a tap target while making it visually clear.

Touch, on the other hand, can be problematic as it is an input mechanism with very “coarse” precision. Users can lack a level of fine control when using a mouse or stylus, for example. A finger, which is larger than a mouse pointer, generally obstructs a user’s view of the exact location on the screen that is being activated or touched. Hence, “coarse” precision.

A smaller pointer offers more precision than a larger thumb when it comes to interacting with an element.

This issue is exacerbated in responsive design, which needs to accommodate for numerous types of fine and coarse inputs. Both input types must be supported for a site that can be accessed by a desktop or laptop with a mouse, as well as a mobile device or tablet with a touch screen.

That makes the actual size we use for a target a pretty important detail. Depending on who is using a control, what that control does, how often it’s used, and where it’s located, we ought to consider using larger, clearer targets to prevent things like unintended actions.

But with all this said, we do actually have a CSS media query that can detect a pointer device so we can target certain styles to either fine or coarse input interactions, and it’s well-supported. Here’s an example pulled right out of the spec:

/* Make radio buttons and check boxes larger if we have an inaccurate primary pointing device */ @media (pointer: coarse) { input[type="checkbox"], input[type="radio"] { min-width: 30px; min-height: 40px; background: transparent; } }

But wait. While this is great and all, Patrick H. Lauke offers a word of caution about this interaction media query and it’s potential for making incorrect assumptions.

Consider that different platforms have different requirements

When WCAG specifies exact values, it’s worth paying attention. Notice that we’re advised to make target sizes at least 44×44 pixels, which is mentioned no fewer than 18 times in the WCAG 2.5.5 explainer.

However, you may have also seen similar requirements with different guidance from the likes of Apple’s “Human Interface Guidelines” for iOS, and Google’s “Material Design” in their platform design requirements.

“Try to maintain a minimum tappable area of 44pt x 44pt for all controls.” (Apple, “Human Interface Guidelines”) “Consider making pointer targets at least 44 x 44 dp.”
(Material Design, “Accessibility”) Consider the “tappable area” of a target

Notice that Apple’s platform requirements refer to a “tappable area” when describing the ideal target size. That means that we’re talking about space as much as we are about the appearance of a target. For example, Google’s Material Design suggests at least a 48×48 dp (density-independent pixels) target size for interactive elements. But what if your design requirements call for a 24×24 dp icon? It’s totally legit to use padding in our favor to create more interactive space around the icon, comprising the 48×48 dp target size. Or, as it’s documented in Material Design:

Touch targets are the parts of the screen that respond to user input. They extend beyond the visual bounds of an element. For example, an icon may appear to be 24×24 dp, but the padding surrounding it comprises the full 48×48 dp touch target.

CodePen Embed Fallback Consider responsive layout behavior

That’s right, we’ve gotta consider how things shift and move around in a design that’s meant to respond to different viewport sizes. One example might be buttons that stack on small screens but are inline on larger screen. We want to make sure that transition accounts for the placement of surrounding elements in order to prevent overlapping elements or targets.

Speaking of inline, there’s a particular piece of the WCAG’s exception for inline targets that’s worth highlighting:

Inline: Content displayed can often be reflowed based on the screen width available (responsive design). In reflowed content, the targets can appear anywhere on a line and can change position based on the width of the available screen. Since targets can appear anywhere on the line, the size cannot be larger than the available text and spacing between the sentences or paragraphs, otherwise the targets could overlap. It is for this reason targets which are contained within one or more sentences are excluded from the target size requirements.

(Emphasis mine)

Now, we’re not necessarily talking about buttons that are side-by-side here. We can links within text and that text might break the target’s placement, possibly into two lines.

While it might be difficult to tap one target without inadvertently tapping the other, the WCAG makes an exception for inline targets, like links within paragraphs. Consider the target’s relationship to its surroundings

We just saw how inline links within a block of text are exempt from the 44×44 rule. There are similar exceptions depending on the target’s relationship to the elements around it.

Let’s take the example that the WCAG explainer provides, again, in it’s description of inline target exceptions:

If the target is the full sentence and the sentence is not in a block of text, then the target needs to be at least 44 by 44 CSS pixels.

That’s a good one. We ought to consider whether the target is its own block or part of a larger block of text. If the target is its own block, then it needs to abide by the rules, whether it’s a button with a short label, or a complete sentence that’s linked up. On the flip side, a complete sentence that’s linked up inside another block of text doesn’t have to meet the target size requirements.

If the target is its own block of text (left), then it needs to adhere to the WCAG criterion. Otherwise, it is exempt (right).

You might think that something like a linked icon at the end of a sentence or paragraph would need to play by the rules, but the WCAG is clear that these targets are exempt:

A footnote or an icon within or at the end of a sentence is considered to be part of a sentence and therefore are excluded from the minimum target size.

And that makes sense. Imagine content with a line height of, say 32 pixels and an icon at the end that’s all padded up to be 44×44 pixels and how easy it would be to inadvertently activate the icon.

CodePen Embed Fallback Consider whether the target is styled by the User Agent

If the target is completely un-styled — in the sense that you’ve added no CSS to it — and instead takes on the default styles provided by the browser, then there’s no need to stress the 44×44 rule. That makes sense. The User Agent is like system-level UI so changing it superficially with our own styles would be overriding an entire system which could lead to inconsistencies in that UI.

You’re fine just as you are, little button.

So, yeah, if you’re rockin’ a default <button> or the like, and there are no other styles or sizing applied to it, then it’s good to go. But lots of us use resets to normalize UI elements across browsers, so watch for that in your codebase because that’s going to affect the User Agent styles of your target.

Consider if there are other ways to activate the functionality

We’ve all used in-page anchor links, right? Heck, CSS-Tricks often has a table of contents at the top of an article that’s merely a list of anchor links.

Should these be at least 44×44 pixels?

WCAG actually uses anchor links as an example of something that’s off the hook as far as meeting the target size requirements. Why? Because it’s just as possible to manually scroll down to a specific location on a page as it is to click a link to jump there. There are two ways to accomplish the same thing, and one of those ways is built right into the browser.

But we still ought to use care when working with something like a table of contents. I’m not entirely clear here, but given that a table of contents is list of links, each link may very well constitute its own block of text that’s not part of a larger block of a text, like a paragraph. So, in this sort of case, maybe a little extra space between list items is still a good idea. There’s less change of accidentally clipping or tapping two or more targets at once.

Wrapping up

WCAG 2.5.5 criterion provides guidance for applying target sizes that are clear, unobstructed, and easy to activate. As we saw, there are plenty of cases where the size of a target can make all the difference in the world when it comes to completing an action.

The interesting thing about the target size guidelines is what is exempted from them. While we didn’t cover each specific exemption on its own, we did look at a bunch situations that require careful consideration for sizing a target, from the type of input device that’s in use to the relationship of the target to its surrounding elements, and plenty of things between.

The key to accessible target sizing isn’t necessary about using less styling on a target (although we did see that default User Agent styles are exempt), but rather having context and styling accordingly. There are probably dozens more situations we could have covered here and examined how styles come into play — so if you have some, share!

And as far as styling goes, CSS specifications have specific features, like the interation media query for pointer, to make target sizing even better for people. Used well, it could be a great way to detect if a visitor is using a fine or coarse input device. That way, we can tailor things to make their experience better than if we treated those differences the same.

So, yes, target sizes are an easy thing to brush off and ignore. But hopefully now you’re like me and have a genuine appreciation for targets that are correctly sized now that you have the information to make correctly sized targets of your own.

The post Looking at WCAG 2.5.5 for Better Target Sizes appeared first on CSS-Tricks.

You can support CSS-Tricks by being an MVP Supporter.

Links on Accessibility

Css Tricks - Mon, 06/07/2021 - 9:52am
  • Show/Hide password accessibility and password hints tutorial — Nicolas Steenhout goes deep on <input type="password"> accessibility. For one thing, being able to toggle it to type="text" should be possible, while announcing, politely, the change. But also, put the password hints (for choosing a password) before the input and programmatically connect them. And a bunch of other stuff. (Video version)
  • Practical accessibility, part 2: Name (almost) everything — Maggie Wachs explains how it’s all about the ability to move about the page.
  • Modern CSS Upgrades To Improve Accessibility — Stephanie Eckles shows off :focus-visible, outline-offset, order and other properties that can both help and hurt accessibility. My favorite are the clever uses of min() and max() which do things like reduce excessive margin on page zoom and maintain tappable area sizes.
  • WebAIM Million – 2021 Update — Jared Smith notes that things are getting better, even if just a bit. Is that the first time ever?! Things certainly aren’t “good” but it’s an encouraging trend.
  • Shift further left with Deque’s axe-linter for VS Code — Jonathan Thickens intros this new editor plugin which calls out errors just as if they were syntax, spelling, or formatting errors. As it should be! I’m using it and it works great. “Shift left” means “test earlier in the process” and “as you code” is about as early as it gets.
  • Content-visibility and Accessible Semantics — Marcy Sutton notes that the accessibility issues that hurt content-visibility when it first rolled have been resolved. This is the original blog post that documented what they were.
  • More Accessible Skeletons — Adrian Roselli notes that aria-busy="true" for a bit of skeleton HTML isn’t enough, as there is a little more attribute-shuffling to do, paired with CSS selectors to hide what needs to be hidden. (Demo)
  • Giving a damn about accessibility — Sheri Byrne-Haber’s “candid and practical handbook for designers.” Free digital (and audio) book. &#x1f4d2;

The post Links on Accessibility appeared first on CSS-Tricks.

You can support CSS-Tricks by being an MVP Supporter.

Principles for user-centered front-end development

Css Tricks - Fri, 06/04/2021 - 10:36am

Colin Oakley:

Accessible — Use semantic HTML, and make sure we meet the WCAG 2.1 AA standard as a minimum and it works with assisted technologies (this sits alongside the DWP Accessibility Manual)

• Agnostic — Build mobile-first and make it work across a range of devices, and user contexts

• Robust — Use progressive enhancement, make sure what we build fails gracefully

• Performant — Optimise our code/assets for the best possible performance across a range of networks and devices

• Secure — Create a secure service which protects users’ privacy. Use strict content security policies and guard against common OWASP attacks.

Direct Link to ArticlePermalink

The post Principles for user-centered front-end development appeared first on CSS-Tricks.

You can support CSS-Tricks by being an MVP Supporter.

Can I :has()

Css Tricks - Fri, 06/04/2021 - 4:37am

I just joked that we’re basically getting everything we want in CSS super fast (mostly referring to container queries, my gosh, can you imagine they are actually coming?). Now we might actually get parent selectors?! As in .parent:has(.child) { }. Traditionally it’s been nope, too slow, browsers can’t do it. Brian Kardell:

Igalia engineers have been looking into this problem. We’ve been having discussions with Chromium developers, looking into Firefox and WebKit codebases and doing some initial protypes and tests to really get our heads around it. Through this, we’ve provided lots of data about performance of what we have already and where we believe challenges and possibilities lie. We’ve begun sketching out an explainer with all of our design notes and questions linked up

Like I said in 2010: Want!

Here’s some other use cases in the blog post and comment section.

Direct Link to ArticlePermalink

The post Can I :has() appeared first on CSS-Tricks.

You can support CSS-Tricks by being an MVP Supporter.

Are Custom Properties a “Menu of What Will Change”?

Css Tricks - Wed, 06/02/2021 - 3:35am

PPK laid out an interesting situation in “Two options for using custom properties” where he and Stefan Judis had two different approaches for doing the same thing with custom properties. In one approach, hover and focus styles for a link are handled with two different custom properties, one for each state. In the other approach, a single custom property is used.

Two custom properties:

.component1 { --linkcolor: red; --hovercolor: blue; } .component2 { --linkcolor: purple; --hovercolor: cyan; } a { color: var(--linkcolor); } a:hover,a:focus { color: var(--hovercolor) }

One custom property:

.component1 a { --componentcolor: red; } .component1 :is(a:hover,a:focus) { --componentcolor: blue; } .component2 a { --componentcolor: purple; } .component2 :is(a:hover,a:focus) { --componentcolor: cyan; } a { color: var(--componentcolor) }

There is something more natural feeling about using two properties, like it’s very explicit about what a particular custom property is meant to do. But there is a lot of elegance to using one custom property. Not just for the sake of being one-less custom property, but that the custom property is 1-to-1 matched with a single property.

Taking this a bit further, you could set up a single ruleset with one custom property per property, giving it a sort of menu for what things will change. To that PPK says:

Now you essentially found a definition file. Not only do you see the component’s default styles, you also see what might change and what will not.

That is to say, you’d use a custom property for anything you intend to change, and anything you don’t, you wouldn’t. That’s certainly an interesting approach that I wouldn’t blame anyone for trying.

.lil-grid { /* will change */ --padding: 1rem; padding: var(--padding); --grid-template-columns: 1fr 1fr 1fr; grid-columns: var(--grid-template-columns); /* won't change */ border: 1px solid #ccc; gap: 1rem; }

My hesitation with this is that it’s, at best, a hint at what will and won’t change. For example, I can still change things even though they aren’t set in a custom property. Later, I could do:

.lil-grid.two-up { grid-columns: 1fr 1fr; }

That wipes out the custom property usage. Similarly, I could never change the value of --grid-template-columns, meaning it looks like it changes under different circumstances, but never does.

Likewise, I could do:

.lil-grid.thick { border-width: 3px; }

…and even though my original component ruleset implies that the border width doesn’t change, it does with a modifier class.

So, in order to make an approach like that work, you treat it like a convention that you stick to, like a generic coding standard. I’d worry it becomes a pain in the butt, though. For any declaration you decide to change, you gotta go back and refactor it to either be or not be a custom property.

This makes me think about the “implicit styling API” that is HTML and CSS. We’ve already got a styling API in browsers. HTML is turned into the DOM in the browser, and we style the DOM with CSS. Select things, style them.

Maybe we don’t need a menu for what you can and cannot style because that’s what the DOM and CSS already are. That’s not to say a well-crafted set of custom properties can’t be a part of that, but they don’t need to represent hardline rules on what changes and what doesn’t.

Speaking of implicit styling APIs, Jim Nielsen writes in “Shadow DOM and Its Effect on the Unofficial Styling API”:

[…] the shadow DOM breaks the self-documenting style API we’ve had on the web for years.

What style API? If you want to style an element on screen, you open the dev tools, look at the DOM, find the element you want, figure out the right selector to target that element, write your selector and styles, and you’re done.

That’s pretty remarkable when you stop and think about it.

I suppose that’s my biggest beef with web components. I don’t dislike the Shadow DOM; in fact, it’s probably my favorite aspect of web components. I just dislike how I have to invent a styling API for them (à la custom properties that wiggle inside, or ::part) rather than use the styling API that has served us well forever: DOM + CSS.

The post Are Custom Properties a “Menu of What Will Change”? appeared first on CSS-Tricks.

You can support CSS-Tricks by being an MVP Supporter.

Jetpack Boost Handles Critical CSS For You

Css Tricks - Tue, 06/01/2021 - 4:16am

Critical CSS is one of those things I see in my performance reports but always seem to ignore. I know what it means. It means to put only the CSS required to render things immediately visible in a <style> tag in the <head> so it comes across in the first network request, then load the rest asynchronously, which will help the page load faster.

You’ve probably also seen the nag in Lighthouse performance reports as well:

Lighthouse tells me the critical CSS is an opportunity and even gives me a some WordPress-specific tips.

I’m not a big-complex-build-process sort of person, and unfortunately a lot of tooling for critical CSS involves including it within an existing build process.

I caught wind of Jetpack Boost and it’s designed to (among other performance-y things) make critical CSS easy for WordPress sites. Having a (free!) plugin that takes care of that really appeals to me.

Jetpack Boost is freely available in the WordPress Plugin Directory, so it installs just like any other plugin.

Search, install and activate! &#x1f680;

Activating the plugin adds a “Jetpack Boost” item to the WordPress admin menu, and that leads to a handy screen that runs sorta like Lighthouse, but in WordPress. And wouldn’t you know, there’s an option to generate critical CSS right there. All I had to do was toggle the feature on and Jetpack Boost starts working.

My score can only go up from here, right?!

It doesn’t take long for the process to run. I switched windows to check my email for a minute and it was already done by the time I switched back. And, hey, look what it did for me while I slacked off:

Not too shabby for clicking one button! But we’ve gotta compare apples to apples, right? Let’s go back into Lighthouse to see what it says.

Now if only I could bring that initial server response time down. &#x1f9d0;

We can even view the source to see that the proof is indeed in the pudding:

Whoa, that’s more than I expected!

It’s seriously cool to see the Jetpack team so focused on performance, and to the extent that they’ve dedicated an entire plugin to it. Performance has always been part of Jetpack’s settings. But making it front-and-center like this really allows Jetpack to do more interesting things with performance, like grading and critical CSS, in ways that go beyond basic settings. I’d imagine we’ll see more of Jetpack’s performance settings making the move over to the new plugin at some point.

Kudos to the Jetpack team! This is really nice enhancement, and certainly timely, given Google’s recent push on Core Web Vitals and how they’ll affect SEO.

The post Jetpack Boost Handles Critical CSS For You appeared first on CSS-Tricks.

You can support CSS-Tricks by being an MVP Supporter.

Serverless Functions: The Secret to Ultra-Productive Front-End Teams

Css Tricks - Mon, 05/31/2021 - 7:16am

Modern apps place high demands on front-end developers. Web apps require complex functionality, and the lion’s share of that work is falling to front-end devs:

  • building modern, accessible user interfaces
  • creating interactive elements and complex animations
  • managing complex application state
  • meta-programming: build scripts, transpilers, bundlers, linters, etc.
  • reading from REST, GraphQL, and other APIs
  • middle-tier programming: proxies, redirects, routing, middleware, auth, etc.

This list is daunting on its own, but it gets really rough if your tech stack doesn’t optimize for simplicity. A complex infrastructure introduces hidden responsibilities that introduce risk, slowdowns, and frustration.

Depending on the infrastructure we choose, we may also inadvertently add server configuration, release management, and other DevOps duties to a front-end developer’s plate.

Software architecture has a direct impact on team productivity. Choose tools that avoid hidden complexity to help your teams accomplish more and feel less overloaded.

The sneaky middle tier — where front-end tasks can balloon in complexity

Let’s look at a task I’ve seen assigned to multiple front-end teams: create a simple REST API to combine data from a few services into a single request for the frontend. If you just yelled at your computer, “But that’s not a frontend task!” — I agree! But who am I to let facts hinder the backlog?

An API that’s only needed by the frontend falls into middle-tier programming. For example, if the front end combines the data from several backend services and derives a few additional fields, a common approach is to add a proxy API so the frontend isn’t making multiple API calls and doing a bunch of business logic on the client side.

There’s not a clear line to which back-end team should own an API like this. Getting it onto another team’s backlog — and getting updates made in the future — can be a bureaucratic nightmare, so the front-end team ends up with the responsibility.

This is a story that ends differently depending on the architectural choices we make. Let’s look at two common approaches to handling this task:

  • Build an Express app on Node to create the REST API
  • Use serverless functions to create the REST API

Express + Node comes with a surprising amount of hidden complexity and overhead. Serverless lets front-end developers deploy and scale the API quickly so they can get back to their other front-end tasks.

Solution 1: Build and deploy the API using Node and Express (and Docker and Kubernetes)

Earlier in my career, the standard operating procedure was to use Node and Express to stand up a REST API. On the surface, this seems relatively straightforward. We can create the whole REST API in a file called server.js:

const express = require('express'); const PORT = 8080; const HOST = '0.0.0.0'; const app = express(); app.use(express.static('site')); // simple REST API to load movies by slug const movies = require('./data.json'); app.get('/api/movies/:slug', (req, res) => { const { slug } = req.params; const movie = movies.find((m) => m.slug === slug); res.json(movie); }); app.listen(PORT, HOST, () => { console.log(`app running on http://${HOST}:${PORT}`); });

This code isn’t too far removed from front-end JavaScript. There’s a decent amount of boilerplate in here that will trip up a front-end dev if they’ve never seen it before, but it’s manageable.

If we run node server.js, we can visit http://localhost:8080/api/movies/some-movie and see a JSON object with details for the movie with the slug some-movie (assuming you’ve defined that in data.json).

Deployment introduces a ton of extra overhead

Building the API is only the beginning, however. We need to get this API deployed in a way that can handle a decent amount of traffic without falling down. Suddenly, things get a lot more complicated.

We need several more tools:

  • somewhere to deploy this (e.g. DigitalOcean, Google Cloud Platform, AWS)
  • a container to keep local dev and production consistent (i.e. Docker)
  • a way to make sure the deployment stays live and can handle traffic spikes (i.e. Kubernetes)

At this point, we’re way outside front-end territory. I’ve done this kind of work before, but my solution was to copy-paste from a tutorial or Stack Overflow answer.

The Docker config is somewhat comprehensible, but I have no idea if it’s secure or optimized:

FROM node:14 WORKDIR /usr/src/app COPY package*.json ./ RUN npm install COPY . . EXPOSE 8080 CMD [ "node", "server.js" ]

Next, we need to figure out how to deploy the Docker container into Kubernetes. Why? I’m not really sure, but that’s what the back end teams at the company use, so we should follow best practices.

This requires more configuration (all copy-and-pasted). We entrust our fate to Google and come up with Docker’s instructions for deploying a container to Kubernetes.

Our initial task of “stand up a quick Node API” has ballooned into a suite of tasks that don’t line up with our core skill set. The first time I got handed a task like this, I lost several days getting things configured and waiting on feedback from the backend teams to make sure I wasn’t causing more problems than I was solving.

Some companies have a DevOps team to check this work and make sure it doesn’t do anything terrible. Others end up trusting the hivemind of Stack Overflow and hoping for the best.

With this approach, things start out manageable with some Node code, but quickly spiral out into multiple layers of config spanning areas of expertise that are well beyond what we should expect a frontend developer to know.

Solution 2: Build the same REST API using serverless functions

If we choose serverless functions, the story can be dramatically different. Serverless is a great companion to Jamstack web apps that provides front-end developers with the ability to handle middle tier programming without the unnecessary complexity of figuring out how to deploy and scale a server.

There are multiple frameworks and platforms that make deploying serverless functions painless. My preferred solution is to use Netlify since it enables automated continuous delivery of both the front end and serverless functions. For this example, we’ll use Netlify Functions to manage our serverless API.

Using Functions as a Service (a fancy way of describing platforms that handle the infrastructure and scaling for serverless functions) means that we can focus only on the business logic and know that our middle tier service can handle huge amounts of traffic without falling down. We don’t need to deal with Docker containers or Kubernetes or even the boilerplate of a Node server — it Just Works™ so we can ship a solution and move on to our next task.

First, we can define our REST API in a serverless function at netlify/functions/movie-by-slug.js:

const movies = require('./data.json'); exports.handler = async (event) => { const slug = event.path.replace('/api/movies/', ''); const movie = movies.find((m) => m.slug === slug); return { statusCode: 200, body: JSON.stringify(movie), }; };

To add the proper routing, we can create a netlify.toml at the root of the project:

[[redirects]] from = "/api/movies/*" to = "/.netlify/functions/movie-by-slug" status = 200

This is significantly less configuration than we’d need for the Node/Express approach. What I prefer about this approach is that the config here is stripped down to only what we care about: the specific paths our API should handle. The rest — build commands, ports, and so on — is handled for us with good defaults.

If we have the Netlify CLI installed, we can run this locally right away with the command ntl dev, which knows to look for serverless functions in the netlify/functions directory.

Visiting http://localhost:888/api/movies/booper will show a JSON object containing details about the “booper” movie.

So far, this doesn’t feel too different from the Node and Express setup. However, when we go to deploy, the difference is huge. Here’s what it takes to deploy this site to production:

  1. Commit the serverless function and netlify.toml to repo and push it up on GitHub, Bitbucket, or GitLab
  2. Use the Netlify CLI to create a new site connected to your git repo: ntl init

That’s it! The API is now deployed and capable of scaling on demand to millions of hits. Changes will be automatically deployed whenever they’re pushed to the main repo branch.

You can see this in action at https://serverless-rest-api.netlify.app and check out the source code on GitHub.

Serverless unlocks a huge amount of potential for front-end developers

Serverless functions are not a replacement for all back-ends, but they’re an extremely powerful option for handling middle-tier development. Serverless avoids the unintentional complexity that can cause organizational bottlenecks and severe efficiency problems.

Using serverless functions allows front-end developers to complete middle-tier programming tasks without taking on the additional boilerplate and DevOps overhead that creates risk and decreases productivity.

If our goal is to empower frontend teams to quickly and confidently ship software, choosing serverless functions bakes productivity into the infrastructure. Since adopting this approach as my default Jamstack starter, I’ve been able to ship faster than ever, whether I’m working alone, with other front-end devs, or cross-functionally with teams across a company.

The post Serverless Functions: The Secret to Ultra-Productive Front-End Teams appeared first on CSS-Tricks.

You can support CSS-Tricks by being an MVP Supporter.

Local: Always Getting Better

Css Tricks - Mon, 05/31/2021 - 7:13am

I’ve been using Local for ages. Four years ago, I wrote about how I got all my WordPress sites running locally on it. I just wanted to give it another high five because it’s still here and still great. In fact, much great than it was back then.

Disclosure, Flywheel, the makers of Local, sponsor this site, but this post isn’t sponsored. I just wanted to talk about a tool I use. It’s not the only player in town. Even old school MAMP PRO is has gotten a lot better and many devs seem to like it. People that live on the command line tend to love Laravel Valet. There is another WordPress host getting in on the game here: DevKinsta.

The core of Local is still very much the same. It’s an app you run locally (Windows, Mac, or Linux) and it helps you spin up WordPress sites incredibly easily. Just a few choices and clicks and it’s going. This is particularly useful because WordPress has dependencies that make it run (PHP, MySQL, a web server, etc) and while you can absolutely do that by hand or with other tools, Local does it in a containerized way that doesn’t mess with your machine and can help you run locally with settings that are close to or entirely match your production site.

That stuff has always been true. Here are things that are new, compared to my post from four years ago!

  • Sites start up nearly instantaneously. Maybe around a year or a bit more ago Local had a beta build they dubbed Local “Lightning” because it was something of a re-write that made it way faster. Now it’s just how Local works, and it’s fast as heck.
  • You can easily pull and push sites to production (and/or staging) very easily. Back then, you could pull I think but not push. I still wire up my own deployment because I usually want it to be Git-based, but the pulling is awfully handy. Like, you sit down to work on a site, and first thing, you can just yank down a copy of production so you’re working with exactly what is live. That’s how I work anyway. I know that many people work other ways. You could have your local or staging environment be the source of truth and do a lot more pushing than pulling.
  • Instant reload. This is refreshing for my little WordPress sites where I didn’t even bother to spin up a build process or Sass or anything. Usually, those build processes also help with live reloading, so it’s tempting to reach for them just for that, but no longer needed here. When I do need a build process, I’ll often wire up Gulp, but also CodeKit still works great and its server can proxy Local’s server just fine.
  • One-click admin login. This is actually the feature that inspired me to write this post. Such a tiny quality of life thing. There is a button that says Admin. You can click that and, rather than just taking you to the login screen, it auto-logs you in as a particular admin user. SO NICE.
  • There is a plugin system. My back-end friends got me on TablePlus, so I love that there is an extension that allows me to one-click open my WordPress DBs in TablePlus. There is also an image optimizer plugin, which scans the whole site for images it can make smaller. I just used that the other day because might as well.

That’s not comprehensive of course, it’s just a smattering of features that demonstrate how this product started good and keeps getting better.

Bonus: I think it’s classy how they shout out to the open source shoulders they stand on:

The post Local: Always Getting Better appeared first on CSS-Tricks.

You can support CSS-Tricks by being an MVP Supporter.

To $ or Not to $: Displaying Terminal Code Snippets

Css Tricks - Thu, 05/27/2021 - 8:22am

It’s very popular to put a $ on lines that are intended to be a command in code documentation that involves the terminal (i.e. the command line).

Like this:

$ brew install somepackage

The point of that is that it mimics the prompt that you (may) see on your command line. Here’s mine:

So the dollar sign ($) is a little technique that people use to indicate this line of code is supposed to be run on the command line.

Minor trouble

The trouble with that is that I (and I’ll wager most other people too) will copy and paste commands like that from that documentation.

If I run that command above in my terminal exactly as it’s written…

…it doesn’t work. $ is not a command. How do you deal with this? You just have to know. You just need to have had this problem before and somehow learned that what the documentation is actually telling you is to run the command brew install somepackage (without the dollar sign) at the command line.

I say minor trouble as there are all sorts of stuff like this in every job in the world. When I put something like font-size: 2.2rem in a blog post, I don’t also say, “Put that declaration in a ruleset in a CSS file that your HTML file links to.” You just have to know those those things.

Fixing it with CSS

The fact that it’s only minor trouble and that tech is laden with things you just need to know doesn’t mean that we can’t try to fix this and do a little better.

The idea for this post came from this tweet that got way more likes than I thought it would:

If you really think it's more understandable to put a $ in docs for terminal commands, e.g.

$ brew install buttnugget

then a UX touch is:

code.command::before {
content: "$ ";
}

so that I don't copy it when I copy the command and have it fail in the actual terminal.

— Chris Coyier (@chriscoyier) May 5, 2021

To expand on that, I’d expect you’re probably marking up your docs something like:

<p>Install package like:</p> <pre><code class="command">brew install package</code></pre>

Now you can insert the $ as a pseudo-element rather than as actual text:

code.command::before { content: "$ "; }

Now you aren’t just saving yourself a character in the HTML, the $ cannot be selected, because that’s how pseudo-elements work. So now you’re now a bit better in the UX department. Even if the user double-clicks the line or tries to select all of it, they won’t get the $ screwing up the copy-paste.

Hopefully they aren’t equally frustrated by not being able to copy the $. &#x1f62c;

So, anyway, something like this incredible design by me:

CodePen Embed Fallback Fixing it with text

A lot of documentation for code-things are on a public git repo place like GitHub. You don’t have access to CSS to style what GitHub looks like, so while there is trickery available, you can’t just plop a line of CSS in there to style things.

We might have to (gasp) use our words:

<p> Install the package by entering this command at your terminal: </p> <kbd class="command">brew install package</kbd> Other thoughts
  • You probably wouldn’t bother syntax highlighting it at all. I don’t think I’ve ever seen a terminal that syntax highlights commands as you enter them.
  • Eric Meyer suggested the <kbd> element which is the Keyboard Input element. I like that. I’ve long used <code> but I think <kbd> is more appropriate here.
  • Tim Chase suggested using a <span> and including the prompt in the HTML so you can style it uniquely if you want, including making it not selectable with user-select: none;.
  • Justin Searls has a dotfiles trick where if you accidently copy/paste the $, it just ignores it and runs everything after it.
  • Jackson Bates suggests being very careful about what you copy and paste to a terminal.
  • I learned that $ is also a way of denoting “unprivileged” commands while # is for root commands. Part of that reason is that if you copy-paste a root command, it won’t run as it will be recognized as a comment.

The post To $ or Not to $: Displaying Terminal Code Snippets appeared first on CSS-Tricks.

You can support CSS-Tricks by being an MVP Supporter.

Links on Web Components

Css Tricks - Wed, 05/26/2021 - 7:56am
  • How we use Web Components at GitHub — Kristján Oddsson talks about how GitHub is using web components. I remember they were very early adopters, and it says here they released a <relative-time> component in 2014! Now they’ve got a whole bunch of open source components. So easy to use! Awesome! I wanted to poke around their HTML and see them in action, so I View’d Source and used the RegEx (<\w+-[\w|-|]+.*>) (thanks, Andrew) to look for them. Seven on the logged-in homepage, so they ain’t blowin’ smoke.
  • Using web components to encapsulate CSS and resolve design system conflicts — Tyler Williams says the encapsulation (Shadow DOM) of web components meant avoiding styling conflicts with an older CSS system. He also proves that companies that make sites for Git repos love web components.
  • Container Queries in Web Components — Max Böck shares that the :host of a web component can be the @container which is extremely great and is absolutely how all web components should be written.
  • Faster Integration with Web Components — Jason Grigsby does client work and says that web components don’t make integration fast or easy, they make integration fast and easy.
  • FicusJS — I remember being told once that native web components weren’t really meant to be used “raw” but meant to be low-level such that tooling could be built on top of them. We see that in competition amongst renderers, like lit-html vs htm. Then, in layers of tooling on top of that, like Ficus here, that adds a bunch of fancy stuff like state, methods, and events.
  • Shadow DOM and Its Effect on the Unofficial Styling API — Jim Nielsen expands on the idea I poked at on ShopTalk that the DOM is the styling API. It’s self-documenting, in a way. “As an author, you have to spend time and effort thinking about, architecting, and then documenting a styling API for your component. And as a consumer, you have to read, understand, and implement that API.” Yes. That’s why, to me, it feels like a good idea to have an option to “reach into the Shadow DOM from outside CSS” in an unencumbered way.
  • Awesome Standalones — I think Dave’s list here is exactly the kind of thing that gets developers feet wet and thinking about web components as actually useful.

Web components are

— Yehuda Katz (@wycats) May 10, 2021

Two years ago, hold true:

ive made a chart of how people feel about web components over time. pic.twitter.com/Iwina6UxAB

— Chris Coyier (@chriscoyier) April 9, 2019

The post Links on Web Components appeared first on CSS-Tricks.

You can support CSS-Tricks by being an MVP Supporter.

Creating Powerful Websites with Serverless-Driven CMS Development

Css Tricks - Tue, 05/25/2021 - 1:00am

Choosing the right tools to build a website for your organization is essential, but it can be tough to find the right fit. Simple site builders like Wix and Squarespace are easy for marketers to use, but severely limit developers when it comes to customizing site functionality. WordPress is a more robust content management system (CMS), but it requires clunky plugins with infrequent updates and potential security issues

Other site-building tools, such as Gatsby or Hexo, are developer-friendly, but make it very challenging for content creators without technical backgrounds to make even simple updates on their own. These tools often don’t meet the needs of large creative teams running corporate websites.

But there is an option that solves for both audiences. HubSpot’s CMS Hub is a content management system powered by a full CRM Platform that empowers developers to build advanced functionality and marketers to make updates and publish content on their own.

One of the features CMS Hub offers developers is the ability to create serverless functions. These functions make it possible to enhance a website’s backend functionality with integrated plugins that are much easier to develop, deploy, and maintain than third-party WordPress plugins. 

Throughout this article, you’ll get a hands-on look at how HubSpot serverless functions help you build custom websites that clients love. To provide a super-quick preview of what is possible, we’ll fetch news data using GET functions that could be used to populate a dynamic webpage. You’ll need to know some JavaScript to follow along. 

HubSpot Serverless Functions

Serverless architecture enables developers to build and run applications and services without managing the server’s infrastructure. You don’t need to provision, scale, and maintain servers or install and manage databases to host and serve your web applications. When your business grows, it is much easier to scale.

HubSpot’s serverless functions are as powerful as WordPress plugins. They are capable of interacting with HubSpot’s CRM platform as well as integrating with third-party services through APIs. You can use serverless functions to enhance your site, for example:

  • Getting data and storing it in HubDB or the HubSpot CRM
  • Integrating your website with third-party services like Google Forms
  • Creating event registration systems
  • Submitting forms that send data to other services

The functions’ code is stored in the developer file system and is accessed from the Design Manager user interface (UI) or the command-line interface (CLI). You can use the CLI to generate and edit the code locally using your preferred local development tools then upload these changes to HubSpot.

To try the example serverless function in the next section, you need to have access to a CMS Hub Enterprise account or sign up for a free developer testing account. We’ll deploy serverless functions into a site created based on the CMS Boilerplate.

(If you are not familiar with HubSpot development, you may want to check out the quick start guide before following along with the examples below.)

Fetching News Data Using GET Requests

Let’s start by implementing a serverless function that sends a GET request to a third-party REST API to fetch the latest news data using the Axios client. This API searches for online news articles that mention the keyword “HubSpot.”

Note: We’ll be using a third-party API available from NewsAPI.org to retrieve news data, so you first need to register for their API key.

APIs that require authentication or use API keys are not safe for a website’s frontend as they expose your credentials. Serverless functions are a good solution as an intermediary, keeping your credentials secret.

Head over to a CLI and run the following commands:

cd local-cms-dev mkdir myfunctions hs create function

First, we navigate to our local CMS project, and we call the hs create function command to generate a simple boilerplate function.

You’ll be prompted for some information about your functions, such as:

  • Name of the folder where your function will be created. Enter myfunctions/getnews.
  • Name of the JavaScript file for your function. Enter getnews.
  • Select the HTTP method for the endpoint. Select GET.
  • Path portion of the URL created for the function. Enter getnews.

You should get a message saying that a function for the endpoint “/_hcms/API/getnews” has been created. This means, once uploaded, our function will be available from the /_hcms/API/getnews endpoint. 

Before uploading the function, let’s first implement our desired functionality.

Open the myfunctions\getnews.function\getnews.js file. You’ll find some boilerplate code for a serverless function that sends a GET request to the HubSpot search API. Remove the boilerplate code and leave only the following updated code:

const axios = require('axios'); const API_KEY = '<YOUR_API_KEY_HERE>'; exports.main = async (_, sendResponse) => { };

Note that you should normally add your API key via the command-line interface hs secrets command, but adding it here is sufficient for the purpose of demonstrating the function.

We require the Axios library to send HTTP requests, and we export a main function that HubSpot executes when a request is made to the associated endpoint. We also define an API_KEY variable that holds the API key from the news API.

Next, inside the body of the main function, add the following code:

const response = await axios.get(`https://newsapi.org/v2/everything?q=HubSpot&sortBy=popularity&apiKey=${API_KEY}`); sendResponse({ body: { response: response.data }, statusCode: 200 });

We call Axios to send a GET request to the API endpoint, then we call the sendResponse method to send the fetched data back to the client. We could call this API directly from the frontend code, but we would need to expose our API key, which should be secret. Thanks to the serverless function, fetching data happens on the server side, so we don’t have to expose the secret.

Finally, run the following command to upload your function:

hs upload myfunctions myfunctions

This command uploads files from the myfunctions local folder to a myfunctions folder (that will be created) in your account’s Design Manager.

Finally, run the method by visiting the /_hcms/API/getnews endpoint with your web browser. In our case, we need to visit this link. Here, you should see a list of news articles about HubSpot – albeit without any front-end design. 

While it is beyond the scope of this article, our next step would be to take the data from the NewsAPI and create a template that would allow us to output the news results onto a dynamic webpage. And with this, we’ll have a place where anyone can quickly catch up on all the latest news mentioning HubSpot or any other keyword you decide to include.  

Next Steps

When you need a small brochure-based website and won’t be making many updates, any CMS will do. However, when you are looking to create advanced digital experiences to grow your organization, HubSpot’s CMS Hub offers the functionality and flexibility you need. Plus, you can work with your preferred tools and modern workflows such as CLIs, integrated development environments (IDEs), and GitHub. 

Hopefully, this article has provided an initial glimpse of what is possible with HubSpot’s serverless functions. But don’t stop here, dive in and experiment with adding custom functionality to your own HubSpot-powered website. Your imagination is the limit. Sign up for a free developer test account to get started.

Further reading:

Ahmed Bouchefra is a developer and technical author with a BAC + 5 diploma in software development. Ahmed builds apps and authors technical content about JavaScript, Angular, Ionic, and more.

The post Creating Powerful Websites with Serverless-Driven CMS Development appeared first on CSS-Tricks.

You can support CSS-Tricks by being an MVP Supporter.

proxy-www

Css Tricks - Mon, 05/24/2021 - 9:09am

I like a good trick. What if… a URL was… a promise… that fetched said URL?

www.codepen.io.then((response) => { console.log(response); });

That’s what @justjavac did with JavaScript Proxys. A clever trick, that. Don’t @ me about the practicality. Trick, folks.

Direct Link to ArticlePermalink

The post proxy-www appeared first on CSS-Tricks.

You can support CSS-Tricks by being an MVP Supporter.

Should DevTools teach the CSS cascade?

Css Tricks - Fri, 05/21/2021 - 1:22pm

Stefan Judis, two days before I mouthed off about using (X, X, X, X) for talking about specificity, has a great blog post not only using that format, but advocating that browser DevTools should show us that value by selectors.

I think that the above additions could help to educate developers about CSS tremendously. The only downside I can think of is that additional information might overwhelm developers, but I would take that risk in favor of more people learning CSS properly.

I’d be for it. The crossed-off UI for the “losing” selectors is attempting to teach this, but without actually teaching it. I wouldn’t be that worried about the information being overwhelming. I think if they are considerate about the design, it can be done tastefully. DevTools is a very information-dense place anyway.

Direct Link to ArticlePermalink

The post Should DevTools teach the CSS cascade? appeared first on CSS-Tricks.

You can support CSS-Tricks by being an MVP Supporter.

CSS Hell

Css Tricks - Fri, 05/21/2021 - 4:29am

Collection of common CSS mistakes, and how to fix them

From Stefánia Péter.

Clever idea for a site! Some of them are little mind-twisters that could bite you, and some of them are honing in on best practices that may affect accessibility.

Why “CSS Hell”?

It’s a joke idea I stole from HTMHell. I hope adding some fun and sarcasm to learning might help raising awareness of how !important a good CSS code is.

Direct Link to ArticlePermalink

The post CSS Hell appeared first on CSS-Tricks.

You can support CSS-Tricks by being an MVP Supporter.

Can We Create a “Resize Hack” With Container Queries?

Css Tricks - Thu, 05/20/2021 - 4:24am

If you follow new developments in CSS, you’ve likely heard of the impending arrival of container queries. We’re going to look at the basics here, but if you’d like another look, check out Una’s “Next Gen CSS: @container” article. After we have a poke at the basics ourselves, we’re going to build something super fun with them: a fresh take on the classic CSS meme featuring Peter Griffin fussing with window blinds. ;)

So, what is a container query? It’s… exactly that. Much like we have media queries for querying things such as the viewport size, a container query allows us to query the size of a container. Based on that, we can then apply different styles to the children of said container.

What does it look like? Well, the exact standards are being worked out. Currently, though, it’s something like this:

.container { contain: layout size; /* Or... */ contain: layout inline-size; } @container (min-width: 768px) { .child { background: hotpink; } }

The layout keyword turns on layout-containment for an element. inline-size allows users to be more specific about containment. This currently means we can only query the container’s width. With size, we are able to query the container’s height.

Again, we things could still change. At the time of writing, the only way to use container queries (without a polyfill) is behind a flag in Chrome Canary (chrome://flags). I would definitely recommend having a quick read through the drafts over on csswg.org.

The easiest way to start playing would be to whip up a couple quick demos that sport a resizable container element.

CodePen Embed Fallback CodePen Embed Fallback

Try changing the contain values (in Chrome Canary) and see how the demos respond. These demo uses contain: layout size which doesn’t restrict the axis. When both the height and width of the containers meet certain thresholds, the shirt sizing adjusts in the first demo. The second demo shows how the axes can work individually instead, where the beard changes color, but only when adjusting the horizontal axis.

@container (min-width: 400px) and (min-height: 400px) { .t-shirt__container { --size: "L"; --scale: 2; } }

That’s what you need to know to about container queries for now. It’s really just a few new lines of CSS.

The only thing is: most demos for container queries I’ve seen so far use a pretty standard “card” example to demonstrate the concept. Don’t get me wrong, because cards are a great use case for container queries. A card component is practically the poster child of container queries. Consider a generic card design and how it could get affected when used in different layouts. This is a common problem. Many of us have worked on projects where we wind up making various card variations, all catering to the different layouts that use them.

But cards don‘t inspire much to start playing with container queries. I want to see them pushed to greater limits to do interesting things. I‘ve played with them a little in that t-shirt sizing demo. And I was going to wait until there was better browser support until I started digging in further (I’m a Brave user currently). But then Bramus shared there was a container query polyfill!

Shout out to @bramus for sharing the Container Queries polyfill by @jon_neal the other day &#x1f44f;

This prompted me to get “hacking”! &#x1f605;https://t.co/Em5TLyslip

— Jhey &#x1f43b;&#x1f6e0; (Exploring Opportunities ✨) (@jh3yy) April 30, 2021

And this got me thinking about ways to “hack” container queries.

⚠️ Spoiler alert: My hack didn’t work. It did momentarily, or at least I thought it did. But, this was actually a blessing because it prompted more conversation around container queries.

What was my idea? I wanted to create something sort of like the “Checkbox Hack” but for container queries.

<div class="container"> <div class="container__resizer"></div> <div class="container__fixed-content"></div> </div>

The idea is that you could have a container with a resizable element inside it, and then another element that gets fixed positioning outside of the container. Resizing containers could trigger container queries and restyle the fixed elements.

.container { contain: layout size; } .container__resize { resize: vertical; overflow: hidden; width: 200px; min-height: 100px; max-height: 500px; } .container__fixed-content { position: fixed; left: 200%; top: 0; background: red; } @container(min-height: 300px) { .container__fixed-content { background: blue; } }

Try resizing the red box in this demo. It will change the color of the purple box.

CodePen Embed Fallback Can we debunk a classic CSS meme with container queries?

Seeing this work excited me a bunch. Finally, an opportunity to create a version of the Peter Griffin CSS meme with CSS and debunk it!

You’ve probably seen the meme. It’s a knock on the Cascade and how difficult it is to manage it. I created the demo using cqfill@0.5.0… with my own little touches, of course. &#x1f605;

CodePen Embed Fallback

Moving the cord handle, resizes an element which in turn affects the container size. Different container breakpoints would update a CSS variable, --open, from 0 to 1, where 1 is equal to an “open” and 0 is equal to a “closed” state.

@container (min-height: 54px) { .blinds__blinds { --open: 0.1; } } @media --css-container and (min-height: 54px) { .blinds__blinds { --open: 0.1; } } @container (min-height: 58px) { .blinds__blinds { --open: 0.2; } } @media --css-container and (min-height: 58px) { .blinds__blinds { --open: 0.2; } } @container (min-height: 62px) { .blinds__blinds { --open: 0.3; } } @media --css-container and (min-height: 62px) { .blinds__blinds { --open: 0.3; } }

But…. as I mentioned, this hack isn’t possible.

Hmmm, containing inline-size shouldn’t allow block (height) queries. You’re likely hacking a bug in the js polyfill.

I love the idea, but I don’t think this approach will work using Container Queries in CSS.

— Miriam (But Terrible) (@TerribleMia) May 1, 2021

What’s great here is that it prompted conversation around how container queries work. It also highlighted a bug with the container query polyfill which is now fixed. I would love to see this “hack” work though.

Miriam Suzanne has been creating some fantastic content around container queries. The capabilities have been changing a bunch. That’s the risk of living on the bleeding edge. One of her latest articles sums up the current status.

I’ll get this fixed soon. Following the spec is CRITICAL.

BTW, I’m kinda worried about how many videos & demos already rely on the “export” behavior. The yet-published code on main drops this requirement, so `import ‘/path/to/cqfill.js’` will be all that is needed.

— Jonathan Neal (@jon_neal) May 2, 2021

Although my original demo/hack didn’t work, we can still kinda use a “resize” hack to create those blinds. Again, we can query height if we use contain: layout size. Side note: it’s interesting how we’re currently unable to use contain to query a container’s height based on resizing its child elements.

Anyway. Consider this demo:

CodePen Embed Fallback

The arrow rotates as the container is resized. The trick here is to use a container query to update a scoped CSS custom property.

.container { contain: layout size; } .arrow { transform: rotate(var(--rotate, 0deg)); } @container(min-height: 200px) { .arrow { --rotate: 90deg; } }

We‘ve kinda got a container query trick here then. The drawback with not being able to use the first hack concept is that we can’t go completely 3D. Overflow hidden will stop that. We also need the cord to go beneath the window which means the windowsill would get in the way.

But, we can almost get there.

CodePen Embed Fallback

This demo uses a preprocessor to generate the container query steps. At each step, a scoped custom property gets updated. This reveals Peter and opens the blinds.

The trick here is to scale up the container to make the resize handle bigger. Then I scale down the content to fit back where it’s meant to.

This fun demo “debunking the meme” isn’t 100% there yet, but, we’re getting closer. Container queries are an exciting prospect. And it’ll be interesting to see how they change as browser support evolves. It’ll also be exciting to see how people push the limits with them or use them in different ways.

Who know? The “Resize Hack” might fit in nicely alongside the infamous “Checkbox Hack” one day.

The post Can We Create a “Resize Hack” With Container Queries? appeared first on CSS-Tricks.

You can support CSS-Tricks by being an MVP Supporter.

svg-loader: A Different Way to Work With External SVG

Css Tricks - Wed, 05/19/2021 - 4:28am

SVGs are awesome: they are small, look sharp on any scale, and can be customized without creating a separate file. However, there is something I feel is missing in web standards today: a way to include them as an external file that also retains the format’s customization powers.

For instance, let’s say you want to use your website’s logo stored as web-logo.svg. You can do:

<img src="/images/logo.svg" />

That’s fine if your logo is going to look the same everywhere. But in many cases, you have 2-3 variations of the same logo. Slack, for example, has two versions.

Even the colors in the main logo are slightly different.

If we had a way to customize fill color of our logo above, we could pass any arbitrary color to render all the variations.

Take the case of icons, too. You wouldn’t want to do something like this, would you?

<img src="/icons/heart-blue.svg" /> <img src="/icons/heart-red.svg" /> Load external SVGs as inline elements

To address this, I have created a library called svg-loader. Simply put, it fetches the SVG files via XHR and loads them as inline elements, allowing you to customize the properties like fill and stroke, just like inline SVGs.

For example, I have a logo on my side-project, SVGBox. Instead of creating a different file for every variation, I can have one file and customize the fill color:

CodePen Embed Fallback

I used data-src to set the URL of SVG file. The fill attribute overrides fill of the original SVG file.

To use the library, the only thing I have to ensure is that files being served have appropriate CORS headers for XHRs to succeed. The library also caches the files locally, making the subsequent much faster. Even for the first load, the performance is comparable to using <img> tags.

This concept isn’t new. svg-inject does something similar. However, svg-loader is easier to use as we only have to include the library somewhere in your code (either via a <script> tag, or in the JavaScript bundle). No extra code is needed.

Dynamically-added elements and change in attributes are also handled automatically, which ensures that it works with all web frameworks. Here’s an example in React:

But why?

This approach may feel unorthodox because it introduces a JavaScript dependency and there are already multiple ways to use SVGs, including inline and from external sources. But there’s a good case for using SVGs this way. Let’s examine them by answering the common questions.

Can we not just inline SVG ourselves?

Inlining is the simplest way to use SVGs. Just copy and paste the SVG code in the HTML. That’s what svg-loader is ultimately doing. So, why add the extra steps to load a SVG file from somewhere else? There are two major reasons:

  1. Inline SVGs make the code verbose: SVGs can be anywhere from a few lines to a few hundred. Inline SVGs can work well if what you need is just a couple of icons and they are all tiny. But it becomes a major pain if they are sizeable or many, because then, they become long strings of text in code that isn’t “business logic.” The code becomes hard to parse.

    It’s the same thing as preferring an external stylesheet over a <style> tag or using images instead of data URIs. It’s no wonder that in React codebases, the preferred approach is to use SVG as a separate component, rather than define it as a part of JSX.
  1. External SVGs are much more convenient: Copying and pasting often does the job, but external SVGs can be really convenient. Say you’re experimenting with which icon to use in your app. If you’re using inline SVGs, that means going back and forth to get the SVG code. But with external SVGs, you only have to know the name of the file.

    Take a look at this example. One of the most extensive icon repository on GitHub is Material Design Icons. With svg-loader and unpkg, we can start using any of 5,000+ icons right away.
CodePen Embed Fallback Isn’t it inefficient to trigger an HTTP request for every SVG versus making a sprite?

Not really. With HTTP2, the cost of making an HTTP request has become less relevant. Yes, there are still benefits of bundling (e.g., better compression), but for non-blocking resources and XHRs, the pros are almost non-existent in real-world scenarios.

Here’s a Pen loading 50 icons in a similar fashion as above. (Open in incognito mode as the files are cached by default):

CodePen Embed Fallback What about <use> tag (SVG symbols)?

SVG symbols separate the definition of the SVG file from its use. Instead of defining the SVG everywhere, we can have something like this:

<svg> <use xlink:href="#heart-icon" /> </svg>

The problem is that none of the browsers support using symbols files hosted on a third-party domain. Therefore, we can’t do something like this:

<svg> <use xlink:href="https://icons.com/symbols.svg#heart-icon" /> </svg>

Safari doesn’t even support symbols files hosted on the same domain.

Can we not use a build tool that inlines the SVGs?

I couldn’t find an obvious way to fetch SVGs from a URL and inline them in common bundlers, like webpack and Grunt, although they exist for inlining SVG files stored locally. Even if a plugin that does this exists, setting up bundlers isn’t exactly straightforward. In fact, I often avoid using them until the project has reached acertain level of complexity. We must also realize that a majority of the internet is alien to things like webpack and React. Simple scripts can have a much wider appeal.

What about the <object> tag?

The <object> tag is a native way to include external SVG files that work across all the browsers.:

<object data="https://unpkg.com/mdi-svg@2.2.43/svg/access-point-network.svg" width="32" height="32"></object>

However, the drawback is we’re unable to customize the SVG’s attributes unless it’s hosted on the same domain (and the <object> tag doesn’t respect CORS headers). Even if the file is hosted on the same domain, we’d require JavaScript to manipulate the fill, like this:

<object data="https://unpkg.com/mdi-svg@2.2.43/svg/access-point-network.svg" width="32" height="32" onload="this.contentDocument.querySelector('svg').fill = 'red'"></object>

In short, using external SVG files this way makes it ultra-convenient to use icons and other SVG assets. As covered earlier, with unpkg, we can use any icon on GitHub without needing extra code. We can avoid creating a pipeline in a bundler to process SVG files or a component for every icon, and just host the icons on a CDN.

Loading SVG files this way packs a lot of benefits with very little cost.

The post svg-loader: A Different Way to Work With External SVG appeared first on CSS-Tricks.

You can support CSS-Tricks by being an MVP Supporter.

Pinned Audio WordPress Theme

Css Tricks - Tue, 05/18/2021 - 9:14am

I’m afraid I have to start this with a whole backstory, as the journey here is the point, not so much the theme.

A fella wrote to me a while back outlining a situation he was in. His company has a bunch of WordPress sites for public radio, many of which are essentially homes for podcasts. There is one specific bit of functionality he thought would be ideal for them all: to have a “pinned” audio player. Like you could play a podcast, then continue navigating around the site without that podcast stopping.

This is somewhat tricky to pull off in WordPress, because WordPress does full page reloads like any other regular website not doing anything special with link handling or history manipulation. When a page reloads, any audio on the page stops playing. That’s just how the web works.

So how would you pull it off on a WordPress site? Well, you could make it a headless WordPress site and rebuild the entire front-end as a Single Page App. Sounds fun to me, but I’d be hesitant to make that call just for this one thing.

What else could you do? You could find a way to make the page never reload. I remember doing this on a little static site 10 years ago, but that wasn’t a full blown WordPress site and I didn’t even bother updating the URL back then.

What if you did this…

  1. Intercept internal link clicks
  2. Ajax’d the content from that URL
  3. Replaced the content on the page with that new content

I’ll do this in jQuery quick for ya:

$("a").on("click", () => { const url = $(this).attr("href"); $.get(url + " main", (data) => { $("main").html(data); history.pushState({}, "", url); }); });

That’s not far off from being literally functional. You’d wanna watch for a popstate event to deal with the back button, but that’s only a few more lines.

In this hypothetical world, you’d lay out the site like:

<html> <!-- ... --> <body> <main></main> <audio src="" controls ...></audio> </body> </html>

So all that <main> content gets swapped out, the URL changes, but your <audio> player is left alone to keep playing in peace. You’d write more JavaScript to give people a way to update what podcast is playing and such.

Turns out there is more to think about here though. Are any inline scripts on the content going to run? What about updating the <title> too? There are enough edge concerns you probably will get annoyed dealing with it.

I wanted to have a play with this stuff, so I tossed together a WordPress theme and reached for Turbo instead of hand-writing something. Turbo (the new version of Turbolinks) is designed just for this. It’s a JavaScript library you drop on the page (no build process, no config) and it just works. It intercepts internal link clicks, Ajax’s for new content, etc. But it has this interesting feature where if you put a data-turbo-permanent attribute on an HTML element, it will persist it across that reload. So I did that for the audio player here.

Here’s the thing though.

I just don’t have time to finish this project properly. It was fun to have a play, but my interest in it has kinda petered out. So I’ll leave it alone for now:

Live Demo GitHub Repo

It almost works, minus one glaring bug that the audio stops playing on the first navigation, then works after that. I’m sure it’s fixable, but I just don’t have much skin in this game. I figure I’ll just bow out and leave this code around for someone to pick up if it’s useful for them.

Another thing at play here is that Turbo is from Basecamp, and Basecamp has rather imploded recently making it not feel great to be using their software. Exacerbated by the fact that Sam Stephenson wrote 75% of Turbo and has said he won’t be touching it (or other related projects) unless the software is moved to its own foundation. Turbo was already in a shaky place since it seemed buggy compared to Turbolinks, and now is on very gnarly ground.

The post Pinned Audio WordPress Theme appeared first on CSS-Tricks.

You can support CSS-Tricks by being an MVP Supporter.

A Love Letter to HTML & CSS

Css Tricks - Mon, 05/17/2021 - 4:27am

Ashley Kolodziej — May 2021

Dear HTML & CSS

I see you.

In the back there, behind JavaScript and React and PHP and all those “real” programming languages, I see you. And I appreciate you.

I’ve seen the YouTube videos. You’ve been condensed down to a sixty-second blip on the path to bigger and better things, a one-trick div pony at the back of the race. You’re a support character. Everyone knows HTML these days. Even if that’s not the case, it’s not hard to learn, they say.

I know it’s not true.

You are the foundation of the Internet. You are the bridge between humans and information. When we say HTML isn’t an expertise in and of itself, when we take you for granted, we leave behind the people and systems who access that information using web crawlers and accessibility technology.

They say you’re not a real programming language like the others, that you’re just markup, and technically speaking, I suppose that’s right. Technically speaking, JavaScript and PHP are scripting languages. I remember when it wasn’t cool to know JavaScript, when it wasn’t a “real” language too. Sometimes, I feel like these distinctions are meaningless, like we built a vocabulary to hold you (and by extension, ourselves as developers) back. You, as a markup language, have your own unique value and strengths. Knowing how to work with you best is a true expertise, one that is too often overlooked.

Markup requires systematic thinking. What structure is the best match for this content? How can we make this content easier to discover and parse in the right order? What tags do we need to ensure a screen reader will parse your information correctly? I want you to know I know how important you are, and I still ask these questions.

I think of you every time I test a website in VoiceOver and discover it is completely unusable, with my keyboard’s focus jumping away to places I can’t actually interact with and no clear sectioning and headings to help navigate.

And to my longtime friend, CSS. I want you to know I understand you are so much more than just a pretty face. Sure, your main job is to, well, style markup. But why should that be any less celebrated than the other languages? You are the visual translation of information. What good is all the information in the world if we can’t easily understand it? You hold the keys to hierarchy and contrast and layout, the keys to visual communication.

Your language is an art. I recognize your importance, the balance of performance in rendering and specificity and predicting when and where other systems or designers might want to override something. Sure, you style, and you style well. But what the world forgets sometimes is you are, at heart, a planner: the cascading part of Cascading Style Sheets. Oh, to be JavaScript where you can do whatever you want, whenever you want, and change markup and styles on the fly. Don’t they know inline styles are some of the most specific styles around?

I know, and I respect that. There is a time and place for specificity, and I cherish your ability to manage that. I love your system of overrides, of thinking ahead to what should and shouldn’t be modifiable by another developer easily. I find the appreciation of specificity and !important and contrast and all the beautiful little things you do well increasingly lost in the pursuit of the newest and shiniest frameworks.

But I am still here for you, HTML and CSS. And I will continue to show everyone I can how much you both have to offer. Because without that foundational care and expertise, we wouldn’t be able to communicate this information at all. You are the languages at the core of equitable information distribution, and I want you to know that even if you aren’t in the spotlight right now, I remember that.

Even if it sometimes feels I’m the only person out there who still does.

With love, Ashley Kolodziej const paths = document.querySelectorAll('#Layer_1 path'); let xx = 0; function recursiveCursive( path ) { const animateTo = path.getTotalLength(); path.style.strokeDasharray = animateTo; path.style.strokeDashoffset = -animateTo; path.ontransitionend = () => { xx++; if( undefined !== paths[xx] ) { recursiveCursive( paths[xx] ); } }; } const checkHandwriting = function (entries) { const [entry] = entries; if ( entry.isIntersecting ) { recursiveCursive(paths[xx]); observer.unobserve(handwriting); } }; let observer = new IntersectionObserver(checkHandwriting, { threshold: 0.5 }); let handwriting = document.querySelector('#Layer_1'); observer.observe(handwriting);

The post A Love Letter to HTML & CSS appeared first on CSS-Tricks.

You can support CSS-Tricks by being an MVP Supporter.

DevTools for CSS layouts 2021 edition

Css Tricks - Thu, 05/13/2021 - 1:22pm

Chen Hui Jing covers some recent movement in DevTools:

Firefox’s grid inspector was pretty full-featured from the get-to and released together with CSS grid in Firefox 52. It was constantly improved upon since. Chrome added a basic grid inspector tool in Chrome 62 that let developers highlight elements using grid layout, but more robust features were only added in Chrome 87. And now, Webkit [sic] has joined the party, as Safari Technology Preview 123 adds Grid inspecting features as well.

You love to see it. DevTools have a massive impact on how front-end developers think about, build, and of course, debug websites. Stuff like seeing the numbered grid lines visually is a huge deal. I’ve done enough mentally counting what rows/columns I want to place things on, thank you very much.

Direct Link to ArticlePermalink

The post DevTools for CSS layouts 2021 edition appeared first on CSS-Tricks.

You can support CSS-Tricks by being an MVP Supporter.

DevTools for CSS layouts 2021 edition

Css Tricks - Thu, 05/13/2021 - 1:22pm

Chen Hui Jing covers some recent movement in DevTools:

Firefox’s grid inspector was pretty full-featured from the get-to and released together with CSS grid in Firefox 52. It was constantly improved upon since. Chrome added a basic grid inspector tool in Chrome 62 that let developers highlight elements using grid layout, but more robust features were only added in Chrome 87. And now, Webkit [sic] has joined the party, as Safari Technology Preview 123 adds Grid inspecting features as well.

You love to see it. DevTools have a massive impact on how front-end developers think about, build, and of course, debug websites. Stuff like seeing the numbered grid lines visually is a huge deal. I’ve done enough mentally counting what rows/columns I want to place things on, thank you very much.

Direct Link to ArticlePermalink

The post DevTools for CSS layouts 2021 edition appeared first on CSS-Tricks.

You can support CSS-Tricks by being an MVP Supporter.

Syndicate content
©2003 - Present Akamai Design & Development.