Developer News

Reactive jQuery for Spaghetti-fied Legacy Codebases (or When You Can’t Have Nice Things)

Css Tricks - Wed, 07/22/2020 - 4:50am

I can hear you crying out now: “Why on Earth would you want to use jQuery when there are much better tools available? Madness! What sort of maniac are you?” These are reasonable questions, and I’ll answer them with a little bit of context.

In my current job, I am responsible for the care and feeding of a legacy website. It’s old. The front-end relies on jQuery, and like most old legacy systems, it’s not in the best shape. That alone isn’t the worst, but I’m working with additional constraints. For example, we’re working on a full rewrite of the system, so massive refactoring work isn’t being approved, and I’m also not permitted to add new dependencies to the existing system without a full security review, which historically can take up to a year. Effectively, jQuery is the only JavaScript library I can use, since it’s already there. 

My company has only recently come to realize that front-end developers might have important skills to contribute, so the entire front end of the app was written by developers unaware of best practices, and often contemptuous of their assignment. As a result, the code quality is wildly uneven and quite poor and unidiomatic overall.

Yeah, I work in that legacy codebase: quintessential jQuery spaghetti.

Someone has to do it, and since there will always be more legacy code in the world than greenfield projects, there will always be lots of us. I don’t want your sympathy, either. Dealing with this stuff, learning to cope with front-end spaghetti on such a massive scale has made me a better, if crankier, developer.

So how do you know if you’ve got spaghetti jQuery on your hands? One reliable code smell I’ve found is a lack of the venerable old .toggle(). If you’ve managed to successfully not think about jQuery for a while, it is a library that smooths cross-browser compatibility issues while also making DOM queries and mutations incredibly easy. There’s nothing inherently wrong with that, but direct DOM manipulation can be very hard to scale if you’re not careful. The more DOM-manipulation you write, the more defensive against DOM mutation you become. Eventually, you can find yourself with an entire codebase written that way and, combined with less-than-ideal scope management, you are essentially working in an app where all of the state is in the DOM and you can never trust what state the DOM will be in when you need to make changes; changes could swoop in from anywhere in your app whether you like it or not. Your code gets more procedural, bloating things up with more explicit instructions, trying to pull all the data you need from the DOM itself and force it into the state you need it to be in.

This is why .toggle() is often the first thing to go: if you can’t be sure whether an element is visible or not, you have to use .show() and .hide() instead. I’m not saying .show() and .hide() should be Considered Harmful™, but I’ve found they’re a good indication that there might be bigger problems afoot.

What can you do to combat this? One solution my coworkers and I have found takes a hint directly from the reactive frameworks we’d rather be using: observables and state management. We’ve all found that hand-rolling state objects and event-driven update functions while treating our DOM like a one-way dataflow template leads to more predictable results that are easier to change over time.

We each approach the problem a little differently. My take on reactive jQuery is distinctly flavored like Vue drop-in and takes advantage of some “advanced” CSS.

CodePen Embed Fallback

If you check out the script, you’ll see there are two different things happening. First, we have a State object that holds all of the values for our page, and we have a big mess of events.

var State = { num: 0, firstName: "", lastName: "", titleColor: "black", updateState: function(key, value){ this[key] = value; $("[data-text]").each(function(index, elem){ var tag = $(elem).attr("data-tag"); $(elem).text(State[tag]); }); $("[data-color]").each(function(index, elem){ var tag = $(elem).attr("data-tag"); $(elem).attr("data-color", State[tag]); }); } };

I’ll admit it, I love custom HTML attributes, and I’ve applied them liberally throughout my solution. I’ve never liked how HTML classes often do double-duty as CSS hooks and JavaScript hooks, and how if you use a class for both purposes at once, you’ve introduced brittleness into your script. This problem goes away completely with HTML attributes. Classes become classes again, and the attributes become whatever metadata or styling hook I need.

If you look at the HTML, you’ll find that every element in the DOM that needs to display data has a data-tag attribute with a value that corresponds to a property in the State object that contains the data to be displayed, and an attribute with no value that describes the sort of transformation that needs to happen to the element it’s applied to. This example has two different sorts of transformations, text and color.

<h1 data-tag="titleColor" data-color>jDux is super cool!</h1>

On to the events. Every change we want to make to our data is fired by an event. In the script, you’ll find every event we’re concerned about listed with its own .on() method. Every event triggers an update method and sends two pieces of information: which property in the State object that needs to be updated, and the new value it should be set to.

$("#inc").on("click", function(){ State.updateState("num", State.num + 1) }); $("#dec").on("click", function(){ State.updateState("num", State.num - 1) }); $("#firstNameInput").on("input", function(){ State.updateState("firstName", $(this).val() ) }); $("#lastNameInput").on("input", function(){ State.updateState("lastName", $(this).val() ) }); $('[class^=button]').on("click", function(e) { State.updateState('titleColor', e.target.innerText); });

This brings us to State.updateState(), the update function that keeps your page in sync with your state object. Every time it runs, it updates all the tagged values on the page. It’s not the most efficient thing to redo everything on the page every time, but it’s a lot simpler, and as I hope I’ve already made clear, this is an imperfect solution for an imperfect codebase.

$(document).ready(function(){ State.updateState(); });

The first thing the update function does is update the value according to the property it receives. Then it runs the two transformations I mentioned. For text elements, it makes a list of all data-text nodes, grabs their data-tag value, and sets the text to whatever is in the tagged property. Color works a little differently, setting the data-color attribute to the value of the tagged property, and then relies on the CSS, which styles the data-color properties to show the correct style.

I’ve also added a document.ready, so we can run the update function on load and display our default values. You can pull default values from the DOM, or an AJAX call, or just load the State object with them already entered as I’ve done here.

And that’s it! All we do is keep the state in the JavaScript, observe our events, and react to changes as they happen. Simple, right?

What’s the benefit here? Working with a pattern like this maintains a single source of truth in your state object that you control, you can trust and you can enforce. If you ever lose trust that your DOM is correct, all you need to do is re-run the update function with no arguments and your values become consistent with the state object again.

Is this kind of hokey and primitive? Absolutely. Would you want to build an entire system out of this? Certainly not. If you have better tools available to you, you should use them. But if you’re in a highly restrictive legacy codebase like I am, try writing your next feature with Reactive jQuery and see if it makes your code, and your life, simpler.

The post Reactive jQuery for Spaghetti-fied Legacy Codebases (or When You Can’t Have Nice Things) appeared first on CSS-Tricks.

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

What ya need there is a bit of templating

Css Tricks - Tue, 07/21/2020 - 2:23pm

I had a fella write in to me the other day. He had some HTML, CSS, and JavaScript, and it just wasn’t behaving like he thought it ought to. The HTML had some placeholders in it and the JavaScript had some data in it, and the assumption was that the data would fill the placeholders.

To those of us with some degree of web knowledge, we can look at this and see why it’s not working like he thought it would. But I think it’s also valuable to try to see things from that perspective and then look at solutions that are hopefully as simple as the original problem seems to be.

The HTML was something like this… <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <title>Test</title> <link rel="stylesheet" href="test.css"> <script src="data.js"></script> </head> <body> <section> <div>{company_name}</div> </section> </body> </html> The JavaScript was like this… var company_data = { "{company_name}" : "SOME COMPANY", }; There is nothing invalid going on here.

That’s all perfectly valid code. It is linked up right. It will run. It just doesn’t do anything besides render {company_name} to the screen. The expectation is that it would render SOME COMPANY to the screen instead, replacing the {company_name} placeholder with the data from the JavaScript file.

Let’s fix it with a one-liner.

In this exact scenario, to display the correct company name, we need to select that element in the DOM and replace its content with our data. We could do that by adding this one extra line to the JavaScript:

var company_data = { "{company_name}": "SOME COMPANY" }; document.querySelector("div").innerHTML = company_data["{company_name}"];

That’s not particularly re-usable or resiliant, but hey, it’s also not over-thinking or over-tooling it.

The expectation was templating

I think we can see at this point that what he hoped would happen is that this sort of templating would automatically happen. Provide an object with keys that match what is in the HTML, the content in that HTML is automatically swapped out. It just doesn’t work that way with raw web technologies.

No joke, there are hundreds of ways to go about handling this. Here’s a few off the top of my head:

  • Use a templating language like Handlebars or Mustache
  • Use a static site generator like Eleventy, which uses Liquid by default
  • Make an HTML <template> and write your own script to use it
  • Make a Web Component
  • Use a back-end language instead, or a language like Nunjucks to process ahead of time
  • Use a preprocessor like Pug

As a general preference, I’d say doing the templating server-side or during a build is ideal — why mess with the DOM if you don’t need to?

But just to ignore that advice for a second, here’s an example of doing it client-side with Handlebars, just so the fella from the original email has a working example of how that can work:

CodePen Embed Fallback

The post What ya need there is a bit of templating appeared first on CSS-Tricks.

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

Using Flexbox and text ellipsis together

Css Tricks - Tue, 07/21/2020 - 12:19pm

You can truncate a single line of text with an ellipsis (…) fairly easily with text-overflow and a few friends. But, as you might expect, that truncation happens at the end of the line of text. What if you want to truncate content in the middle?

Leonardo Faria details good use cases for this, like in an operating system window listing files. The line of text is a file name and a file extension. When that line truncates, it truncates just the name, always leaving the extension at the end. The trick is a flexbox parent so you can use overflow on just the file name part, but have to make sure to reset the min-width, as the natural value there is min-content, which prevents the truncation which is confusing.

CodePen Embed Fallback

Direct Link to ArticlePermalink

The post Using Flexbox and text ellipsis together appeared first on CSS-Tricks.

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

marketstack: A Market Data API

Css Tricks - Tue, 07/21/2020 - 4:46am

(This is a sponsored post.)

I like the apilayer company tagline: “Automate What Should Be Automated.” They have this thick suite of products that are all APIs with clear documentation. They all have usable free tiers to develop against and prove out an idea, and then paid plans if you need to start using the APIs more aggressively. They have a brand new one: marketstack.

With this API, you have access to stock market data both current and historical. Got an idea for an app (or business!) that needs stock data? Wanna chart out how Apple is doing? Hit the REST API with your key and the AAPL stock symbol and you’ll get back just the JSON data you need. If you’ve always wanted to build a stock market app, this totally opens that door.

That’s what I love about stuff like this. I’ve seen so many people with startup ideas, but then end up being limited by the fact that they just don’t have the data they need to make it actually useful. So many business ideas are really founded on what kind of data you have access to. APIs like marketstack open those doors in affordable ways to everyone.

I think picking out technology stacks is fun, even just to think about. Like doesn’t it sound fun to build an Electron app with something like Electron Forge so you have a React+webpack setup, then hit the marketstack API for interesting market data and use nivo to build charts, chucking whatever data you need to save into Fauna?

Direct Link to ArticlePermalink

The post marketstack: A Market Data API appeared first on CSS-Tricks.

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

When do you use inline-block?

Css Tricks - Mon, 07/20/2020 - 11:08am

The inline-block value for display is a classic! It’s not new and browser support is certainly not something you need to worry about. I’m sure many of us reach for it intuitively. But let’s put a point on it. What is it actually useful for? When do you pick it over other, perhaps similar, options?

(I bet this makes for interesting replies.)

What is the last thing you used `display: inline-block` for?

— Chris Coyier (@chriscoyier) June 19, 2020 Buttons

The most common answer I heard was: I always use it on buttons.

Ultimately, I think that makes sense, but it contributes to a what I see as a slight misunderstanding. The idea is that you want elements that look like buttons (which might be crafted with <a>, <button>, or perhaps <input>) to lay inline — like they do naturally — but be able to have margin and padding. That’s the slight misunderstanding part: display: inline; elements can still have margin and padding, and it probably behaves like you expect it to.

The tricky part is that:

  • The block-direction margin on inline elements is ignored entirely
  • The padding on inline elements doesn’t affect the height of the line of text

So, while the buttons themselves are pretty much styled just fine, the parent element and surrounding text probably isn’t. Here’s a demo that:

The padding from the inline buttons breaks them out of the container, which is a little weird.

Things get worse when wrapping starts to happen with inline buttons:

So yeah, inline-block makes pretty good sense on buttons I’d say. But…

Don’t forget inline-flex and inline-grid

With the display values inline-flex and inline-grid, you’ll get all the same good behavior that you will from inline-block, but the elements (often buttons) can benefit from a stronger inline layout system.

Take the example of buttons-with-icons, like this:

<a href="#" class="button> <svg> ... </svg> Text </a>

To get the text and icon aligned perfectly in the center, it’s tempting to do like:

.button svg { vertical-align: middle; }

Which never gets it quite right…

Those icons are sitting a pixel or two too low from center, at least to my eye.

But this is an easy fix with inline-flex:

.button { display: inline-flex; align-items: center; } Perfectly aligned icons (and someday we’ll be able to size using lh units nicely!)

With inline-flex or inline-grid, you have all the power of a flexbox or grid layout system within a block that lays out in the inline direction.

Blocks that can still wrap

An inline-block elements will respect a width. That’s another difference between them and straight-up inline elements. People used to¹ build column layout systems with inline-block, because it basically can do what floats could do here, except without the need to worry about clearing the float², allowing people to take advantage of wrapping which happens a bit more elegantly than float.

The idea of inline-blocks behaving like columns that can wrap (even down to 1 column) lives on to this day because it’s a trick that can be used in HTML emails to allow for multi-column layouts that collapse to single-column on small screens without the need for media queries (which some email clients don’t support).

Yesterday in an HTML email, on divs that wrap tables, to allow for responsive columns without media queries

— Dan Denney (@dandenney) June 19, 2020

Dan’s example.

transform on an inline element

Inline elements can’t take a transform. So if you need that, it’ll need to be inline-block.

CodePen Embed Fallback Column children that don’t break in the middle of themselves

CSS columns can be used on paragraphs of text where you don’t really care if any given paragraph breaks across columns. But sometimes CSS columns are used for blocks where that would be awkward. Say the blocks have their own backgrounds and padding. The breaks are pretty weird visually.

This is a weird trick that I can’t say I 100% understand, but if you toss display: inline-block; on those boxes (and probably width: 100%; to make sure they stay column-width), then they won’t break and the padding is preserved.

Demo Quick way to make a list go horizontal

This was another mega-popular answer to my original tweet. List elements stack list items vertically, like block-level elements. They aren’t actually blocks. They are display: list-item;, which is actually somewhat important here, as we’ll see. The popular use case is “when I want to lay out a list horizontally”.

So you’ve got a list…

<ul> <li>Three</li> <li>Little</li> <li>Piggies</li> </ul>

You wanna knock it over in a row instead, you can…

li { display: inline-block; }

And you got it.

I took a quick listen in VoiceOver and the inline-block list still announces the element as a list, but doesn’t speak the bullet points, which makes sense as they aren’t there. That’s the thing with changing the display of the list items themselves away from list-item: they lose their, ahem, list-item-y-ness.

An alternative would be to make the parent a flexbox container…

ul { display: flex; }

…which achieves the horizontal row thing (the flexbox default), but leaves the bullets as you aren’t changing the display of the list items themselves. It’s on you to manually remove that if you want.

Demo Centered lists

Speaking of lists, Jeff Starr just blogged about the idea of lists within centered text, which can get awkward as well. The awkwardness is that the text inside the list items can be centered, but the list item itself is still full-width, creating this situation where the bullet stays aligned to the left.

Jeff’s solution was to inline-block the whole list. That keeps the list only as wide as the natural width of the content, allowing the bullets to leave the left edge and travel with the centered content. As long as there are block-level elements before and after, that is a good solution.

By way of an alternative, if the goal is to shrink the width of the list to the width of the content, that could also be achieved like this without stopping the list from being block-level:

ul { width: max-content; margin: 0 auto; text-align: left; }
  1. There is another tricky thing with inline-block. Like inline elements, any whitespace between them essentially renders as a space. So two 50% wide `inline-block` elements won’t fit on a line if there is any whitespace between them. Good thing there are tricks to fix that.
  2. I say “used to” because, if you were going to make a column system today, you’d almost certainly use flexbox or grid — or not build a “system” at all because just using the syntax of these largely negates the need for a system in the first place.

The post When do you use inline-block? appeared first on CSS-Tricks.

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

Levels of Fix

Css Tricks - Mon, 07/20/2020 - 10:33am

On the web, we have the opportunity to do work that fixes things for people. It’s fascinating to me how different the scope of those fixes can be.

Consider the media query prefers-reduced-motion. Eric wrote:

I think it’s also worth pointing out the true value prefers-reduced-motion represents: Not attracting buzzword-hungry recruiters on LinkedIn, but improving the quality of life for the people who benefit from the effect it creates. Using this media query could spare someone from having to unnecessarily endure a tremendous amount of pain for simply having the curiosity to click on a link or scroll down a page.

The use of this media query is exclusively to make people’s experience on the web better. We can write code that reduces motion for users who have explicitly asked for reduced motion.

It’s worth noting that because people ask for reduced motion doesn’t mean they are asking for absolutely zero motion. But let’s set that aside for a moment. It’s probably better to err toward zero if you aren’t prepared to do the nuanced work of figuring out what level of reduction is best for your users.

So let’s say we’re going to nuke all motion for a site. We could do this:

@media (prefers-reduced-motion: reduce), (update: slow) { *, ::before, ::after { animation-delay: -1ms !important; animation-duration: 1ms !important; animation-iteration-count: 1 !important; background-attachment: initial !important; scroll-behavior: auto !important; transition-duration: 0s !important; transition-delay: 0s !important; } }

By doing that, we fix the site for all users who prefer less motion for all of those users, for one site. That’s one scope we can hit.

Another thing we could do as a web worker is build a browser extension. Miraculously, the web has a standardized format for extensions, so you can largely write it once and ship the thing to any desktop browser. When you build an extension, you can’t really force anyone to use it, and chances are that a very low percentage of people visiting your site will have it installed, even less so of those who could benefit from it. But for those that do, you’ve fixed not just one site but all sites for that one person. That’s a very different but also very interesting and powerful scope.

It’s no wonder then that some people are drawn to working on the browsers themselves. Or for the standards organizations that guide that work. I’m not saying that browsers should or would implement something like forced reduced motion at the CSS level, but they could. And if you fix something at the browsers or standards level, you might just fix something for all sites for all users, which is the biggest scope there is.

It’s these different scopes that are so interesting to me:

  • Fixing one site for all users
  • Fixing all sites for one user
  • Fixing all sites for all users

You don’t have to just pick just one. Most of us probably do most of our work in that first bucket. But it’s worth thinking about if any of your work could go towards the others.

The post Levels of Fix appeared first on CSS-Tricks.

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

How to Italicize Text

Css Tricks - Fri, 07/17/2020 - 12:16pm

HTML and CSS offer us the ability to italicize text. I’m talking about text like this. Let’s cover everything you’ll need to know.

What is italic text and why would you italicize text?

You italicize text most often to call attention to it. Literally to emphasize a word, so that someone reading the sentence will give that word or phrase some extra oomph, as you might intend as the writer. Or, it might be following a particular style guide, like italicizing the title of something, say a published article.

Use the <em> tag

The “em” in <em> literally stands for emphasis. Browsers will, by default, make italicize text that is wrapped in HTML <em> tags.

<p> That was a <em>wonderful</em> party, Bebe. </p>

Imagine the sound of that sentence, where the reader is emphasizing that word giving the sentence a different feel that if they didn’t.

Use the <i> tag

The <i> element is to apply italics to text without implying emphasis. It’s to visually set some text apart from other text without implying that a reader is applying extra weight to those words. Perhaps something like:

<p><i>Miranda thought:</i> What an interesting metaphor on the global economy.</p> <p><i>Chris thought:</i> Is that mustard?</p> What’s the difference between <i> and <em>?

One more time:

  • <em> is for emphasis
  • <i> is for italic text without the emphasis

If you’re tempted to use <i> for the title of something, like:

<p> The book <!-- Not the end of the world, but... --> <i>Mr. Penumbra's 24-Hour Bookstore</i> is good. </p> <p> The book <!-- ...this is more semantically correct. --> <cite>Mr. Penumbra's 24-Hour Bookstore</cite> is good. </p>

Fortunately browsers italicize content wrapped in <cite> tags, just like <i> does, so no further work is required there if you’re citing a work (e.g. Moby Dick) or a publication (e.g. The New York Times).

Use your own HTML class and CSS

If the goal is set text apart visually, then we don’t have to reach for the <i> element. Spans have no semantic meaning and can be styled for visual emphasis:

<p> Shoes are <span class="emphasis">on sale</span> this week! </p> .emphasis { background: lightyellow; font-style: italic; }

The CSS property font-style is the one you need for making text italic, which you can apply to any selector you like.

Watch out for “Faux Italic”

Not all fonts have italicized characters. Or, you might be in a situation where the italic version of the font isn’t loaded. In either case, the browser will try to fake it anyway, which almost always looks awful (or at least much worse than using an actual italic font). 

Nothing is going to warn you about this — you kinda just need an eye for it. Here’s an example of the font Merriweather in faux italic:

CodePen Embed Fallback Unicode italics

There are a zillion characters available in Unicode, including letters that have an italic vibe.

CodePen Embed Fallback

You might use this when you don’t have HTML control to do things like italics like, say, on Twitter when composing a tweet.

The accessibility of this is awful. It will reach each character individually, making it (presumably, to me) hard to understand the word. Be very careful when using this, if you e even use it all.

Italics in variable fonts

This is a bit of an advanced concept, but there are things called variable fonts. They offer customization right in the browser. So rather than a second font file for the bold version, they have information in them to bold themselves with that one file. But “bold” is just an example of what a variable font might offer. Not all of them necessarily do.

A variable font might have a “slant” or “italic” option and you could apply that look that way.

v-fonts.com

There it is, five different answers to the question of when to italicize text. Hopefully this also helps with the next logical question: Which method should I use?

The post How to Italicize Text appeared first on CSS-Tricks.

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

How to Italicize Text

Css Tricks - Fri, 07/17/2020 - 12:16pm

HTML and CSS offer us the ability to italicize text. I’m talking about text like this. Let’s cover everything you’ll need to know.

What is italic text and why would you italicize text?

You italicize text most often to call attention to it. Literally to emphasize a word, so that someone reading the sentence will give that word or phrase some extra oomph, as you might intend as the writer. Or, it might be following a particular style guide, like italicizing the title of something, say a published article.

Use the <em> tag

The “em” in <em> literally stands for emphasis. Browsers will, by default, make italicize text that is wrapped in HTML <em> tags.

<p> That was a <em>wonderful</em> party, Bebe. </p>

Imagine the sound of that sentence, where the reader is emphasizing that word giving the sentence a different feel that if they didn’t.

Use the <i> tag

The <i> element is to apply italics to text without implying emphasis. It’s to visually set some text apart from other text without implying that a reader is applying extra weight to those words. Perhaps something like:

<p><i>Miranda thought:</i> What an interesting metaphor on the global economy.</p> <p><i>Chris thought:</i> Is that mustard?</p> What’s the difference between <i> and <em>?

One more time:

  • <em> is for emphasis
  • <i> is for italic text without the emphasis

If you’re tempted to use <i> for the title of something, like:

<p> The book <!-- Not the end of the world, but... --> <i>Mr. Penumbra's 24-Hour Bookstore</i> is good. </p> <p> The book <!-- ...this is more semantically correct. --> <cite>Mr. Penumbra's 24-Hour Bookstore</cite> is good. </p>

Fortunately browsers italicize content wrapped in <cite> tags, just like <i> does, so no further work is required there if you’re citing a work (e.g. Moby Dick) or a publication (e.g. The New York Times).

Use your own HTML class and CSS

If the goal is set text apart visually, then we don’t have to reach for the <i> element. Spans have no semantic meaning and can be styled for visual emphasis:

<p> Shoes are <span class="emphasis">on sale</span> this week! </p> .emphasis { background: lightyellow; font-style: italic; }

The CSS property font-style is the one you need for making text italic, which you can apply to any selector you like.

Watch out for “Faux Italic”

Not all fonts have italicized characters. Or, you might be in a situation where the italic version of the font isn’t loaded. In either case, the browser will try to fake it anyway, which almost always looks awful (or at least much worse than using an actual italic font). 

Nothing is going to warn you about this — you kinda just need an eye for it. Here’s an example of the font Merriweather in faux italic:

CodePen Embed Fallback Unicode italics

There are a zillion characters available in Unicode, including letters that have an italic vibe.

CodePen Embed Fallback

You might use this when you don’t have HTML control to do things like italics like, say, on Twitter when composing a tweet.

The accessibility of this is awful. It will reach each character individually, making it (presumably, to me) hard to understand the word. Be very careful when using this, if you e even use it all.

Italics in variable fonts

This is a bit of an advanced concept, but there are things called variable fonts. They offer customization right in the browser. So rather than a second font file for the bold version, they have information in them to bold themselves with that one file. But “bold” is just an example of what a variable font might offer. Not all of them necessarily do.

A variable font might have a “slant” or “italic” option and you could apply that look that way.

v-fonts.com

There it is, five different answers to the question of when to italicize text. Hopefully this also helps with the next logical question: Which method should I use?

The post How to Italicize Text appeared first on CSS-Tricks.

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

CSS Painting Order

Css Tricks - Fri, 07/17/2020 - 9:42am

Usually, when I see terms like “painting order” or “stacking context” my brain will start to shut off and my eyes will gloss over. Not that my brain doesn’t normally shut off more often than not, but that’s another topic for another time.

Martin Robinson over at Igalia touches on these concepts using an example that’s pretty easy to grok, even for me. He starts with two boxes that overlap with negative margins.

Then he introduces a third box that’s a child of the green box. The green box is given a z-index of -1. As you might expect, both the green and yellow boxes stack below the blue box.

Here’s where my brain started melting. If the z-index of the green box stays the same at -1 but we give it’s child a massive value, say 1,000, things look… exactly the same.

I’m sure many of you can already guess (or simply flat out know) why the blue box stays on top, even though changing the yellow box’s z-index implies it should be on top instead, but I sure didn’t. Martin found the technical answer in the CSS2 specification buried deep down in Appendix E, which he graciously linked up — otherwise, I’m sure I’d never have found it.

We learn from the Appendix E that a stacking context is an atomically painted collection of page items. What does this mean? To put it simply, it means that things inside a stacking context are painted together, as a unit, and that items outside the stacking content will never be painted between them. Having an active z-index is one of the situations in CSS which triggers the creation of a stacking context. Is there a way we can adjust our example above so that the third element belongs to the same stacking context as the first two elements? The answer is that we must remove it from the stacking context created by the second element.

So, yeah. As long as the yellow box is a child of the green box, the two form a stacking context that the blue box has no part of. Getting yellow above blue requires removing it from blue’s stacking context.

That’s the crux of Martin’s post, but he takes it even further and it’s worth heading over there. If you do, you’ll see how stacking order leads to some bonafide CSS tricks.

It’s not the first time we’ve linked up proof that z-index is not a level playing field so I’m going to try to commit this to memory the next (and inevitable) time I wrestle with stacking elements.

Direct Link to ArticlePermalink

The post CSS Painting Order appeared first on CSS-Tricks.

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

CSS Painting Order

Css Tricks - Fri, 07/17/2020 - 9:42am

Usually, when I see terms like “painting order” or “stacking context” my brain will start to shut off and my eyes will gloss over. Not that my brain doesn’t normally shut off more often than not, but that’s another topic for another time.

Martin Robinson over at Igalia touches on these concepts using an example that’s pretty easy to grok, even for me. He starts with two boxes that overlap with negative margins.

<div class="blue box">1</div> <div class="green box">2</div>

Then he introduces a third box that’s a child of the green box. The green box is given a z-index of -1. As you might expect, both the green and yellow boxes stack below the blue box.

<div class="blue box">0</div> <div class="green box" style="position: relative; z-index: -1;">-1 <div class="yellow box">-1</div> </div>

Here’s where my brain started melting. If the z-index of the green box stays the same at -1 but we give it’s child a massive value, say 1,000, things look… exactly the same.

<div class="blue box">0</div> <div class="green box" style="position: relative; z-index: -1;">-1 <div class="yellow box" style="position: relative; z-index: 1000;">1000</div> </div>

I’m sure many of you can already guess (or simply flat out know) why the blue box stays on top, even though changing the yellow box’s z-index implies it should be on top instead, but I sure didn’t. Martin found the technical answer in the CSS2 specification buried deep down in Appendix E, which he graciously linked up — otherwise, I’m sure I’d never have found it.

We learn from the Appendix E that a stacking context is an atomically painted collection of page items. What does this mean? To put it simply, it means that things inside a stacking context are painted together, as a unit, and that items outside the stacking content will never be painted between them. Having an active z-index is one of the situations in CSS which triggers the creation of a stacking context. Is there a way we can adjust our example above so that the third element belongs to the same stacking context as the first two elements? The answer is that we must remove it from the stacking context created by the second element.

So, yeah. As long as the yellow box is a child of the green box, the two form a stacking context that the blue box has no part of. Getting yellow above blue requires removing it from green’s stacking context.

That’s the crux of Martin’s post, but he takes it even further and it’s worth heading over there. If you do, you’ll see how stacking order leads to some bonafide CSS tricks.

It’s not the first time we’ve linked up proof that z-index is not a level playing field so I’m going to try to commit this to memory the next (and inevitable) time I wrestle with stacking elements.

Direct Link to ArticlePermalink

The post CSS Painting Order appeared first on CSS-Tricks.

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

Develop, Preview, Test

Css Tricks - Fri, 07/17/2020 - 8:03am

Guillermo:

I want to make the case that prioritizing end-to-end (E2E) testing for the critical parts of your app will reduce risk and give you the best return. Further, I’ll show how you can adopt this methodology in mere minutes.

His test is:

  1. Spin up Puppeteer (Headless Chrome) and Chai
  2. Go to the homepage
  3. Test if the homepage has his name on it.

YES.

Just one super basic integration goes a long way. If your site spins up, returns a page, and renders stuff on it that you expect, a lot is going right. Then, once you have that, you can toss in a handful more where you navigate around a little and click some things. And, if it still works, you’re in pretty good shape.

I’ve had a little trouble with Cypress over the years, but you’ll probably have better luck than I did. Overall, I think it’s the nicest player in the integration test market.

Direct Link to ArticlePermalink

The post Develop, Preview, Test appeared first on CSS-Tricks.

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

Develop, Preview, Test

Css Tricks - Fri, 07/17/2020 - 8:03am

Guillermo:

I want to make the case that prioritizing end-to-end (E2E) testing for the critical parts of your app will reduce risk and give you the best return. Further, I’ll show how you can adopt this methodology in mere minutes.

His test is:

  1. Spin up Puppeteer (Headless Chrome) and Chai
  2. Go to the homepage
  3. Test if the homepage has his name on it.

YES.

Just one super basic integration goes a long way. If your site spins up, returns a page, and renders stuff on it that you expect, a lot is going right. Then, once you have that, you can toss in a handful more where you navigate around a little and click some things. And, if it still works, you’re in pretty good shape.

I’ve had a little trouble with Cypress over the years, but you’ll probably have better luck than I did. Overall, I think it’s the nicest player in the integration test market.

Direct Link to ArticlePermalink

The post Develop, Preview, Test appeared first on CSS-Tricks.

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

On dependency

Css Tricks - Thu, 07/16/2020 - 2:46pm

Rob Weychert:

But I can’t host your site or even my own site. I didn’t build the CMS. Other people made the hardware and software I use to generate and optimize images. Other people made the fonts. Other people standardized the digital formats for those images and fonts. I didn’t write the HTML and CSS specifications, nor the browsers that interpret them, nor the operating systems that run the browsers. I didn’t solder the circuit boards. And so on.

There is so much hardware and software behind a website to the extent that there is certainly no one person who understands it all. We build everything on each other’s shoulders. (Related: I, Website)

But we can exert some influence about what technology we choose to use. Rob has three major considerations:

  1. Complexity: How complex is it, who absorbs the cost of that complexity, and is that acceptable?
  2. Comprehensibility: Do I understand how it works, and if not, does that matter?
  3. Reliability: How consistently and for how long can I expect it to work?

I like that system. But even more, I like that he has a system at all. I bet most people don’t. That’s why “just npm install the problem away” is such a reliable conference joke.

Direct Link to ArticlePermalink

The post On dependency appeared first on CSS-Tricks.

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

On dependency

Css Tricks - Thu, 07/16/2020 - 2:46pm

Rob Weychert:

But I can’t host your site or even my own site. I didn’t build the CMS. Other people made the hardware and software I use to generate and optimize images. Other people made the fonts. Other people standardized the digital formats for those images and fonts. I didn’t write the HTML and CSS specifications, nor the browsers that interpret them, nor the operating systems that run the browsers. I didn’t solder the circuit boards. And so on.

There is so much hardware and software behind a website to the extent that there is certainly no one person who understands it all. We build everything on each other’s shoulders. (Related: I, Website)

But we can exert some influence about what technology we choose to use. Rob has three major considerations:

  1. Complexity: How complex is it, who absorbs the cost of that complexity, and is that acceptable?
  2. Comprehensibility: Do I understand how it works, and if not, does that matter?
  3. Reliability: How consistently and for how long can I expect it to work?

I like that system. But even more, I like that he has a system at all. I bet most people don’t. That’s why “just npm install the problem away” is such a reliable conference joke.

Direct Link to ArticlePermalink

The post On dependency appeared first on CSS-Tricks.

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

Backdrop Filter effect with CSS

Css Tricks - Thu, 07/16/2020 - 10:35am

I love these little posts where some tricky-looking design is solved by a single line of CSS using a little-known property. In this case, the design is a frosted glass effect and the CSS property is backdrop-filter.

The approach? Easy peasy:

.container { backdrop-filter: blur(10px); }

The comments in the post are worth looking into because they address cross-browser support. Coverage is actually pretty good. Caniuse shows 83% global coverage with Firefox (and, predictably, Internet Explorer) lacking support. One commenter offered a nice fallback, along with a small tweak that desaturates the effect:

.container { background: rgba(0,0,0,0.8); backdrop-filter: saturate(180%) blur(10px); }

Nice. But we can take it a little further by sprinkling @supports in there, as demonstrated in our background-filter Almanac entry:

.container { background: rgba(0,0,0,0.8); } @supports (-webkit-backdrop-filter: none) or (backdrop-filter: none) { .container { -webkit-backdrop-filter: blur(10px); backdrop-filter: blur(10px); } }

Notice the -webkit prefix in there. It’s still worth using it in production, though that’s not a big deal assuming you’re wired up with Autoprefixer. Here’s the demo from the Almanac:

CodePen Embed Fallback

OK, so maybe not the one-line solution it appeared to be. But hey, it’s cool that this sort of thing is relatively trivial in CSS.

Direct Link to ArticlePermalink

The post Backdrop Filter effect with CSS appeared first on CSS-Tricks.

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

Irregular-shaped Links with Subgrid

Css Tricks - Thu, 07/16/2020 - 4:44am

Michelle Barker covers a situation where you need offset rectangles part of a clickable area. The tricky part is having just the rectangles be clickable. That rules out using some parent element and making the whole larger encompassing rectangle clickable, which is a common (but equally tricky) pattern.

Kicking one rectangle outside the bounds of the linked one with absolute positioning could work, but Michelle takes a path here that lays everything out on a grid, then uses pointer-events to get the click areas just right. Feels more robust to me.

CodePen Embed Fallback

Yet another good example of why we need subgrid everywhere, stat.

Direct Link to ArticlePermalink

The post Irregular-shaped Links with Subgrid appeared first on CSS-Tricks.

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

Tradeoffs and Shifting Complexity

Css Tricks - Wed, 07/15/2020 - 1:37pm

This is a masterclass from Dave:

After you hit the wall of unremovable complexity, any “advances” are a shell game, making tradeoffs that get passed down to the user … you get “advances” by shifting where the complexity lives.

You don’t get free reductions in complexity. In CSS land, you don’t get to pick some styling strategy and have all your troubles go away. This is plenty of nuance here, but largely whatever technologies you pick, you’re just placing the complexity in different buckets.

CodePen Embed Fallback

The best we can hope for is picking buckets that feel the most comfortable and productive for us and our teams.

Direct Link to ArticlePermalink

The post Tradeoffs and Shifting Complexity appeared first on CSS-Tricks.

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

Making lil’ me

Css Tricks - Wed, 07/15/2020 - 9:09am

Cassie Evans made a lovely illustration of herself and then used Greensock to add a flourish of animations to polish it off. Cassie wrote a series of posts about how she did it:

In this post we’ll cover how to get values from the mouse movement and plug them into an animation. This is my favourite thing about SVG animation. Not mouse movement in particular, but interactivity. Exporting animation as an mp4 is cool and all. But you can’t play with it. Animating on the web opens up so many cool possibilities!

Speaking of combining great illustrations with impressive animations, Jhey Tompkins recently shared a bunch of tips he’s learned from building complex CSS illustrations. This first piece of advice? It takes time and have patience. I’m sure he needed all the patience in the world to pull off his animated Matryoshka dolls.

Direct Link to ArticlePermalink

The post Making lil’ me appeared first on CSS-Tricks.

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

Make Jamstack Slow? Challenge Accepted.

Css Tricks - Wed, 07/15/2020 - 4:46am

“Jamstack is slowwwww.” That’s not something you hear often, right? Especially, when one of the main selling points of Jamstack is performance. But yeah, it’s true that even a Jamstack site can suffer hits to performance just like any other site. 

Don’t think that by choosing Jamstack you no longer have to think about performance. Jamstack can be fast — really fast — but you have to make the right choices. Let’s see if we can spot some of the poor decisions that can lead to a “slow” Jamstack site.

To do that, we’re going to build a really slow Gatsby site. Seems strange right? Why would we intentionally do that!? It’s the sort of thing where, if we make it, then perhaps we can gain a better understanding of what affects Jamstack performance and how to avoid bottlenecks.

We will use continuous performance testing and Google Lighthouse to audit every change. This will highlight the importance of testing every code change. Our site will start with a top Lighthouse performance score of 100. From there, we will make changes until it scores a mere 17. It is easier to do than you might think!

Let’s get started!

Creating our Jamstack site

We are going to use Gatsby for our test site. Let’s start by installing the Gatsby CLI installed:

npm install -g gatsby-cli

We can up a new Gatsby site using this command:

gatsby new slow-jamstack

Let’s cd into the new slow-jamstack project directory and start the development server:

cd slow-jamstack gatsby develop

To add Lighthouse to the mix, we need a Gatsby production build. We can use Vercel to host the site, giving Lighthouse a way to runs its tests. That requires installing the Vercel command-line tool and logging in:

npm install -g vercel-cli vercel

This will create the site in Vercel and put it on a live server. Here’s the example I’ve already set up that we’ll use for testing.

We’ve gotta use Chrome to access directly from DevTools and run a performance audit. No surprise here, the default Gatsby site is fast:

A score of 100 is the fastest you can get. Let’s see what we can do to slow it down.

Slow CSS

CSS frameworks are great. They can do a lot of heavy lifting for you. When deciding on a CSS framework use one that is modular or employs CSS-in-JS so that the only CSS you need is what’s loaded.

But let’s make the bad decision to reach for an entire framework just to style a button component. In fact, let’s even grab the heaviest framework while we’re at it. These are the sizes of some popular frameworks:

FrameworkCSS Size (gzip)Bootstrap68kb (12kb)Bulma73kb (10kb)Foundation30kb (7kb)Milligram10kb (3kb)Pure17kb (4kb)SemanticUI146kb (20kb)UIKit33kb (6kb)

Alright, SemanticUI it is! The “right” way to load this framework would be to use a Sass or Less package, which would allow us to choose the parts of the framework we need. The wrong way would be to load all the CSS and JavaScript files in the <head> of the HTML. That’s what we’ll do with the full SemanticUI stylesheet. Plus, we’re going to link up jQuery because it’s a SemanticUI dependency.

We want these files to load in the head so let’s jump into the html.js file. This is not available in the src directory until we run a command to copy over the default from the cache:

cp .cache/default-html.js src/html.js

That gives us html.js in the src directory. Open it up and add the required stylesheet and scripts:

<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/semantic-ui@2.4.2/dist/semantic.css"></link> <script src="https://code.jquery.com/jquery-3.1.1.js"></script> <script src="https://cdn.jsdelivr.net/npm/semantic-ui@2.4.2/dist/semantic.js"></script>  

Now let’s push the changes straight to our production URL:

vercel --prod

OK, let’s view the audit…

Zoikes! A 33% reduction!

We have reduced the speed of the site down to a score of 66. Remember that we are not even using this framework at the moment. All we have done is load the files in the head and that reduced the performance score by one-third. Our Time to Interactive (TTI) jumped from a quick 1.9 seconds to a noticeable 4.9 seconds. And look at the possible savings we could get with from Lighthouse’s recommendations.

Slow marketing dependencies

Next, we are going to look at marketing tags and how these third-party scripts can affect performance. Let’s pretend we work with a marketing department and they want to start measuring traffic with Google Analytics. They also have a Facebook campaign and want to track it as well. 

They give us the details of the scripts that we need to add to get everything working. First, for Google Analytics:

<script async src="https://www.googletagmanager.com/gtag/js?id=UA-4369823-4"></script> <script   dangerouslySetInnerHTML={{ __html: `   window.dataLayer = window.dataLayer || [];   function gtag(){dataLayer.push(arguments);}   gtag('js', new Date());   gtag('config', 'UA-4369823-4');   `}} />

Then for the Facebook campaign:

<script   dangerouslySetInnerHTML={{ __html: `     !function(f,b,e,v,n,t,s)     {if(f.fbq)return;n=f.fbq=function(){n.callMethod?     n.callMethod.apply(n,arguments):n.queue.push(arguments)};     if(!f._fbq)f._fbq=n;n.push=n;n.loaded=!0;n.version='2.0';     n.queue=[];t=b.createElement(e);t.async=!0;     t.src=v;s=b.getElementsByTagName(e)[0];     s.parentNode.insertBefore(t,s)}(window, document,'script',     'https://connect.facebook.net/en_US/fbevents.js');     fbq('init', '3180830148641968');     fbq('track', 'PageView');     `}} /> <noscript><img height="1" width="1" src="https://www.facebook.com/tr?id=3180830148641968&ev=PageView&noscript=1"/></noscript>

We’ll place these scripts inside html.js, again in the <head> section, before the closing </head> tag.

Just like before, let’s push to Vercel and re-run Lighthouse:

vercel --prod

Wow, the site is already down to 51 and all we’ve done is tack on one framework and a couple of measly scripts. Together, they/ve reduced the score by a whopping 49 points, nearly half of where we started.

Slow images

We haven’t added any images to the site yet but we know we absolutely would in a real-life scenario. We are going to add 100 images to the page. Sure, 100 is a lot for a single page but, then again, we know that images are often the biggest culprits of bloated web pages so we might as well let them shine.

We’ll make things a little worse by hot loading the images directly from https://placeimg.com instead of serving them on our own server.

Let’s crack open index.js and drop this code in, which will loop through 100 instances of images:

const IndexPage = () => {   const items = []   for(var i = 0; i < 100; i++) {     const url = `http://placeimg.com/640/360/any?=${i}`     items.push(<img key={i} alt={i} src={url} />)   }      return (     <Layout>       // ...       {items}       // ...     </Layout>   ) }

The 100 images are all different and will all load as the page loads, thereby blocking the rendering. OK, let’s push to Vercel and see what’s up.

vercel --prod That score deserves a sad trombone. &#x1f3ba;

OK, we now have a very slow Jamstack site. The images are blocking the rendering of the page and the TTI is now a whopping 16.5 seconds. We have taken a very fast Jamstack site and dropped it to a Lighthouse score of 17 — a reduction of 83 points!

Now, you may be think that you would never make these poor decisions when building an app. But you are missing the point. Every choice we make has an impact on performance. It’s a balance and performance does not come free. Even on Jamstack sites.

Making Jamstack fast again

You have seen that we cannot ignore client-side performance when using Jamstack. 

So why do people say that Jamstack is fast? Well, the main advantage of Jamstack — or using static site generators in general — is caching. Static files are cached on the edge reducing Time to First Byte (TTFB).

This is always going to be faster than going to a single-origin web server before generating the page. This is a great feature of Jamstack and gives you a fighting chance to create a page that can hit 100 in Lighthouse. (But, hey, as a side note, remember that great scores aren’t always indicative of an actual user experience.)

See, I told you we could make Jamstack slow! There are also many other things that can slow it down, but hopefully this drives home the point.

While we’re talking about performance, here are a few of my favorite performance articles on here at CSS-Tricks:

The post Make Jamstack Slow? Challenge Accepted. appeared first on CSS-Tricks.

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

Netlify Does Cache Invalidation For You

Css Tricks - Tue, 07/14/2020 - 2:46pm

This is one of my favorite Netlify features. Say you’re working on a site and you change as asset like a CSS, JavaScript, or image file. Ya know, like do our job. On Netlify, you don’t have to think about how that’s going to play out with deployment, browsers, and cache. Netlify just handles it for you.

Netlify calls this Instant Cache Invalidation, part of the “rocketjuice” of Netlify.

On all the sites I work on that aren’t on Netlify, I do have to think about it (ugh). If you look at this very websites source, you’ll see a link to a stylesheet something like this:

<link href="https://css-tricks.com/wp-content/themes/CSS-Tricks-17/style.css?cache_bust=1594590986788" rel="stylesheet">

See that ?cache_bust= stuff at the end of the stylesheet URL? Those are just gibberish characters I put into that URL manually (based on a Date() call) so that when I push a change to the file, it breaks both the CDN and people’s own browser cache and they get the new file. If I didn’t do that, the changes I push won’t be seen until all the cache expires or is manually removed by users, which is… bad. I might be fixing a bug! Or releasing a new feature! It’s extra bad because that CSS might go along with some HTML which doesn’t cache as aggressively and could lead to a mismatch of HTML and expected CSS.

I work on some sites where I change that cache-busting string by hand because I’m too lazy to automate it. Usually, I do automate it though. I recently shared my Gulpfile which I hand-wrote, and part of which deals with this cache-busting. It is work to write, work to maintain, and work to use during development. You can even read the comments on that post and see other people’s strategies for doing the same thing that are different than how I do it. Errrrrrybody be cache-busting.

Not on Netlify.

Again, you change an asset, push it up, Netlify knows it’s changed and does all the cache busting for you. So your stylesheet can be linked up like:

<link href="dont-even-worry-about-it.css" rel="stylesheet" />

The post Netlify Does Cache Invalidation For You appeared first on CSS-Tricks.

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

Syndicate content
©2003 - Present Akamai Design & Development.