Front End Web Development

Endangered Alphabets

Typography - Mon, 07/24/2017 - 3:39am

I started the Endangered Alphabets Project in 2010 when I discovered that about a third of the world’s 120-plus writing systems may become extinct within the next one or two generations.

As you probably know, every culture has its own spoken language, and in many cases its own written language, too — a writing system it has developed to express and record its own beliefs, its own experiences, its understanding of the world. What the members of that culture have collectively written in that script is the record of their cultural identity: spiritual texts, historical documents, poems, deeds, letters between family members.

Especially for indigenous and minority cultures, though, there is tremendous pressure — institutional pressure, governmental pressure, economic pressure, even military pressure — to abandon their traditional writing systems and use some more “convenient” or “global” script. If they give in to that pressure, everything written in their own script becomes incomprehensible and lost to the very culture that created and wrote in it.

The United Nations’ Universal Declaration on the Rights of Indigenous People says: “Indigenous peoples have the right to revitalize, use, develop and transmit to future generations their histories, languages, oral traditions, philosophies, writing systems and literatures, and to designate and retain their own names for communities, places and persons.”

In fact, not only are such rights rarely protected by law, but the world’s governments themselves are the most likely candidates to infringe on or refuse such rights.

Denying members of a minority culture the right to read, write and speak in their mother tongue defines them as inferior and unimportant, and leaves them vulnerable, marginalized, and open to abuse. The extent and quality of education go down, while levels of homelessness and incarceration, and even suicide go up — the kind of situation that has led to the endangerment or eradication of hundreds of Aboriginal languages in Australia and Native American languages in the U.S.

In an effort to slow this catastrophe and even, in some cases, to revive endangered traditional scripts, I’ve spent the past seven years carving pieces of text or even individual letters and words in many of these endangered alphabets. These carvings have been exhibited all over North America and Europe, including at the Smithsonian.

But what I’ve come to see, perhaps too slowly, is that documenting and speaking out about cultural genocide is not enough. To save and revive a language, you have to start with the children, and to reach children you need games.

So I’m starting to develop letter/word/alphabet games in endangered writing systems.

We are so accustomed to word games we often don’t realize how vital they are. Games such as Scrabble, Boggle, Hangman and Bananagrams teach not only spelling but letter manipulation and word recognition, and instill a deep and increasingly complex innate sense of letter combinations and language structures.

Perhaps even more importantly, they reinforce and develop the understood interrelationship between spoken and the written words, and they instill in users a sense that these words, not only in their meanings but in their very shapes and design, are profoundly and inextricably connected to everything we know, how we think, and what we believe.

Designing word games in non-Latin scripts, though, turns out to be a lot trickier than it seems to those of us who grew up on Boggle. In a minute I’m going to be asking for your help, but first let me explain the fascinating underlying issues.

Let’s start with an easy one. Many writing systems use waaaaay more symbols than we do. Khmer, for example, uses more than 80 letters, Pahauh Hmong has more than 60 syllabic consonants, plus tone indicators. If you’re making a Scrabble-type game, you’d need awfully big trays to hold your tiles!

More subtly, and I think more interestingly, we Latinates (and English speakers and writers in particular) subliminally think of writing in terms of the origins of our own script. Let me explain.

Endangered alphabets; from left to right: Mongolian, Manchu, and Baybayin.

To us, each letter is a small monument like the Roman monuments from which we drew our sense of formal typography: upright, balanced, capable of standing alone on its own two feet. In an alphabet game, then, we can play with letters as if they were Legos, picking them up, combining them, detaching them, recombining them to form other words.

In part, this is because of the visual connotations of our letters, their imperial symmetry and balance. But it’s also because those visual qualities are more important than the sounds they convey. Despite the robust physicality of our printed letters, they are actually almost absurdly inexact. Every vowel can be pronounced in multiple ways, and consonant clusters such as gh are notoriously ambiguous.

The result is that we have a writing system that is notoriously hard for non-English-speakers to learn, yet works astonishingly well for three-dimensional letter-based games such as Scrabble and Boggle. Stripped to their essentials, the letters work equally well for words that require them to be pronounced in all kinds of ways. If we have a U we can use it for GUT or, sounding entirely different, for GUEST.

Non-Latin-based writing systems are in many ways much more conscientious in phonetically representing the spoken word but that also makes them less suitable for certain word games. The northern Thai script called Lanna faithfully represents a far wider range of vowel sounds than we hear and use, but to do so it uses a cluster of glyphs to represent every sound. Consequently, it is far less flexible for the gamer, and the game designer. Imagine yourself playing Scrabble in Lanna: you’d need a tray of maybe 20 tiles to have a hope of creating a single word, and you’d have to stack tiles on top of each other to represent sound combinations. It could be all kinds of fun, but it certainly wouldn’t be easy.

Yet another challenge arises when you consider a word game in Mongolian. Not simply because Mongolian is a vertical script — that’s just a ninety-degree change of alignment. No, one of the delightful features of Mongolian is that it is inherently calligraphic. Every word begins with a certain set of flourishes and ends with another set of flourishes, and to achieve this graphic embellishment individual letters have different shapes depending on whether they are at the beginning or end of the word (in which case they are distinctly elaborate) or in the middle (in which case they are simple, straightforward and efficient). Perhaps this accounts for the fact that there is currently a resurgence of Mongolian calligraphy, but not of Mongolian Boggle!

So here’s my invitation to you. Well, two invitations.

The first is to help me design games that help children (and/or adults) in minority and indigenous cultures learn, or re-learn, their traditional alphabets.

These need to be easy and cheap to manufacture. Ideally they don’t need a reliable Internet connection or even a supply of electricity. I’m currently exploring wooden puzzles, sets of playing cards that have letters instead of numbers, a Scrabble-like board game, and domino-style games also with letters rather than number-dots. Send your thoughts to brookes@champlain.edu.

The second is that, as I need to fund the development, prototype manufacture, field testing, shipping and whatnot, I’d love it if you can back my current Kickstarter campaign. The campaign ends on August 3. Please help if you can!

Header photo: Children coloring in endangered alphabet coloring books in an event held at the Smithsonian.



Sponsored by Hoefler & Co.

Endangered Alphabets

Introducing four new foundry partners on Typekit

Nice Web Type - Fri, 07/21/2017 - 7:59am

Our four newest foundry partners make for a truly international team, with CAST from Italy, Kostic Type Foundry from Serbia, TipoType from Uruguay, and Latinotype from Chile. Welcome to all!

TipoType

Brother 1816 from TipoType.

Rufina Stencil and Ornaments from Tipotype. Both specimens courtesy of Tipotype.

Not many people can claim they started the first type foundry in their country, but Fernando Diaz, Vicente Lamonaca, and Martin Sommaruga of TipoType can — and they proudly represent Uruguay on the world stage of type design. In fact, Brother 1816 was just selected as one of Typographica’s favorite typefaces of 2016. See all the typefaces we’ve added from TipoType.

CAST (Cooperativa Anonima Servizi Tipografici)

Saffran, Rialto, and Brevier from CAST.

Run by Luciano Perondi, Erasmo Ciufo, and Riccardo Olocco, CAST is a rare all-Italian digital type foundry. Along with designing retail and custom typefaces, they actively publish educational articles on typography and offer technical advice to other companies.

The humanist sans faces in the collection are impressive in their craftsmanship and utility. Also in the collection are Brevier and Saffran, both developed to be highly legible at small sizes. At large sizes, their idiosyncratic details reveal a more intriguing personality, with exaggerated inktraps and stencil-like details.

Latinotype

Los Lana Niu from Latinotype.

Basic Sans from Latinotype.

Luciano Vergara, Daniel Hernandez, and Miguel Hernandez founded Latinotype 10 years ago in Santiago, Chile. They have been very prolific in that time, creating a large collection of typefaces. We have added a few great sans styles on Typekit that are anything but Basic, along with Los Lana Niu, a curveless display face whose chiselled shapes are a fresh take on how to accomplish the “carved in stone” look. Check out the whole collection.

Kostic Type Foundry

Chiavettieri from Kostic Type Foundry.

Zoran and Nikola, father and son, run Kostic Type Foundry out of Serbia. Chiavettieri, a sophisticated text typeface, was named one of Typographica’s favorite typefaces of 2015. Along with some fairly conventional designs, Kostic has released typefaces that sparked fierce debate on our team, such as Battleslab and Taurunum. Have a look at the full collection, and let us know what you think.

Got a regular appetite for new fonts? Keep up with us on Instagram for peeks at the newest type in our library — and tag us there if you see something you like out in the wild!


A Collection of Interesting Facts about CSS Grid Layout

Css Tricks - Fri, 07/21/2017 - 3:24am

A few weeks ago I held a CSS Grid Layout workshop. Since I'm, like most of us, also pretty new to the topic, I learned a lot while preparing the slides and demos.
I decided to share some of the stuff that was particularly interesting to me, with you.

Have fun!

Negative values lower than -1 may be used for grid-row-end and grid-column-end

In a lot of code examples and tutorials you will see that you can use grid-column-start: 1 and grid-column-end: -1 (or the shorthand grid-column: 1 / -1) to span an element from the first line to the last. My friend Max made me aware that it's possible to use lower values than -1 as well.

.grid-item { grid-column: 1 / -2; }

For example, you can set grid-column: 1 / -2 to span the cells between the first and the second to last line.

See the Pen Grid item from first to second to last by Manuel Matuzovic (@matuzo) on CodePen.

It's possible to use negative values in grid-column/row-start

Another interesting thing about negative values is that you can use them on grid-column/row-start as well. The difference between positive and negative values is that with negative values the placement will come from the opposite side. If you set grid-column-start: -2 the item will be placed on the second to last line.

.item { grid-column-start: -3; grid-row: -2; }

See the Pen Negative values in grid-column/row-start by Manuel Matuzovic (@matuzo) on CodePen.

Generated content pseudo-elements (::before and ::after) are treated as grid items

It may seem obvious that pseudo-elements generated with CSS become grid items if they're within a grid container, but I wasn't sure about that. So I created a quick demo to verify it. In the following Pen you can see that generated elements become grid- and flex-items if they are within a corresponding container.

See the Pen Experiment: Pseudo elements as grid items by Manuel Matuzovic (@matuzo) on CodePen.

Animating CSS Grid Layout properties

According to the CSS Grid Layout Module Level 1 specification there are 5 animatable grid properties:

  • grid-gap, grid-row-gap, grid-column-gap
  • grid-template-columns, grid-template-rows

Currently only the animation of grid-gap, grid-row-gap, grid-column-gap is implemented and only in Firefox and Firefox Mobile. I wrote a post about animating CSS Grid Layout properties, where you'll find some more details and a demo.

The value of grid-column/row-end can be lower than the start value

In level 4 of the CSS Grid Garden game I learned that the value of grid-column-end or grid-row-end may be lower than the respective start equivalent.

.item:first-child { grid-column-end: 2; grid-column-start: 4; }

The item in the above code will start on the 4th line and end on the 2nd, or in other words, start on the 2nd line and end on the 4th.

See the Pen Lower grid-column-end value than grid-column-start by Manuel Matuzovic (@matuzo) on CodePen.

Using the `span` keyword on grid-column/row-start and grid-column/row-end

A grid item by default spans a single cell. If you want to change that, the span keyword can be quite convenient. For example setting grid-column-start: 1 and grid-column-end: span 2 will make the grid item span two cells, from the first to the third line.

You can also use the span keyword with grid-column-start. If you set grid-column-end: -1 and grid-column-start: span 2 the grid-item will be placed at the last line and span 2 cells, from the last to third to last line.

See the Pen CSS Grid Layout: span keyword by Manuel Matuzovic (@matuzo) on CodePen.

grid-template-areas and implicit named lines

If you create template areas in a grid, you automatically get four implicit named lines, two naming the row-start and row-end and two for the column-start and column-end. By adding the -start or -end suffix to the name of the area, they're applicable like any other named line.

.grid { display: grid; grid-template-columns: 1fr 200px 200px; grid-template-areas: "header header header" "articles favorites posts" } .footer { grid-column-start: favorites-start; grid-column-end: posts-end; }

See an example for implicit named lines in this Pen.

Grid is available in the insider version of Microsoft Edge

Support for CSS Grid Layout is pretty great since all major browsers, except IE and Edge, support it. For a lot of projects you can start using CSS Grid Layouts today. Support for Microsoft Edge will probably come pretty soon, because it's already available in the insider version of Microsoft Edge.

This browser support data is from Caniuse, which has more detail. A number indicates that browser supports the feature at that version and up.

DesktopChromeOperaFirefoxIEEdgeSafari57445211*1610.1Mobile / TabletiOS SafariOpera MobileOpera MiniAndroidAndroid ChromeAndroid Firefox10.3NoNo565954

If you want to learn more about Grids check out The Complete Guide to Grid, Getting Started with CSS Grid, Grid By Example and my Collection of Grid demos on CodePen.

A Collection of Interesting Facts about CSS Grid Layout is a post from CSS-Tricks

?Edit your website, from your website

Css Tricks - Thu, 07/20/2017 - 3:44am

Stuck making "a few easy changes" to the website for someone? Component IO makes it quick and simple for you or your team to make edits (even for non-technical users).

You can manage content with a WYSIWYG editor or instantly update HTML, CSS, and JavaScript right from your website. Make changes faster, empower your team, and avoid redeployment bugs. Works with every web technology, from WordPress to Rails to React.

Join hundreds of projects already using Component IO, with a free tier and plans from $7.95/mo. It's built to make web development easier for everyone.

Try it free

Direct Link to ArticlePermalink

?Edit your website, from your website is a post from CSS-Tricks

Playing with Shadow DOM

Css Tricks - Thu, 07/20/2017 - 3:44am

About a year ago, Twitter announced it would start displaying embedded tweets with the shadow DOM rather than an <iframe>, if the browser supports shadom DOM.

Why? Well, speed is one reason.

They say:

Much lower memory utilization in the browser, and much faster render times. Tweets will appear faster and pages will scroll more smoothly, even when displaying multiple Tweets on the same page.

Why the choice? Why is it necessary to use either iframes or shadow DOM? Why not just inject the content onto the page?

It's a totally understandable need for control. An embedded Tweet should look and behave just exactly like an embedded Tweet. They don't want to worry about the styles of the page bleeding in and messing that up.

An <iframe> makes style scoping very easy. Point the src of the iframe at a URL that displays what you want an embedded tweet to look like, and you're good. The only styles used will be those you include in that document.

Twitter does this iframe-injection in a progressive enhancement and syndication-friendly way. They provide a <blockquote> with the Tweet and a <script>. The script does the iframe-injection. If the script doesn't run, no matter, a happy blockquote. If the script does run, a fully functional embedded Tweet.

That script is the key here. Scripts can do just about anything, and they host it, so they can change it up anytime. That's what they use to detect shadow DOM support and go that route instead. And as we covered, shadow DOM is faster to render and has lower memory needs. Shadow DOM can also help with the style scoping thing, which we'll look at in a moment.

Height flexibility

There's another thing too, that happens to be near and dear to my heart. An <iframe> doesn't adjust in height to fit its contents like you expect other elements to do. You set a height and that's that. It will have scrollbars, if you allow it and the content needs it. Back in the Wufoo days, we had to jump quite a few hoops to get embedded forms (in frames) to be as tall as they needed to be. Today, at CodePen, our Embedded Pens have adjustable heights, but there isn't any option for just "as tall as they need to be". (I'm exactly sure if that makes sense for CodePen Embeds or not, but anyway, you can't do it right now.)

An element with a shadow DOM is just like any other element and that it will expand to the content naturally. I'm sure that is appealing to Twitter as well. If they calculate the height wrong, they run the risk of cutting of content or at least having the embedded Tweet look busted.

Most Basic Usage

Here's the bare minimum of how you establish a shadow DOM and put stuff in it:

See the Pen Most basic shadow DOM by Chris Coyier (@chriscoyier) on CodePen.

Notice how the styling within the Shadow DOM doesn't leak out to the regular paragraph element? Both paragraphs would be red if they did.

And notice how the paragraph inside the shadow DOM isn't sans-serif like the one outside? Well, normally that would be. Inherited styles still inherit through the shadow DOM (so in that way it's not quite as strong a barrier as an iframe). But, we're forcing it back to the initial state on purpose like this:

:host { all: initial; } Handling that fallback

My first thought for dealing with a fallback for browsers that don't support shadow DOM was that you could chuck the same exact content you were stuffing into the shadow DOM into an iframe with srcdoc, like...

<iframe srcdoc="the same content">

Or more likely this is something you're doing in JavaScript, so you'd test for support first, then either do the shadow DOM stuff or dynamically create the iframe:

See the Pen Shadow DOM Basic by Chris Coyier (@chriscoyier) on CodePen.

Turns out srcdoc isn't the best choice (alone) for a fallback as there is no IE or Edge support for it. But also that it's not too big of a deal to just use a data URL for the regular src. Here's a fork by Šime Vidas where he fixes that up:

let content = ` <style> body { /* for fallback iframe */ margin: 0; } p { border: 1px solid #ccc; padding: 1rem; color: red; font-family: sans-serif; } </style> <p>Element with Shadow DOM</p> `; let el = document.querySelector('.my-element'); if (document.body.attachShadow) { let shadow = el.attachShadow({ mode: 'open' }); // Allows JS access inside shadow.innerHTML = content; } else { let newiframe = document.createElement('iframe'); 'srcdoc' in newiframe ? newiframe.srcdoc = content : newiframe.src = 'data:text/html;charset=UTF-8,' + content; let parent = el.parentNode; parent.replaceChild(newiframe, el); } TL;DR
  • Shadow DOM is pretty cool.
  • It's comparable to an iframe in many ways, including style encapsulation. Embedded third-party content is a pretty good use case.
  • It's possible to use it while falling back to an iframe pretty easily.
  • It's a part of the larger world of web components, but you don't have to go all-in on all that if you don't want to.

Here's another simple demo (this one using a custom element), but instead of rolling our own back support, it's polyfilled.

Playing with Shadow DOM is a post from CSS-Tricks

Implementing Webmentions

Css Tricks - Wed, 07/19/2017 - 8:46am

We get a decent amount of comments on blog posts right here on CSS-Tricks (thanks!), but I'd also say the hay day for that is over. These days, if someone writes some sort of reaction to a blog post, it could be on their own blog, or more likely, on some social media site. It makes sense. That's their home base and it's more useful to them to keep their words there.

It's a shame, though. This fragmented conversation is slightly more useful for each individual person, it's less useful as a whole. There is no canonical conversation thread. That's what Webmentions are all about, an official spec! In a sense, they allow the conversation to be dispursed but brought all together in a canonical conversation thread on the main post.

Webmentions don't need to be an alternative to comments, although when you pop over to real Drew McLellan's post you'll see he's using them that way. They can be in addition to "regular" comments. Surely the idea of turning off regular comments is appealing from a community perspective (less asshats likely when you need to link to your published words) and a technical debt perspective.

Rachel Andrew also recently implemented them, and this is classic Jeremy Keith stuff.

Direct Link to ArticlePermalink

Implementing Webmentions is a post from CSS-Tricks

Intro to Hoodie and React

Css Tricks - Wed, 07/19/2017 - 3:01am

Let's take a look at Hoodie, the "Back-End as a Service" (BaaS) built specifically for front-end developers. I want to explain why I feel like it is a well-designed tool and deserves more exposure among the spectrum of competitors than it gets today. I've put together a demo that demonstrates some of the key features of the service, but I feel the need to first set the scene for its use case. Feel free to jump over to the demo repo if you want to get the code. Otherwise, join me for a brief overview.

Setting the Scene

It is no secret that JavaScript is eating the world these days and with its explosion in popularity, an ever-expanding ecosystem of tooling has arisen. The ease of developing a web app has skyrocketed in recent years thanks to these tools. Developer tools Prettier and ESLint give us freedom to write how we like and still output clean code. Frameworks like React and Vue provide indispensable models for creating interactive experiences. Build tools like Webpack and Babel allow us to use the latest and greatest language features and patterns without sacrificing speed and efficiency.

Much of the focus in JavaScript these days seems to be on front-end tools, but it does not mean there is no love to be found on the back-end. This same pattern of automation and abstraction is available on the server side, too, primarily in the form of what we call "Backend as a Service" (BaaS). This model provides a way for front end developers to link their web or mobile apps to backend services without the need to write server code.

Many of these services have been around for awhile, but no real winner has come forth. Parse, an early player in the space, was gobbled up by Facebook in 2013 and subsequently shut down. Firebase was acquired by Google and is slowly making headway in developing market share. Then only a few weeks ago, MongoDB announced their own BaaS, Stitch, with hopes of capitalizing on the market penetration of their DB.

BaaS Advantages

There are an overwhelming number of BaaS options, however, they all have the same primary advantages at their core.

  • Streamlined development: The obvious advantage of having no custom server is that it removes the need to develop one! This means your development team will perform less context switching and ultimately have more time to focus on core logic. No server language knowledge required!
  • No boilerplate servers: Many servers end up existing for the sole purpose of connecting a client with relevant data. This often results in massive amounts of web framework and DAL boilerplate code. The BaaS model removes the need for this repetitive code.

These are just the main advantages of BaaS. Hoodie provides these and many more unique capabilities that we will walk through in the next section.

Try on your Hoodie

To demonstrate some of the out-of-the-box functionality provided by Hoodie, I am going to walk you through a few pieces of a simple Markdown note taking web application. It is going to handle user authentication, full CRUD of users' notes, and the ability to keep working even when a connection to the internet is lost.

You can follow along with the code by cloning the hoodie-notes GitHub repository to your local machine and running it using the directions in the README.

This walkthrough is meant to focus on the implementation of the hoodie-client and thus, assumes prior knowledge of React, Redux, and ES6. Knowledge of these, although helpful, is not necessary to understand the scope of what we will discuss here.

The Basics

There are really only three things you have to do to get started with Hoodie.

  1. Place your static files in a folder called /public at the root of your project. We place our index.html and all transpiled JS and image files here so they can be exposed to clients.
  2. Initialize the Hoodie client in your front end code:

    const hoodie = new Hoodie({ url: window.location.origin, PouchDB: require('pouchdb-browser') })
  3. Start your hoodie server by running hoodie in the terminal

Of course, there is more to creating the app, but that is all you really need to get started!

User Auth

Hoodie makes user and session management incredibly simple. The Account API can be used to create users, manage their login sessions, and update their accounts. All code handling these API calls is stored in the user reducer.

When our app starts up, we see a login screen with the option to create a user or log in.

When either of these buttons are pressed, the corresponding Redux thunk is dispatched to handle the authentication. We use the signUp and signIn functions to handle these events. To create a new account, we make the following call:

hoodie.account.signUp({ username: 'guest', password: '1234' }) .then(account => { // successful creation }).catch(err => { // account creation failure })

Once we have an account in the system, we can login in the future with:

hoodie.account.signIn({ username: 'guest', password: '1234' }) .then(account => { // successful login }).catch(err => { // login failure })

We now have user authentication, authorization, and session management without writing a single line of server code. To add a cherry on top, Hoodie manages sessions in local storage, meaning that you can refresh the page without the need to log back in. To leverage this, we can execute the following logic the initial rendering of our app:

hoodie.account.get() .then({ session, username }=> { if (session) console.log(`${username} is already logged in!`) }).catch(err => { // session check failure })

And to logout we only need to call hoodie.account.signOut(). Cool!

CRUD Notes

Perhaps the nicest thing about user management in Hoodie is that all documents created while logged in are only accessible by that authenticated user. Authorization is entirely abstracted from us, allowing us to focus on the simple logic of creating, retrieving, updating, and deleting documents using the Store API. All code handling these API calls is stored in the notes reducer.

Let's start off with creating a new note:

hoodie.store.add({ title: '', text: '' }) .then(note => console.log(note)) .catch(err => console.error(err))

We can pass any object we would like to the add function, but here we create an empty note with a title and text field. In return, we are given a new object in the Hoodie datastore with its corresponding unique ID and the properties we gave it.

When we want to update that document, it is as simple as passing that same note back in with the updated (or even new) properties:

hoodie.store.update(note) .then(note => console.log(note)) .catch(err => console.error(err))

Hoodie handles all the diffing and associated logic that it takes to update the store. All we need to do is pass in the note to the update function. Then, when the user elects to delete that note, we pass its ID to the remove function:

hoodie.store.remove(note._id) .then(()=> console.log(`Removed note ${note._id}`)) .catch(err => console.error(err))

The last thing we need to do is retrieve our notes when the user logs back in. Since we are only storing notes in the datastore, we can go ahead and retrieve all of the user's documents with the findAll function:

hoodie.store.findAll() .then(notes => console.log(notes)) .catch(err => console.error(err))

If we wanted, we could use the find function to look up individual documents as well.

Putting all of these calls together, we've essentially replaced a /notes REST API endpoint that otherwise would have required a fair amount of boilerplate request handling and DAL code. You might say this is lazy, but I'd say we are working smart!

Monitoring the connection status

Hoodie was built with an offline-first mentality, meaning that it assumes that clients will be offline for extended periods of time during their session. This attitude prioritizes the handling of these events such that it does not produce errors, but instead allows users to keep working as usual without fear of data loss. This functionality is enabled under the hood by PouchDB and a clever syncing strategy, however, the developer using the hoodie-client does not need to be privy to this as it is all handled behind the scenes.

We'll see how this improves our user experience in a bit, but first let's see how we can monitor this connection using the Connection Status API. When the app first renders, we can establish listeners for our connection status on the root component like so:

componentDidMount() { hoodie.connectionStatus.startChecking({interval: 3000}) hoodie.connectionStatus.on('disconnect', () => this.props.updateStatus(false)) hoodie.connectionStatus.on('reconnect', () => this.props.updateStatus(true)) }

In this case, we tell Hoodie to periodically check our connection status and then attach two listeners to handle changes in connections. When either of these events fire, we update the corresponding value in our Redux store and adjust the connection indicator in the UI accordingly. This is all the code we need to alert the user that they have lost a connection to our server.

To test this, open up the app in a browser. You'll see the connection indicator in the top left of the app. If you stop the server while the page is still open, you will see the status change to "Disconnected" on the next interval.

While you are disconnected, you can continue to add, edit, and remove notes as you would otherwise. Changes are stored locally and Hoodie keeps track of the changes that are made while you are offline.

Once you're ready, turn the server back on and the indicator will once again change back to "Connected" status. Hoodie then syncs with the server in the background and the user is none the wiser about the lapse of connectivity (outside of our indicator, of course).

If you don't believe it's that easy, go ahead and refresh your page. You'll see that the data you created while offline is all there, as if you never lost the connection. Pretty incredible stuff considering we did nothing to make it happen!

Why I Like Hoodie

Hoodie is not the only BaaS offering by any means, but I consider it a great option for several reasons

  1. Simple API: In this walkthrough, we were able to cover 3 out of 4 of the Hoodie APIs. They are incredibly simple, without much superfluous functionality. I am a big fan of simplicity over complexity until the latter cannot be avoided and Hoodie definitely fits that bill.
  2. Free and self-hosted: Putting Hoodie into production yourself can seem like a drag, but I believe such a service gives you long-term assurance. Paid, hosted services require a bet on that service's reliability and longevity (see: Parse). This, along with vendor lock-in, keep me on the side of self-hosting when it makes sense.
  3. Open Source: No explanation needed here...support the OSS community!
  4. Offline-first: Hoodie provides a seamless solution to the relevant problem of intermittent connectivity and removes the burden of implementation from developers.
  5. Plugins: Hoodie supports 3rd party plugins to provide support for additional server-side functionality outside the scope of the API. It allows for some clever solutions when you begin to miss the flexibility of having your own server.
  6. Philosophy: The developers who built and support Hoodie have clearly thought hard about what the service represents and why they built it. Their promotion of openness, empowerment, and decentralization (among other things) is great to see at the core of an open source project. I love everything about this!
Considerations

Before you make the call to cut ties with your server in favor of a BaaS like Hoodie, there are some things you should consider.

Do you favor increased development speed or future flexibility? If the former is your priority, then go with a BaaS! If you really care about performance and scale, you're probably better off spinning up your own server(s). This points toward using a BaaS for an MVP or light-weight app and creating a custom server for well-defined, complex applications.

Does your app require integration with any 3rd party services? If so, it is likely you will need the flexibility of your own server for implementing your own custom implementation logic rather than constrain yourself to a Hoodie plugin.

Lastly, the documentation for Hoodie is severely lacking. It will help you get started, but many API definitions are missing from the docs and you will have to fill in some of the blanks yourself. This is mitigated by the fact that the interface is extremely well thought out. Nonetheless, it makes for a frustrating experience if you are used to complete documentation.

Conclusion

For front end developers, using a BaaS is a great prospect when considering your options for creating a web application. It avoids the need for writing server logic and implementing what essentially amounts to a boilerplate REST API. Hoodie delivers this possibility, with the added bonus of a clean interface, simple user management, and offline-first capabilities.

If all you need is a simple CRUD application, consider using Hoodie for your next app!

Additional Resources

Intro to Hoodie and React is a post from CSS-Tricks

More Gotchas Getting Inline SVG Into Production—Part II

Css Tricks - Tue, 07/18/2017 - 1:49am

The following is a guest post by Rob Levin and Chris Rumble. Rob and Chris both work on the product design team at Mavenlink. Rob is also creator and host of the SVG Immersion Podcast and wrote the original 5 Gotchas article back in '14. Chris, is a UI and Motion Designer/Developer based out of San Francisco. In this article, they go over some additional issues they encountered after incorporating inline SVGs in to Mavenlink's flagship application more then 2 years ago. The article illustrations were done by Rob and—in the spirit of our topic—are 100% vector SVGs!

Wow, it's been over 2 years since we posted the 5 Gotchas Getting SVG Into Production article. Well, we've encountered some new gotchas making it time for another follow up post! We'll label these 6-10 paying homage to the first 5 gotchas in the original post :)

Gotcha Six: IE Drag & Drop SVG Disappears

If you take a look at the animated GIF above, you'll notice that I have a dropdown of task icons on the left, I attempt to drag the row outside of the sortable's container element, and then, when I drop the row back, the SVG icons have completely disappeared. This insidious bug didn't seem to happen on Windows 7 IE11 in my tests, but, did happen in Windows 10's IE11! Although, in our example, the issue is happening due to use of a combination of jQuery UI Sortable and the nestedSortable plugin (which needs to be able to drag items off the container to achieve the nesting, any sort of detaching of DOM elements and/or moving them in the DOM, etc., could result in this disappearing behavior. Oddly, I wasn't able to find a Microsoft ticket at time of writing, but, if you have access to a Windows 10 / IE11 setup, you can see for yourself how this will happen in this simple pen which was forked from fergaldoyle. The Pen shows the same essential disappearing behavior happening, but, this time it's caused by simply moving an element containing an SVG icon via JavaScript's appendChild.

A solution to this is to reset the href.baseVal attribute on all <use> elements that descend from event.target container element when a callback is called. For example, in the case of using Sortable, we were able to call the following method from inside Sortable's stop callback:

function ie11SortableShim(uiItem) { function shimUse(i, useElement) { if (useElement.href && useElement.href.baseVal) { // this triggers fixing of href for IE useElement.href.baseVal = useElement.href.baseVal; } } if (isIE11()) { $(uiItem).find('use').each(shimUse); } };

I've left out the isIE11 implementation, as it can be done a number of ways (sadly, most reliably through sniffing the window.navigator.userAgent string and matching a regex). But, the general idea is, find all the <use> elements in your container element, and then reassign their href.baseVal to trigger to IE to re-fetch those external xlink:href's. Now, you may have an entire row of complex nested sub-views and may need to go with a more brute force approach. In my case, I also needed to do:

$(uiItem).hide().show(0);

to rerender the row. Your mileage may vary ;)

If you're experiencing this outside of Sortable, you likely just need to hook into some "after" event on whatever the parent/container element is, and then do the same sort of thing.

As I'm boggled by this IE11 specific issue, I'd love to hear if you've encountered this issue yourself, have any alternate solutions and/or greater understanding of the root IE issues, so do leave a comment if so.

Gotcha Seven: IE Performance Boosts Replacing SVG4Everybody with Ajax Strategy

In the original article, we recommended using SVG4Everybody as a means of shimming IE versions that don't support using an external SVG definitions file and then referencing via the xlink:href attribute. But, it turns out to be problematic for performance to do so, and probably more kludgy as well, since it's based off user agent sniffing regex. A more "straight forward" approach, is to use Ajax to pull in the SVG sprite. Here's a slice of our code that does this which is, essentially, the same as what you'll find in the linked article:

loadSprite = null; (function() { var loading = false; return loadSprite = function(path) { if (loading) { return; } return document.addEventListener('DOMContentLoaded', function(event) { var xhr; loading = true; xhr = new XMLHttpRequest(); xhr.open('GET', path, true); xhr.responseType = 'document'; xhr.onload = function(event) { var el, style; el = xhr.responseXML.documentElement; style = el.style; style.display = 'none'; return document.body.insertBefore(el, document.body.childNodes[0]); }; return xhr.send(); }); }; })(); module.exports = { loadSprite: loadSprite, };

The interesting part about all this for us, was that—on our icon-heavy pages—we went from ~15 seconds down to ~1-2 seconds (for first uncached page hit) in IE11.

Something to consider about using the Ajax approach, you'll need to potentially deal with a "flash of no SVG" until the HTTP request is resolved. But, in cases where you already have a heavy initial loading SPA style application that throws up a spinner or progress indicator, that might be a sunk cost. Alternatively, you may wish to just go ahead and inline your SVG definition/sprite and take the cache hit for better-percieved performance. If so, measure just how much you're increasing the payload.

Gotcha Eight: Designing Non-Scaling Stroke Icons

In cases where you want to have various sizes of the same icon, you may want to lock down the stroke sizes of those icons…

Why, what's the issue?

Imagine you have a height: 10px; width: 10px; icon with some 1px shapes and scale it to 15px. Those 1px shapes will now be 1.5px which ends up creating a soft or fuzzy icon due to borders being displayed on sub-pixel boundaries. This softness also depends on what you scale to, as that will have a bearing on whether your icons are on sub-pixel boundaries. Generally, it's best to control the sharpness of your icons rather than leaving them up to the will of the viewer's browser.

The other problem is more of a visual weight issue. As you scale a standard icon using fills, it scales proportionately...I can hear you saying "SVG's are supposed to that". Yes, but being able to control the stroke of your icons can help them feel more related and seen as more of a family. I like to think of it like using a text typeface for titling, rather than a display or titling typeface, you can do it but why when you could have a tight and sharp UI.

Prepping the Icon

I primarily use Illustrator to create icons, but plenty of tools out there will work fine. This is just my workflow with one of those tools. I start creating an icon by focusing on what it needs to communicate not really anything technical. After I'm satisfied that it solves my visual needs I then start scaling and tweaking it to fit our technical needs. First, size and align your icon to the pixel grid (??Y in Illustrator for pixel preview, on a Mac) at the size you are going to be using it. I try to keep diagonals on 45° and adjust any curves or odd shapes to keep them from getting weird. No formula exists for this, just get it as close as you can to something you like. Sometimes I scrap the whole idea if it's not gonna work at the size I need and start from scratch. If it's the best visual solution but no one can identify it... it's not worth anything.

Exporting AI

I usually just use the Export As "SVG" option in Illustrator, I find it gives me a standard and minimal place to start. I use the Presentation Attributes setting and save it off. It will come out looking something like this:

<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 18 18"> <title>icon-task-stroke</title> <polyline points="5.5 1.5 0.5 1.5 0.5 4.5 0.5 17.5 17.5 17.5 17.5 1.5 12.5 1.5" fill="none" stroke="#b6b6b6" stroke-miterlimit="10"/> <rect x="5.5" y="0.5" width="7" height="4" fill="none" stroke="#b6b6b6" stroke-miterlimit="10"/> <line x1="3" y1="4.5" x2="0.5" y2="4.5" fill="none" stroke="#b6b6b6" stroke-miterlimit="10"/> <line x1="17.5" y1="4.5" x2="15" y2="4.5" fill="none" stroke="#b6b6b6" stroke-miterlimit="10"/> <polyline points="6 10 8 12 12 8" fill="none" stroke="#ffa800" stroke-miterlimit="10" stroke-width="1"/> </svg>

I know you see a couple of 1/2 pixels in there! Seems like there are a few schools of thought on this. I prefer to have the stroke line up to the pixel grid as that is what will display in the end. The coordinates are placed on the 1/2 pixel so that your 1px stroke is 1/2 on each side of the path. It looks something like this (in Illustrator):

Gotcha Nine: Implementing Non-Scaling Stroke Clean Up

Our Grunt task, which Rob talks about in the previous article, cleans up almost everything. Unfortunately for the non-scaling-stroke you have some hand-cleaning to do on the SVG, but I promise it is easy! Just add a class to the paths on which you want to restrict stroke scaling. Then, in your CSS add a class and apply the attribute vector-effect: non-scaling-stroke; which should look something like this:

.non-scaling-stroke { vector-effect: non-scaling-stroke; } <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 18 18"> <title>icon-task-stroke</title> <polyline class="non-scaling-stroke" points="5.5 1.5 0.5 1.5 0.5 4.5 0.5 17.5 17.5 17.5 17.5 1.5 12.5 1.5" stroke="#b6b6b6" stroke-miterlimit="10"/> <rect class="non-scaling-stroke" x="5.5" y="0.5" width="7" height="4" stroke="#b6b6b6" stroke-miterlimit="10"/> <line class="non-scaling-stroke" x1="3" y1="4.5" x2="0.5" y2="4.5" stroke="#b6b6b6" stroke-miterlimit="10"/> <line class="non-scaling-stroke" x1="17.5" y1="4.5" x2="15" y2="4.5" stroke="#b6b6b6" stroke-miterlimit="10"/> <polyline class="non-scaling-stroke" stroke="currentcolor" points="6 10 8 12 12 8" stroke="#ffa800" stroke-miterlimit="10" stroke-width="1"/> </svg>

This keeps the strokes, if specified, from changing (in other words, the strokes will remain at 1px even if the overall SVG is scaled) when the SVG is scaled. We also add fill: none; to a class in our CSS script where we also control the stroke color as they will fill with #000000 by default.That's it! Now, you have beautiful pixel adherent strokes that will maintain stroke width!

And after all is said and done (and you have preprocessed via grunt-svgstore per the first article), your SVG will look like this in the defs file:

<svg> <symbol viewBox="0 0 18 18" id="icon-task-stroke"> <title>icon-task-stroke</title> <path class="non-scaling-stroke" stroke-miterlimit="10" d="M5.5 1.5h-5v16h17v-16h-5"/> <path class="non-scaling-stroke" stroke-miterlimit="10" d="M5.5.5h7v4h-7zM3 4.5H.5M17.5 4.5H15"/> <path class="non-scaling-stroke" stroke="currentColor" stroke-miterlimit="10" d="M6 10l2 2 4-4"/> </symbol> </svg> CodePen Example

The icon set on the left is scaling proportionately, and on the right, we are using the vector-effect: non-scaling-stroke;. If your noticing that your resized SVG icon's strokes are starting to look out of control, the above technique will give you the ability to lock those babies down.

See the Pen SVG Icons: Non-Scaling Stroke by Chris Rumble (@Rumbleish) on CodePen.

Gotcha Ten: Accessibility

With everything involved in getting your SVG icon system up-and-running, it's easy to overlook accessibility. That's a shame, because SVGs are inherently accessible, especially if compared to icon fonts which are known to not always play well with screen readers. At bare minimum, we need to sprinkle a bit of code to prevent any text embedded within our SVG icons from being announced by screen readers. Although we'd love to just add a <title> tag with alternative text and "call it a day", the folks at Simply Accessible have found that Firefox and NVDA will not, in fact, announce the <title> text.

Their recommendation is to apply the aria-hidden="true" attribute to the <svg> itself, and then add an adjacent span element with a .visuallyhidden class. The CSS for that visually hidden element will be hidden visually, but its text will available to the screen reader to announce. I'm bummed that it doesn't feel very semantic, but it may be a reasonable comprimise while support for the more intuitively reasonable <title> tag (and combinations of friends like role, aria-labelledby, etc.) work across both browser and screen reader implementations. To my mind, the aria-hidden on the SVG may be the biggest win, as we wouldn't want to inadvertantly set off the screen reader for, say, 50 icons on a page!

Here's the general patterns borrowed but alterned a bit from Simply Accessible's pen:

<a href="/somewhere/foo.html"> <svg class="icon icon-close" viewBox="0 0 32 32" aria-hidden="true"> <use xlink:href="#icon-close"></use> </svg> <span class="visuallyhidden">Close</span> </a>

As stated before, the two things interesting here are:

  1. aria-hidden attribute applied to prevent screen readers from announcing any text embedded within the SVG.
  2. The nasty but useful visuallyhidden span which WILL be announced by screen reader.

Honestly, if you would rather just code this with the <title> tag et al approach, I wouldn't necessarily argue with you as it this does feel kludgy. But, as I show you the code we've used that follows, you could see going with this solution as a version 1 implementation, and then making that switch quite easily when support is better…

Assuming you have some sort of centralized template helper or utils system for generating your use xlink:href fragments, it's quite easy to implement the above. We do this in Coffeescript, but since JavaScript is more universal, here's the code that gets resolved to:

templateHelpers = { svgIcon: function(iconName, iconClasses, iconAltText) { var altTextElement = iconAltText ? "" + iconAltText + "" : ''; var titleElement = iconTitle ? "<title>" + iconTitle + "</title>" : ''; iconClasses = iconClasses ? " " + iconClasses : ''; return this.safe.call(this, "<svg aria-hidden='true' class='icon-new " + iconClasses + "'><use xlink:href='#" + iconName + "'>" + titleElement + "</use></svg>" + altTextElement); }, ...

Why are we putting the <title> tag as a child of <use> instead of the <svg>? According to Amelia Bellamy-Royds(Invited Expert developing SVG & ARIA specs @w3c. Author of SVG books from @oreillymedia), you will get tooltips in more browsers.

Here's the CSS for .visuallyhidden. If you're wondering why we're doing it this particular why and not, say, display: none;, or other familiar means, see Chris Coyier's article which explains this in depth:

.visuallyhidden { border: 0; clip: rect(0 0 0 0); height: 1px; width: 1px; margin: -1px; padding: 0; overflow: hidden; position: absolute; }

This code is not meant to be used "copy pasta" style, as your system will likely have nuanced differences. But, it shows the general approach, and, the important bits are:

  • the iconAltText, which allows the caller to provide alternative text if it seems appropriate (e.g. the icon is not purely decorative)
  • the aria-hidden="true" which now, is always placed on the SVG element.
  • the .visuallyhidden class will hide the element visually, while still making the text in that element available for screen readers

As you can see, it'd be quite easy to later refactor this code to use the <title> approach usually recommended down the road, and at least the maintainence hit won't be bad should we choose to do so. The relevant refactor changes would likely be similar to:

var aria = iconAltText ? 'role="img" aria-label="' + iconAltText + '"' : 'aria-hidden="true"'; return this.safe.call(this, "<svg " + aria + " class='icon-new " + iconClasses + "'><use xlink:href='#" + iconName + "'>" + titleElement + "</use></svg>");

So, in this version (credit to Amelia for the aria part!), if the caller passes alternative text in, we do NOT hide the SVG, and, we also do not use the visually hidden span technique, while adding the role and aria-label attributes to the SVG. This feels much cleaner, but the jury is out on whether screen readers are going to support this approach as well as using the visually hidden span technique. Maybe the experts (Amelia and Simply Accessible folks), will chime in on the comments :)

Bonus Gotcha: make viewBox width and height integers or scaling gets funky

If you have an SVG icon that you export with a resulting viewBox like: viewBox="0 0 100 86.81", you may have issues if you use transform: scale. For example, if your generally setting the width and height equal as is typical (e.g. 16px x 16px), you might expect that the SVG should just center itself in it's containing box, especially if you're using the defaults for preserveAspectRatio. But, if you attempt to scale it at all, you'll start to notice clipping.

In the following Adobe Illustrator screen capture, you see that "Snap to Grid" and "Snap to Pixel" are both selected:

The following pen shows the first three icons getting clipped. This particular icon (it's defined as a <symbol> and then referenced using the xlink:href strategy we've already went over), has a viewBox with non-integer height of 86.81, and thus we see the clipping on the sides. The next 3 examples (icons 4-6), have integer width and heights (the third argument to viewBox is width and the fourth is height), and does not clip.

See the Pen SVG Icons: Scale Clip Test 2 by Rob Levin (@roblevin) on CodePen.

Conclusions

The above challenges are just some of the ones we've encountered at Mavenlink having had a comprehensive SVG icon system in our application for well over 2 years now. The mysterious nature of some of these is par for the course given our splintered world of various browsers, screen readers, and operating systems. But, perhaps these additional gotchas will help you and your team to better harden your SVG icon implementations!

More Gotchas Getting Inline SVG Into Production—Part II is a post from CSS-Tricks

Looking for new clients

QuirksBlog - Tue, 07/18/2017 - 1:20am

From September on I am looking for new clients. In fact, I am looking so hard that I updated my About page, something I haven’t done for years.

I’d love to get a job around setting up or troubleshooting an in-house front-end team, or representing unknown browsers to unsuspecting front-enders. I always like fundamental browser research jobs as well, but they’re relatively hard to get since there is limited global interest in that service. Or I can give a new “how to deal with browsers” workshop I’m developing — or even make a website under certain circumstances which boil down to “no frameworks or libraries.”

I have no clue if this is going to help, and I would really hate to be forced into a full-time job, since I’ve become too used to freelancing. But we’ll see.

Anyway, spreading the word would be greatly appreciated.

Exchange from Frere-Jones Type, now in Typekit Marketplace

Nice Web Type - Mon, 07/17/2017 - 5:28am

Fresh off the release of Retina, designed by Tobias Frere-Jones for the grueling small sizes of stock listings, comes Exchange — a counterpart text typeface that was also originally made for the Wall Street Journal. Now Exchange is available to everyone, for web and sync use, on Typekit Marketplace.

The epitome of contemporary news text typefaces, Exchange features refined, balanced letterforms that are expressive in a quiet, consistent way. Its upright letterforms feel smart and well-prepared, like a fresh haircut or a tailored pair of slacks. Its italics are like a brisk walk, its bolds like a sturdy leather briefcase.

Christian Schwartz remarked, “Exchange is the logical endpoint for most of the current trends in news text faces,” naming Exchange one of Typographica’s favorite typefaces.

Comparing (from top) Ionic, Exchange, and Bell Gothic.

Exchange uses optical tricks gleaned from historically successful typefaces for incredible clarity and copy-fitting efficiency at text sizes. Tobias writes:

Exchange’s two main teachers are the “Ionics” of nineteenth century Britain (an early form of slab serif) and Bell Gothic from 1938 in the US. The Ionic serif was a powerful tool for binding letters together into words. And the lowercase arches of Bell Gothic were a terrific defense against ink spread. (Bell Gothic was made for printing phone books at high speed on thin paper, so its strategies have a natural sympathy with newspapers.)

Comprising ten standard styles ranging from Extra Light to Bold, as well as eight MicroPlus styles made for use at small sizes both on screen and in print, Exchange features excellent language support and, as you might expect, all of the features required for the finest text typesetting.

All styles of Exchange are available to license from Typekit Marketplace, which you do not need a paid Creative Cloud subscription to use. With an Adobe ID, you can sync the fonts via the Creative Cloud desktop app. The fonts you purchase are then yours to use in any desktop application, and can be hosted on the web via Typekit as well.

Let us know where you use it, and get in touch with us on Twitter or email if you have any questions about finding Exchange on Marketplace.


Musings on HTTP/2 and Bundling

Css Tricks - Mon, 07/17/2017 - 2:43am

HTTP/2 has been one of my areas of interest. In fact, I've written a few articles about it just in the last year. In one of those articles I made this unchecked assertion:

If the user is on HTTP/2: You'll serve more and smaller assets. You’ll avoid stuff like image sprites, inlined CSS, and scripts, and concatenated style sheets and scripts.

I wasn't the only one to say this, though, in all fairness to Rachel, she qualifies her assertion with caveats in her article. To be fair, it's not bad advice in theory. HTTP/2's multiplexing ability gives us leeway to avoid bundling without suffering the ill effects of head-of-line blocking (something we're painfully familiar with in HTTP/1 environments). Unraveling some of these HTTP/1-specific optimizations can make development easier, too. In a time when web development seems more complicated than ever, who wouldn't appreciate a little more simplicity?

As with anything that seems simple in theory, putting something into practice can be a messy affair. As time has progressed, I've received great feedback from thoughtful readers on this subject that has made me re-think my unchecked assertions on what practices make the most sense for HTTP/2 environments.

The case against bundling

The debate over unbundling assets for HTTP/2 centers primarily around caching. The premise is if you serve more (and smaller) assets instead of a giant bundle, caching efficiency for return users with primed caches will be better. Makes sense. If one small asset changes and the cache entry for it is invalidated, it will be downloaded again on the next visit. However, if only one tiny part of a bundle changes, the entire giant bundle has to be downloaded again. Not exactly optimal.

Why unbundling could be suboptimal

There are times when unraveling bundles makes sense. For instance, code splitting promotes smaller and more numerous assets that are loaded only for specific parts of a site/app. This makes perfect sense. Rather than loading your site's entire JS bundle up front, you chunk it out into smaller pieces that you load on demand. This keeps the payloads of individual pages low. It also minimizes parsing time. This is good, because excessive parsing can make for a janky and unpleasant experience as a page paints and becomes interactive, but has not yet not fully loaded.

But there's a drawback to this we sometimes miss when we split assets too finely: Compression ratios. Generally speaking, smaller assets don't compress as well as larger ones. In fact, if some assets are too small, some server configurations will avoid compressing them altogether, as there are no practical gains to be made. Let's look at how well some popular JavaScript libraries compress:

Filename Uncompressed Size Gzip (Ratio %) Brotli (Ratio %) jquery-ui-1.12.1.min.js 247.72 KB 66.47 KB (26.83%) 55.8 KB (22.53%) angular-1.6.4.min.js 163.21 KB 57.13 KB (35%) 49.99 KB (30.63%) react-0.14.3.min.js 118.44 KB 30.62 KB (25.85%) 25.1 KB (21.19% jquery-3.2.1.min.js 84.63 KB 29.49 KB (34.85%) 26.63 KB (31.45%) vue-2.3.3.min.js 77.16 KB 28.18 KB (36.52%) zepto-1.2.0.min.js 25.77 KB 9.57 KB (37.14%) preact-8.1.0.min.js 7.92 KB 3.31 KB (41.79%) 3.01 KB (38.01%) rlite-2.0.1.min.js 1.07 KB 0.59 KB (55.14%) 0.5 KB (46.73%)

Sure, this comparison table is overkill, but it illustrates a key point: Large files, as a rule of thumb, tend to yield higher compression ratios than smaller ones. When you split a large bundle into teeny tiny chunks, you won't get as much benefit from compression.

Of course, there's more to performance than asset size. In the case of JavaScript, we may want to tip our hand toward smaller page/template-specific files because the initial load of a specific page will be more streamlined with regard to both file size and parse time. Even if those smaller assets don't compress as well individually. Personally, that would be my inclination if I were building an app. On traditional, synchronous "site"-like experiences, I'm not as inclined to pursue code-splitting.

Yet, there's more to consider than JavaScript. Take SVG sprites, for example. Where these assets are concerned, bundling appears more sensible. Especially for large sprite sets. I performed a basic test on a very large icon set of 223 icons. In one test, I served a sprited version of the icon set. In the other, I served each icon as individual assets. In the test with the SVG sprite, the total size of the icon set represents just under 10 KB of compressed data. In the test with the unbundled assets, the total size of the same icon set was 115 KB of compressed data. Even with multiplexing, there's simply no way 115 KB can be served faster than 10 KB on any given connection. The compression doesn't go far enough on the individualized icons to make up the difference. Technical aside: The SVG images were optimized by SVGO in both tests.

Side note: One astute commenter has pointed out that Firefox dev tools show that in the unsprited test, approximately 38 KB of data was transferred. That could affect how you optimize. Just something to keep in mind.

Browsers that don't support HTTP/2

Yep, this is a thing. Opera Mini in particular seems to be a holdout in this regard, and depending on your users, this may not be an audience segment to ignore. While around 80% of people globally surf with browsers that can support HTTP/2, that number declines in some corners of the world. Shy of 50% of all users in India, for example, use a browser that can communicate to HTTP/2 servers (according to caniuse, anyway). This is at least the picture for now, and support is trending upward, but we're a long ways from ubiquitous support for the protocol in browsers.

What happens when a user talks to an HTTP/2 server with a browser that doesn't support it? The server falls back to HTTP/1. This means you're back to the old paradigms of performance optimization. So again, do your homework. Check your analytics and see where your users are coming from. Better yet, leverage caniuse.com's ability to analyze your analytics and see what your audience supports.

The reality check

Would any sane developer architect their front end code to load 223 separate SVG images? I hope not, but nothing really surprises me anymore. In all but the most complex and feature-rich applications, you'd be hard-pressed to find so much iconography. But, it could make more sense for you to coalesce those icons in a sprite and load it up front and reap the benefits of faster rendering on subsequent page navigations.

Which leads me to the inevitable conclusion: In the nooks and crannies of the web performance discipline there are no simple answers, except "do your research". Rely on analytics to decide if bundling is a good idea for your HTTP/2-driven site. Do you have a lot of users that only go to one or two pages and leave? Maybe don't waste your time bundling stuff. Do your users navigate deeply throughout your site and spend significant time there? Maybe bundle.

This much is clear to me: If you move your HTTP/1-optimized site to an HTTP/2 host and change nothing in your client-side architecture, it's not going to be a big deal. So don't trust blanket statements some web developer writing blog posts (i.e., me). Figure out how your users behave, what optimizations makes the best sense for your situation, and adjust your code accordingly. Good luck!

Jeremy Wagner is the author of Web Performance in Action, an upcoming title from Manning Publications. Use coupon code sswagner to save 42%.

Check him out on Twitter: @malchata

Musings on HTTP/2 and Bundling is a post from CSS-Tricks

Did CSS get more complicated since the late nineties?

Css Tricks - Sat, 07/15/2017 - 2:53am

Hidde de Vries gathers some of the early thinking about CSS:

There is quite a bit of information on the web about how CSS was designed. Keeping it simple was a core principle. It continued to be — from the early days and the first implementations in the late nineties until current developments now.

The four main design principles listed are fascinating:

  • Authors can specify as much or little as they want
  • It is not a programming language by design
  • They are agnostic as to which medium they are used for
  • It is stream-based

So... did it?

I think lots has changed since the early nineties, but not really things that touch on how we apply CSS to structured markup.

Direct Link to ArticlePermalink

Did CSS get more complicated since the late nineties? is a post from CSS-Tricks

Inkwell: welcome to our universe

Typography - Fri, 07/14/2017 - 3:44am

Informal is not an adjective that readily comes to mind in describing anything in the type catalogue of New York foundry, Hoefler & Co. From the highly formal sparkle of Renaissance inspired text romans like Requiem through its humanist sans, Ideal Sans, to the precision and aplomb of the shaded and layered Obsidian, all walk the page with a decidedly formal poise. Perhaps the closest they have come to informality is in the beautiful cursive letterforms in the italic styles of the recently released ‘non-typewriter typewriter face’, Operator – but again, informal those letters are not.

Inkwell, then, is unusual in two respects: first, that it marks H&Co’s first foray into informal fonts (and scripts!); and second, that it is a family that extends across genres from a constructed, yet assuredly handwritten inline script through informal Blackletter and Tuscan styles. Uniting these otherwise disparate family members are, not the calligrapher’s quills and nibs but the everyday writing tools that we all reach for to take and make notes.

Each core style in this ‘little universe of fonts’ comes in six weights. I particularly like the Tuscan. Why bifurcate the terminals when you can simply bifurcate everything – even the symbols and punctuation! Wonderful.

A selection of symbols from Inkwell Tuscan Medium

If informal fonts were candy, then comic sans is the jaw-aching, tongue-staining gobstopper – Inkwell, the Fair Trade, organic, very dark chocolate. Too, Inkwell demonstrates that informal need not mean disheveled and insolent. Inkwell is beautifully turned out – informal yet sophisticated.

For much greater erudition and eloquence than I can ever muster on the subject of Inkwell’s genesis and evolution, go enjoy Jonathan Hoefler’s talk at the Typographics conference.



Sponsored by Hoefler & Co.

Inkwell: welcome to our universe

Let’s say you wanna open source a little thing…

Css Tricks - Fri, 07/14/2017 - 3:43am

Let's say you've written a super handy little bit of JavaScript. Nice! Well done, you. Surely, the world can benefit from this. A handful of people, at least. No need to keep this locked up. You've benefitted from open source tremendously in your career. This is the perfect opportunity to give back!

Let's do this.

You're going to need to chuck it into a GitHub repo. That's like table stakes for open source. This is where people can find it, link to it, see the code, and all that. It's a place you can push changes to if you need to.

You'll need to pick a license for it. If the point of this is "giving back" you really do need to, otherwise, it's essentially like you have the exclusive copyright of it. It's somewhat counter-intuitive, but picking a license opens up usage, rather than tightening it.

You'll need to put a README in there. As amazingly self-documenting you think your code is, it isn't. You'll need some plain-language writing in there to explain what your thing is and does. Usage samples are vital.

You'll probably wanna chuck some demos in there, too. Maybe a whole `/demos/` directory so the proof can be in the pudding.

While you've made some demos, you might as well puts some tests in there. Those go hand-in-hand. Tests give people who might use your thing some peace of mind that it's going to work and that as an author you care about making sure it does. If you plan to keep your thing updated, tests will ensure you don't break things as you make changes.

Speaking of people using your thing... just how are they going to do that? You probably can't just leave a raw function theThing () in `the-thing.js`! This isn't the 1800's, they'll tell you. You didn't even wrap an IIFE around it?! You should have at least made it a singleton.

People are going to want to const theThing = require("the-thing.js"); that sucker. That's the CommonJS format, which seems reasonable. But that's kinda more for Node.js than the browser, so it also seems reasonable to use define() and return a function, otherwise known as AMD. Fortunatly there is UMD, which is like both of those at the same time.

Wait wait wait. ES6 has now firmly arrived and it has its own module format. People are for sure going to want to import { theThing } from './the-thing.js';, which means you're going to need to export function theThing() { }.

So what should you do here? Heck if I know. I'm sure someone smart will say something in the comments.

Whatever you decide though, you'll probably separate that "module" concern away from your authored code. Perhaps a build process can help get all that together for you. Perhaps you can offer your thing in all the different module formats, so everybody is happy. What do you use for that build process? Grunt? Gulp? Too old? The hip thing these days is an npm script, which is just some terminal commands put into a `package.json` file.

While your build processing, you might as well have that thing run your tests. You also might as well create an uglified version. Every library has a `the-thing.min.js`, right? You might as well put all that auto generated stuff into a `/dist/` folder. Maybe you'll even be super hip and not check that into the repo. If you want this thing, you grab the repo and build it yourself!

Still, you do want people to use this thing. Having the public repo isn't enough, it's also going to need to go on npm, which is a whole different site and world. Hopefully, you've done some naming research early, as you'll need to name your package and that must be unique. There is a variety of other stuff to know here too, like making sure the repo is clean and you've ignored things you don't want everyone to download with the package.

Wait what about Yarn? Isn't that the new npm or something? You might want to publish there too. Some folks are hanging onto Bower as well, so you might wanna make your thing work there too.

OK! Done! Better take a quick nap and get ready for the demands to start rolling in on the issues board!

Just kidding everything will be fine.

Let’s say you wanna open source a little thing… is a post from CSS-Tricks

PWA Stats

Css Tricks - Fri, 07/14/2017 - 2:17am

A community-driven list of stats and news related to Progressive Web Apps

Things like:

Twitter Lite saw a 65% increase in pages per session, 75% in Tweets, and a 20% decrease in bounce rate. Twitter Lite loads in under 3 seconds for repeat visits even on slow networks.

It's in the same veins as WPO Stats, which is focused solely on web performance and positive effects of doing a good job.

Direct Link to ArticlePermalink

PWA Stats is a post from CSS-Tricks

Join us to test a new feature on Typekit

Nice Web Type - Thu, 07/13/2017 - 7:25am

We’ve been working on a new feature for finding fonts on Typekit, and we’d love to see what you think of it before we officially launch it later this year.

Will you be in San Francisco or New York anytime from July 24 — August 4? We’re going to run user testing sessions in our office locations in both cities during that time and welcome you to join!

Testing sessions will take about an hour, and participants will all get a $25 gift card for their time. You don’t need to have an active Typekit or Creative Cloud subscription to participate, and we won’t be testing you on your typographic know-how either. We’ll have a computer all set up for the session when you get here, and we’ll be eager to hear your thoughts!

Interested? Great! We’ll need a little info so we can get in touch with you and schedule a time, so please submit this registration form to get started. You’ll hear back from us by the end of the next business day.


Media Temple

Css Tricks - Thu, 07/13/2017 - 2:49am

Media Temple has always been huge supporters of the web design and development communities. They got some deals cookin' right now to celebrate the 20th anniversary of CSS itself. Funny to think this site is just about exactly half as old as its namesake. Over on their blog, Alex Rojas rounded up some highlights of those first 20 years, and I did similarly.

I've used Media Temple for hosting for this site, and dozens and dozens of others, throughout my years in web development.

One of the things I always think about with hosting is speed. To be perfectly honest, a host can only do so much for you. As long as you're on good hardware that is appropriate for your site, the rest of that, say 90%, is on you. You need to make good choices, write good code, do persistent monitoring, and all that.

When you're working on site performance, and looking at that all-important waterfall of requests, the vast majority of that are front-end concerns. It's that very first line, the document itself, that is the primary back-end concern, and where hosting comes most into play.

I'll take a 100ms timing for that document any day.

Direct Link to ArticlePermalink

Media Temple is a post from CSS-Tricks

Methods to Organize CSS

Css Tricks - Thu, 07/13/2017 - 2:48am

Developer Ben Frain once remarked that it's easy to write CSS code, but it is hard to scale and support it. This article describes the set of solutions out there to deal with this problem.

OOCSS

OOCSS stands for object-oriented CSS. This approach has two main ideas:

  • Separation of structure and design
  • Separation of container and content

Using this structure, the developer obtains general classes that can be used in different places.

At this step, there are two pieces of news (as usual, good and bad):

  • Good: reducing the amount of code by reusing it (DRY principle).
  • Bad: complex support. When you change the style of a particular element, you will most likely have to change not only CSS (because most classes are common), but also add classes to the markup.

Also, the OOCSS approach itself does not offer specific rules, but abstract recommendations, so how this method ends up in production varies.

As it happens, the ideas in OOCSS inspired others to create their own, more concrete, ways of code structuring.

SMACSS

SMACSS stands for Scalable and Modular Architecture for CSS. The main goal of the approach is to reduce the amount of code and simplify code support.

Jonathan Snook divides styles into 5 parts:

  1. Base rules. These are styles of the main website elements - body, input, button, ul, ol, etc. In this section, we use mainly HTML tags and attribute selectors, in exceptional cases - classes (for example, if you have JavaScript-style selections);
  2. Layout rules. Here are the styles of global elements, the size of the cap, footer, sidebar, etc. Jonathan suggests using id here in selectors since these elements will not occur more than 1 time on the page. However, the author of the article considers this a bad practice (whenever an id appears in the styles, somewhere in the world the kitten is sad).
  3. Modules rules. Blocks that can be used multiple times on a single page. For module classes, it is not recommended to use id and tag selectors (for reuse and context independence, respectively).
  4. State rules. In this section, the various statuses of the modules and the basis of the site are prescribed. This is the only section in which the use of the keyword "! Important" is acceptable.
  5. Theme rules. Design styles that you might need to replace.

It is also recommended to enter the namespace for classes belonging to a certain group, and also to use a separate namespace for the classes used in JavaScript.

This approach makes it easier to write and maintain code, and has attracted a large number of developers.

Atomic CSS

With Atomic CSS, a separate class is created for each reusable property. For example, margin-top: 1px; assumes creation of a class mt-1 or width: 200px; the class w-200.

This style allows you to minimize the amount of CSS-code by reusing declarations, and it's also relatively easy to enter changes into modules, for example, when changing a technical task.

However, this approach has significant drawbacks:

  • Class names are descriptive property names, not describing the semantic nature of the element, which can sometimes complicate development.
  • Display settings are directly in the HTML.

Because of these shortcomings, the approach has been met with a significant amount of criticism. Nevertheless, the approach can be effective for large projects.

Also, Atomic CSS is used in various frameworks to specify corrective element styles and in some layers of other methodologies.

MCSS

MCSS is Multilayer CSS. This style of code writing suggests splitting styles into several parts, called layers.

  • Zero layer or foundation. The code responsible for resetting browser styles (e.g. reset.css or normalize.css);
  • Base layer includes styles of reusable elements on the site: buttons, input fields for text, hints, etc.
  • Project layer includes separate modules and a "context" - modifications of the elements depending on the client browser, the device on which the site/application is viewed, user roles, and so on.
  • Cosmetic layer is written the OOCSS style, making minor changes in the appearance of elements. It is recommended to leave only styles that affect the appearance and are not capable of breaking the layout of the site (e.g colors and non-critical indents).

The hierarchy of interaction between layers is very important:

  • The base layer defines neutral styles and does not affect other layers.
  • Elements of the base layer can only affect the classes of its layer.
  • Elements of the project layer can affect the base and project layers.
  • The cosmetic layer is designed in the form of descriptive OOCSS-classes ("atomic" classes) and does not affect other CSS-code, being selectively applied in the markup.
AMCSS

AMCSS is "Attribute Modules for CSS".

Let's look at an example:

<div class="button button--large button--blue">Button</div>

Such a chain of classes is not simple, so let's group these values by attributes.

Here's what happens:

<div button="large blue">Button</div>

To avoid names collisions, it's a good idea to add namespaces to the attributes. Then our button code takes the following form:

<div am-button="large blue">Button</div>

If you use the validator to check the code and it doesn't like the am-button attribute, you can prefix data- before the attribute name.

A little-known selector "~ =" (IE7+) is used, which works as a class attribute: it selects elements whose attribute values contain the specified words, separated by spaces. So, the selector of the form [class~="link"][class~="button"] is similar to the selector a.class.button. Even by specificity, since the selector specificities for the class and the attribute are equal to each other!

Accordingly, the CSS code

.button {...} .button--large {...} .button--blue {...}

Converts to

[am-button] {...} [am-button~="large"] {...} [am-button~="blue"] {...}

If you think this code is too unusual, you can use a less radical AMCSS form:

<div am-button am-button-large am-button-blue></div> FUN

FUN stands for Flat hierarchy of selectors, Utility styles, Name-spaced components.

There is a certain principle behind each letter of the name:

  • F, flat hierarchy of selectors: it is recommended to use the classes to select items, avoid a cascade without the need, and do not use ids.
  • U, utility styles: it is encouraged to create the service atomic styles for solving typical makeup tasks, for example, w100 for width: 100%; or fr for float: right;
  • N, name-spaced components: Ben recommends to add namespaces for specifying the styles of specific modules elements. This approach will avoid overlapping in class names.

Some developers note that the code written using these principles is quite convenient to write and maintain; in some way, the author took the best from SMACSS and laid out this technique in a simple and concise manner.

This approach imposes quite a few requirements on the project and the code structure, it only establishes the preferred form of recording selectors and the way they are used in the markup. But in small projects, these rules can be quite enough to create high-quality code.

Conclusion

As you can see, there is no ideal one among these approaches. Therefore none of these methods is an absolute rule - you can take an approach from begin to create something of your own, or create a new approach from scratch.

Methods to Organize CSS is a post from CSS-Tricks

Empathy Prompts

Css Tricks - Thu, 07/13/2017 - 2:44am

Activities to help you develop empathy for the variety of people that use your thing. Eric Bailey:

This project is geared towards anyone involved with making digital products. It is my hope that this reaches both:

  • People who are not necessarily involved in the day-to-day part of the process, but who help shape things like budget, timeline, and scope, and
  • People who work every day to help to give these products shape and form

These prompts are intended to help build empathy, not describe any one person's experience. These prompts are not intended to tokenize the experience of the individuals experiencing these conditions.

I love the "share" link on the page. It's basically window.prompt("go ahead");

Direct Link to ArticlePermalink

Empathy Prompts is a post from CSS-Tricks

Net Neutraility

Css Tricks - Wed, 07/12/2017 - 6:46am

I'm linking up a "call to action" style site here as it's nicely done and explain the situation fairly well. Right now, there are rules (in the United States) against internet providers prioritizing speed and access on a site-by-site basis. If they could, they probably would, and that's straight up bad for the internet.

In other "good for the internet" news... does my site need HTTPS?

Direct Link to ArticlePermalink

Net Neutraility is a post from CSS-Tricks

Syndicate content
©2003 - Present Akamai Design & Development.