Front End Web Development

Night Mode with Mix Blend Mode: Difference

Css Tricks - Mon, 05/27/2019 - 5:53am

Dark mode designs are all the rage right now but here’s an interesting take: Wei Gao has built a night mode on her own site that uses mix-blend-mode: difference to create an effect that looks like this:

Wei explains how she implemented this technique and the edge cases she encountered along the way. I especially love what she had to say about mix-blend-mode functions here:

I remember first playing around with them in Photoshop years ago. Now that browsers are becoming more powerful and we are seeing complex graphical features native to browser rendering. This doesn’t mean we should implement a full photoshop in browsers and nor should we limit our imaginations to just that. Browsers and web pages have their own contexts and goals, as well as a different set of limits. Maybe we should welcome them like new habitants and discover use cases native to this territory.

Indeed! Although Wei's technique is pretty unique and awesome on its own, this all ties back into the thing that kicked off the whole trend: the prefers-color-scheme media feature that was released in Safari as part of the MacOS 10.4 release that gave us a dark mode preference setting. This is a developing space, so we're certain to see more innovations and approaches ahead.

Direct Link to ArticlePermalink

The post Night Mode with Mix Blend Mode: Difference appeared first on CSS-Tricks.

Code as Documentation: New Strategies with CSS Grid

Css Tricks - Fri, 05/24/2019 - 4:36am

I work for Supercool, a fast-moving design agency that makes custom built sites for arts clients, powered by the off-the-shelf system, Craft CMS; it's high-spec graphic design with relatively demanding typography and art direction. Over the past few months we’ve been moving to CSS grid. We’re transitioning slowly, allowing ourselves to discover new paradigms and design methods, instead of simply porting old habits to a new syntax.

So far, we've developed a number of really useful strategies for keeping track of the layout. I've written a couple of surprisingly nifty mixins, using named areas and templates, and we've hit upon some basic conventions to create highly readable code. I thought it would be valuable to walk through a fully-developed production implementation of a single major component using grid, digging in to some of the design questions it throws up and steering you away from some pitfalls we’ve encountered. CSS grid is a large spec, with lots of possible approaches and lots of right ways to do things, but at some point you have to lock down your method and get it live.

I’m expecting some basic familiarity with CSS, Sass, BEM, and some interest in the task of prototyping fully-realized, accessible, custom frameworks with 50+ components from Sketch or Photoshop-type documents on a tight timeline (say, a week).

First, let’s identify and separate out the design into distinct coding tasks and plan how we’ll approach them:

  1. Type: The designer has already defined a type system.
  2. Colors: First, we build a theme model and then include that in the partial.
  3. Content: What elements are in this block? What are its variations? This is where our BEM mixin comes in.
  4. Layout: This is how the content is placed in the block. You might want to skip directly to this.
  5. Conventions: This is exactly how we choose to write all the above. There are many right answers in CSS, so what is important is that we all just agree to a convention, the rules of the road. This really comes first, but for the sake of this article, we’ll conclude here.
Type system

We use utility classes (e.g. h-text--h1, h-text--badge) for type styles. There may be a hundred type styles in a project. We export those styles from Sketch right into our Patternlab using Typex. That’s a whole other article on its own, so let’s just stipulate type as handled. We won’t bring type into our component partial.

Color usage

See the Pen
CSS Variable fallbacks mixin v2
by limograf (@Sally_McGrath)
on CodePen.

Theming is a few tiny mixins dropped in, so we ideally won’t see a ton of color rules in our partial. We store them all together in a _themer.scss partial in our "Mixins and Models" library, so we can be sure to follow the design system of the site. This way, when someone comes back to the build later on, they have a key reference partial describing the design and branding rules. When building and maintaining numerous sites in broadly the same market — but each all with different brand spec — you’ve gotta make sure you don’t mix up one brand with another! So, much like type, we abstract the color rules away from the partial. In essence, we’re really only looking at layout (as much as possible) in our _header.scss file.

Given that we agree the convention to always theme using our mixin, this is how it would be included on an element:

@include var($property, $value);

Then we’ll set a theme model, of how colors work on this particular site and apply that theme to a component with:

@include theme;

Here’s the sample theme model we’re going to use with this page header. It’s super simple.

See the Pen
theme model
by limograf (@Sally_McGrath)
on CodePen.

We’re pairing a color with black or white. We depend on a contrast rule and flip them for emphasis, maybe on events, like hover, or a highlighted call to action. This is all we need to do to make that happen and now we have a document of how color should really work on this site. We can go to and check against if we need to debug or expand the UI.

We also want to prep inheritance to help us, so let’s identify some helpful conventions:

  • Set the fills on SVG icons to currentColor in your pipeline (and default size them as width: 1em; height: 1em; font-size: inherit; in the CSS while we’re at it).
  • Set <body> and <a> to currentColor) at base.
  • Write shorthand, inheriting borders (e.g. 1px solid or 1px solid currentColor).

Using this theme model, we might generate any number of themes, perhaps storing them as utility classes, or looping over a list of modifiers inside a component, or just allowing the user to set variables right on the block in the CMS. When IE 11 drops below 1% in our stats, we can do much more with variables, but this is enough for our current purposes.

Let’s not get side-tracked. What about grid?!

Content components

Grid lets us describe exactly what content we have in each partial in a new way. It’s really a game changer for design agencies building new UI for every project and we’re discovering new (and fun) applications for it as we explore.

To give context: we customize each interface for our clients, with custom fields made to suit their specific needs and their content model, using Craft CMS. We have internal tools that pull in events from ticketing APIs and create entries from that data, which may then be edited and expanded (or created entirely) in the CMS. The client can fill in or edit named fields in permanent page regions, and also add in whole designed, branded content blocks into the layout of each page as they build them.

There’s a lot of UI. The clients have a lot of control over content and we have a lot of control over the HTML, so we can ensure a high standard of accessible, semantic code on the page. We develop the content model together during discovery and then turn ’em loose on content creation. They add what they want and we ensure that it works and always looks right. Better than right! Super. (Sorry! :P)

So, as a developer, I have to balance competing priorities:

  • Accessibility, usability
  • Branding and graphic design
  • Performance
  • Maintenance and codebase health

Let’s look at those one by one:

Accessibility

Accessible, logical HTML is my jam. At minimum, I require a green accessibility score on Lighthouse score for my projects. (Who am I kidding, I want that delicious 100!) Core paths and pages are tested with a couple of screen readers, the keyboard tab, keyboard navigation), low vision simulators, dasher, voice access and binary switch. (I also work for Robots and Cake so this is a big part of my development.) I add giant clickable phone numbers and email addresses to pages over and over. I just want to get people where they are going.

I’ve been concerned about the way content can be re-ordered with grid (and flexbox, for that matter). Having gone through a few builds now, I actually think grid can help us with this problem. With CSS Grid, there’s no reason to move around HTML in service to the layout. We can go back to thinking about the whole document as a logical, linear sequence as our first concern.

Branding vs. Performance vs. Maintenance

Arts venues require high-spec graphic design, unified across print and web, and have constantly changing materials (e.g. programs, brochures, tickets, posters, microsites, etc.) they need to get out to their audiences, including contractual marketing obligations that must be met. As you can imagine, we have a lot of high quality large images we have to prioritize and typically come with strong print-led branding. That means we may be serving around fifteen custom fonts (including weight variations, display faces, etc.) and complex CSS to the page as well. We have to keep ourselves as lean as we can. We are shipping CSS that’s around 20 KB nano Gzipped at the moment but I’m working on reducing it further.

However, we do keep the grid area names full length by setting reduce identifiers to false in our PostCSS task. It’s vastly more useful to have the layout maps available in DevTools than it is to save those few bytes. For maintenance, self-documentation, and the sake of your future self who is debugging this site without repo access on a delayed train in Sowerby Bridge: keep the maps.

Code health

The way to balance all these competing needs is to articulate and agree on conventions so that there’s less to fix in testing and so that solved problems stay solved. We examine all the components we build and make sure they always start with a heading, that links go places, and buttons trigger actions, that countable objects are delivered as a list and preceded by a landmark heading, that navs are <nav> and times are <time> and div soup is eaten for breakfast— the basics.

With CSS Grid, there’s no excuse to move around HTML in service to the layout. Your content can always flow logically while changes in layout happen in CSS. And, as there’s no need for margins or padding to create gutters, you can simply declare:

.o-grid .o-grid { width:100%; }

...to be sure any number of nested groups all visually occupy the same page grid. The HTML can be a clearer guide to what things really are: a closer document.

See the Pen
lock down semantic accessible structures
by limograf (@Sally_McGrath)
on CodePen.

There’s a lot to manage between the heading and the action, and it’s my challenge to keep track of all these fields in all those components and make it traversable, scannable, linearizable, and easily read in some kind of logical, understandable manner, while making sure I’m faithfully executing the design spec.

Let’s bring in my first, surprisingly useful, grid mixin.

@mixin template($elements...) { @each $element in $elements { &__#{$element} { grid-area: $element; } } }

Using this mixin everywhere means:

  1. Each component partial now starts out with a list of all its possible elements, which is a very handy piece of documentation, especially when Twigging the actual front-end component.
  2. The mixin takes care of assigning the grid areas.
  3. Element and component names stay consistent across Sketch, CSS, and HTML and any inconsistencies will be very obvious, as the layout will fail. I’m firm, but fair.
  4. BEM naming is enforced automatically but isn’t muddling things up in the partial.

Now, in the partial, we will just declare grid-template-areas, using normal English words, giving us a series of maps of the layouts that also match the database fields. Super readable!

Here’s an example of this mixin working:

See the Pen
BEM ELEMENT AUTO ASSIGN
by limograf (@Sally_McGrath)
on CodePen.

We decided to stick to named areas for internal grids because I read a great article on this very site explaining how Autoprefixer can handle grid for IE 11 if you stick to the listed supported properties — and it does for the most part. If you view this test case with Autoprefixer applied in the super useful Debug Mode in a browser test, you’ll see it working.

So far, so good.

But there are pitfalls! You must set inline elements to block to make sure they always operate as grid cells in IE 11. Comment out the marked line in the example to see what happens otherwise:

Debug has caught an issue.

Ouch! Be careful with those blocks. You may find some versions of IE 11 don’t even pick up this fix, in which case you might try just using plain ol’ <p> tags... sigh.

I don’t include display: grid in this mixin because there are scenarios where the actual grid is set on an inner container, for example, but we’d still want the grid-areas to match on the correct BEM class.

So:

.c-header{ @include template(title, pretitle, posttitle, producer, venue, credit, quote, nav, infobar, search); }

Let’s lay these suckers out.

Layout

Let’s identify a few more rules of the road to ensure this component slides right into a page layout without hassle. At time of writing, there’s no subgrid) available (but there will be!), so this component knows nothing of the parent grid it’s living in. This happens to match the BEM component approach well — as each component is written flat, and orphaned, to limit inheritance. I’m not advocating for BEM (or BEM-ish as we obviously use) here — I’m just saying that if you’re already using it, this is a bonus.

In this example, the designer has set a page layout of 12 column grid with 20px (1.25rem) gutters, site-wide, with no offset pieces. Our component is a page region and will occupy all 12 grid columns. In this transitional period, we’re still using this kind of set grid as we have a ton of systems still based on this idea that we have to integrate with. So, here’s our convention for this condition: for a full width region drop the grip gap and write the grid template columns as fractional units (fr) of 12.

Doing things this way means:

  1. the sight lines of this internal grid broadly follow the grid it sits within;
  2. it’s easy to see the underlying design rules in the code; and
  3. it’s easy to line things up exactly, if required.
A quick note on "lining up"

Wait... what do I mean 'to have things line up exactly'? Doesn’t it already line up exactly?

Two equal columns split mid-gutter of the parent 12-column grid.

Well, no. The fractional units approach divides across the space perfectly, so you end up in the gutter. Two even columns lands you halfway across the gutter. Two columns where one is 2/3 and the other is 1/3 will split 1/3 of the way across that gutter, and so on.

Two unequal columns (set to 2fr and 1fr, respectively) split a third of the way into a gutter of the 12-column parent grid.

It’s not exactly hard to fix the alignment, as we know the width of our page grid gutter. For example, on an even split, we could include the grid gap.

However, we can’t do that with any other division. What we can do is add that gap as a margin — the margin is added inside no matter what box sizing you have set. In this example, we have three columns (two named areas and one empty space), splitting our gutter into thirds:

This is how to calculate those margins: Make sure the total fr units sum results in 12. Divide the grid gap by the number of columns in the parent grid, then multiply that like so:

The right margin multiplier of n is equal to the sum of the fr units to the right of n. The left margin of n is equal to the sum of the fr units to the left of n.

So, for grid-template-columns with a value of 2fr 3fr 2fr 4fr 1fr:

2 3 2 4 1 0/10 2/7 5/5 7/1 11/0

See the Pen
name spec inside and number spec outside -- page region, desktop
by limograf (@Sally_McGrath)
on CodePen.

You could even write that as a mixin if you find yourself writing calc() a lot. Something like this for aligning an inner grid to the parent grid:

See the Pen
auto align inner grid to parent grid
by limograf (@Sally_McGrath)
on CodePen.

...and something like this to auto-calculate margins when the name is specified inside but the number is specified outside the grid:

See the Pen
name spec inside and number spec outside -- auto calc margins
by limograf (@Sally_McGrath)
on CodePen.

I’m sure you can think of other solutions, like switching to named lines, or adding in extra fixed-width columns or even writing all maps with 12 named areas per row. There are so many ways you can deal with this, but I think a lot of them remove the advantage of named areas. Areas give us a readable layout map that contains what our future selves need to know. It is code as documentation.

To be clear, the design problem I’m walking us through is not one of alignment. Alignment is easy with grid. The question is not of solving the immediate, trivial, layout problem, but of solving it in a way that supports our goal of being able to come back in six months and grasp:

  1. What elements are in the component.
  2. How they are laid out.
  3. Why the code is written in this way.

The grid specification is huge and it’s easy to get lost in the options. Perhaps it’s a better plan to reset to a 12-column grid and use the number spec (i.e. explicitly link to our page grid, which uses the number spec) when absolute alignment is required — but I do feel there’s a smarter, simpler solution waiting to be found. For this site, we ended up writing a page grid object and added nested internal grid cells to it with classes: .o-page-grid__sidebar.

What do you all think? I definitely foresee differing perspectives on this. &#x1f926;‍♀️

A real, live grid!

We can use this to create a generic page header:

See the Pen
01 - Generic Page header
by limograf (@Sally_McGrath)
on CodePen.

Or, we can create a variation of the homepage:

See the Pen
02 - Home page
by limograf (@Sally_McGrath)
on CodePen.

What about a hero header that breaks out of our container? Sure! Or we can deliver it outside the container as well:

See the Pen
03 - Hero
by limograf (@Sally_McGrath)
on CodePen.

What next? A themed event header with a full width info bar that sticks and an internal button that lines up with the sidebar on the parent grid? You bet. I’ll include a parent grid so it’s easier to see:

See the Pen
04 - Event header
by limograf (@Sally_McGrath)
on CodePen.

What about a search with a central alignment? Let’s use a collapsing columns technique:

See the Pen
06 - Search with central alignment
by limograf (@Sally_McGrath)
on CodePen.

Here’s a demo of all these variations as one partial. Yes, it’s a map! And it’s a wrap!

Conventions

Phew, we covered a lot! But you can see how flexible and self-documenting a system like this can be, right?

  1. Type is handled with a separate type system.
  2. Colors are handled by a theme partial that describes the underlying color rules of the design, rather than simply coloring elements ad hoc.
  3. Elements are called what they are, in English, and included as a list at the top of the partial with the template mixin. This list can be taken into Twig or a template as a reference.
  4. Correct HTML is always used and nesting doesn’t break grid. That means you can apply any number of nested grids to the same layout space by setting a convention.
  5. Precise alignment is done in a number spec, and not a name spec (but note that alignment is possible with name spec).
  6. IE 11 is supported.
  7. I do have one more quick note and example of another component built with named areas. In this example, cards are not regions, but components placed in a grid, so there’s no reason to use the fr of 12 convention. You can expect a media object partial to look like this:

    .c-card { &--news { align-content: start; grid-template-areas: "image" "datetime" "title"; } &--search { justify-content: start; grid-template-columns: 1fr 3fr; grid-template-areas: "image page" "image title" "image summary"; } &--merchandise { grid-gap: 0; grid-template-columns: $b 1fr 1fr $b; grid-template-areas: "image image image image" ". title title ." ". summary summary ." ". price action ."; } &--donations { // donations thanks button is too long and must take up more space than input grid-gap: 0; grid-template-columns: $b 1fr 2fr $b; grid-template-areas: "image image image image" ". title title ." ". summary summary ." ". input action ."; } } // ...

    The post Code as Documentation: New Strategies with CSS Grid appeared first on CSS-Tricks.

Weekly Platform News: Mozilla WebThings, Internet Explorer mode, GraphQL

Css Tricks - Fri, 05/24/2019 - 4:28am

Šime posts regular content for web developers on webplatform.news.

Mozilla WebThings provides complete privacy for user data

If you, like many we surveyed, are also concerned about the security & privacy of you smart home check out @MozillaIoT's decentralized, open source solution for keeping your smarthome devices at bay—or learn more dropping by our Bay Area Maker Faire booth! https://t.co/rUcYpjBySH

— Mozilla Hacks (@mozhacks) May 17, 2019

Josephine Lau: Smart home companies require that users’ data goes through their servers, which means that people are giving up their privacy for the convenience of a smart home device (e.g., smart light bulb).

We’ve learned that people are concerned about the privacy of their smart home data. And yet, when there’s no alternative, they feel the need to trade away their privacy for convenience.

Mozilla WebThings is an alternative approach to the Internet of Things that stores user data in the user’s home. Devices can be controlled locally via a web interface, and the data is tunneled through a private HTTPS connection.

A diagram showing how Mozilla doesn’t store user data in the cloud, unlike smart home vendors. An Internet Explorer mode is coming to Edge

Still have questions on the recently announced IE mode? Our very own Fred Pullen has all the answers. Check out his in-depth breakdown on how the new IE mode works, and the benefits it will bring to our enterprise community once it goes live.https://t.co/RgewXGC1G2

— Microsoft Edge Dev (@MSEdgeDev) May 17, 2019

Fred Pullen: The next version of Edge will include an Internet Explorer mode for backward compatibility with legacy websites. Edge will also for the first time be available on older versions of Windows (including Windows 7 and 8.1).

By introducing Internet Explorer mode, we’re effectively blurring the lines between the browsers. From an end-user standpoint, it seems like a single browser. … You can use IE mode to limit the sites that instantiate Internet Explorer just to the sites that you approved.

Quick hits: Other interesting articles

Introducing the first Microsoft Edge preview builds for macOS (Microsoft Edge Blog)

Edge Canary (analogous to Chrome Canary) is now officially available on macOS. This version of Edge updates daily.

With our new Chromium foundation, you can expect a consistent rendering experience across the Windows and macOS versions of Microsoft Edge.

#EmberJS2019 More Accessible Than Ever (Yehuda Katz)

Navigating from one page to another in a client-side web app provides no feedback by default in virtually all popular routing solutions across the client-side ecosystem.

Their goal is to make Ember’s router more accessible and screen reader friendly.

Opinion: Five developer trends to watch in 2019 (DeveloperTech)

The article includes a good, short explanation of what GraphQL is and what problems it solves.

Part 2: What the Fr(action)? (CSS IRL)

Read the last section ("Intrinsic and extrinsic sizing"). All three columns have the size 1fr but the middle one is wider because of its content. This can be prevented by using the size minmax(0, 1fr) instead.

Parallel streaming of progressive images (Cloudflare Blog)

Instead of loading from top to bottom, progressive images appear blurry at first and become sharper as more data loads.

The benefits of progressive rendering are unique to JPEG (supported in all browsers) and JPEG 2000 (supported in Safari). GIF and PNG have interlaced modes, but these modes come at a cost of worse compression. WebP doesn't even support progressive rendering at all. This creates a dilemma: WebP is usually 20%-30% smaller than a JPEG of equivalent quality, but progressive JPEG appears to load 50% faster.

The post Weekly Platform News: Mozilla WebThings, Internet Explorer mode, GraphQL appeared first on CSS-Tricks.

The Power of Serverless v2.0! (Now an Open-Source Gatsby Site Hosted on Netlify)

Css Tricks - Thu, 05/23/2019 - 9:01am

I created a website called The Power of Serverless for Front-End Developers over at thepowerofserverless.info a little while back while I was learning about that whole idea. I know a little more now but still have an endless amount to learn. Still, I felt like it was time to revamp that site a bit.

For one thing, just like our little conferences website, the new site is a subdomain of this very site:

https://serverless.css-tricks.com/

Why? What's this site all about?

The whole idea behind the serverless buzzword is a pretty big deal. Rather than maintaining your own servers, which you already buy from some other company, you architect your app such that everything is run on commoditized servers you access on-demand instead.

Hosting becomes static, which is rife with advantages. Just look at Netlify who offer blazing-fast static hosting and innovate around the developer experience. The bits you still need back-end services for run in cloud functions that are cheap and efficient.

This is a big deal for front-end developers. We've already seen a massive growth in what we are capable of doing on the front end, thanks to the expanding power of JavaScript. Now a JavaScript developer can be building entire websites from end-to-end with the JAMstack concept.

But you still need to know how to string it all together. Who do you use to process forms? Where do you store the data? What can I use for user authentication? What content management systems are available in this world? That's what this site is all about! I'd like the site to be able to explain the concept and offer resources, but more importantly, be a directory to the slew of services out there that make up this new serverless world.

The site also features a section containing ideas that might help you figure out how you might use serverless technology. Perhaps you'll even take a spin making a serverless site.

Design by Kylie Timpani and illustration by Geri Coady

Kylie Timpani (yes, the same Kylie who worked on the v17 design of this site!) did all the visual design for this project.

Geri Coady did all the illustration work.

If anything looks off or weird, blame my poor implementation of their work. I'm still making my way through checklists of improvements as we speak. Sometimes you just gotta launch things and improve as you go.

Everything is on GitHub and contributions are welcome

It's all right here.

I'd appreciate any help cleaning up copy, adding services, making it more accessible... really anything you think would improve the site. Feel free to link up your own work, although I tend to find that contributions are stronger when you are propping up someone else rather than yourself. It's ultimately my call whether your pull request is accepted. That might be subjective sometimes.

Before doing anything dramatic, probably best to talk it out by emailing me or opening an issue. There's already a handful of issues in there.

I suspect companies that exist in this space will be interested in being represented in here somewhere, and I'm cool with that. Go for it. Perhaps we can open up some kind of sponsorship opportunities as well.

Creating with components: A good idea

I went with Gatsby for this project. A little site like this (a couple of pages of static content) deserves to be rendered entirely server-side. Gatsby does that, even though you work entirely in React, which is generally thought of as a client-side technology. Next.js and react-static are similar in spirit.

I purposely wanted to work in JavaScript because I feel like JavaScript has been doing the best job around the idea of architecting sites in components. Sure, you could sling some partials and pass local variables in Rails partials or Nunjucks includes, but it's a far cry from the versatility you get in a framework like React, Vue or Angular that are designing entirely to help build components for the front end.

The fact that these JavaScript frameworks are getting first-class server-side rendering stories is big. Plus, after the site's initial render, the site "hydrates" and you end up getting that SPA feel anyway... fantastic. Yet another thing that shows how a JavaScript-focused front-end developer is getting more and more powerful.

As an aside: I don't have much experience with more complicated content data structures and JAMstack sites. I suspect once you've gone past this "little simple cards of data" structure, you might be beyond what front-matter Markdown files are best suited toward and need to get into a more full-fledged CMS situation, hopefully with a GraphQL endpoint to get whatever you need. Ripe space, for sure.

The post The Power of Serverless v2.0! (Now an Open-Source Gatsby Site Hosted on Netlify) appeared first on CSS-Tricks.

Front-End Documentation, Style Guides and the Rise of MDX

Css Tricks - Thu, 05/23/2019 - 4:29am

You can have the best open source project in the world but, if it doesn’t have good documentation, chances are it’ll never take off. In the office, good documentation could save you having to repeatedly answer the same questions. Documentation ensures that people can figure out how things work if key employees decide to leave the company or change roles. Well documented coding guidelines help bring consistency to a codebase.

If you’re writing long-form text, Markdown is clearly a great alternative to authoring HTML. Sometimes though, Markdown syntax isn’t enough. It’s always been possible to write straight HTML inside of Markdown documents. This includes custom elements so, if you’re building a design system with native web components, it’s easy to incorporate them inside your text-based documentation. If you’re working with React (or any other framework that speaks JSX, like Preact or Vue), you can do the same thing by using MDX.

This article is a broad overview of the tools available for writing documentation and for building style guides. Not all the tools listed here make use of MDX but it’s increasingly being incorporated into documentation tooling.

What is MDX?

A .mdx file has exactly the same syntax as a regular Markdown file, but lets you import interactive JSX components and embed them within your content. Support for Vue components is in alpha. It’s easy to get MDX set up with Create React App. There are MDX plugins for Next.js and Gatsby. The forthcoming version two release of Docusaurus will also come with built-in support.

Writing documentation with Docusaurus

Docusaurus is made by Facebook and used by every Facebook open source project, apart from React. It’s also used by many major open source projects outside of Facebook, including Redux, Prettier, Gulp and Babel.

Projects making use of Docusaurus.

You can use Docusaurus to document anything — it isn’t front-end specific. Docusaurus uses React under the hood, but you don’t have to know that framework to make use of it. It’ll take your Markdown files and turn them into a nicely-structured, well-formatted and readable documentation site, with a nice design right out of the box.

The Redux site shows the typical Docusaurus layout

Sites created with Docusaurus can also include a Markdown-based blog. Prism.js is included by default for zero-setup syntax highlighting. While relatively new, Docusaurus has proven popular, being voted the number one new tool of 2018 on StackShare.

Other options for written content

Docusaurus specifically caters to building documentation. Of course, there are a million and one ways to make a website — so you could roll your own solution with any back-end language, CMS, or static site generator.

The documentation sites for React, IBM’s design system, Apollo and Ghost CMS use Gatsby, for example — a generic static site generator often used for blogs. If you work with the Vue framework, VuePress is becoming a popular option. MkDocs is an open source static site generator for creating documentation, written in Python and configured with a single YAML file. GitBook is a popular paid product that’s free for open-source and non-profit teams. If you're building internal documentation and want something easy, the reading experience on GitHub itself isn’t half bad, so you could just commit some Markdown files and leave it at that.

Documenting components: Docz, Storybook and Styleguidist

Style guides, design systems, pattern libraries — whatever you want to call them — have become a hugely popular area of concern in the last decade. What’s really made the difference in turning them from vanity projects into useful tools isn’t the pontificating of thought leaders but the emergence of component-driven frameworks, like React, and the tools mentioned here.

Storybook, Docz and Styleguidist all do much the same thing: display interactive UI components and document their API. A project may have dozens or even hundreds of components to keep track of — all with a variety to states and styles. If you want components to be reused, people have to know that they exist. We aid discoverability when we catalog components. A style guide gives an easily searchable and scannable overview of all your UI components. This helps to maintain visual consistency and avoid duplicating work.

These tools provide a convenient way to review different states. It can be difficult to reproduce every state of a component in the context of a real application. Rather than needing to click through an actual app, developing a component in isolation can be helpful. Hard-to-reach states (like a loading state, for example) can be mocked.

Dan Green wrote a nice synopsis of the benefits of using Storybook, but it applies equally to Docz and Styleguidist:

"Storybook has made it really easy for designers who code to collaborate with engineers. By working in storybook they don't need to get a whole environment running (docker container, etc). For Wave, we have many important components that are only visible in the middle of a process that is short lived and time consuming to reproduce (i.e. a loading screen that only shows while a user is having their payment account set up). Before Storybook, we didn't have a good way to work on these components and were forced to temporary hacks in order to make them visible. Now, with Storybook we have an isolated place to easily work on them, which has the bonus feature of being easily accessible for designers and PMs. It also makes it really easy for us to show off these states in sprint demos."

- Dan Green, Wave Financial

As well as visualizing different states side-by-side and listing props, its often helpful to have written content about a component — whether its explaining the design rationale, use-cases, or describing the results of user-testing. Markdown is easy enough for *anybody* to learn — ideally a style guide should be a joint resource for designers and developers that both disciplines contribute to. Docz, Styleguidist and Storybook all offer a way to seamlessly intermingle Markdown with the components themselves.

Docz

Currently, Docz is a React-only project, but is working on support for Preact, Vue and web components. Docz is the newest of the three tools, but has already amounted over 14,000+ stars on GitHub. It is, to my mind, the easiest solution to work with. Docz provides two components — <Playground> and <Props>. These are imported and used directly in .mdx files.

import { Playground, Props } from "docz"; import Button from "../src/Button"; ## You can _write_ **markdown** ### You can import and use components <Button>click</Button>

You can wrap your own React components with <Playground> to create the equivalent of an embedded CodePen or CodeSandbox — a view of your component alongside editable code.

<Playground> <Button>click</Button> </Playground>

<Props> will show all the available props for a given React component, default values, and whether the prop is required.

<Props of={Button} />

I personally find this MDX-based approach the simplest to understand and the easiest to work with.

If you’re a fan of the React-based static-site generator Gatsby, Docz offers great integration.

Styleguidist

Just like with Docz, examples are written using Markdown syntax. Styleguidist uses Markdown code blocks (triple backticks) in regular .md files rather than MDX:

```js <Button onClick={() => console.log('clicked')>Push Me</Button> ```

Code blocks in Markdown usually just show the code. With Styleguidist, any code block with a language tag of js, jsx or javascript will be rendered as a React component along with the code. Just like with Docz, the code is editable — you can change props and instantly see the result.

Styleguidist will automatically create a table of props from either PropTypes, Flow or Typescript declarations.

Styleguidist currently supports React and Vue.

Storybook

Storybook markets itself as "a development environment for UI components." Rather than writing examples of components inside Markdown or MDX files, you write *stories* inside Javascript files. A *story* documents a particular state of a component. A component might have stories for a loading state and a disabled state, for example.

storiesOf('Button', module) .add('disabled', () => ( <Button disabled>lorem ipsum</Button> ))

Storybook is less straightforward to use than Styleguidist and Docz. At over 36,000 GitHub stars though, it’s the most popular option. It’s an open source project with 657 contributors and a full-time maintainer. It is used by, among others, Airbnb, Algolia, Atlassian, Lyft, and Salesforce. Storybook supports more frameworks than any other offering — React, React Native, Vue, Angular, Mithril, Ember, Riot, Svelte and plain HTML are all supported.

Writing documentation about components currently requires addons. In a future release, Storybook is taking inspiration from Docz and adopting MDX.

# Button Some _notes_ about your button written with **markdown syntax**. <Story name="disabled"> <Button disabled>lorem ipsum</Button> </Story>

Storybook’s new Docs feature is being rolled out incrementally over the next couple of months and looks set to be a big step forward.

Do you use @storybookjs for component docs or design systems? You're gonna love DocBlocks:
&#x1f4e6; Drop into MDX
&#x1f3d7; Modular and composable
&#x1f91d; Compatible w/ @gatsbyjs, #nextjs, etc

&#x1f51c; https://t.co/AmE4l9B3FU by @mshilman pic.twitter.com/Q48PQCmiEt

— Dominic Nguyen (@domyen) April 28, 2019

Wrapping up

The benefits of pattern libraries have been extolled at nauseating length in a million Medium articles. When done well, they aid visual consistency and facilitate the creation of cohesive products. Of course, none of these tools can magic up a design system. That takes careful thought about both design and CSS. But when it comes time to communicate that system to the rest of an organization, Docz, Storybook and Styleguidist are all great options.

The post Front-End Documentation, Style Guides and the Rise of MDX appeared first on CSS-Tricks.

The Browser Can Remember Edited Content

Css Tricks - Wed, 05/22/2019 - 4:32am

You can make the text inside any HTML element editable by adding the contenteditable attribute.

<div contenteditable> Hey, I'm like a textarea kinda now! </div>

I wouldn't say there are wheelbarrows full of use-cases for that, but it's neat. One possible use might be an in-progress design in which editing the content from the design itself is useful either for you, or for someone else (a client?) who needs to change the text.

So, great, contenteditable. Now someone can click into the text and edit it.

There is nothing permanent about those changes. Refresh the page, look in another browser or whatever. Those edits are gone.

Say you wanted to do a little better job and make the changes persistent. You aren't trying to build a CMS here, or save the data through an authenticated connection to a database or anything. You just wanna make the edits to the text are maintained if the page refreshes.

One way is to chuck the data from the text changes you make into localStorage.

  1. When text is edited (on blur of the element), save the data to localStorage using a namespace and the
    ID of the element as the key.
  2. When the page loads, look through localStorage and see if there are any keys that match elements on the page and, if so, replace the content.
const editables = document.querySelectorAll("[contenteditable]"); // save edits editables.forEach(el => { el.addEventListener("blur", () => { localStorage.setItem("dataStorage-" + el.id, el.innerHTML); }) }); // once on load for (var key in localStorage) { if (key.includes("dataStorage-")) { const id = key.replace("dataStorage-",""); document.querySelector("#" + id).innerHTML = localStorage.getItem(key); } }

See the Pen
localStorage + contenteditable
by Chris Coyier (@chriscoyier)
on CodePen.

This reminds me of a few other things...

  • document.designMode = "on" is like a shortcut for making every element on the page behave like it has contenteditable.
  • Mavo is a little bit like this concept only with authentication, true data storage options, and editing UI.
  • If performance is a concern, KV storage is supposed to be a speeder async version of localStorage.

The post The Browser Can Remember Edited Content appeared first on CSS-Tricks.

Getting Started with React Testing Library

Css Tricks - Wed, 05/22/2019 - 4:19am

I can guess what you are thinking: another React testing library? So many have already been covered here on CSS-Tricks (heck, I’ve already posted one covering Jest and Enzyme) so aren’t there already enough options to go around?

But react-testing-library is not just another testing library. It’s a testing library, yes, but one that’s built with one fundamental principle that separates it from the rest.

The more your tests resemble the way your software is used, the more confidence they can give you.

It tries to address tests for how a user will use your application. In fact, it’s done in such a way that tests won’t break even when you refactor components. And I know that’s something we’ve all run into at some point in our React journey.

We’re going to spend some time writing tests together using react-testing-library for a light to-do application I built. You can clone the repo locally:

git clone https://github.com/kinsomicrote/todoapp-test.git

And, if you do that, install the required packages next:

## yarn yarn add --dev react-testing-library jest-dom ## npm npm install --save-dev react-testing-library jest-dom

In case you’re wondering why Jest is in there, we’re using it for assertion. Create a folder called __test__ inside the src directory and create a new file called App.test.js.

Taking snapshots

Snapshot tests keep a record of tests that have been performed on a tested component as a way to visually see what’s changes between changes.

When we first run this test, we take the first snapshot of how the component looks. As such, the first test is bound to pass because, well, there’s no other snapshot to compare it to that would indicate something failed. It only fails when we make a new change to the component by adding a new element, class, component, or text. Adding something that was not there when the snapshot was either created or last updated.

The snapshot test will be the first test we will be writing here. Let’s open the App.test.js file and make it look like this:

import React from 'react'; import { render, cleanup } from "react-testing-library"; import "jest-dom/extend-expect"; import App from './App'; afterEach(cleanup); it("matches snapshot", () => { const { asFragment } = render(<App />); expect(asFragment()).toMatchSnapshot(); });

This imports the necessary packages we are using to write and run the tests. render is used to display the component we want to test. We make use of cleanup to clear things out after each test runs — as you can see with the afterEach(cleanup) line.

Using asFragment, we get a DocumentFragment of the rendered component. Then we expect it to match the snapshot that had been created.

Let’s run the test to see what happens:

## yarn yarn test ## npm npm test

As we now know, a snapshot of the component gets created in a new folder called __snapshots__ inside the __tests__ directory if this is our first test. We actually get a file called App.test.js.snap in there that will look like this:

// Jest Snapshot v1, https://goo.gl/fbAQLP exports[`matches snapshot 1`] = ` <DocumentFragment> <div class="container" > <div class="row" > <div class="col-md-6" > <h2> Add Todo </h2> </div> </div> <form> <div class="row" > <div class="col-md-6" > <input class="form-control" data-testid="todo-input" placeholder="Enter a task" type="text" value="" /> </div> </div> <div class="row" > <div class="col-md-6" > <button class="btn btn-primary" data-testid="add-task" type="submit" > Add Task </button> </div> </div> </form> <div class="row todo-list" > <div class="col-md-6" > <h3> Lists </h3> <ul data-testid="todos-ul" > <li> <div> Buy Milk <button class="btn btn-danger" > X </button> </div> </li> <li> <div> Write tutorial <button class="btn btn-danger" > X </button> </div> </li> </ul> </div> </div> </div> </DocumentFragment> `; Now, let’s Test DOM elements and events

Our app includes two to-do items that display by default the first time the app runs. We want to make sure that they do, in fact, show up by default on the first app run so, to test this, we have to target the unordered list (<ul>) and check the length. We expect the length to be equal to two — the number of items.

it('it displays default todo items', () => { const { getByTestId } = render(<App />); const todoList = getByTestId('todos-ul'); expect(todoList.children.length).toBe(2); });

We’re making use of getByTestId in that snippet to extract the test IDs from the App component. We then set todoList to target the todos-ul element. That’s what should return as two.

Using what we’ve learned so far, see if you can write a test to assert that a user can enter values in the input field. Here are the things you’ll want to do:

  • Get the input field
  • Set a value for the input field
  • Trigger a change event
  • Assert that the input field has its value as the one you set for it in Step 2

Don’t peek at my answer below! Take as much time as you need.

Still going? Great! I’ll go grab some coffee and be right back.

Mmm, coffee. ☕️

Oh, you’re done! You rock. Let’s compare answers. Mine looks like this:

it('allows input', () => { const {getByTestId } = render(<App />) let item = 'Learn React' const todoInputElement = getByTestId('todo-input'); todoInputElement.value = item; fireEvent.change(todoInputElement); expect(todoInputElement.value).toBe('Learn React') });

Using getByTestId, I am able to extract the test IDs in the application. Then I create a variable which is set to the string Learn React, and make it the value of the input field. Next, I obtain the input field using its test ID and fire the change event after setting the value of the input field. With that done, I assert that the value of the input field is indeed Learn React.

Does that check out with your answer? Leave a comment if you have another way of going about it!

Next, let’s test that we can add a new to-do item. We’ll need to get the input field, the button for adding new items and the unordered list because those are all of the elements needed to create an new item.

We set a value for the input field and then trigger a button click to add the task. We’re able to do this by obtaining the button using getByText — by triggering a click event on the DOM element with the text Add Task, we should be able to add a new to-do item.

Let’s assert that the number of children (list items) in unordered list element is equal to three. This assumes that the default tasks are still in tact.

it('adds a new todo item', () => { const { getByText, getByTestId } = render(<App />); const todoInputElement = getByTestId('todo-input'); const todoList = getByTestId('todos-ul'); todoInputElement.value = 'Learn React'; fireEvent.change(todoInputElement); fireEvent.click(getByText('Add Task')) expect(todoList.children.length).toBe(3); });

Pretty nice, right?

This is just one way to test in React

You can try react-testing-library in your next React application. The documentation in the repo is super thorough and — like most tools — the best place to start. Kent C. Dodds built it and has a full course on testing over at Frontend Masters (subscription required) that also covers the ins and outs of react-testing-library.

That said, this is just one testing resource for React. There are others, of course, but hopefully this is one you’re interested in trying out now that you’ve seen a bit of it but use what’s best for your project, of course.

The post Getting Started with React Testing Library appeared first on CSS-Tricks.

What Does it Mean to Be “Full Stack”?

Css Tricks - Tue, 05/21/2019 - 4:41am

I was asked this recently by a fellow developer who was at the same web tech conference I was at. This developer had met a lot of new people who literally introduced themselves as full-stack developers sort of the way Bob Vance, Vance Refrigeration would on The Office, but it was Tony Frank, Full-Stack Developer instead.

I suspect the developer asking the question taken from the title of this post already knew the basic idea of what people mean by "full-stack developer," but was wondering what the heck it's all about. There was a tone in the question. A tone that suggested this person isn't exactly in love with the term. The traditional explanation A person who identifies (or has the job title of) "full-stack" developer can do both what is considered front-end development work and back-end development work. These days, probably a bit of DevOps (e.g. Git, testing, and getting sites to production). The "stack" is all these things combined, so a full-stack developer is shorthand for: when it comes to building websites, I can do it all.

There are some stacks that have achieved notoriety over the years. Maybe you've heard of the LAMP stack?

Linux Apache MySQL PHP

A full-stack developer on that stack means you know Linux, Apache, MySQL, and PHP. (Abstractly: server software, web server, database, back-end language.) This site runs on that stack, and I'm solely responsible for its development, so I guess I'm a full-stack developer in some loose sense.

But "loose" is a generous interpretation. I don't know the first thing about Linux, except that's what runs my web servers. I don't know much about Apache, except that I sometimes use HTAccess directives to do things. I could count the number of MySQL queries I've written on my two hands, and I only really know PHP in the context of WordPress.

Looked at that way, I'm barely a developer at all. Full stack, on the other hand, generally refers to tossing front-end tasks into the mix and I'm competent enough in that space that my front-end skill set alone, has allowed me to build dozens (or hundreds!) of sites throughout my career. Full-stack-enough, anyway.

There are loads of other stacks.

LAMP isn't particularly prescriptive about how you build the front-end. It came from an era where it was assumed you'd build a back end to spit out HTML and that's your front end.

Another stack that's achieved notoriety since the Grand Arrival of JavaScript is the MEAN stack.

MongoDB Express Angular Node

It is perfectly plausible to replace parts of a stack. Perhaps you'd use Nginx instead of Apache, or PostgreSQL instead of MySQL in what's otherwise LAMP stack. MEAN is notable in that every layer of the stack was replaced with new technology. Node brought JavaScript to the back end, which could power web servers, handle routing, connect data sources, run build processes, compile code, and more.

A full-stack developer in this world is writing nearly everything in JavaScript. No wonder there is somewhat of an explosion of people considering themselves "full" stack. A single language, like JavaScript, that runs in browsers itself and is a paramount front-end technology is a widely transferrable skill.

The MEAN stack can have layers swapped out just as easily as LAMP. Perhaps you use a data store like Fauna or Firebase instead. Perhaps you use Vue or React instead of Angular. Perhaps you don't need Express because you leave your routing to a framework or do it client-side.

Shawn Wang calls another a popular stack STAR:

Design Systems TypeScript Apollo React

That's JavaScript all the way down.

It's notable that, while we're still thinking of this as a stack, we're thinking less about our servers and server software to the point they aren't really a key part of the stack. Not that developers and companies don't take it seriously, but it's more abstracted now than it has traditionally been. I'd point to the world of serverless as a case in point. The questions aren't about what operating system our servers should use; it's what platform is the most cost-effective to run our JavaScript functions.

So, stacks evolve over time. But it's not just what technologies they use, but what technology we even consider a part of a stack. What full-stack means morphs over time.. We're in a place right now where knowing JavaScript grants you a full-stack merit badge. You can work with client site frameworks, architect components and piece them together to build an entire front end. You can write web servers. You can write back-end code that talks to APIs. You can do all the state management you need. You can construct build processes and deployment pipelines. You can even bring CSS into JavaScript if you're so inclined.

Even if you're largely focused on JavaScript, people's skillsets are generally wider than that. Throw in some HTML and CSS competency, Git foo, and a little DevOps hobby and you're a real web powerhouse. You can do it all! A renaissance man! Lord of the seven kingdoms!

I think that's kinda awesome, actually. It truly empowers developers. While it's worth considering where the barriers of entrance are for front-end development, it's also interesting to consider all the places where that bar has been lowered. It's particularly cool for me to see front-end development grow and grow to the point of nearly swallowing up the entire stack. The All-Powerful Front-End Developer, as it were.

It reminds me an awful lot of how powerful being a WordPress site-slinger feels. You can do a lot, even if you don't deeply understand every little bit of it.

My conference acquaintance went on:

Why are some developers so proud of being a full stack? Many of them say it with a prideful smile. They, for some reason, feel the need to emphasize full stack when introducing themselves.

I suspect it's just that: Pride.

Pride is a tricky thing. It meant the world to me when my parents ceaselessly told me they were proud of me or something I did. A positive thing on both sides. But, strangely enough, pride is also one of the seven deadly sins and one, as they say, that might be the root of all the rest. I don't want to over-blow things, but I think there is some connection here. It's one thing to be empowered and to feel strong and capable, but it's another to be boastful and not sense the edges of your ability.

We've all got plenty of edges, particularly when it comes to doing an exemplary job versus merely getting the job done. Standing out these days requires being exemplary. How is your visual design skill? Are you building design systems or implementing existing ones? How many years have you maintained systems? Do you have a good eye for the most painful kinds of technical debt? How are you at helping co-workers succeed? Can you facilitate a user testing session? How good are you at diagnosing performance bottlenecks? What if there are serious server problems? Does your full stack moniker help you comprehend server logs? Are you versed in accessibility audits? Have you ever dealt with tricky relational data and slow queries?

I'm not trying to convince anyone they aren't a full-stack developer or don't deserve that particular merit badge — just that the web is a big place with divergent needs and ever-morphing stacks that all require different sets of skills. If you're interviewing for a job asking for a full-stack developer, by all means, tell them how full-stack-y you are.

The post What Does it Mean to Be “Full Stack”? appeared first on CSS-Tricks.

How I Use CleanMyMac X

Css Tricks - Tue, 05/21/2019 - 4:37am

[Chris]: I'm a lifelong Mac user. Ever since our family upgraded from a Commodore 128 to an Apple Macintosh Performa 636 (CD) when I was in middle school, I've never owned or worked on anything other than a Mac. I'm pretty dedicated to running a clean, fast, optimized, safe, and organized machine. If I was a woodworker, my truck would probably be a mess, but my shop would probably be in perfect shape. Organized pegboard of tools, swept floor, and sharp tools.

If it seems off to see a review of this Mac software seems here on a web development blog, it shouldn't. Keeping a clean machine makes sure we can do out job without anything getting in the way. Just look up what Abraham Lincoln had to say about sharpening axes.

I really like CleanMyMac X. I've used it for years and years, and it is my primary tool for helping me keep a clean shop.

Nicely designed UI, wouldn't you say?

The cornerstone of CleanMyMac X is to regularly run a scan of your whole system and follow its recommendations for what to clean up. The scan only takes a few minutes, even on my machine, which is pretty loaded with files including god-knows how many node_modules folders and such. Plus, it provides an alert once it finishes.

Then you get a bit of an overview of things CleanMyMac X can help you with, and away you go.

Give it another few minutes to do its thing, and a boatload of the heavy lifting will be done for you.

Clearing up hard drive space is one of CleanMyMac X's superpowers

If you haven't run it in a while (particularly on your first-ever run), you're going to be clearing many, many gigabytes of unused junk off your system. That's a lot of space, making this tool a godsend if you're dealing with space issues on your hard drive, as I certainly have.

But what I've found is that tracking down big and old files is the best way to clear up space. They have a feature that literally does exactly that, which helps me track down giant files that I have zero use for anymore. I find stuff like enormous log files, old SQL dumps I don't need any more, original media recordings that have already been backed up. That kind of thing.

The new Space Lens feature is great to helps you visualize the biggest hoarders on your system. It helped me discover that the largest offenders on my system were recordings for CodePen Radio, which could easily be removed from my system with no harm.

Dropbox has a "selective sync" feature that allows me to keep some files backed up, but not keep them locally on my Mac. CleanMyMac X gives me hints on the best directories to use for certain files.

Nuking applications correctly

I used to rely on a little tool called AppZapper to delete apps, because it had this neat feature where it would entirely clean up after the app. Not only would the app be gone, but any files strewn across the entire system that relate to that app as well, of which there might be a dozen... or more.

I don't need that anymore because CleanMyMac X does this automatically! Say I'm cleaning out my Applications folder and find an app that I just don't use whatsoever. I can simply drag that application to the trash. CleanMyMac X will notice that I did that and help me delete it correctly.

Popping over to the app, I can see exactly what it's doing:

Saving myself from a restart

I can't quite explain why, but sometimes my machine feels bogged down. It runs slowly and every task seems to take forever. The dreaded Mac beachball seems to happen for even the simplest of things. Maybe it's because of how many different development environments I spin up and down, coupled with the fact that I only restart once a week... if that. Who knows.

Restarting usually does make for a snappier machine, but sometimes I really want to avoid it. Like, when I'm in the middle of some long-running task, or I'm trying to complete a thought, or I only have 30 minutes left in my work day and I want to use them to do work. I've found the reason for the slowness usually has to do with my RAM usage peaking out, and amazingly, CleanMyMac X has a one-click solution for that right in the handy-dandy menu bar app:

This machine that I'm writing on and that I just took that screenshot with is brand-spanking new. I went with 32 GB of RAM because my old machine came with 16 GB and had these RAM issues constantly. In that screenshot above, you can see I'm using 23 GB of RAM just sitting here hardly doing anything other than typing up this blog post. &#x1f97a;. But I can get a lot of that back after "freeing up" RAM.

CleanMyMac X will even remind me of low RAM, among other things, and help you prevent that from causing bigger issues.

I find CleanMyMax X pretty dang reliable and valuable. I'm grateful for that since trust is paramount with an application like this. I'm not just going to let any app scour my hard drive, delete files and have this general kind of access. I wouldn't want to be in a position where I really needed an app like this right away and had to choose something without being able to lean on years of trust.

The post How I Use CleanMyMac X appeared first on CSS-Tricks.

The “Inside” Problem

Css Tricks - Mon, 05/20/2019 - 6:36am

So, you're working on a design. You need a full-width container element because the design has a background-color that goes from edge-to-edge horizontally. But the content inside doesn’t necessarily need to be edge-to-edge. You want to:

  1. Limit the width (for large screens)
  2. Pad the edges
  3. Center the content

It's "the inside problem" in web layout. It's not hard, it's just that there are lots of considerations.

The "inside" issue. Centered, max-width/padding containers inside full-width color bands.

What's your favorite pattern?

(Just a fun every day thing with many possible solutions to consider!) pic.twitter.com/pNYf5YsQMp

— Chris Coyier (@chriscoyier) March 14, 2019

The classic solution is an outer and inner container.

The parent element is naturally as wide as it's own parent, and let's assume that's the <body> element, or the entire width of the browser window. That takes the background-color and pads the left and right sides. The inside element is what limits the width inside and centers.

<footer> <div class="inside"> Content </div> </footer> footer { --contentWidth: 400px; background: lightcoral; padding: 2rem 1rem; } .inside { max-width: var(--contentWidth); margin: 0 auto; }

This is what my brain reaches for first. Doesn't use anything fancy and feels perfectly understandable. That "inside" element isn't wonderfully desirable, only because it feels like busywork to remember to add it to the markup each time this pattern is used, but it does the trick with few other downsides.

See the Pen
Classic "inside" element
by Chris Coyier (@chriscoyier)
on CodePen.

What if you only can use a single element?

These type of limitations aren't my favorite, because I feel like a healthy project allows designers and developers to have whatever kind of control over the final HTML, CSS, and JavaScript output they need to do the best possible job. But, alas, sometimes you’re in a weird position as a contractor or have legacy CMS issues or whatever.

If you only have a single element to work with, padding sorrrrrta kinnnnda works. The trick is to use calc() and subtract half of the content’s maximum width from 100%.

<footer> Content </footer> footer { --contentWidth: 600px; background: lightcoral; padding: 2rem calc((100% - var(--contentWidth)) / 2); }

See the Pen
VOYxOa
by Chris Coyier (@chriscoyier)
on CodePen.

The problem here is that it doesn't prevent edge-touching, which might make this entirely unacceptable. Maybe you could select elements inside (paragraphs and whatnot...) and add padding to those (with a universal selector, like footer > *). It's tempting to put padding way up on the <body> or something to prevent edge-touching, but that doesn't work because we want that edge-to-edge background color.

What if you're already inside a container you can't control and need to break out of it?

Well, you can always do the ol' full-width utility thing. This will work in a centered container of any width:

.full-width { width: 100vw; margin-left: 50%; transform: translateX(-50%); }

But that leaves the content inside at full width as well. So, you'd need to turn to an inside element again.

See the Pen
Full width element with inside element
by Chris Coyier (@chriscoyier)
on CodePen.

Also, as soon as you have a vertical scrollbar, that 100vw value will trigger an obnoxious horizontal scrollbar. Some sites can pull off something like this to get rid of that scroll:

body { overflow-x: hidden; }

That’s pretty nice. If you can't do that, though, you might need to set an explicit width on the scrollbar, then subtract that from 100vw.

body { scrollbar-width: 20px; /* future standards way */ } body::-webkit-scrollbar { /* long-standing webkit way */ width: 20px; } .full-width { width: calc(100vw - 20px); }

Even that kinda sucks as it means the full-width container isn't quite full width when there is no vertical scrolling. I'd love to see CSS step it up here and help, probably with improved viewport units handling.

There are a variety of other ways of handling this full-width container thing, like Yanking to the edges with margins and such. However, they all ultimately need viewport units and suffer from the same scrollbar-related fate as a result.

If you can definitely hide the overflow-x on the parent, then extreme negative-margin and positive-padding can do the trick.

This is kinda cool in that it uses nothing modern at all. All very old school CSS properties.

See the Pen
Full Width Bars Using Negative Margins
by Chris Coyier (@chriscoyier)
on CodePen.

Can CSS Grid or Flexbox help here?

Meh. Not really.

I mean, sure, you could set up a three-column grid and place the content in the center column, while using the outside columns as padding. I don't think that's a particularly compelling use of grid and it adds complication for no benefit — that is, unless you're already using and taking advantage of grid at this scope.

Fake the edges instead.

There is no law that the background-color needs to come from one single continuous element. You could always "fake" the left and right sides by kicking out a huge box-shadow or placing a pseudo element wherever needed.

We cover various techniques around that here.

The post The “Inside” Problem appeared first on CSS-Tricks.

The “Inside” Problem

Css Tricks - Mon, 05/20/2019 - 6:36am

So, you're working on a design. You need a full-width container element because the design has a background-color that goes from edge-to-edge horizontally. But the content inside doesn’t necessarily need to be edge-to-edge. You want to:

  1. Limit the width (for large screens)
  2. Pad the edges
  3. Center the content

It's "the inside problem" in web layout. It's not hard, it's just that there are lots of considerations.

The "inside" issue. Centered, max-width/padding containers inside full-width color bands.

What's your favorite pattern?

(Just a fun every day thing with many possible solutions to consider!) pic.twitter.com/pNYf5YsQMp

— Chris Coyier (@chriscoyier) March 14, 2019

The classic solution is an outer and inner container.

The parent element is naturally as wide as it's own parent, and let's assume that's the <body> element, or the entire width of the browser window. That takes the background-color and pads the left and right sides. The inside element is what limits the width inside and centers.

<footer> <div class="inside"> Content </div> </footer> footer { --contentWidth: 400px; background: lightcoral; padding: 2rem 1rem; } .inside { max-width: var(--contentWidth); margin: 0 auto; }

This is what my brain reaches for first. Doesn't use anything fancy and feels perfectly understandable. That "inside" element isn't wonderfully desirable, only because it feels like busywork to remember to add it to the markup each time this pattern is used, but it does the trick with few other downsides.

See the Pen
Classic "inside" element
by Chris Coyier (@chriscoyier)
on CodePen.

What if you only can use a single element?

These type of limitations aren't my favorite, because I feel like a healthy project allows designers and developers to have whatever kind of control over the final HTML, CSS, and JavaScript output they need to do the best possible job. But, alas, sometimes you’re in a weird position as a contractor or have legacy CMS issues or whatever.

If you only have a single element to work with, padding sorrrrrta kinnnnda works. The trick is to use calc() and subtract half of the content’s maximum width from 100%.

<footer> Content </footer> footer { --contentWidth: 600px; background: lightcoral; padding: 2rem calc((100% - var(--contentWidth)) / 2); }

See the Pen
VOYxOa
by Chris Coyier (@chriscoyier)
on CodePen.

The problem here is that it doesn't prevent edge-touching, which might make this entirely unacceptable. Maybe you could select elements inside (paragraphs and whatnot...) and add padding to those (with a universal selector, like footer > *). It's tempting to put padding way up on the <body> or something to prevent edge-touching, but that doesn't work because we want that edge-to-edge background color.

What if you're already inside a container you can't control and need to break out of it?

Well, you can always do the ol' full-width utility thing. This will work in a centered container of any width:

.full-width { width: 100vw; margin-left: 50%; transform: translateX(-50%); }

But that leaves the content inside at full width as well. So, you'd need to turn to an inside element again.

See the Pen
Full width element with inside element
by Chris Coyier (@chriscoyier)
on CodePen.

Also, as soon as you have a vertical scrollbar, that 100vw value will trigger an obnoxious horizontal scrollbar. Some sites can pull off something like this to get rid of that scroll:

body { overflow-x: hidden; }

That’s pretty nice. If you can't do that, though, you might need to set an explicit width on the scrollbar, then subtract that from 100vw.

body { scrollbar-width: 20px; /* future standards way */ } body::-webkit-scrollbar { /* long-standing webkit way */ width: 20px; } .full-width { width: calc(100vw - 20px); }

Even that kinda sucks as it means the full-width container isn't quite full width when there is no vertical scrolling. I'd love to see CSS step it up here and help, probably with improved viewport units handling.

There are a variety of other ways of handling this full-width container thing, like Yanking to the edges with margins and such. However, they all ultimately need viewport units and suffer from the same scrollbar-related fate as a result.

If you can definitely hide the overflow-x on the parent, then extreme negative-margin and positive-padding can do the trick.

This is kinda cool in that it uses nothing modern at all. All very old school CSS properties.

See the Pen
Full Width Bars Using Negative Margins
by Chris Coyier (@chriscoyier)
on CodePen.

Can CSS Grid or Flexbox help here?

Meh. Not really.

I mean, sure, you could set up a three-column grid and place the content in the center column, while using the outside columns as padding. I don't think that's a particularly compelling use of grid and it adds complication for no benefit — that is, unless you're already using and taking advantage of grid at this scope.

Fake the edges instead.

There is no law that the background-color needs to come from one single continuous element. You could always "fake" the left and right sides by kicking out a huge box-shadow or placing a pseudo element wherever needed.

We cover various techniques around that here.

The post The “Inside” Problem appeared first on CSS-Tricks.

Creating a Diversity Scholarship Program for Your Conference

Css Tricks - Mon, 05/20/2019 - 4:27am

My partner and I ran a design and development conference company for eight years. During that time, we produced hundreds of hours of conferences, both on-site and online. Diversity scholarships were only becoming a typical conference offering around the time we decided to sunset our business. So, when we committed to collaborate on an updated ARTIFACT conference, I knew right away I wanted to make Diversity Scholarships available.

We always worked on making our events inclusive, so adding a program that would enhance that inclusion even more seemed like a no-brainer. When I started to research how to create a diversity scholarship program, though, the only examples I could find were finished programs, and not much documentation about the thinking or planning that created them. It’s not unusual to improvise a solution to a problem and make changes on the fly, in fact it's pretty routine when you run a small business. A diversity scholarship program was something I wanted to get right, though?—?or at least as “right” as possible?—?the first time around. I decided to look a little deeper than what was available online.

Tech conference organizers: have you offered diversity scholarships for your events? Would you be willing to answer a few questions about it? PM or @ me if interested. TIA!

Other sentient beings reading this: Can I get an RT to reach as many organizers as possible? Thanks!

— Ari Stiles (@ari4nne) March 11, 2019

Twitter helped me find conference organizers who had created and run diversity scholarship programs. I ended up talking to several organizers about their experiences, in addition to comparing a couple dozen programs and applications online.

Between sessions at the Open Source Summit (photo courtesy of the Linux Foundation) Before we dive in

There are two types of readers I’d like to address:

  1. If you don’t think the lack of diversity in tech is a problem, or don’t see why a scholarship program is necessary, this article is not for you. It is written with the assumption that the reader is already convinced of the merits of diversity, and is looking for ways to build a more diverse audience at the conferences or tech events they host; or
  2. If you are overwhelmed by the lack-of-diversity-in-tech issue, so much that you feel uncomfortable even addressing it, you are not alone. The problem is systemic, with deep, historical roots. It’s important to remember that you alone cannot solve the problems of an entire industry with one program or one event. Focus instead on what you can create, even with limited resources. Ask for help when you need it?—?most conference organizers I’ve met are glad to help.
From the beginning

So much of the planning for an inclusive conference takes place before you even begin talking about things like diversity scholarships. If your destination city is a relatively inexpensive and easy place to visit; if your venue is accessible and you’ve made plans for accommodations like live captioning; if your ticket prices are reasonable; and if your speaker lineup is genuinely diverse, you’ve got a strong foundation to build on.

Most of this can be accomplished with research. Cities popular with tourists tend to have reasonable transportation and accommodation prices. Cities with big tech hubs often have large, sometimes state-of-the art meeting spaces to hold conferences. Finding cities that have both can be a challenge, but the combination ultimately makes your conference more accessible to different types of attendees.

Creating a diverse lineup of speakers may attract a more diverse set of attendees (left to right: Sample speaker lineups from Hopper Celebration, Alterconf, and Clarity Conference)

A little more work may have to go into your speaker lineup. Although there has been some progress on this issue, the majority of tech conferences still mostly feature white men. There have been plenty of articles written on how to create a diverse speaker lineup, but one of my favorite tips is to focus on your conference content first and foremost. Thinking in terms of content makes it easier to look past a potential speaker’s popularity. It also works against your natural bias toward picking “friends” or people you have worked with before. By focusing instead on the content a speaker provides, you can evaluate how that content might add to your overall theme and how it might affect your audience. Curating content is more work than just lining up a group of well-known speakers, but it pays off in the form of a more focused conference and?—?usually?—?a more diverse lineup.

You'll also need to encourage open discussion among your co-organizers about diversity issues. My first job in conference planning was for South by SouthWest Interactive (SXSWi), and I feel lucky to have gotten my start working in an environment where these discussions were regular, open, and just “part of the process.” As with any skill, the more you practice talking about diversity, the easier it becomes.

Craft Conference has put together a video about their diversity program. These testimonials may help further the conversation with your colleagues.

Ask yourself why

Diversity and equity scholarship programs have become popular offerings at tech conferences for many reasons. We need more diversity in the industry, and the current thinking is that more diverse conferences can create more leadership and presentation opportunities for underrepresented populations. Diversity can lead to more robust discussions, too. This goal stated plainly on the Web site for #Perfmatters, run by Estelle Weyl:

"We want to ensure the conversation is stimulating and help everyone see their own Web app issues from new and different perspectives. For that, we need attendees with different perspectives. While we love everyone, conferences where all attendees come from corporations with generous continuing education budgets aren’t as interesting for participants as when attendees represent different work and life experiences."

It can be useful to do a little soul-searching to think about why you and your co-organizers want to do this. “More than anything,” says Tenessa Gemelke, organizer of Confab, “we wanted to remove obstacles, not just check boxes.” It’s easy to tell ourselves that because we’ve recruited a few women or people of color, we’ve “taken care of” conference diversity and we can move on to the next task. The needs of your diversity scholarship recipients are not checklist items?—?they are the building blocks of a more inclusive community.

Brainstorming a bit about the reasons you want to build a diversity scholarship program can help you set goals, identify problems specific to your target audience, and define limits. You might even discover that you have secondary objectives, which is not unusual.

Justin Reese is the Founder of Code & Supply and co-creator of several conferences based in Pittsburgh, PA. In addition to the traditional uses for diversity scholarships, he and his staff occasionally use scholarship funds to send up-and-coming hometown speakers to other cities. “We want people to see the talent and resources we have here in Pittsburgh,” says Reese. He and his team think of Code & Supply scholarships as a way to showcase local talent and build a robust, diverse tech community in their home town.

At ARTIFACT, we think of diversity and inclusion as the future of technology. So, in addition to building a robust, inclusive community, we see our diversity scholarship program as a vital part of a forward-thinking conference. Techniques and workflow change not only because of new gadgets and platforms, but because of new audiences and different types of teams.

Taking stock

Once you’ve settled on your “why,” it’s best to determine your “what”?—?as in, what you have to offer. Do you have any resources or perks on hand that will require no help from sponsors? For example, some conferences have more space than they need. Can you give some tickets away for free, or at a discount? Or if you have limited space, can you make a few free or discounted tickets possible by bumping up the cost of your other tickets? Make a list of what you can offer for free or from simple changes to your conference plan.

Other services that you might consider offering through your diversity scholarship program:

  • Assisting with travel
  • Assisting with accommodations
  • Meal stipends
  • On-site childcare
  • On-site nursing / feeding spaces

Some organizers even make travel and hotel reservations for their diversity scholarship attendees. It makes sense?—?most conferences already make these arrangements for their presenters, so it’s easy to do it for a few more people. This service may help scholarship dollars stretch a little further too, if the extra travel or booked rooms are available at a bulk discount.

If you want to offer more than just the basics, you will probably have to work with sponsors. The good news here is that sponsors often enjoy investing in diversity initiatives. Before approaching a potential sponsor, though, it’s wise to be clear on how you plan to spend the money. Consider creating a one-sheet that states your goals, the underrepresented groups you are trying to recruit, and what perks the sponsor can expect for participating. This way, you have something to leave behind for sponsors who want to think it over or who need to present the idea to others before it gets approval. Be sure to include your contact information.

Set your goals

It’s useful to think about how many diversity scholarships you’d like to offer in an ideal situation. In practice, that perfect number will probably drop based on your budget or lack of space, but having a lofty goal may encourage you to try a little harder.

Among the conference organizers I spoke with, the number of diversity scholarship recipients ranged from two to fifteen percent of total ticket sales. Those with higher numbers started with higher goals.

Attendees at JSCamp Barcelona Making it happen

Figuring out the logistics of a diversity scholarship plan may be the most complicated part of the process. Trying to figure out how to juggle all the tasks involved is what spurred me to do all this research in the first place!

Implementation will include some combination of the following steps, not necessarily in this order:

Put someone in charge

Your entire staff may be involved with processing diversity scholarships, but it’s a good idea to have one person oversee the whole program for the sake of continuity. There is a great deal of communication involved with this process, so it helps to choose a point person with strong organization and communication skills. The most significant qualification, though, is a real passion for creating a diverse conference community.

Create a reasonable timeline

With input from your team, set application deadlines, reviewing deadlines, and scholarship offer deadlines. Every organizer I spoke with suggested making these deadlines early in the process and sticking to them.

You’ll need enough time to review applications and make scholarship offers early enough to give your attendees time to plan. Remember that they might have to request time off work, make family care arrangements, and deal with other obligations. People from out of town need at least two months notice, and international attendees may need three months or more. Early deadlines help everyone. No one in your organization wants to review applications at the last minute anyway, since conference planning gets more intense in the weeks leading up to the event.

Any unclaimed scholarship resources can be used by qualified local attendees in the weeks leading up to your event. Since they don't have to factor in travel or accommodations, it is easier for local attendees to make plans at the last minute.

Make your scholarship program easy to find

Devote a page to your diversity scholarship program on your site, then link to that page as reasonably often as possible. If you can‘t list it in your main menu, consider linking it from the site footer and from the ticket sales page, in addition to posting about it regularly on social media.

Clearly state who qualifies for aid

The list may vary a bit based on your typical audience, but we chose the following criteria:

  • People of color
  • Indigenous persons
  • People with disabilities
  • People who identify as LGBTQIA+
  • Women
  • Veterans and new graduates just beginning their tech careers
  • Full-time students
  • People who work for nonprofit/educational/government institution with limited funds
  • People who are 55 years old or older
  • People who are currently unemployed / underemployed
  • People experiencing temporary financial hardship

Be sure to list the types of aid available (determined earlier, when you were “taking stock"). It’s also good to let your applicants know that not every application will be accommodated, and that all applications will be verified.

Collect the information you need?

Most conferences use some kind of online application form to collect and organize data. If you are not able to code one yourself, Google Forms or Wufoo make it pretty easy to build a form. Keep the application as simple as you can?—?you’ll need:

  • name,
  • contact information,
  • the reason(s) they qualify for aid (instead of a blank field, consider listing qualifications on the form as a way of reiterating the types of attendees you are trying to recruit),
  • the type of aid they are requesting (again, listing they types of aid available will help applicants understand what’s possible), and
  • maybe a statement about why they want to attend or why they need aid at this time.

You’ll want the form to compile data in a way that will be easy to sort through later, like a spreadsheet.

Preserve the anonymity of your applicants

Asking for help in a society that values self-sufficiency over shared responsibility can be tough. Don’t make it harder by asking applicants to divulge too much personal information, participate in open interviews with committee members, or meet with sponsors as part of your program. If a committee will be reviewing applications, consider anonymizing the entries before review.

Verify applications

This should be an ongoing process for several reasons. Some applicants will qualify for your program for reasons that are not always verifiable, so the person doing the vetting may need to contact them and clarify the request.

Other applicants may either misunderstand or overlook your qualifying criteria. The most common mistake many applicants make is assuming they qualify for aid only because their employer won’t cover the cost of the conference. This is where additional information will help: why isn’t this covered? Does the company have very limited funds, or is their travel budget just maxed out already? Does the applicant qualify for a diversity scholarship on other grounds? Applicants should know early in the process if their application is refused or if more information is needed.

Evaluate applications

Once the application deadline is met, evaluation begins. If your applications have been properly vetted, then the hardest work is already done. If a committee is evaluating applications, it’s good to not only figure out a way to anonymize applications, but also to streamline the evaluation process. Maybe give each committee member two or three questions to rate for each applicant. Possible evaluation questions:

  • How clearly is the need for aid stated?
  • How much aid is needed?
  • How much would this attendee impact the conference?
  • How much would the conference impact this attendee?

These can be rated on a scale, maybe one to ten, with ten being highest. This makes calculating scores easy. Other data you might choose to consider: when was the application received? Do you want to consider more local applicants than those from out-of-town?

Make and process scholarship offers and refusals

Evaluations have been made, so you are probably left with a set of applicants you want to offer scholarships to, some applicants you are not sure about yet, and a few that you plan to refuse. Start by making offers to those applicants you want to help attend the conference. Clearly state how much help you are offering and a deadline for accepting or refusing the offer.

If you are working with a particularly long waiting list, or the process is going slowly (more than two weeks since you began awarding scholarships), it’s courteous to let people know they are on a waiting list.

At ARTIFACT, we are assuming that some applicants may have a change in plans and therefore may have to refuse the scholarship. In that case, we will be passing along their offer to the next person on our waiting list.

Once all the offers have been made and accepted, it’s time to email the rest of the applicants, thank them for their participation, and let them know they won’t be receiving a scholarship offer. If you can, it’s nice to offer something to those who didn’t receive a scholarship: maybe a discounted ticket if they still choose to attend, or an invitation to any after-hour events, where you have room for a few extra people.

Create feedback mechanisms

In addition to all the input you sought from your colleagues in the beginning, you’ll need feedback on every aspect of the program. Make that easy to do by including an email address or link to a feedback form on your scholarship description page, your application form, and anywhere else on your site that seems appropriate. Once you start awarding scholarships, make communication a high priority. Consider creating a way to collect anonymous feedback from scholarship awardees and sponsors—easier to do if you have a larger conference—to foster honest, less inhibited comments.

Wait and see (and listen)

Now that everything needed for your diversity scholarship program is in place, it’s time to follow your plan and take note of what works and what doesn’t. Stay flexible, as you may have to change some parts of your program on the fly. Keep thinking in terms of equity for all of your applicants, and communicate openly about any changes you make. Applicants are more likely to trust a transparent process.

Listen more than you talk. Always.

Scholarship recipients for the Tapia Conference, a conference that celebrates and nurtures diversity in computing Follow up

Once ARTIFACT 2019 has concluded, I’ll be compiling all of our results and feedback in one place and writing a follow-up to this article. Until then, I’d like to thank all the conference organizers who took the time to answer my questions about diversity scholarship programs: Tenessa Gemelke, Estelle Weyl, Justin Reese, Val Head, Dave Poole, Jenn Strater, Ádám Boros, and PJ Hagerty.

In the meantime, here are some other resources you might find helpful:

The post Creating a Diversity Scholarship Program for Your Conference appeared first on CSS-Tricks.

Creating a Diversity Scholarship Program for Your Conference

Css Tricks - Mon, 05/20/2019 - 4:27am

My partner and I ran a design and development conference company for eight years. During that time, we produced hundreds of hours of conferences, both on-site and online. Diversity scholarships were only becoming a typical conference offering around the time we decided to sunset our business. So, when we committed to collaborate on an updated ARTIFACT conference, I knew right away I wanted to make Diversity Scholarships available.

We always worked on making our events inclusive, so adding a program that would enhance that inclusion even more seemed like a no-brainer. When I started to research how to create a diversity scholarship program, though, the only examples I could find were finished programs, and not much documentation about the thinking or planning that created them. It’s not unusual to improvise a solution to a problem and make changes on the fly, in fact it's pretty routine when you run a small business. A diversity scholarship program was something I wanted to get right, though?—?or at least as “right” as possible?—?the first time around. I decided to look a little deeper than what was available online.

Tech conference organizers: have you offered diversity scholarships for your events? Would you be willing to answer a few questions about it? PM or @ me if interested. TIA!

Other sentient beings reading this: Can I get an RT to reach as many organizers as possible? Thanks!

— Ari Stiles (@ari4nne) March 11, 2019

Twitter helped me find conference organizers who had created and run diversity scholarship programs. I ended up talking to several organizers about their experiences, in addition to comparing a couple dozen programs and applications online.

Between sessions at the Open Source Summit (photo courtesy of the Linux Foundation) Before we dive in

There are two types of readers I’d like to address:

  1. If you don’t think the lack of diversity in tech is a problem, or don’t see why a scholarship program is necessary, this article is not for you. It is written with the assumption that the reader is already convinced of the merits of diversity, and is looking for ways to build a more diverse audience at the conferences or tech events they host; or
  2. If you are overwhelmed by the lack-of-diversity-in-tech issue, so much that you feel uncomfortable even addressing it, you are not alone. The problem is systemic, with deep, historical roots. It’s important to remember that you alone cannot solve the problems of an entire industry with one program or one event. Focus instead on what you can create, even with limited resources. Ask for help when you need it?—?most conference organizers I’ve met are glad to help.
From the beginning

So much of the planning for an inclusive conference takes place before you even begin talking about things like diversity scholarships. If your destination city is a relatively inexpensive and easy place to visit; if your venue is accessible and you’ve made plans for accommodations like live captioning; if your ticket prices are reasonable; and if your speaker lineup is genuinely diverse, you’ve got a strong foundation to build on.

Most of this can be accomplished with research. Cities popular with tourists tend to have reasonable transportation and accommodation prices. Cities with big tech hubs often have large, sometimes state-of-the art meeting spaces to hold conferences. Finding cities that have both can be a challenge, but the combination ultimately makes your conference more accessible to different types of attendees.

Creating a diverse lineup of speakers may attract a more diverse set of attendees (left to right: Sample speaker lineups from Hopper Celebration, Alterconf, and Clarity Conference)

A little more work may have to go into your speaker lineup. Although there has been some progress on this issue, the majority of tech conferences still mostly feature white men. There have been plenty of articles written on how to create a diverse speaker lineup, but one of my favorite tips is to focus on your conference content first and foremost. Thinking in terms of content makes it easier to look past a potential speaker’s popularity. It also works against your natural bias toward picking “friends” or people you have worked with before. By focusing instead on the content a speaker provides, you can evaluate how that content might add to your overall theme and how it might affect your audience. Curating content is more work than just lining up a group of well-known speakers, but it pays off in the form of a more focused conference and?—?usually?—?a more diverse lineup.

You'll also need to encourage open discussion among your co-organizers about diversity issues. My first job in conference planning was for South by SouthWest Interactive (SXSWi), and I feel lucky to have gotten my start working in an environment where these discussions were regular, open, and just “part of the process.” As with any skill, the more you practice talking about diversity, the easier it becomes.

Craft Conference has put together a video about their diversity program. These testimonials may help further the conversation with your colleagues.

Ask yourself why

Diversity and equity scholarship programs have become popular offerings at tech conferences for many reasons. We need more diversity in the industry, and the current thinking is that more diverse conferences can create more leadership and presentation opportunities for underrepresented populations. Diversity can lead to more robust discussions, too. This goal stated plainly on the Web site for #Perfmatters, run by Estelle Weyl:

"We want to ensure the conversation is stimulating and help everyone see their own Web app issues from new and different perspectives. For that, we need attendees with different perspectives. While we love everyone, conferences where all attendees come from corporations with generous continuing education budgets aren’t as interesting for participants as when attendees represent different work and life experiences."

It can be useful to do a little soul-searching to think about why you and your co-organizers want to do this. “More than anything,” says Tenessa Gemelke, organizer of Confab, “we wanted to remove obstacles, not just check boxes.” It’s easy to tell ourselves that because we’ve recruited a few women or people of color, we’ve “taken care of” conference diversity and we can move on to the next task. The needs of your diversity scholarship recipients are not checklist items?—?they are the building blocks of a more inclusive community.

Brainstorming a bit about the reasons you want to build a diversity scholarship program can help you set goals, identify problems specific to your target audience, and define limits. You might even discover that you have secondary objectives, which is not unusual.

Justin Reese is the Founder of Code & Supply and co-creator of several conferences based in Pittsburgh, PA. In addition to the traditional uses for diversity scholarships, he and his staff occasionally use scholarship funds to send up-and-coming hometown speakers to other cities. “We want people to see the talent and resources we have here in Pittsburgh,” says Reese. He and his team think of Code & Supply scholarships as a way to showcase local talent and build a robust, diverse tech community in their home town.

At ARTIFACT, we think of diversity and inclusion as the future of technology. So, in addition to building a robust, inclusive community, we see our diversity scholarship program as a vital part of a forward-thinking conference. Techniques and workflow change not only because of new gadgets and platforms, but because of new audiences and different types of teams.

Taking stock

Once you’ve settled on your “why,” it’s best to determine your “what”?—?as in, what you have to offer. Do you have any resources or perks on hand that will require no help from sponsors? For example, some conferences have more space than they need. Can you give some tickets away for free, or at a discount? Or if you have limited space, can you make a few free or discounted tickets possible by bumping up the cost of your other tickets? Make a list of what you can offer for free or from simple changes to your conference plan.

Other services that you might consider offering through your diversity scholarship program:

  • Assisting with travel
  • Assisting with accommodations
  • Meal stipends
  • On-site childcare
  • On-site nursing / feeding spaces

Some organizers even make travel and hotel reservations for their diversity scholarship attendees. It makes sense?—?most conferences already make these arrangements for their presenters, so it’s easy to do it for a few more people. This service may help scholarship dollars stretch a little further too, if the extra travel or booked rooms are available at a bulk discount.

If you want to offer more than just the basics, you will probably have to work with sponsors. The good news here is that sponsors often enjoy investing in diversity initiatives. Before approaching a potential sponsor, though, it’s wise to be clear on how you plan to spend the money. Consider creating a one-sheet that states your goals, the underrepresented groups you are trying to recruit, and what perks the sponsor can expect for participating. This way, you have something to leave behind for sponsors who want to think it over or who need to present the idea to others before it gets approval. Be sure to include your contact information.

Set your goals

It’s useful to think about how many diversity scholarships you’d like to offer in an ideal situation. In practice, that perfect number will probably drop based on your budget or lack of space, but having a lofty goal may encourage you to try a little harder.

Among the conference organizers I spoke with, the number of diversity scholarship recipients ranged from two to fifteen percent of total ticket sales. Those with higher numbers started with higher goals.

Attendees at JSCamp Barcelona Making it happen

Figuring out the logistics of a diversity scholarship plan may be the most complicated part of the process. Trying to figure out how to juggle all the tasks involved is what spurred me to do all this research in the first place!

Implementation will include some combination of the following steps, not necessarily in this order:

Put someone in charge

Your entire staff may be involved with processing diversity scholarships, but it’s a good idea to have one person oversee the whole program for the sake of continuity. There is a great deal of communication involved with this process, so it helps to choose a point person with strong organization and communication skills. The most significant qualification, though, is a real passion for creating a diverse conference community.

Create a reasonable timeline

With input from your team, set application deadlines, reviewing deadlines, and scholarship offer deadlines. Every organizer I spoke with suggested making these deadlines early in the process and sticking to them.

You’ll need enough time to review applications and make scholarship offers early enough to give your attendees time to plan. Remember that they might have to request time off work, make family care arrangements, and deal with other obligations. People from out of town need at least two months notice, and international attendees may need three months or more. Early deadlines help everyone. No one in your organization wants to review applications at the last minute anyway, since conference planning gets more intense in the weeks leading up to the event.

Any unclaimed scholarship resources can be used by qualified local attendees in the weeks leading up to your event. Since they don't have to factor in travel or accommodations, it is easier for local attendees to make plans at the last minute.

Make your scholarship program easy to find

Devote a page to your diversity scholarship program on your site, then link to that page as reasonably often as possible. If you can‘t list it in your main menu, consider linking it from the site footer and from the ticket sales page, in addition to posting about it regularly on social media.

Clearly state who qualifies for aid

The list may vary a bit based on your typical audience, but we chose the following criteria:

  • People of color
  • Indigenous persons
  • People with disabilities
  • People who identify as LGBTQIA+
  • Women
  • Veterans and new graduates just beginning their tech careers
  • Full-time students
  • People who work for nonprofit/educational/government institution with limited funds
  • People who are 55 years old or older
  • People who are currently unemployed / underemployed
  • People experiencing temporary financial hardship

Be sure to list the types of aid available (determined earlier, when you were “taking stock"). It’s also good to let your applicants know that not every application will be accommodated, and that all applications will be verified.

Collect the information you need?

Most conferences use some kind of online application form to collect and organize data. If you are not able to code one yourself, Google Forms or Wufoo make it pretty easy to build a form. Keep the application as simple as you can?—?you’ll need:

  • name,
  • contact information,
  • the reason(s) they qualify for aid (instead of a blank field, consider listing qualifications on the form as a way of reiterating the types of attendees you are trying to recruit),
  • the type of aid they are requesting (again, listing they types of aid available will help applicants understand what’s possible), and
  • maybe a statement about why they want to attend or why they need aid at this time.

You’ll want the form to compile data in a way that will be easy to sort through later, like a spreadsheet.

Preserve the anonymity of your applicants

Asking for help in a society that values self-sufficiency over shared responsibility can be tough. Don’t make it harder by asking applicants to divulge too much personal information, participate in open interviews with committee members, or meet with sponsors as part of your program. If a committee will be reviewing applications, consider anonymizing the entries before review.

Verify applications

This should be an ongoing process for several reasons. Some applicants will qualify for your program for reasons that are not always verifiable, so the person doing the vetting may need to contact them and clarify the request.

Other applicants may either misunderstand or overlook your qualifying criteria. The most common mistake many applicants make is assuming they qualify for aid only because their employer won’t cover the cost of the conference. This is where additional information will help: why isn’t this covered? Does the company have very limited funds, or is their travel budget just maxed out already? Does the applicant qualify for a diversity scholarship on other grounds? Applicants should know early in the process if their application is refused or if more information is needed.

Evaluate applications

Once the application deadline is met, evaluation begins. If your applications have been properly vetted, then the hardest work is already done. If a committee is evaluating applications, it’s good to not only figure out a way to anonymize applications, but also to streamline the evaluation process. Maybe give each committee member two or three questions to rate for each applicant. Possible evaluation questions:

  • How clearly is the need for aid stated?
  • How much aid is needed?
  • How much would this attendee impact the conference?
  • How much would the conference impact this attendee?

These can be rated on a scale, maybe one to ten, with ten being highest. This makes calculating scores easy. Other data you might choose to consider: when was the application received? Do you want to consider more local applicants than those from out-of-town?

Make and process scholarship offers and refusals

Evaluations have been made, so you are probably left with a set of applicants you want to offer scholarships to, some applicants you are not sure about yet, and a few that you plan to refuse. Start by making offers to those applicants you want to help attend the conference. Clearly state how much help you are offering and a deadline for accepting or refusing the offer.

If you are working with a particularly long waiting list, or the process is going slowly (more than two weeks since you began awarding scholarships), it’s courteous to let people know they are on a waiting list.

At ARTIFACT, we are assuming that some applicants may have a change in plans and therefore may have to refuse the scholarship. In that case, we will be passing along their offer to the next person on our waiting list.

Once all the offers have been made and accepted, it’s time to email the rest of the applicants, thank them for their participation, and let them know they won’t be receiving a scholarship offer. If you can, it’s nice to offer something to those who didn’t receive a scholarship: maybe a discounted ticket if they still choose to attend, or an invitation to any after-hour events, where you have room for a few extra people.

Create feedback mechanisms

In addition to all the input you sought from your colleagues in the beginning, you’ll need feedback on every aspect of the program. Make that easy to do by including an email address or link to a feedback form on your scholarship description page, your application form, and anywhere else on your site that seems appropriate. Once you start awarding scholarships, make communication a high priority. Consider creating a way to collect anonymous feedback from scholarship awardees and sponsors—easier to do if you have a larger conference—to foster honest, less inhibited comments.

Wait and see (and listen)

Now that everything needed for your diversity scholarship program is in place, it’s time to follow your plan and take note of what works and what doesn’t. Stay flexible, as you may have to change some parts of your program on the fly. Keep thinking in terms of equity for all of your applicants, and communicate openly about any changes you make. Applicants are more likely to trust a transparent process.

Listen more than you talk. Always.

Scholarship recipients for the Tapia Conference, a conference that celebrates and nurtures diversity in computing Follow up

Once ARTIFACT 2019 has concluded, I’ll be compiling all of our results and feedback in one place and writing a follow-up to this article. Until then, I’d like to thank all the conference organizers who took the time to answer my questions about diversity scholarship programs: Tenessa Gemelke, Estelle Weyl, Justin Reese, Val Head, Dave Poole, Jenn Strater, Ádám Boros, and PJ Hagerty.

In the meantime, here are some other resources you might find helpful:

The post Creating a Diversity Scholarship Program for Your Conference appeared first on CSS-Tricks.

Footnotes That Work in RSS Readers

Css Tricks - Fri, 05/17/2019 - 10:52am

Feedbin is the RSS reader I'm using at the moment. I was reading one of Harry's blog posts on it the other day, and I noticed a nice little interactive touch right inside Feedbin. There was a button-looking element with the number one which, as it turned out, was a footnote. I hovered over it, and it revealed the note.

The HTML for the footnote on the blog post itself looks like this:

<p>...they’d managed to place 27.9MB of images onto the Critical Path. Almost 30MB of previously non-render blocking assets had just been turned into blocking ones on purpose with no escape hatch. Start render time was as high as 27.1s over a cable connection<sup id="fnref:1"> <a href="#fn:1" class="footnote">1</a></sup>.</p>

Just an anchor link that points to #fn:1, and the <sup> makes it look like a footnote link. This is how the styling would look by default:

The HTML for the list of footnotes at the bottom of the blog post looks like this:

<div class="footnotes"> <ol> <li id="fn:1"> <p>5Mb up, 1Mb down, 28ms RTT.&nbsp;<a href="#fnref:1" class="reversefootnote">&#x21a9;</a></p> </li> </ol> </div>

As a little side note, I notice Harry is using scroll-behavior to smooth the scroll. He's also got some nice :target styling in there.

All in all, we have:

  1. a link to go down and read the note
  2. a link to pop back up

Nothing special there. No fancy libraries or anything. Just semantic HTML. That should work in any RSS reader, assuming they don't futz with the hash links and maintain the IDs on the elements as written.

It's Feedbin that sees this markup pattern and decides to do the extra UI styling and fancy interaction. By inspecting what's going on, it looks like they hide the originals and replace them with their own special stuff:

Ah ha! A Bigfoot spotting! It's right in their source.

That means they fire off Bigfoot when articles are loaded and it does the trick. Like this:

See the Pen
Bigfoot Footnotes
by Chris Coyier (@chriscoyier)
on CodePen.

That said, it's based on an already functional foundation. Lemme end this with that same markup pattern, and I'll try to look at it in different RSS readers to see what they do. Feel free to report what it does in your RSS reader of choice in the comments, if it does anything at all.

Azul is an abstract board game designed by Michael Kiesling and released by Plan B Games1 in 2017. From two to four players collect tiles to fill up a 5x5 player board. Players collect tiles by taking all the tiles of one color from a repository, and placing them in a row, taking turns until all the tiles for that round are taken. At that point, one tile from every filled row moves over to each player's 5x5 board, while the rest of the tiles in the filled row are discarded. Each tile scores based on where it is placed in relation to other tiles on the board. Rounds continue until at least one player has made a row of tiles all the way across their 5x5 board.

  1. Plan B makes other cool games like Century and Reef. 

The post Footnotes That Work in RSS Readers appeared first on CSS-Tricks.

Everything You Ever Wanted to Know About inputmode

Css Tricks - Fri, 05/17/2019 - 6:40am

The inputmode global attribute provides a hint to browsers for devices with onscreen keyboards to help them decide which keyboard to display when a user has selected any input or textarea element.

<input type="text" inputmode="" /> <textarea inputmode="" />

Unlike changing the type of the form, inputmode doesn’t change the way the browser interprets the input — it instructs the browser which keyboard to display.

The inputmode attribute has a long history but has only very recently been adopted by the two major mobile browsers: Safari for iOS and Chrome for Android. Before that, it was implemented in Firefox for Android way back in 2012, and then subsequently removed several months later (though it is still available via a flag).

Almost six years later, Chrome for Android implemented the feature — and with the recent release of iOS 12.2, Safari now supports it too.

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

DesktopChromeOperaFirefoxIEEdgeSafari665320No75NoMobile / TabletiOS SafariOpera MobileOpera MiniAndroidAndroid ChromeAndroid Firefox12.2NoNo6774No

But before we go deep into the ins and outs of the attribute, consider that the WHATWG living standard provides inputmode documentation while the W3C 5.2 spec no longer lists it in its contents, which suggests they consider it obsolete. Given that WHATWG has documented it and browsers have worked toward supporting it, we’re going to go assume WHATWG specifications are the standard.

inputmode accepts a number of values. Let’s go through them, one by one.

None <input type="text" inputmode="none" />

We’re starting here because it’s very possible we don’t want any type of keyboard on an input. Using inputmode=none will not show a keyboard at all on Chrome for Android. iOS 12.2 will still show its default alphanumeric keyboard, so specifying none could be sort of a reset for iOS in that regard. Regardless, none is intended for content that renders its own keyboard control.

Numeric <input type="text" inputmode="numeric" />

This one is probably the one of the more common inputmode values out in the wild because it’s ideal for inputs that require numbers but no letters — things like PIN entry, zip codes, credit card numbers, etc. Using the numeric value with an input of type="text" may actually make more sense than setting the input to type="number" alone because, unlike a , <code>inputmode="numeric" can be used with maxlength, minlength and pattern attributes, making it more versatile for different use cases.

The numeric value on Chrome Android (left) and iOS 12.2 (right)

I’ve often seen sites using type=tel on an input to display a numeric keyboard, and that checks out as a workaround, but isn’t semantically correct. If that bums you out, remember that inputmode supports patterns, we can add pattern="\d*" to the input for the same effect. That said, only use this if you are certain the input should only allow numeric input because Android (unlike iOS) doesn’t allow the user to change to the keyboard to use letters, which might inadvertently prevent users from submitting valid data.

Tel <input type="text" inputmode="tel" />

Entering a telephone number using a standard alphanumeric keyboard can be a pain. For one, each number on a telephone keyboard (except 1 and 0) represents three letters (e.g. 2 represents A, B and C) which are displayed with the number. The alphanumeric keyboard does not reference those letters, so decoding a telephone number containing letters (e.g. 1-800-COLLECT) takes more mental power.

The tel value on Chrome Android (left) and iOS 12.2 (right)

Using inputmode set to tel will produce a standard-looking telephone keyboard, including keys for digits 0 to 9, the pound (#) character, and the asterisk (*) character. Plus, we get those alphabetic mnemonic labels (e.g. ABC).

Decimal <input type="text" inputmode="decimal" /> The decimal value on Chrome Android (left) and iOS 12.2 (right)

An inputmode set to the decimal value results in a subtle change in iOS where the keyboard appears to be exactly the same as the tel value, but replaces the +*# key with a simple decimal (.). On the flip side, this has no effect on Android, which will simply use the numeric keyboard.

Email <input type="text" inputmode="email" />

I’m sure you (and at least someone you know) has filled out a form that asks for an email address, only to make you swap keyboards to access the @ character. It’s not life-threatening or anything, but certainly not a great user experience either.

That’s where the email value comes in. It brings the @ character into the fray, as well as the decimal (.) character.

The email value on Chrome Android (left) and iOS 12.2 (right)

This could also be a useful keyboard to show users who need to enter a Twitter username, given that@ is a core Twitter character for identifying users. However, the email address suggestions that iOS display above the keyboard may cause confusion.

Another use case could be if you have your own email validation script and don't want to use the browsers built-in email validation.

URL <input type="text" inputmode="url" /> The url value on Chrome Android (left) and iOS 12.2 (right)

The url value provides a handy shortcut for users to append TLDs (e.g. .com or .co.uk) with a single key, as well keys typically used in web addresses, like the dot (.) and forward slash (/) characters. The exact TLD displayed on the keyboard is tied to the user’s locale.

This could also be a useful keyboard to show users if your input accepts domain names (e.g. css-tricks.com) as well as full URIs (e.g. https://css-tricks.com). Use type="url" instead if your input requires validating the input.

Search <input type="text" inputmode="search" /> The search value on Chrome Android (left) and iOS 12.2 (right)

This displays a blue Go key on iOS and a green Enter key on Android, both in place of where Return. As you may have guessed by the value’s name, search is useful for search forms, providing that submission key to make a query.

If you'd like to showSearch instead of Enter on iOS and a magnifying glass icon on Android in place of the green arrow, use type=search instead.

Other things you oughta know
  • Chromium-based browsers on Android — such as Microsoft Edge, Brave and Opera — share the same inputmode behavior as Chrome.
  • I haven’t included details of keyboards on iPad for the sake of brevity. It’s mostly the same as iPhone but includes more keys. Same is true for Android tablets, save for third-party keyboards, which might be another topic worth covering.
  • The original proposed spec had the values kana and katakana for Japanese input but they were never implemented by any browser and have since been removed from the spec.
  • latin-name was also one of the values of the original spec and has since been removed. Interestingly, if it’s used now on Safari for iOS, it will display the user’s name as a suggestion above the keyboard.

    The latin-name value displays my name as an auto-fill suggestion
Demo

Oh, you want to see how all of these input modes work for yourself? Here’s a demo you can use on a device with a touchscreen keyboard to see the differences.

References

Weekly news: PWA Issue on iOS, Performance Culture, Anti-Tracking in Browsers

Css Tricks - Fri, 05/17/2019 - 4:30am

Šime posts regular content for web developers on webplatform.news. Each week, he covers timely news at the intersection of development standards and the tools that make them available on the web.

Installed PWAs cannot easily be restarted on iOS

iOS 12.2 PWAs
&#x1f501; In-App browser for external content (OAuth)
&#x1f4be; New lifecycle (No Reload)
&#x1f519;Navigation gestures
&#x1f91d;WebShare
⚠️Motion Sensors disabled; old getUserMedia removed
&#x1f44d; IntersectionObserver, ConicGradients, datalist, color picker, AbortFetchhttps://t.co/LNzq6MzqjR

— Maximiliano Firtman @ &#x1f1f1;&#x1f1f9; Vilnius (@firt) March 26, 2019

Maximiliano Firtman: On iOS, it is not possible to restart an installed PWA by closing it from the recently used apps screen and then immediately reopening it. Instead of restarting the app, iOS restores its state. This can be a problem for users if the PWA gets stuck in a broken state.

<input> with type 'file' bug on #iOS 12.2 #PWA
Open the input, put the PWA in bg by pressing home button. The input stops working. True for any input with type 'file' throughout the app. It works after a phone restart. pic.twitter.com/IfzsXy91RK

— Pankaj Nathani ⭐️ (@croozeus) April 11, 2019

After some undefined time, the saved context seems to disappear. So if you get out of the PWA, do nothing with your phone and wait some hours to go back to the PWA, it restarts from scratch.

Instilling a performance culture at The Telegraph

We've been working hard at The Telegraph to improve third-party performance. Here is an insight into our approach - https://t.co/4hhRDYaidS #webperf ⚡️

— Gareth Clubb (@digitalclubb) April 30, 2019

Gareth Clubb: At The Telegraph (a major UK newspaper), we set up a web performance working group to tackle our “organizational” performance challenges and instill a performance culture. The group meets regularly to review third-party tags and work on improving our site’s performance.

We’ve started deferring all JavaScript (including our own) using the <script defer> attribute. This change alone nearly doubled our (un-throttled) Lighthouse performance score.

Deferring our JavaScript hasn’t skewed any existing analytics and it certainly hasn’t delayed any advertising. [...] The First Ad Loaded metric improved by an average of four seconds.

We also removed 1 MB of third-party payload from our new front end. When one of our teams requests the addition of any new script, we now test the script in isolation and reject it if it degrades our metrics (first contentful paint, etc.).

When we started this process, we had a collection of very old scripts and couldn’t track the original requester. We removed those on the premise that, if they were important, people would get back in touch?—?no one did.

Microsoft plans to add tracking prevention to the Edge browser

Kyle Pflug: Microsoft has announced plans to add options for blocking trackers to the Edge browser. Malicious trackers would be blocked automatically, and the user would have the option to additionally block all potential trackers.

This would make Edge the fourth major browser with some form of built-in anti-tracking feature (two other major browsers, Opera and UC Browser, include ad blockers instead).

  1. In 2015, Firefox added Tracking Protection?—?recently renamed to Content Blocking?—?becoming the first major browser to protect users from third-party trackers (when browsing the web in private mode).
  2. Since 2017, Safari prevents cross-site tracking by default, through a feature called Intelligent Tracking Prevention (ITP). Users are prompted to allow tracking when they try to interact with third-party widgets on websites.

  3. Earlier this year, Samsung Internet added an experimental feature called Smart Anti-Tracking that denies third-party trackers access to cookies.

The post Weekly news: PWA Issue on iOS, Performance Culture, Anti-Tracking in Browsers appeared first on CSS-Tricks.

Iterating a React Design with Styled Components

Css Tricks - Thu, 05/16/2019 - 4:29am

In a perfect world, our projects would have unlimited resources and time. Our teams would begin coding with well thought out and highly refined UX designs. There would be consensus among developers about the best way to approach styling. There’d be one or more CSS gurus on the team who could ensure that functionality and style could roll out simultaneously without it turning into a train-wreck.

I’ve actually seen this happen in large enterprise environments. It’s a beautiful thing. This article is not for those people.

On the flip side of the coin is the tiny startup that has zero funding, one or two front-end developers, and a very short timeline to demonstrate some functionality. It doesn’t have to look perfect, but it should at least render reasonably well on desktop, tablet, and mobile. This gets them to a point where it can be shown to advisors and early users; maybe even potential investors who’ve expressed an interest in the concept. Once they get some cashflow from sales and/or investment, they can get a dedicated UX designer and polish the interface.

What follows is for this latter group.

Project Kickoff Meeting

Let’s invent a company to get the ball rolling.

Solar Excursions is a small travel agency aiming to serve the near-future’s burgeoning space tourism industry.

Our tiny development team has agreed that React will be used for the UI. One of our front-end developers is big on Sass, and the other is enamored with CSS in JavaScript. But they’ll be hard pressed to knock out their initial sprint goals; there’s certainly no time for arguing about the best possible styling approach. Both coders agree the choice doesn’t matter much in the long run, as long as its consistently executed. They’re certain that implementing the styling from scratch under the gun now will incur technical debt that will have to be cleaned up later.

After some discussion, the team opts to plan for one or more "styling refactor" sprints. For now, we’ll just focus on getting something up on the screen using React-Bootstrap. That way we’ll be able to quickly build working desktop and mobile layouts without much fuss.

The less time spent on front-end styling the better, because we’ll also need the UI to hook up to the services our backend developer will be cranking out. And, as our application architecture begins to take shape, both front-enders agree it’s important that it be unit tested. They have a lot on their plate.

Based on my discussions with the Powers That Be, as a dedicated project manager, I slaved over Balsamiq for at least ten minutes to provide the team with mockups for the booking page on desktop and mobile. I assume they’ll make tablet meet in the middle and look reasonable.

Initial mockups for the Solar Excursions Trip Booking Page on desktop (left) and mobile (right). Sprint Zero: Review Meeting

Pizza all around! The team worked really hard to hit its goals, and we now have a booking page with a layout that approximates the mockups. The infrastructure for services is coming together, but there’s quite a way to go before we can connect the UI to it. In the interim, the front-enders are using a hardcoded mock data structure.

The first iteration of the page in code using react-bootstrap.

Here’s a look at our UI code so far:

This is all straightforward React. We’re using some of that Hooks hotness, but it’s probably passé to most of you by now.

The key takeaway to notice here is how four of our five application components import and use components from react-bootstrap. Only the main App component is unaffected. That’s because it just composes the top level view with our custom components.

// App.js imports import React, { useState } from "react"; import Navigation from "./Navigation"; import Page from "./Page"; // Navigation.js imports import React from "react"; import { Navbar, Dropdown, Nav } from "react-bootstrap"; // Page.js imports import React from "react"; import PosterCarousel from "./PosterCarousel"; import DestinationLayout from "./DestinationLayout"; import { Container, Row, Col } from "react-bootstrap"; // PosterCarousel.js imports import React from "react"; import { Alert, Carousel, Image } from "react-bootstrap"; // DestinationLayout.js imports import React, { useState, useEffect } from "react"; import { Button, Card, Col, Container, Dropdown, Jumbotron, ListGroup, Row, ToggleButtonGroup, ToggleButton } from "react-bootstrap";

The decision to move fast with Bootstrap has allowed us to hit our sprint goals, but we’re already accumulating technical debt. This is just four affected components, but as the application grows, it’s clear the "styling refactor" sprints that we planned for are going to become exponentially harder. And we haven’t even customized these components much. Once we have tens of components, all using Bootstrap with lots of inline styling to pretty them up, refactoring them to remove react-bootstrap dependencies will be a scary proposition indeed.

Rather than building more of the booking pipeline pages, the team decides that we’ll spend the next sprint working to isolate the react-bootstrap usage in a custom component kit since our services are still under construction. Application components will only use components from this kit. That way, when it comes time to ween ourselves from react-bootstrap, the process will be much easier. We won’t have to refactor thirty usages of the react-bootstrap Button throughout the app, we’ll just rewrite the internals of our KitButton component.

Sprint One: Review Meeting

Well, that was easy. High-fives. No change to the visual appearance of the UI, but we now have a "kit" folder that’s sibling to "components" in our React source. It has a bunch of files like KitButton.js, which basically export renamed react-bootstrap components.

An example component from our kit looks like this:

// KitButton.js import { Button, ToggleButton, ToggleButtonGroup } from "react-bootstrap"; export const KitButton = Button; export const KitToggleButton = ToggleButton; export const KitToggleButtonGroup = ToggleButtonGroup;

We wrap those all kit components up into a module like this:

// kit/index.js import { KitCard } from "./KitCard"; import { KitHero } from "./KitHero"; import { KitList } from "./KitList"; import { KitImage } from "./KitImage"; import { KitCarousel } from "./KitCarousel"; import { KitDropdown } from "./KitDropdown"; import { KitAttribution } from "./KitAttribution"; import { KitNavbar, KitNav } from "./KitNavbar"; import { KitContainer, KitRow, KitCol } from "./KitContainer"; import { KitButton, KitToggleButton, KitToggleButtonGroup } from "./KitButton"; export { KitCard, KitHero, KitList, KitImage, KitCarousel, KitDropdown, KitAttribution, KitButton, KitToggleButton, KitToggleButtonGroup, KitContainer, KitRow, KitCol, KitNavbar, KitNav };

And now our application components are completely free of react-bootstrap. Here are the imports for the affected components:

// Navigation.js imports import React from "react"; import { KitNavbar, KitNav, KitDropdown } from "../kit"; // Page.js imports import React from "react"; import PosterCarousel from "./PosterCarousel"; import DestinationLayout from "./DestinationLayout"; import { KitContainer, KitRow, KitCol } from "../kit"; // PosterCarousel.js imports import React from "react"; import { KitAttribution, KitImage, KitCarousel } from "../kit"; // DestinationLayout.js imports import React, { useState, useEffect } from "react"; import { KitCard, KitHero, KitList, KitButton, KitToggleButton, KitToggleButtonGroup, KitDropdown, KitContainer, KitRow, KitCol } from "../kit";

Here’s the front-end codebase now:

Although we’ve corralled all of the react imports into our kit components, our application components still rely a bit on the react-bootstrap implementation because the attributes we place on our kit component instances are the same as those of react-bootstrap. That constrains us when it comes to re-implementing the kit components, because we need to adhere to the same API. For instance:

// From Navigation.js <KitNavbar bg="dark" variant="dark" fixed="top">

Ideally, we wouldn’t have to add those react-bootstrap specific attributes when we instantiate our KitNavbar.

The front-enders promise to refactor those out as we go, now that we’ve identified them as problematic. And any new references to react-bootstrap components will go into our kit instead of directly into the application components.

Meanwhile, we’ve shared our mock data with the server engineer, who is working hard to build separate server environments, implement the database schema, and expose some services to us.

That gives us time to add some gloss to our UI in the next sprint — which is good because the Powers That Be would like to see separate themes for each destination. As the user browses destinations, we need to have the UI color scheme change to match the displayed travel poster. Also, we want to try and spiff up those components a bit to begin evolving our own look and feel. Once we have some money coming in, we’ll get a designer to do a complete overhaul, but hopefully we can reach a happy medium for our early users.

Sprint Two: Review Meeting

Wow! The team really pulled out all the stops this sprint. We got per-destination themes, customized components, and a lot of the lingering react-bootstrap API implementations removed from the application components.

Here’s what the desktop looks like now:

Check out the solarized theme for the red planet!

In order to pull this off, the front-enders brought in the Styled Components library. It made styling the individual kit components a breeze, as well as adding support for multiple themes.

Let’s look at a few highlights of their changes for this sprint.

First, for global things like pulling in fonts and setting the page body styles, we have a new kit component called KitGlobal.

// KitGlobal.js import { createGlobalStyle } from "styled-components"; export const KitGlobal = createGlobalStyle` body { @import url('https://fonts.googleapis.com/css?family=Orbitron:500|Nunito:600|Alegreya+Sans+SC:700'); background-color: ${props => props.theme.foreground}; overflow-x: hidden; } `;

It uses the createGlobalStyle helper to define the CSS for the body element. That imports our desired web fonts from Google, sets the background color to whatever the current theme’s "foreground" value is, and turns off overflow in the x-direction to eliminate a pesky horizontal scrollbar. We use that KitGlobal component in the render method of our App component.

Also in the App component, we import ThemeProvider from styled-components, and something called "themes" from ../theme. We use React’s useState to set the initial theme to themes.luna and React’s useEffect to call setTheme whenever the "destination" changes. The returned component is now wrapped in ThemeProvider, which is passed "theme" as a prop. Here’s the App component in its entirety.

// App.js import React, { useState, useEffect } from "react"; import { ThemeProvider } from "styled-components"; import themes from "../theme/"; import { KitGlobal } from "../kit"; import Navigation from "./Navigation"; import Page from "./Page"; export default function App(props) { const [destinationIndex, setDestinationIndex] = useState(0); const [theme, setTheme] = useState(themes.luna); const destination = props.destinations[destinationIndex]; useEffect(() => { setTheme(themes[destination.theme]); }, [destination]); return ( <ThemeProvider theme={theme}> <React.Fragment> <KitGlobal /> <Navigation {...props} destinationIndex={destinationIndex} setDestinationIndex={setDestinationIndex} /> <Page {...props} destinationIndex={destinationIndex} setDestinationIndex={setDestinationIndex} /> </React.Fragment> </ThemeProvider> ); }

KitGlobal is rendering like any other component. Nothing special there, only that the body tag is affected. ThemeProvider is using the React Context API to pass theme down to whatever components need it (which is all of them). In order to fully understand that, we also need to take a look at what a theme actually is.

To create a theme, one of our front-enders took all the travel posters and created palettes for each by extracting the prominent colors. That was fairly simple.

We used TinyEye for this.

Obviously, we weren’t going to use all the colors. The approach was mainly to dub the most used two colors foreground and background. Then we took three more colors, generally ordered from lightest to darkest as accent1, accent2, and accent3. Finally, we picked two contrasting colors to call text1 and text2. For the above destination, that looked like:

// theme/index.js (partial list) const themes = { ... mars: { background: "#a53237", foreground: "#f66f40", accent1: "#f8986d", accent2: "#9c4952", accent3: "#f66f40", text1: "#f5e5e1", text2: "#354f55" }, ... }; export default themes;

Once we have a theme for each destination, and it is being passed into all the components (including the kit components that our application components are now built from), we need to use styled-components to apply those theme colors as well as our custom visual styling, like the panel corners and "border glow."

This is a simple example where we made our KitHero component apply the theme and custom styles to the Bootstrap Jumbotron:

// KitHero.js import styled from "styled-components"; import { Jumbotron } from "react-bootstrap"; export const KitHero = styled(Jumbotron)` background-color: ${props => props.theme.accent1}; color: ${props => props.theme.text2}; border-radius: 7px 25px; border-color: ${props => props.theme.accent3}; border-style: solid; border-width: 1px; box-shadow: 0 0 1px 2px #fdb813, 0 0 3px 4px #f8986d; font-family: "Nunito", sans-serif; margin-bottom: 20px; `;

In this case, we’re good to go with what gets returned from styled-components, so we just name it KitHero and export it.

When we use it in the application, it looks like this:

// DestinationLayout.js (partial code) const renderHero = () => { return ( <KitHero> <h2>{destination.header}</h2> <p>{destination.blurb}</p> <KitButton>Book Your Trip Now!</KitButton> </KitHero> ); };

Then there are more complex cases where we want to preset some attributes on the react-bootstrap component. For instance, the KitNavbar component which we identified earlier as having a bunch of react-bootstrap attributes that we’d rather not pass from the application’s declaration of the component.

Now for a look at how that was handled:

// KitNavbar.js (partial code) import React, { Component } from "react"; import styled from "styled-components"; import { Navbar } from "react-bootstrap"; const StyledBootstrapNavbar = styled(Navbar)` background-color: ${props => props.theme.background}; box-shadow: 0 0 1px 2px #fdb813, 0 0 3px 4px #f8986d; display: flex; flex-direction: horizontal; justify-content: space-between; font-family: "Nunito", sans-serif; `; export class KitNavbar extends Component { render() { const { ...props } = this.props; return <StyledBootstrapNavbar fixed="top" {...props} />; } }

First, we create a component called StyledBootstrapNavbar using styled-components. We were able to handle some of the attributes with the CSS we passed to styled-components. But in order to continue leveraging (for now) the reliable stickiness of the component to the top of the screen while everything else is scrolled, our front-enders elected to continue using react-bootstrap’s fixed attribute. In order to do that, we had to create a KitNavbar component that rendered an instance of StyledBootstrapNavbar with the fixed=top attribute. We also passed through all the props, which includes its children.

We only have to create a separate class that renders styled-component’s work and passes props through to it if we want to explicitly set some attributes in our kit component by default. In most cases, we can just name and return styled-component’s output and use it as we did with KitHero above.

Now, when we render the KitNavbar in our application’s Navigation component, it looks like this:

// Navigation.js (partial code) return ( <KitNavbar> <KitNavbarBrand> <KitLogo /> Solar Excursions </KitNavbarBrand> {renderDestinationMenu()} </KitNavbar> );

Finally, we took our first stabs at refactoring our kit components away from react-bootstrap. The KitAttribution component is a Bootstrap Alert which, for our purposes, is little more than an ordinary div. We were able to easily refactor to remove its dependency on react-bootstrap.

This is the component as it emerged from the previous sprint:

// KitAttribution.js (using react-bootstrap) import { Alert } from "react-bootstrap"; export const KitAttribution = Alert;

This is what it looks like now:

// KitAttribution.js import styled from "styled-components"; export const KitAttribution = styled.div` text-align: center; background-color: ${props => props.theme.accent1}; color: ${props => props.theme.text2}; border-radius: 7px 25px; border-color: ${props => props.theme.accent3}; border-style: solid; border-width: 1px; box-shadow: 0 0 1px 2px #fdb813, 0 0 3px 4px #f8986d; font-family: "Alegreya Sans SC", sans-serif; > a { color: ${props => props.theme.text2}; font-family: "Nunito", sans-serif; } > a:hover { color: ${props => props.theme.background}; text-decoration-color: ${props => props.theme.accent3}; } `;

Notice how we no longer import react-bootstrap and we use styled.div as the component base. They won’t all be so easy, but it’s a process.

Here are the results of our team’s styling and theming efforts in sprint two:

View the themed page on its own here.

Conclusion

After three sprints, our team is well on its way to having a scalable component architecture in place for the UI.

  • We are moving quickly thanks to react-bootstrap, but are no longer piling up loads of technical debt as a result of it.
  • Thanks to styled-components, we were able to implement multiple themes (like how almost every app on the Internet these days sports dark and light modes). We also don’t look like an out-of-the-box Bootstrap app anymore.
  • By implementing a custom component kit that contains all references to react-bootstrap, we can refactor away from it as time permits.

Fork the final codebase on GitHub.

The post Iterating a React Design with Styled Components appeared first on CSS-Tricks.

Evergreen Googlebot

Css Tricks - Thu, 05/16/2019 - 4:28am

I've heard people say that the #1 most exciting and important thing that came out of Google I/O this year was the evergreen Googlebot:

Today, we are happy to announce that Googlebot now runs the latest Chromium rendering engine (74 at the time of this post) when rendering pages for Search. Moving forward, Googlebot will regularly update its rendering engine to ensure support for latest web platform features.

Before this, I guess I never even thought about it.

I guess part of it is that some people did already know that the old version didn't support some newfangled JavaScript stuff, and thus literally packaged their app with old JavaScript to be more SEO-friendly.

A bunch of people were apparently shipping older code simply for the sake of Googlebot, and now they don't have to. Sure, I'll call that a win.

Don't read this news as "don't worry about your JavaScript-rendered pages and SEO" though, because Google Webmasters is still telling us that pages with content that requires JavaScript to render are put into a special slower queue for both initial crawling and for updates. Not necessarily a penalty, but certainly a delay. I'm sure that's enough to make server-side rendering a priority for sites where SEO is the whole ballgame.

Direct Link to ArticlePermalink

The post Evergreen Googlebot appeared first on CSS-Tricks.

Using Jetpack to Accelerate WordPress Development

Css Tricks - Thu, 05/16/2019 - 4:25am

(This is a sponsored post.)

[Geoff:] I've built a fair number of WordPress sites in my day. It's been my go-to since the 2.x-ish days because it works for any site, big or small. That's the sort of solution and flexibility you like to have as a freelancer.

Boy, I wish I had Jetpack available in those early days.

Like WordPress itself, Jetpack is a good solution for many, many of the types of things clients are looking for from a WordPress site. I used to spend hours researching the right plugin for a specific feature, whether that was for comment filtering, asset caching, beefier search functionality, creating custom post types on the fly... you name it. All of that — and a heckuva lot more — is included in Jetpack right out of the box.

Here's what I'm talking about. A friend of mine runs a pop-up gallery here locally. She displays paintings, photographs, sculptures... basically anything super artsy from super talented locals. That includes events, socials, performances and screenings. The wild thing is that it "pops" up in different spots, based on what she's showing and what public space is available. So, you get how a website would be helpful for visitors to keep tabs on what's coming up and where things are going to take place, not to mention getting a recap on past events.

We've all made sites for friends, right? It's the kind of thing you do for free on the side. That makes it something you want to do well, but not necessarily spend a ton of time making. That's where Jetpack really helped me out in this case.

If Jetpack is new to you, it's a WordPress plugin that, as part of what it does, is bring features from WordPress.com and makes them available on your self-hosted WordPress sites.

For example, my friend really needed to showcase work. This is less of a content site and more of a visual experience, so media plays a big role. Photos, video, audio. You get it. Good thing Jetpack has a "Portfolio" custom post type at the ready.

That's a perfect start for showing things off, but my friend also needed a carousel to allow visitors to browse photos from events and artist works. This would've been something I probably would have turned to the WordPress plugin directory for in the past, or perhaps some (back then) jQuery plugin, but thankfully Jetpack had my back there, too.

While we're on the topic of media, we know that heavy image files are a recipe for slow sites. There's a ton of WordPress plugins that can help with caching, gzipping, and even lazy loading, but all that's already in Jetpack. Why go reinvent the wheel, especially on what's supposed to be a pretty quick build?

I think you catch my drift. The fact is that Jetpack is an effective way to supercharge a self-hosted WordPress site, connecting it to many of the same powerful services that you'd otherwise need to go to WordPress.com — or gobs of third-party plugins — to get. Plus, it's built by Automattic, so you know it integrates seamlessly with WordPress. No better confidence than going with something the primary maintainers of WordPress are willing to slap their name on!

Sure, we've only looked at a very simple example of how powerful Jetpack is for a small site. But don't be fooled: Jetpack is capable of handling the needs of large-scale sites as well. In fact, we love Jetpack here at CSS-Tricks because it powers so much of what you see on the site, from social sign-in and automated sharing, to downtime monitoring and site search. It's robust, dependable, and just gosh darn delightful to use.

And, hey, there's a free tier you can start using right away and it includes a generous number of features that help with security, performance, analytics, and theming... and it only goes up from there. &#x1f680;

Get Jetpack

Direct Link to ArticlePermalink

The post Using Jetpack to Accelerate WordPress Development appeared first on CSS-Tricks.

A Deep Dive into Native Lazy-Loading for Images and Frames

Css Tricks - Wed, 05/15/2019 - 5:04am

Today's websites are packed with heavy media assets like images and videos. Images make up around 50% of an average website's traffic. Many of them, however, are never shown to a user because they're placed way below the fold.

What’s this thing about images being lazy, you ask? Lazy-loading is something that’s been covered quite a bit here on CSS-Tricks, including a thorough guide with documentation for different approaches using JavaScript. In short, we’re talking about a mechanism that defers the network traffic necessary to load content when it’s needed — or rather when trigger the load when the content enters the viewport.

The benefit? A smaller initial page that loads faster and saves network requests for items that may not be needed if the user never gets there.

If you read through other lazy-loading guides on this or other sites, you’ll see that we’ve had to resort to different tactics to make lazy-loading work. Well, that’s about to change when lazy-loading will be available natively in HTML as a new loading attribute… at least in Chrome which will hopefully lead to wider adoption. Chrome has already merged the code for native lazy-loading and is expected to ship it in Chrome 75, which is slated to release June 4, 2019.

The pre-native approach

Until now, developers like ourselves have had to use JavaScript (whether it’s a library or something written from scratch) in order to achieve lazy-loading. Most libraries work like this:

  • The initial, server-side HTML response includes an img element without the src attribute so the browser does not load any data. Instead, the image's URL is set as another attribute in the element's data set, e.?g. data-src.
  • <img data-src="https://tiny.pictures/example1.jpg" alt="...">
  • Then, a lazy-loading library is loaded and executed.
  • <script src="LazyLoadingLibrary.js"></script> <script>LazyLoadingLibrary.run()</script>
  • That keeps track of the user's scrolling behavior and tells the browser to load the image when it is about to be scrolled into view. It does that by copying the data-src attribute's value to the previously empty src attribute.
  • <img src="https://tiny.pictures/example1.jpg" data-src="https://tiny.pictures/example1.jpg" alt="...">

This has worked for a pretty long time now and gets the job done. But it’s not ideal for good reasons.

The obvious problem with this approach is the length of the critical path for displaying the website. It consists of three steps, which have to be carried out in sequence (after each other):

  1. Load the initial HTML response
  2. Load the lazy-loading library
  3. Load the image file

If this technique is used for images above the fold the website will flicker during loading because it is first painted without the image (after step 1 or 2, depending on if the script uses defer or async) and then — after having been loaded — include the image. It will also be perceived as loading slowly.

In addition, the lazy-loading library itself puts an extra weight on the website's bandwidth and CPU requirements. And let’s not forget that a JavaScript approach won't work for people who have JavaScript disabled (although we shouldn't really care about them in 2019, should we?).

Oh, and what about sites that rely on RSS to distribute content, like CSS-Tricks? The initial image-less render means there are no images in the RSS version of content as well.

And so on.

Native lazy-loading to the rescue!

As we noted at the start, Chromium and Google Chrome will ship a native lazy-loading mechanism in the form of a new loading attribute, starting in Chrome 75. We’ll go over the attribute and its values in just a bit, but let’s first get it working in our browsers so we can check it out together.

Enable native lazy-loading

Until Chrome 75 is officially released, we have Chrome Canary and can enable lazy-loading manually by switching two flags.

  1. Open chrome://flags in Chromium or Chrome Canary.
  2. Search for lazy.
  3. Enable both the "Enable lazy image loading" and the "Enable lazy frame loading" flag.
  4. Restart the browser with the button in the lower right corner of the screen.
Native lazy-loading flags in Google Chrome

You can check if the feature is properly enabled by opening your JavaScript console (F12). You should see the following warning:

[Intervention] Images loaded lazily and replaced with placeholders. Load events are deferred."

All set? Now we get to dig into the loading attribute.

The loading attribute

Both the img and the iframe elements will accept the loading attribute. It's important to note that its values will not be taken as a strict order by the browser but rather as a hint to help the browser make its own decision whether or not to load the image or frame lazily.

The attribute can have three values which are explained below. Next to the images, you'll find tables listing your individual resource loading timings for this page load. Range response refers to a kind of partial pre-flight request made to determine the image's dimensions (see How it works) for details). If this column is filled, the browser made a successful range request.

Please note the startTime column, which states the time image loading was deferred after the DOM had been parsed. You might have to perform a hard reload (CTRL + Shift + R) to re-trigger range requests.

The auto (or unset) value <img src="auto-cat.jpg" loading="auto" alt="..."> <img src="auto-cat.jpg" alt="..."> <iframe src="https://css-tricks.com/" loading="auto"></iframe> <iframe src="https://css-tricks.com/"></iframe> Auto cat loaded automatically

Setting the loading attribute to auto (or simply leaving the value blank, as in loading="") lets the browser decide whether or not to lazy-load an image. It takes many things into consideration to make that decision, like the platform, whether Data Saver mode is enabled, network conditions, image size, image vs. iframe, the CSS display property, among others. (See How it works) for info about why all this is important.)

The eager value <img src="auto-cat.jpg" loading="eager" alt="..."> <iframe src="https://css-tricks.com/" loading="eager"></iframe> Eager cat loaded eagerly

The eager value provides a hint to the browser that an image should be loaded immediately. If loading was already deferred (e.?g. because it had been set to lazy and was then changed to eager by JavaScript), the browser should start loading the image immediately.

The lazy value <img src="auto-cat.jpg" loading="lazy" alt="..."> <iframe src="https://css-tricks.com/" loading="lazy"></iframe> Lazy cat loaded lazily

The lazy value provides a hints to the browser that an image should be lazy-loaded. It's up to the browser to interpret what exactly this means, but the explainer document states that it should start loading when the user scrolls "near" the image such that it is probably loaded once it actually comes into view.

How the loading attribute works

In contrast to JavaScript lazy-loading libraries, native lazy-loading uses a kind of pre-flight request to get the first 2048?bytes of the image file. Using these, the browser tries to determine the image's dimensions in order to insert an invisible placeholder for the full image and prevent content from jumping during loading.

The image's load event is fired as soon as the full image is loaded, be it after the first request (for images smaller than 2?KB) or after the second one. Please note that the load event may never be fired for certain images because the second request is never made.

In the future, browsers might make twice as many image requests as there would be under the current proposal. First the range request, then the full request. Make sure your servers support the HTTP Range: 0-2047 header and respond with status code 206 (Partial Content) to prevent them from delivering the full image twice.

Due to the higher number of subsequent requests made by the same user, web server support for the HTTP/2 protocol will become more important.

Let’s talk about deferred content. Chrome's rendering engine Blink uses heuristics to determine which content should be deferred and for how long to defer it. You can find a comprehensive list of requirements in Scott Little's design documentation. This is a short breakdown of what will be deferred:

  • Images and frames on all platforms which have loading="lazy" set
  • Images on Chrome for Android with Data Saver enabled and that satisfy all of the following:
    • loading="auto" or unset
    • no width and height attributes smaller than 10px
    • not created programmatically in JavaScript
  • Frames which satisfy all of the following:
    • loading="auto" or unset
    • is from a third-party (different domain or protocol than the embedding page)
    • larger than 4 pixels in height and width (to prevent deferring tiny tracking frames)
    • not marked as display: none or visibility: hidden (again, to prevent deferring tracking frames)
    • not positioned off-screen using negative x or y coordinates
Responsive images with srcset

Native lazy-loading also works with responsive img elements using the srcset attribute. This attribute offers a list of image file candidates to the browser. Based on the user's screen size, display pixel ratio, network conditions, etc., the browser will choose the optimal image candidate for the occasion. Image optimization CDNs like tiny.pictures are able to provide all image candidates in real-time without any back end development necessary.

<img src="https://demo.tiny.pictures/native-lazy-loading/lazy-cat.jpg" srcset="https://demo.tiny.pictures/native-lazy-loading/lazy-cat.jpg?width=400 400w, https://demo.tiny.pictures/native-lazy-loading/lazy-cat.jpg?width=800 800w" loading="lazy" alt="..."> Browser support

At the time of this writing, no browser supports native-loading by default. However, Chrome will enable the feature, as we’ve covered, starting in Chrome 75. No other browser vendor has announced support so far. (Edge being a kind of exception because it will soon make the switch to Chromium.)

You can detect the feature with a few lines of JavaScript:

if ("loading" in HTMLImageElement.prototype) { // Support. } else { // No support. You might want to dynamically import a lazy-loading library here (see below). }

See the Pen
Native lazy-loading browser support
by Erk Struwe (@erkstruwe)
on CodePen.

Automatic fallback to JavaScript solution with low-quality image placeholder

One very cool feature of most JavaScript-based lazy-loading libraries is the low-quality image placeholder (LQIP). Basically, it leverages the idea that browsers load (or perhaps I should say used to load) the src of an img element immediately, even if it gets later replaced by another URL. This way, it’s possible to load a tiny file size, low-quality image file on page load and later replace it with a full-sized version.

We can now use this to mimic the native lazy-loading’s 2 KB range requests in browsers that do not support this feature in order to achieve the same result, namely a placeholder with the actual image dimensions and a tiny file size.

See the Pen
Native lazy-loading with JavaScript library fallback and low-quality image placeholder
by Erk Struwe (@erkstruwe)
on CodePen.

Conclusion

I'm really excited about this feature. And frankly, I'm still wondering why it hasn't got much more attention until now, given the fact that its release is imminent and the impact on global internet traffic will be remarkable, even if only small parts of the heuristics are changed.

Think about it: After a gradual roll-out for the different Chrome platforms and with auto being the default setting, the world's most popular browser will soon lazy-load below-the-fold images and frames by default. Not only will the traffic amount of many badly-written websites drop significantly, but web servers will be hammered with tiny requests for image dimension detection.

And then there's tracking: Assuming many unsuspecting tracking pixels and frames will be prevented from being loaded, the analytics and affiliate industry will have to act. We can only hope they don't panic and add loading="eager" to every single image, rendering this great feature useless for their users. They should rather change their code to be recognized as tracking pixels by the heuristics described above.

Web developers, analytics and operations managers should check their website's behavior with this feature and their servers' support for Range requests and HTTP/2 immediately.

Image optimization CDNs could help out in case there are any issues to be expected or if you’d like to take image delivery optimization to the max (including automatic WebP support, low-quality image placeholders, and much more). Read more about tiny.pictures!

References

The post A Deep Dive into Native Lazy-Loading for Images and Frames appeared first on CSS-Tricks.

Syndicate content
©2003 - Present Akamai Design & Development.