Snippets

These snippets are my attempt to save and organize various bits of code, best practices, and resources relating to web development and design. They also function as a to do list of sorts, for things I want to implement in my own code, but haven't yet. The concept is inspired by Jeremy Keith's links and CSS-Tricks, among other things. Enjoy.

Coding CSS for Context

Dave Rupert recently tweeted asking a question that I see quite often:

CSS

.some-context .thing { /* special rules and overrides */ } 

Does that go in thing.css or some-context.css?

Then, Harry Roberts discussed this concept further in his article of CSS Code Smells Revisited.

Harry uses a practical example of .thing being a .button. (Well, actually, a .btn but whatever. And yes, I just “well, actuallied” myself. It’s preemptive mansplaining.)

You’ll have the standard button that appears throughout your application. And then you have this variation in modal dialogs.

Instinctively, we start writing .modal .button. Hence, Dave’s question of where to put this particular bit of code. It’s interesting to note that the results of Dave’s survey indicated that a slim majority of people prefer that this bit of code live in with the modal CSS and not with the button CSS.

Harry indicated that it should live with the button CSS. And I agree with him. We’re styling a button! It should be in with the buttons.

[...]

One thing you have to worry about is components becoming too complex. Yes, the modal has a button. It could also have inputs and headings and all sorts of things. Over my career, I’ve noticed useful boundaries and tend not to create components with deep hierarchies.

Permalink to this heading.Identifying The Thing

Going back to our thing that we’re trying to style: the button. Yes, right now, we’re styling a button in a modal dialog. Is this the only place that this exists? Right now, quite possibly. Will it always be the only place it exists? If your project is constantly in flux, then not likely.

Here’s what’s important:

  • We want to identify that this is a variation on our button.
  • We want to indicate the purpose of this button style.
  • We want to avoid tying the code to a particular context that could change.

Going with .button--modal, for example, now identifies it as a variation. But fails on the other two points: It indicates its context and doesn’t say what it’s trying to do other than be in a particular place on the page.

So, why is the button in the modal different than regular buttons? (If you’re the designer, ask yourself this. If you’re not the designer, ask them this.) You might get something like, “It needs to be green to draw attention to the fact that it’s a primary action.” Or maybe something like, “the button is smaller because we don’t have as much room.”

This helps you come up with a name like .button--primary or .button--compact.

Either of those names satisfy the three points I mentioned above.

  • It identifies itself as a variation using the BEM double hyphen.
  • It indicates its purpose through the variation name.
  • It hasn’t tied itself to a specific context.

That last point, to me, is the most important. As a designer, I might end up using these styles on a new page that hasn’t been thought up yet. I might want to use a primary button style on a form that isn’t in a modal dialog. I might want to use a compact button in a sidebar where I don’t have a lot of room.

And as Harry also mentioned, by keeping all our button styles in one place, we have the ability to see patterns emerge across an entire project.

Three months down the line, do we suddenly find ourselves with 30 button styles and need to reduce the complexity of our UI? That can be harder to do if button styles are strewn throughout the codebase, hidden within other contexts.

Tags: 

Typefaces: NPM packages for Open Source typefaces — making it easier to self-host webfonts

Permalink to this heading.Why

  • Self-hosting is significantly faster. Loading a typeface from Google Fonts or other hosted font service adds an extra (blocking) network request. In my testing, I’ve found replacing Google Fonts with a self-hosted font can improve a site’s speedindex by ~300 miliseconds on desktop and 1+ seconds on 3g. This is a big deal.
  • Your fonts load offline. It’s annoying to start working on a web project on the train or airplane and see your interface screwed up because you can’t access Google fonts. I remember once being in this situation and doing everything possible to avoid reloading a project as I knew I’d lose the fonts and be forced to stop working.
  • Go beyond Google Fonts. Some of my favorite typefaces aren’t on Google Fonts like Clear Sans, Cooper Hewitt, and Aleo.
  • All web(site|app) dependencies should be managed through NPM whenever possible. Tis the modern way.

Permalink to this heading.What

Each typeface package ships with all the necessary font files and css to self-host an open source typeface.

All Google Fonts have been added as well as a small but growing list of other open source fonts. Open an issue if you want a font added!

Permalink to this heading.How

Couldn’t be easier. This is how you’d add Open Sans.

npm install --save typeface-open-sans

Then in your app or site’s entry file.

require("typeface-open-sans")

And that’s it! You’re now self-hosting Open Sans!

It should take < 5 minutes to swap out Google Fonts.

Typeface assumes you’re using webpack with loaders setup for loading css and font files (you can use Typeface with other setups but webpack makes things really really simple). Assuming your webpack configuration is setup correctly you then just need to require the typeface in the entry file for your project.

Many tools built with webpack such as Gatsby and Create React App are already setup to work with Typefaces. Gatsby by default also embeds your CSS in your <head> for even faster loading.

If you’re not using webpack or equivalent tool that allows you to require css, then you’ll need to manually integrate the index.css and font files from the package into your build system.

Tags: 

Duoload: Simplest website load comparison tool, ever

A screenshot of the Duoload interface, with two websites in iframes side by side.

This is pretty excellent tool. (Note that it cannot be used on sites that disable iframe embedding, however.)

Today I needed a quick tool to compare the loading progression (not just loading time, but also incremental rendering) of two websites, one remote and one in my localhost. Just have them side by side and see how they load relative to each other. Maybe even record the result on video and study it afterwards. That’s all. No special features, no analysis, no stats.

Tags: 

read.isthe.link: A basic functionality Readability almost-clone

A basic functionality [Readability] almost-clone. This service will try to search for the body of the content to a URL, and represent it stripped back and with minimal styling.

Permalink to this heading.Usage

Send your URL to https://read.isthe.link via a query string, and so long as the URL is publically available (i.e. not behind login), then the page can be re-rendered:

https://read.isthe.link?url=https://remysharp.com/node

The page will be cached for a period of time, so subsequent requests will be faster.

Permalink to this heading.Usage with private URLs

You can POST a body to the service and it will give you a hashed URL to redirect to. For example:

Javascript

const xhr = new XMLHttpRequest();
 
xhr.open('POST', 'https://read.isthe.link');
xhr.setRequestHeader('content-type', 'application/x-www-form-urlencoded');
xhr.setRequestHeader('referrer', window.location);
 
xhr.onload = () => {
  const res = JSON.parse(xhr.response);
  window.location = `https://read.isthe.link?url=${res.url}`;
}
 
xhr.send(`body=${encodeURIComponent(document.documentElement.innerHTML)}`);

Permalink to this heading.Issues & feedback

All feedback, suggestions, pull requests to github (please): https://github.com/remy/read-body

MIT Licensed

Tags: 

Pages