Web Standards

Linkbait 42

QuirksBlog - Tue, 12/04/2018 - 12:22am

Full-stack edition. Look no further than here.

  • Microsoft is rumoured to pull the plug on their EdgeHTML rendering engine and move to Chromium for the next Edge version. It’s always a sad moment when a rendering engine leaves us.
    Now as anyone who read my Chromium blog posts knows, one Chromium is not necessarily exactly the same as another. Thus I do not expect EdgeChromium to be 100% the same as Chrome — more like 98%.
    How to solve this? Test more in Edge — 3 years ago. Of course my readers know this and do this; it’s the full-stackers that are the problem.
  • Speaking of which. Heydon takes a stab at defining the problem with full-stack developers. They try to do too much, and as a result, code quality suffers.

    By assuming the role of the Full Stack Developer (which is, in practice, a computer scientist who also writes HTML and CSS), one takes responsibility for all the code, in spite of its radical variance in syntax and purpose, and becomes the gatekeeper of at least some kinds of code one simply doesn’t care about writing well.

    He also points out that one full-stack developer is cheaper than three specialised developers, and cost cutting is certainly part of the reason why full-stack has become so popular.
    Still, to me, it all comes down to the low esteem in which HTML/CSS is held (and Heydon also mentions that). It’s much easier to declare a low-status job redundant than a high-status one. I mean, are there large companies that have the same people do development and devops?
  • In case you’re wondering why full-stack programmers have such problems with CSS (and HTML), Robin Rendle explains. Front-end (i.e. HTML and CSS) is not a problem to be solved because, essentially, it’s already been solved. Just not by full-stack programmers.

    What’s the point in learning about vanilla HTML, CSS and JavaScript if they wind up becoming transpiled by other tools and languages?

    [...] Front-end development is complex because design is complex. Transpiling [...] into HTML and CSS requires vim and nuance, and always will. That’s not going to be resolved by a tool but by diligent work over a long period of time.

  • Jeremy compares CSS to a programming language, and finds that selectors, especially, qualify. Still, that’s exactly the part of CSS that isn’t used a lot, since we all have to go modular and use classes everywhere.
    Foor for thought; also for the book.
  • While ostensibly explaining a React feature, Dan Abramov gives a lesson about JavaScript prototypes and inheritance. Useful reading for all JavaScripters — I learned (or relearned) a thing or two here.
  • Addy Osmani takes a look at the cost of JavaScript. While they work OK-ish on modern desktop computers, huge scripts cause a lot of problems on low-end phones. (News? No, not really. But people don’t listen.) As he says,

    The web is bloated by user “experience”

    If you want facts and figures to convince others, look no further than this article.
  • Harry takes an exhaustive dive into CSS and network performance.

    Your page will only render as quickly as your slowest stylesheet.

    If you ever wanted to know absolutely everything about the way stylesheets can block page rendering, read it all. Did you know, for instance, that you should not place stylesheets before async script snippets? That’s because browsers await the full stylesheet before evaluating the snippet. What if the script requests the colour of a certain element, and the CSS hasn’t come in yet? Better to wait.
    Tons more good stuff here.
  • Interesting experiment by Daniel Buchner. He shows how to use the CSS :invalid pseudo, which triggers onkeypress, in a script, where normally the invalid event would fire onsubmit (or in a few edge cases).
    Read my native form validation series for a LOT more background information about the differences. (I didn’t think of Daniel’s trick, though. Simple, elegant, useful.)
  • Have a tip for the next Linkbait? Or a comment on this one? Let me know (or here or here).

Linkbait 42

QuirksBlog - Tue, 12/04/2018 - 12:22am

Full-stack edition. Look no further than here.

  • Microsoft is rumoured to pull the plug on their EdgeHTML rendering engine and move to Chromium for the next Edge version. It’s always a sad moment when a rendering engine leaves us.
    Now as anyone who read my Chromium blog posts knows, one Chromium is not necessarily exactly the same as another. Thus I do not expect EdgeChromium to be 100% the same as Chrome — more like 98%.
    How to solve this? Test more in Edge — 3 years ago. Of course my readers know this and do this; it’s the full-stackers that are the problem.
  • Speaking of which. Heydon takes a stab at defining the problem with full-stack developers. They try to do too much, and as a result, code quality suffers.

    By assuming the role of the Full Stack Developer (which is, in practice, a computer scientist who also writes HTML and CSS), one takes responsibility for all the code, in spite of its radical variance in syntax and purpose, and becomes the gatekeeper of at least some kinds of code one simply doesn’t care about writing well.

    He also points out that one full-stack developer is cheaper than three specialised developers, and cost cutting is certainly part of the reason why full-stack has become so popular.
    Still, to me, it all comes down to the low esteem in which HTML/CSS is held (and Heydon also mentions that). It’s much easier to declare a low-status job redundant than a high-status one. I mean, are there large companies that have the same people do development and devops?
  • In case you’re wondering why full-stack programmers have such problems with CSS (and HTML), Robin Rendle explains. Front-end (i.e. HTML and CSS) is not a problem to be solved because, essentially, it’s already been solved. Just not by full-stack programmers.

    What’s the point in learning about vanilla HTML, CSS and JavaScript if they wind up becoming transpiled by other tools and languages?

    [...] Front-end development is complex because design is complex. Transpiling [...] into HTML and CSS requires vim and nuance, and always will. That’s not going to be resolved by a tool but by diligent work over a long period of time.

  • Jeremy compares CSS to a programming language, and finds that selectors, especially, qualify. Still, that’s exactly the part of CSS that isn’t used a lot, since we all have to go modular and use classes everywhere.
    Foor for thought; also for the book.
  • While ostensibly explaining a React feature, Dan Abramov gives a lesson about JavaScript prototypes and inheritance. Useful reading for all JavaScripters — I learned (or relearned) a thing or two here.
  • Addy Osmani takes a look at the cost of JavaScript. While they work OK-ish on modern desktop computers, huge scripts cause a lot of problems on low-end phones. (News? No, not really. But people don’t listen.) As he says,

    The web is bloated by user “experience”

    If you want facts and figures to convince others, look no further than this article.
  • Harry takes an exhaustive dive into CSS and network performance.

    Your page will only render as quickly as your slowest stylesheet.

    If you ever wanted to know absolutely everything about the way stylesheets can block page rendering, read it all. Did you know, for instance, that you should not place stylesheets before async script snippets? That’s because browsers await the full stylesheet before evaluating the snippet. What if the script requests the colour of a certain element, and the CSS hasn’t come in yet? Better to wait.
    Tons more good stuff here.
  • Interesting experiment by Daniel Buchner. He shows how to use the CSS :invalid pseudo, which triggers onkeypress, in a script, where normally the invalid event would fire onsubmit (or in a few edge cases).
    Read my native form validation series for a LOT more background information about the differences. (I didn’t think of Daniel’s trick, though. Simple, elegant, useful.)
  • Have a tip for the next Linkbait? Or a comment on this one? Let me know (or here or here).

Too Much Accessibility

Css Tricks - Mon, 12/03/2018 - 11:16am

I like to blog little veins of thought as I see them. We recently linked to an article by Facundo Corradini calling out a tweet of ours where we used an <em> where we probably should have used an <i>.

Bruce Lawson checks if screen readers are the victims of these semantic mistakes...

Whenever I read “some browsers” or “some screenreaders”, I always ask “but which ones?”, as did Ilya Streltsyn, who asked me “what is the current state of the text-level semantics in HTML reality?”

Léonie Watson to the rescue! Over Twitter, Watters wrote

Most are capable of reporting these things on demand, but do not as standard. So you don’t hear the text/font characteristics being announced as you read, but you can query a character/word etc. to discover its characteristics. This is based on the visual presentation of the text though, rather than through any recognition of the elements themselves

Which I suppose is to say that if you're really fretting about screen readers misinterpreting the nuanced usage of your semantic emphasis... you can relax on that one.

Bruce's article led me toward Steve Faulkner's article "Screen Readers lack emphasis" from 2008.

Using the semantic elements strong and em does not convey any useful information to users of JAWS or Window Eyes under typical browsing conditions. While it is good to know this, it is not a reason to not use these elements to convey meaning. Accessibility is not just about people with vision impairment, it’s about all user’s with disabilities, and web standards is not just about accessibility.

So, not much has changed there in a decade. It's unclear to me if things should change here or not, but if virtual voices are improving, it stands to reason they could get better at voice inflections that convey emphasis. I certainly am thinking of voice emphasis when I write those HTML tags.

This idea of too much accessibility has been a bit of a theme.

Please don't read this article as suggesting that we worry too much about accessibility — only that it's possible to worry about the wrong things and even screw up accessibility in the process, just like anything else.

The post Too Much Accessibility appeared first on CSS-Tricks.

The Best iOS SDK Tools For 2019

Usability Geek - Mon, 12/03/2018 - 9:42am
There are lots of iOS apps worth adding to your home screen in 2019 and beyond. You have got Mobike for smart, convenient bike sharing, Blinkist for easy reads and insights and Oh She Glows for...
Categories: Web Standards

Bridging the Gap Between CSS and JavaScript: CSS-in-JS

Css Tricks - Mon, 12/03/2018 - 4:51am

In this article, we’re going to dig into the concept of CSS-in-JS. If you’re already acquainted with this concept, you might still enjoy a stroll through the philosophy of that approach, and you might be even more interested in the next article.

Web development is very interdisciplinary. We’re used to working closely with multiple languages. And, as developing web applications becomes more commonplace and nuanced, we often look for creative ways to bridge the gaps between those languages to make our development environments and workflows easier and more efficient.

The most common examples are typically when using templating languages. For example, one language might be used to generate the code of a more verbose language (often HTML). This is one of the key aspects of front end frameworks — what does manipulating HTML look like? The most recent twist in this area was JSX because it’s not really a templating language; it’s a syntax extension to JavaScript, and it makes working with HTML really succinct.

Web applications go through many state combinations and it’s often challenging to manage content alone. This is why CSS sometimes falls by the wayside — even though managing styling through different states and media queries is equally important and just as challenging. In this two-part series, I would like to place CSS in the spotlight and explore bridging the gap between it and JavaScript. Throughout this series, I will assume that you’re using a module bundler like webpack. As such, I will use React in my examples, but the same or similar principles are applicable to other JavaScript frameworks, including Vue.

The CSS landscape is evolving in many directions because there are a lot of challenges to solve and there is no "correct" path. I’ve been spending considerable effort experimenting with various approaches, mostly on personal projects, so the intention behind this series is only to inform, not to prescribe.

Challenges of CSS

Before diving into code, it’s worth explaining the most notable challenges of styling web applications. The ones I’ll talk about in this series are scoping, conditional and dynamic styles, and reusability.

Scoping

Scoping is a well-known CSS challenge, it’s the idea of writing styles that don’t leak outside of the component, thus avoid unintended side effects. We would like to achieve it ideally without compromising authoring experience.

Conditional and dynamic styles

While the state in front-end applications started getting more and more advanced, CSS was still static. We were only able to apply sets of styles conditionally — if a button was primary, we would probably apply the class "primary" and define its styles in a separate CSS file to apply how it’s going to look like on the screen. Having a couple of predefined button variations was manageable, but what if we want to have a variety of buttons, like specific ones tailored for Twitter, Facebook, Pinterest and who knows what else? What we really want to do is simply pass a color and define states with CSS like hover, focus, disabled etc. This is called dynamic styling because we’re no longer switching between predefined styles — we don’t know what’s coming next. Inline styles might come to mind for tackling this problem, but they don’t support pseudo-classes, attribute selectors, media queries, or the like.

Reusability

Reusing rulesets, media queries etc. is a topic I rarely see mentioned lately because it’s been solved by preprocessors like Sass and Less. But I’d still like to revisit it in this series.

I will list some techniques for dealing with these challenges along with their limitations in both parts of this series. No technique is superior to the others and they aren’t even mutually exclusive; you can choose one or combine them, depending on what you decide will improve the quality of your project.

Setup

We’ll demonstrate different styling techniques using an example component called Photo. We’ll render a responsive image that may have rounded corners while displaying alternative text as a caption. It will be used like this:

<Photo publicId="balloons" alt="Hot air balloons!" rounded />

Before building the actual component, we’ll abstract away the srcSet attribute to keep the example code brief. So, let’s create a utils.js file with two utilities for generating images of different widths using Cloudinary:

import { Cloudinary } from 'cloudinary-core' const cl = Cloudinary.new({ cloud_name: 'demo', secure: true }) export const getSrc = ({ publicId, width }) => cl.url(publicId, { crop: 'scale', width }) export const getSrcSet = ({ publicId, widths }) => widths .map(width => `${getSrc({ publicId, width })} ${width}w`) .join(', ')

We set up our Cloudinary instance to use the name of Cloudinary’s demo cloud, as well as its url method to generate URLs for the image publicId according to the specified options. We’re only interested in modifying the width in this component.

We’ll use these utilities for the src and srcset attributes, respectively:

getSrc({ publicId: 'balloons', width: 200 }) // => 'https://res.cloudinary.com/demo/image/upload/c_scale,w_200/balloons' getSrcSet({ publicId: 'balloons', widths: [200, 400] }) // => 'https://res.cloudinary.com/demo/image/upload/c_scale,w_200/balloons 200w, https://res.cloudinary.com/demo/image/upload/c_scale,w_400/balloons 400w'

If you’re unfamiliar with srcset and sizes attributes, I suggest reading a bit about responsive images first. That way, you’ll have an easier time following the examples.

CSS-in-JS

CSS-in-JS is a styling approach that abstracts the CSS model to the component level, rather than the document level. This idea is that CSS can be scoped to a specific component — and only that component — to the extent that those specific styles aren’t shared with or leaked to other components, and further, called only when they’re needed. CSS-in-JS libraries create styles at runtime by inserting <style> tags in the <head>.

One of the first libraries to put this concept to use is JSS. Here is and example employing its syntax:

import React from 'react' import injectSheet from 'react-jss' import { getSrc, getSrcSet } from './utils' const styles = { photo: { width: 200, '@media (min-width: 30rem)': { width: 400, }, borderRadius: props => (props.rounded ? '1rem' : 0), }, } const Photo = ({ classes, publicId, alt }) => ( <figure> <img className={classes.photo} src={getSrc({ publicId, width: 200 })} srcSet={getSrcSet({ publicId, widths: [200, 400, 800] })} sizes="(min-width: 30rem) 400px, 200px" /> <figcaption>{alt}</figcaption> </figure> ) Photo.defaultProps = { rounded: false, } export default injectSheet(styles)(Photo)

At first glance, the styles object looks like CSS written in object notation with additional features, like passing a function to set the value based on props. The generated classes are unique, so you never need to worry about them clashing with other styles. In other words, you get scoping for free! This is how most CSS-in-JS libraries work — of course, with some twists in features and syntax that we’ll cover as we go.

You can see by the attributes that the width of our rendered image starts at 200px, then when the viewport width becomes at least 30rem, the width increases to 400px wide. We generated an extra 800 source to cover even larger screen densities:

  • 1x screens will use 200 and 400
  • 2x screens will use 400 and 800

styled-components is another CSS-in-JS library, but with a much more familiar syntax that cleverly uses tagged template literals instead of objects to look more like CSS:

import React from 'react' import styled, { css } from 'styled-components' import { getSrc, getSrcSet } from './utils' const mediaQuery = '(min-width: 30rem)' const roundedStyle = css` border-radius: 1rem; ` const Image = styled.img` width: 200px; @media ${mediaQuery} { width: 400px; } ${props => props.rounded && roundedStyle}; ` const Photo = ({ publicId, alt, rounded }) => ( <figure> <Image src={getSrc({ publicId, width: 200 })} srcSet={getSrcSet({ publicId, widths: [200, 400, 800] })} sizes={`${mediaQuery} 400px, 200px`} rounded={rounded} /> <figcaption>{alt}</figcaption> </figure> ) Photo.defaultProps = { rounded: false, } export default Photo

We often create semantically-neutral elements like <div> and <span> solely for styling purposes. This library, and many others, allow us to create and style them in a single motion.

My favorite benefit of this syntax is that it’s like regular CSS, minus interpolations. This means that we can migrate our CSS code more easily and we get to use our existing muscle memory instead of having to familiarize ourselves with writing CSS in the object syntax.

Notice that we can interpolate almost anything into our styles. This specific example demonstrates how we can save the media query in the variable and reuse it in multiple places. Responsive images are an excellent use case for this because the sizes attribute contains basically CSS, so we can use JavaScript to make the code more DRY.

Let’s say that we decided we want to visually hide the caption, but still make it accessible for screen readers. I know that a better way of achieving this would be to use an alt attribute instead, but let’s use a different way for the sake of this example. We can use a library of style mixins called polished — it works great with CSS-in-JS libraries making it great for our example. This library includes a mixin called hideVisually which does exactly what we want and we can use it by interpolating its return value:

import { hideVisually } from 'polished' const Caption = styled.figcaption` ${hideVisually()}; ` <Caption>{alt}</Caption>

Even though hideVisually outputs an object, the styled-components library knows how to interpolate it as styles.

CSS-in-JS libraries have many advanced features like theming, vendor prefixing and even inlining critical CSS, which makes it easy to stop writing CSS files entirely. At this point, you can start to see why CSS-in-JS becomes an enticing concept.

Downsides and limitations

The obvious downside to CSS-in-JS is that it introduces a runtime: the styles need to be loaded, parsed and executed via JavaScript. Authors of CSS-in-JS libraries are adding all kinds of smart optimizations, like Babel plugins, but some runtime costs will nevertheless exist.

It’s also important to note that these libraries aren’t being parsed by PostCSS because PostCSS wasn’t designed to be brought into the runtime. Many use stylis instead as a result because it’s much faster. This means that we unfortunately can’t use PostCSS plugins.

The last downside I’ll mention is the tooling. CSS-in-JS is evolving at a really fast rate and text editor extension, linters, code-formatters etc. need to play catch-up with new features to stay on par. For example, people are using the VS Code extension styled-components for similar CSS-in-JS libraries like emotion, even though they don’t all have the same features. I’ve even seen API choices of proposed features being influenced by the goal of retaining syntax highlighting!

The future

There are two new CSS-in-JS libraries, Linaria and astroturf, that have managed zero runtime by extracting CSS into files. Their APIs are similar to styled-components, but they vary in features and goals.

The goal of Linaria is to mimic the API of CSS-in-JS libraries like styled-components by having built-in features like scoping, nesting and vendor prefixing. Conversely, astroturf is built upon CSS Modules, has limited interpolation capabilities, and encourages using a CSS ecosystem instead of deferring to JavaScript.

I built Gatsby plugins for both libraries if you want to play with them:

Two things to have in mind when using these libraries:

  1. having actual CSS files means that we can process them with familiar tools like PostCSS
  2. Linaria uses custom properties (a.k.a. CSS variables) under the hood, be sure to take their browser support into consideration before using this library
Conclusion

CSS-in-JS are all-in-one styling solutions for bridging the gap between CSS and JavaScript. They are easy to use and they contain useful built-in optimizations — but all of that comes at a cost. Most notably, by using CSS-in-JS, we’re essentially ejecting from the CSS ecosystem and deferring to JavaScript to solve our problems.

Zero-runtime solutions mitigate some of the downsides by bringing back the CSS tools, which ascends the CSS-in-JS discussion to a much more interesting level. What are the actual limitations of preprocessing tools compared to CSS-in-JS? This will be covered in the next part of this series.

Article Series:
  1. CSS-in-JS (This post)
  2. CSS Modules, PostCSS and the Future of CSS

The post Bridging the Gap Between CSS and JavaScript: CSS-in-JS appeared first on CSS-Tricks.

Blue Beanie Day 2018

Css Tricks - Fri, 11/30/2018 - 5:21am

Another year!

You better not cry, you better not shout, I’m telling you why: @BlueBeanieDay is coming Nov. 30! Start sharing your #bbd photos, links, articles, and videos now: https://t.co/3US4vHBsDR#a11y #WebStandards #InclusiveDesign #ProgressiveEnhancement pic.twitter.com/AiV3ktRqka

— zeldman (@zeldman) October 24, 2018

I feel the same this year as I have in the past. Web standards, as an overall idea, has entirely taken hold and won the day. That's worth celebrating, as the web would be kind of a joke without them. So now, our job is to uphold them. We need to cry foul when we see a browser go rogue and ship an API outside the standards process. That version of competition is what could lead the web back to a dark place where we're creating browser-specific versions. That becomes painful, we stop doing it, and slowly, the web loses.

Direct Link to ArticlePermalink

The post Blue Beanie Day 2018 appeared first on CSS-Tricks.

Nesting Components in Figma

Css Tricks - Fri, 11/30/2018 - 5:06am

For the past couple of weeks, I’ve been building our UI Kit at Gusto, where I work, and this is a Figma document that contains all of our design patterns and components so that designers on our team can hop in, go shopping for a component that they need, and then get back to working on the problem that they’re trying to solve.

There’s a couple things that I’ve learned since I started. First, building a UI Kit is immensely delicate work and takes a really long time (although it happens to be very satisfying all the while). But, most importantly, embedding Figma components within other components is sort of magic.

Here’s why.

First, it’s important to note that I’ve tried to break down our components into the smallest, littlest chunks. So, for example, our Breadcrumbs, Tabs, and Progress Bar components are all separate from one another and I’ve dumped them all into a Symbols page.

Here’s an example of how I’ve started to build our form elements:

From what I can tell, this is how a lot of UI Kits are designed — there’s a welcome page that introduces what this document is and how to use it; there’s a symbols page that the design systems folks will maintain that has everything from buttons to forms inside it as symbols or components; and then there’s typically another page that has examples of these symbols that represent the final application.

Shopify’s design system, Polaris, does also this with their Sketch file, but so do a lot of examples I’ve seen from other big design teams:

But anyway, going back to my design in Figma — notice below that a forward slash (/) is used in the name of ProgressBar/Two and ProgressBar/Three components.

Well, that’s Figma’s naming convention for identifying Instances. What this means is that when a designer drags in the ProgressBar component from the UI Kit, they can switch between different options, like this:

That’s nifty! But once I broke up our UI into these tiny components, I started to wonder how I might combine these pieces together to make things even easier for our design team. I soon realized that in our app we have navigation items like breadcrumbs or progress bars but they always have a title associated with them. Once I figured that out, I started a series of new components called Header/Default, Header/Breadcrumbs, Header/ProgressBar, etc., which have all these components embedded within them.

So, now when a designer drags in the Header component into their mockups, they can do the following:

We’re switching between the different Header instances there and that doesn’t look like much, yet. But! Since we’re nesting components within our Header component, designers can jump down into the subcomponents, like ProgressBar and update that, too:

How neat is that? And again, this doesn’t look particularly useful just yet but nesting components within larger components means that you can start to use them in clever ways.

Where this gets interesting is here: at Gusto, we have two different UIs for our types of customers. We have admins that run payroll and then their employees that can access their account to see how much they’ve been paid. There’s different navigation and options for both, so I created two components for them: Frame/Admin and Frame/Employee.

These two components have the sidebar and navigation items but are then placed into a separate component called Layout/Default where we’ve placed our Header component. But since these components are instances and nested together, we can begin to click-clack bits of the UI together to get the precise interface that we want.

Now, whenever designers need to switch between different UIs, they can use these nested components and instances to toggle between them super fast. I’ve only just started experimenting with this but the idea is that by using these nested components you give folks a way to toggle between the different variants inside them whilst also providing a nice API for larger layouts.

If you’re using instances in Figma, Sketch, or another design tool — let me know! I’m constantly on the lookout for improving things here, but I think this is certainly a good start.

The post Nesting Components in Figma appeared first on CSS-Tricks.

Embed a Blog Onto Any Website With DropInBlog

Css Tricks - Fri, 11/30/2018 - 5:02am

With DropInBlog, you can embed a blog into your site in only three minutes. A quick JavaScript/HTML widget, or a full-featured JSON API, is all it takes.

A headless blog you can take anywhere

Ever been working on your existing static site or anything that wasn’t built with WordPress, wanted to integrate a blog, but then couldn’t find a clean solution?

DropInBlog to the rescue.

Now you can quickly integrate a full featured blog into any existing site. Actually, any existing page. Drop it right into your existing template. It’s so easy you can be up and running in just a few minutes. Check out this live example:

See Project

Blogging is simple with the full-featured editor

You’ll feel at home with the simple admin panel. Effortlessly create posts, categories, and authors. Tweak the blog output settings and enable features like share buttons, Disqus or Facebook comments with a couple of clicks.

Try it Free

Embed your blog in no time

You can embed your blog on a site in about three quick minutes. From there, you have a ton of control to customize and even put a variety of widgets to use, like Author List, Recent Post List, Category List... and more!

Check out this short video to see how quickly you can get up and running:

Need help getting setup? Hit up their friendly support on Messenger.

Simple JavaScript or JSON API... it’s your call.

There are a few integration options ranging from the drop-dead simple JavaScript method to the super flexible JSON API. You get to choose what works best for you.

Ready to give DropInBlog a try? Get started for free.

The post Embed a Blog Onto Any Website With DropInBlog appeared first on CSS-Tricks.

DevTools for Designers

Css Tricks - Thu, 11/29/2018 - 12:40pm

This is such an interesting conversation thread that keeps popping up year after year. The idea is that there could (and perhaps should) be in-browser tooling that helps web designers do their job. This tooling already exists to some degree. Let's check in on perspectives from a wide array of people and companies who have shared thoughts on this topic.

Ahmad Shadeed wrote for us last year about how DevTools can be useful to designers in a number of ways, like changing state, content, colors, variables, etc.:

Editing things visually like that will give [designers] more control over some design details, they can tweak things in the browser and show the result to the developer to be implemented.

In a post titled, "A DevTools for Designers", A.J. Kandy wrote that, just because you're a designer, it doesn't mean you don't know how to code — but you might not be production-level and might be faster elsewhere:

I can edit front-end markup; I’m just way faster at drawing rectangles and arranging them into user interfaces. I’m technical, but not a coder.

It sparked a lot of responses and thoughts back when we originally shared the post:

It's one thing to augment the existing DevTools to be better for designers. Firefox has done great work in that area with stuff like their animation tooling, flexbox and grid inspectors. At the same time, it's also nice to see entirely fresh takes on how we can approach it! For example, Google dropped VisBug, an extension with designers squarely in mind. The video is only 30 seconds:

There have been a lot of opinions about browser extensions that allow design editing over the years. Check out options like Stylebot (Chrome store link).

There is another visual design browser plugin called Visual Inspector:

Don't forget this classic trick:

My favourite trick to do in devTools is probably `document.designMode = "on"`. Turn it on and start editing text on any element on a website. Super cool! https://t.co/bdV9yONayT pic.twitter.com/rkC0ZsTCcD

— Simon Vrachliotis (@simonswiss) November 14, 2018

Oliver Williams wrote the following in "The ultimate web design tool: a browser":

Browser dev tools were traditionally useful for debugging JavaScript and inspecting network requests. More recently, we’ve seen browsers add graphical interfaces for manipulating CSS. Most browsers offer a color picker and eyedropper tool for selecting colors. In Chrome, this tool will helpfully display a color-contrast ratio. Chrome also offers a GUI for adding or tweaking text-shadow and box-shadow.

Perhaps design tooling will lead us in this direction in a big way?

✨isual
✨ evelopment
✨ nvironments

☝️Just like most code-based developers use IDEs to develop software today, we're going to start seeing multiple new VDEs emerge that enable a primarily-visual way of designing and shipping software.

— Vlad Magdalin (@callmevlad) November 16, 2018

Vlad works with Webflow, so you can see where he's coming from with that.

Jye SR chimed in with his post, "5 Ways DevTools Made My Life Easier":

... it’s possible to use Chrome DevTools to investigate competitors, see what’s not working with add-ons, change your viewport, understand page load timings and edit the web; all of which can help digital marketers, product managers or anyone working with a website to do their job more efficiently. It’s a tool which I use every day and I hope that you will too!

Hard to look at all that and not see this is where tooling is headed.

The post DevTools for Designers appeared first on CSS-Tricks.

Preventing Content Reflow From Lazy-Loaded Images

Css Tricks - Thu, 11/29/2018 - 5:03am

You know the concept of lazy loading images. It prevents the browser from loading images until those images are in (or nearly in) the browser's viewport.

There are a plethora of JavaScript-based lazy loading solutions. GitHub has over 3,400 different lazy load repos, and those are just the ones with "lazy load" in a searchable string! Most of them rely on the same trick: Instead of putting an image's URL in the src attribute, you put it in data-src — which is the same pattern for responsive images:

  • JavaScript watches the user scroll down the page
  • When the use encounters an image, JavaScript moves the data-src value into src where it belongs
  • The browser requests the image and it loads into view

The result is the browser loading fewer images up front so that the page loads faster. Additionally, if the user never scrolls far enough to see an image, that image is never loaded. That equals faster page loads and less data the user needs to spend.

"This is amazing!" you may be thinking. And, you’re right... it is amazing!

That said, it does indeed introduce a noticeable problem: images not containing the src attribute (including when it’s empty or invalid) have no height. This means that they're not the right size in the page layout until they're lazy-loaded.

When a user scrolls and images are lazy-loaded, those img elements go from a height of 0 pixels to whatever they need to be. This causes reflow, where the content below or around the image gets pushed to make room for the freshly loaded image. Reflow is a problem because it's a user-blocking operation. It slows down the browser by forcing it to recalculate the layout of any elements that are affected by that image's shape. The CSS scroll-behavior property may help here at some point, but its support needs to improve before it’s a viable option.

Lazy loading doesn't guarantee that the image will fully load before it enters the viewport. The result is a perceived janky experience, even if it’s a big performance win.

There are other issues with lazy loading images that are worth mentioning but are outside the scope of this post. For example, if JavaScript fails to run at all, then no images will load on the page. That’s a common concern for any JavaScript-based solution but this article only concerned with solving the problems introduced by reflow.

If we could force pre-loaded images to maintain their normal width and height (i.e. their aspect ratio), we could prevent reflow problems while still lazy loading them. This is something I recently had to solve building a progressive web app at DockYard where I work.

For future reference, there's an HTML attribute called intrinsicsize that's designed to preserve the aspect ratio, but right now, that's just experimental in Chrome.

Here’s how we did it.

Maintaining aspect ratio

There are many ways to go about the way we can maintain aspect ratios. Chris once rounded up an exhaustive list of options, but here’s what we’re looking at for image-specific options.

The image itself

The image src provides a natural aspect ratio. Even when an image is resized responsively, its natural dimensions still apply. Here's a pretty common bit of responsive image CSS:

img { max-width: 100%; height: auto; }

That CSS is telling images not to exceed the width of the element that contains them, but to scale the height properly so that there's no "stretching" or "squishing" as the image is resized. Even if the image has inline height and width attributes, this CSS will keep them behaving nicely on small viewports.

However, that "natural aspect ratio" behavior breaks down if there's no src yet. Browsers don't care about data-src and don't do anything with it, so it’s not really a viable solution for lazy loading reflow; but it is important to help understand the "normal" way images are laid out once they've loaded.

A pseudo-element

Many developers — including myself — have been frustrated trying to use pseudo-elements (e.g. ::before and ::after) to add decorations to img elements. Browsers don't render an image’s pseudo-elements because img is a replaced element, meaning its layout is controlled by an external resource.

However, there is an exception to that rule: If an image’s src attribute is invalid, browsers will render its pseudo-elements. So, if we store the src for an image in data-src and the src is empty, then we can use a pseudo-element to set an aspect ratio:

[data-src]::before { content: ''; display: block; padding-top: 56.25%; }

That'll set a 16:9 aspect ratio on ::before for any element with a data-src attribute. As soon as the data-src becomes the src, the browser stops rendering ::before and the image's natural aspect ratio takes over.

Here’s a demo:

See the Pen Image Aspect Ratio: ::before padding by James Steinbach (@jdsteinbach) on CodePen.

There are a couple drawbacks to this solution, however. First, it relies on CSS and HTML working together. Your stylesheet needs to have a declaration for each image aspect ratio you need to support. It would be much better if the template could insert an image without needing CSS edits.

Second, it doesn't work in Safari 12 and below, or Edge, at the time of writing. That's a pretty big traffic swatch to send poor layouts. To be fair, maintaining the aspect ratio is a bit of a progressive enhancement — there's nothing "broken" about the final rendered page. Still, it’s much more ideal to solve the reflow problem and for images to render as expected.

Data URI (Base64) PNGs

Another way we attempted to preserve the aspect ratio was to inline data URI for the src. as PNG. Using png-pixel.com will help with the lift of all that base64-encoding with any dimensions and colors. This can go straight into the image's src attribute in the HTML:

<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAACCAQAAAA3fa6RAAAADklEQVR42mNkAANGCAUAACMAA2w/AMgAAAAASUVORK5CYII=" data-src="//picsum.photos/900/600" alt="Lazy loading test image" />

The inline PNG there has a 3:2 aspect ratio (the same aspect ratio as the final image). When src is replaced with the data-src value, the image will maintain its aspect ratio exactly like we want!

Here’s a demo:

See the Pen Image Aspect Ratio: inline base64 PNG by James Steinbach (@jdsteinbach) on CodePen.

And, yes, this approach also comes with some drawbacks. Although the browser support is much better, it's complicated to maintain. We need to generate a base64 string for each new image size, then make that object of strings available to whatever templating tool that’s being used. It's also not the most efficient way to represent this data.

I kept exploring and found a smaller way.

Combine SVG with base64

After exploring the inline PNG option, I wondered if SVG might be a smaller format for inline images and here's what I found: An SVG with a viewBox declaration is a placeholder image with an easily editable native aspect ratio.

First, I tried base64-encoding an SVG. Here's an example of what that looked like in my HTML:

<img src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0naHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnIHZpZXdCb3g9JzAgMCAzIDInPjwvc3ZnPg==" data-src="//picsum.photos/900/600" alt="Lazy loading test image">

On small, simple aspect ratios, this is roughly equivalent in size to the base64 PNGs. A 1:1 ratio would be 114 bytes with base64 PNG and 106 bytes with base64 SVG. A 2:3 ratio is 118 bytes with base64 PNG and 106 bytes with base64 SVG.

However, using base64 SVG for larger, more complex ratios stay small, which is a real winner in file size. A 16:9 ratio is 122 bytes in base64 PNG and 110 bytes in base64 SVG. A 923:742 ratio is 3,100 bytes in base64 PNG but only 114b in base64 SVG! (That's not a common aspect ratio, but I needed to test with custom dimensions with my client's use case.)

Here’s a table to see those comparisons more clearly:

Aspect Ratio base64 PNG base64 SVG 1:1 114 bytes 106 bytes 2:3 118 bytes 106 bytes 16:9 122 bytes 110 bytes 923:742 3,100 bytes 114 bytes

The differences are negligible with simple ratios, but you can see how extremely well SVG scales as ratios become complex.

We've got much better browser support now. This technique is supported by all the big players, including Chrome, Firefox, Safari, Opera, IE11, and Edge, but also has great support in mobile browsers, including Safari iOS, Chrome for Android, and Samsung for Android (from 4.4 up).

Here's a demo:

See the Pen Image Aspect Ratio: inline base64 SVG by James Steinbach (@jdsteinbach) on CodePen.

&#x1f3c6; We have a winner!

Yes, we do, but stick with me as we improve this approach even more! I remembered Chris suggesting that we should not use base64 encoding with SVG inlined in CSS background-images and thought that advice might apply here, too.

In this case, instead of base64-encoding the SVGs, I used the "Optimized URL-encoded" technique from that post. Here's the markup:

<img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 3 2'%3E%3C/svg%3E" data-src="//picsum.photos/900/600" alt="Lazy loading test image" />

This is just a tad smaller than base64 SVG. The 1:1 is 106 bytes in base64 and 92 bytes when URL-encoding. 16:9 outputs 110 bytes in base64 and 97 bytes when URL-encoded.

If you're interested in more data size by file and encoding format, this demo compares different byte sizes between all of these techniques.

However, the real benefits that make the URL-encoded SVG a clear winner are that its format is human-readable, easily template-able, and infinitely customizable!

You don't need to create a CSS block or generate a base64 string to get a perfect placeholder for images where the dimensions are unknown! For example, here's a little React component that uses this technique:

const placeholderSrc = (width, height) => `data:image/svg+xml,%3Csvg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 ${width} ${height}"%3E%3C/svg%3E` const lazyImage = ({url, width, height, alt}) => { return ( <img src={placeholderSrc(width, height)} data-src={url} alt={alt} /> ) }

See the Pen React LazyLoad Image with Stable Aspect Ratio by James Steinbach (@jdsteinbach) on CodePen.

Or, if you prefer Vue:

See the Pen Vue LazyLoad Image with Stable Aspect Ratio by James Steinbach (@jdsteinbach) on CodePen.

I'm happy to report that browser support hasn't changed with this improvement — we've still got the full support as base64 SVG!

Conclusion

We've explored several techniques to prevent content reflow by preserving the aspect ratio of a lazy-loaded image before the swap happens. The best technique I was able to find is inlined and optimized URL-encoded SVG with image dimensions defined in the viewBox attribute. That can be scripted with a function like this:

const placeholderSrc = (width, height) => `data:image/svg+xml,%3Csvg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 ${width} ${height}"%3E%3C/svg%3E`

There are several benefits to this technique:

  • Solid browser support across desktop and mobile
  • Smallest byte size
  • Human-readable format
  • Easily templated without run-time encoding calls
  • Infinitely extensible

What do you think of this approach? Have you used something similar or have a completely different way of handling reflow? Let me know!

The post Preventing Content Reflow From Lazy-Loaded Images appeared first on CSS-Tricks.

Wed, 12/31/1969 - 2:00pm
Syndicate content
©2003 - Present Akamai Design & Development.