Archiwum kategorii: CSS

Combining Fonts

Post pobrano z: Combining Fonts

Another one from Jake Archibald!

This one is using two @font-face sets for the same font-family name. The second overrides the first, but only select characters of it, thanks to unicode-range.

You know how designers love ampersands? It’s a thing. Dan Cederholm once pointed out some advice from Robert Bringhurst:

Since the ampersand is more often used in display work than in ordinary text, the more creative versions are often the more useful. There is rarely any reason not to borrow the italic ampersand for use with roman text.

Then Drew McLellan showed how to do that (without a <span>), using unicode-range.

Direct Link to ArticlePermalink


Combining Fonts is a post from CSS-Tricks

Methods for Contrasting Text Against Backgrounds

Post pobrano z: Methods for Contrasting Text Against Backgrounds

It started with seeing a recent Pen of Mandy Michael’s text effects demos. I’m a very visual creature, so the first thing I noticed was the effect, not the title (which clearly states how the effect was achieved). Instantly, my mind went „blend modes!”, which turned out to be wrong.

The demo actually uses clip-path. First of all, the text is duplicated. We have black text below as the actual text content of the element and the white text above as the value of the content property (taken from a data attribute which gets updated via JS). These two are stacked one on top of each other (they completely overlap). Then the pseudo-element with the white text above gets clipped to the shape of the black dress.

However, this means we need to change the clipping path if we change the image and, at this point, it’s anything but easy to figure out polygonal clipping paths with a lot of points via dev tools (which is why having something like Benett Feely’s Clippy with two-way editing directly in dev tools would be immensely useful). So I decided to give my initial idea – blend modes – a try.

Let’s say we have a heading in a contentEditable1 container with a black and white image (well, grayscale) background. The HTML structure is as follows:

<header>
  <h2 contentEditable role='textbox' aria-multiline='true'>And stay alive</h2>
</header>

We set the background-image on the header container, we give the h2 white text and set its mix-blend-mode to difference or exclusion. The relevant CSS is below:

header { background: url(black-and-white-image.jpg) }

h2 {
  color: white;
  mix-blend-mode: difference;
}

I can’t really understand blend modes or normally see a difference between difference and exclusion, but according to MDN, they’re pretty much the same, with exclusion having less contrast. What I can understand in this situation is that having white text over the image gives us a result that’s the image inverted where the text overlaps it. For simple black and white images, black in the original image becomes white where we have white text above it and white in the original image becomes black where we have white text above it.

The result can be seen in the following Pen:

See the Pen by thebabydino (@thebabydino) on CodePen.

Mission accomplished! Both the text and the image can be changed and the effect is preserved without the need for any JavaScript or for any changes to the CSS.

But I instantly found that there was another itch to scratch: what happens if the image isn’t just black and white? Well, let’s try that! Turns out the result actually looks pretty good:

See the Pen by thebabydino (@thebabydino) on CodePen.

However, the text isn’t grayscale anymore and setting filter: grayscale(1) doesn’t change anything. Does any filter value work? Well, tried drop-shadow() next to try to find an answer to this question. And the answer is that, yes, drop-shadow() works, but the way it works – the shadow being blended with the header background2 – provides a clue about why grayscale() didn’t change a thing: filters are applied before blending, our text is white and the output of grayscale() in this case is identical to its input (white in, white out). And, since nothing changes before the blending, its result is the same.

See the Pen by thebabydino (@thebabydino) on CodePen.

This probably shouldn’t have been a surprise. I’ve ran into issues caused by the order in which properties are applied before.

For example, filter is also applied before clip-path, so if we clip an element to a non-rectangular shape and we want to have a drop shadow on it, tough luck, setting the filter on the same element doesn’t give the expected result. This is because the rectangular element gets the filter applied, so we have a drop shadow around its rectangular box and only after that gets clipped to the shape specified via clip-path. This is always the order these two get applied in, regardless of the order you set them in the CSS.

Diagram. A box representing an element (left) 
has a CSS filter applied to become a box with a box-shadow (center) then has a clip-path applied to 
become a star with no shadow (right).
Diagram of how browsers apply filter and clip-path when they’re set on the same element.

The way to solve the filter + clip-path problem is to set the filter on a parent element with nothing visible except the clipped child. The „nothing visible” part is important because, if the parent has some visible text or borders, they’ll get the drop shadow as well, while if it has a background, then the whole background area gets the shadow.

See the Pen by thebabydino (@thebabydino) on CodePen.

However, this solution doesn’t work for the filter + mix-blend-mode problem as well. Wrapping our h2 into a div and setting filter on that div breaks the blending effect.

See the Pen by thebabydino (@thebabydino) on CodePen.

What’s worse is that I can’t seem to think of anything I could do to get around this problem. There might be a way of doing it by duplicating the text and using a luminosity blend mode, but, as mentioned before, I don’t really understand blend modes and I haven’t been able to get that right.

But maybe we could try a different approach altogether, one that doesn’t use blending. All the playing with filters gave me the idea that we could apply the image to the text, then apply an invert() filter, to which we could chain grayscale(), contrast() and more.

With this method using background-clip: text, we also have the advantage of a cross-browser solution, since Firefox and Edge have now implemented this too.

The way we go about this is the following: we make sure the header and the h2 have identical backgrounds and that these backgrounds perfectly overlap. Then we set color: transparent on the h2 and clip its background to text. The final step is to set filter: invert(1) on the h2. The relevant CSS3 is as follows:

h2 {
  background: inherit;
  background-clip: text;
  color: transparent;
  filter: invert(1);
}

The result can be seen in the following Pen:

See the Pen by thebabydino (@thebabydino) on CodePen.

It looks like before, except it’s using a different method and now we can chain more functions to the filter property. For example, we can make the text grayscale and up its contrast:

filter: invert(1) grayscale(1) contrast(9)

See the Pen by thebabydino (@thebabydino) on CodePen.

Tweaking the filter value is also how we add a text shadow. While in the first case (using mix-blend-mode) we can simply set the text-shadow property (and the shadow also gets blended with the background), doing so in the second case breaks things:

See the Pen by thebabydino (@thebabydino) on CodePen.

Fortunately, we can chain drop-shadow() to our filter.

See the Pen by thebabydino (@thebabydino) on CodePen.

The Pen below shows the two methods described in this article. On the left, we have the mix-blend-mode method and on the right, we have the background-clip and filter method (with the extra grayscale and contrast components). The text is editable and the thumbnails allow for changing the background-image:

See the Pen by thebabydino (@thebabydino) on CodePen.

So, if we pit these methods against each other, which is better?

When don’t go into aesthetics because it’s a subjective matter and it probably differs from case to case and even from mood to mood.

As far as basic support is concerned, the last method gets an advantage since it’s supported in Edge, while mix-blend-mode isn’t (but if you want it in Edge, please vote for it because your feedback does matter). Mandy’s original example uses clip-path, another very useful feature, which sadly doesn’t work in Edge either (you can vote for it here).

When it comes to selecting text, the mix-blend-mode method works perfectly and looks the best across the browsers it’s supported.

The editable text, made to contrast with the background image using the mix-blend-mode method, shown selected in its entirety. The selection background is blended with the image underneath.
Selecting text when using the mix-blend-mode method

Using the clip-path method, the selection looks clean and the text remains readable, but it seemed to stumble in Firefox while I was over the pseudo-element text. Fortunately, this problem turned out to have an easy fix: setting pointer-events: none on the pseudo-element.

Animated gif. The editable text, made to contrast with the background image using the clip-path method, gets selected in Firefox. The selection stumbles where the copy of this text, generated via a pseudo-element, overlaps the original. Setting pointer-events: none on the pseudo-element fixes this problem.
Selecting text in Firefox when using the clip-path method

As for the last method, the selection can look ugly and can make the text harder to read. Not to mention that the drop shadow ends up being applied to the whole selection rectangle in this case, not just to the actual text.

The editable text, made to contrast with the background image using the background-clip: text + filter method, shown selected in its entirety. The whole selection box has the filter effect applied, not just the text, so the selection background is grayscale and the drop-shadow is now on the selection box, not just on the text itself.
Selecting text when using the background-clip: text + filter method

Changing the text also gets awkward in Firefox with the last method, the screen getting „dirty” as I type new text.

Animated gif. The editable text, made to contrast with the background image using the background-clip: text + filter method, gets edited in Firefox. As you write, the text becomes clipped and garbled, overlapping itself.
Changing text in Firefox when using the background-clip: text + filter method

The clip-path method also had a problem with changing text in Firefox at first: trying to start editing from the middle of the pseudo-element text didn’t work. Fortunately, setting pointer-events: none on the pseudo-element fixes this as well.

Animated gif. The editable text, made to contrast with the background image using the clip-path method, gets edited in Firefox. The cursor cannot be placed to start editing from the part where the copy of this text, generated via a pseudo-element, overlaps the original. Setting pointer-events: none on the pseudo-element fixes this problem.
Changing text in Firefox when using the clip-path method

As far as flexibility in terms of how we can alter the text goes, the last method fares best because chaining filter functions can take us a long way.

At the end of the day, which is better ends up depending on the particular use case. What browsers should be supported? Does the image change? Does the text change? How should the text be visually altered?


1 contentEditable isn’t accessible in all browsers by default, so we need to provide semantics to fix that.

2 When experimenting with blend modes, be aware of the legibility issues they can produce, particularly regarding contrast. WCAG 2.0 states that, unless the text forms part of purely decorative imagery, it should pass a minimum contrast threshold. Tools like Color ContrastAnalyzer can help you meet that requirement.

3 Prefixes are omitted for brevity, but background-clip still needs the -webkit- prefix for WebKit browsers (Firefox and Edge have implemented it unprefixed, though they both support it with the -webkit- prefix as well, probably because it has already been used to death only with that prefix) and this prefix needs to be added manually/ via a preprocessor mixin, which is something that I normally don’t encourage, but, in this particular case, auto-prefixing via Autoprefixer or Prefixfree doesn’t happen (Prefixfree works via feature detection, which doesn’t catch properties such as background-clip, filter or clip-path and this is the Autoprefixer issue). As for filter, it’s now supported unprefixed in all current desktop browsers and Autoprefixer can prefix it anyway.


Methods for Contrasting Text Against Backgrounds is a post from CSS-Tricks

Ordered Lists with Unicode Symbols

Post pobrano z: Ordered Lists with Unicode Symbols

Ordered lists are among the oldest and most semantically rich elements in HTML. Anytime you need to communicate sequence or ranking, the <ol> tag is there to help. The default appearance of the <ol> tag presents numbers next to each item in the list. You can use the list-style-type property in CSS to change the default to use Roman numerals or the letters of the alphabet. If you are feeling exotic, you can even use numbering from other cultures like Hebrew or Greek. The full list of available values is well-documented and easy to use.

Recently, I saw an opportunity to use dice in place of numbers for several ordered lists explaining the features of an HTML5 game I created called Triple Score Bopzee. To accomplish my goal, I first experimented with a now-familiar technique for using a small image file as the background for the li::before selector in a list. One change I made to the usual procedure is that I decided to avoid list-style-type: none in favor of using list-style-type: decimal and setting list-style-image to a 1×1 transparent GIF. That small change helps the page pass accessibility tests because screen readers will still see the list as a valid numbered list.

I created a Pen to demonstrate this classic technique using GIFs of numbers that contain the balls used in four major sports.

See the Pen Ordered List with Images by Steven Estrella (@sgestrella) on CodePen.

This technique would have worked for my needs on the bopzee web site but I got curious about how I could do it without using any images. The answer was to use the Unicode symbols \2680 through \2685 for the six dice. I created a class selector called „dicey” and used the nth-child and before pseudo selectors to position and choose the Unicode character for each list item. I added a link to the Normalize.css library to smooth out the subtle browser differences.

Here is the Pen for the completed dice list:

See the Pen Ordered Lists with Unicode Dice by Steven Estrella (@sgestrella) on CodePen.

So for a list like this:

<ol class="dicey">
  <li>I rolled a one.</li>
  <li>I rolled a two.</li>
  <li>I rolled a three.</li>
  <li>I rolled a four.</li>
  <li>I rolled a five.</li>
  <li>I rolled a six.</li>
</ol>

This was the trick:

/* Still use a decimal based list for a11y */
ol {
  margin-left:40px;
  list-style:decimal url(data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7);
}

.dicey li:nth-child(1n):before {position:absolute;left:-1em;}

/* Actually set markers with pseudo element unicode */
.dicey li:nth-child(1):before {content: "\2680";}
.dicey li:nth-child(2):before {content: "\2681";}
.dicey li:nth-child(3):before {content: "\2682";}
.dicey li:nth-child(4):before {content: "\2683";}
.dicey li:nth-child(5):before {content: "\2684";}
.dicey li:nth-child(6):before {content: "\2685";}

Initially, I did not specify the font that would display the Unicode symbols. The result was not bad because today every modern web browser and web enabled device has access to at least one font that contains the necessary symbols from the Unicode block called „Miscellaneous Symbols.” There was some variation in appearance but it was quite tolerable. But I knew that if I wanted real control, I would have to find a free web font. I identified a font called DejaVu that would work by looking through the supported fonts list in the table of glyphs for the Miscellaneous Symbols block.

Once I knew the font name, I was able to create a WebFont kit at Font Squirrel. When creating a WebFont kit, it is important to choose the „No subsetting” option to be sure the fonts contain all the Unicode goodness you need for your icons. Or if you are concerned about file size, you can download the original TrueType or OpenType font, then use Font Squirrel’s WebFont generator in expert mode to include only the Unicode range 2600 to 26FF which captures all characters in the Unicode block called „Miscellaneous Symbols.”

Once you get started with Unicode, the fun never stops. I spent way too much time exploring the many icons that are part of the DejaVu font (complete list). There I found icons for playing card suits, astrological signs, arrows, bullets, musical symbols, geometric shapes, and a whole host of squiggles I can’t begin to name. So I took some of my favorites and created a Pen containing several different kinds of lists.

The complete Pen:

See the Pen Ordered Lists with Unicode Symbols by Steven Estrella (@sgestrella) on CodePen.

What about unordered lists?

You can give your <ul> elements the same great Unicode love using a modified form of this technique. Here is a Pen to get you started:

See the Pen Unordered List with Unicode Bullets by Steven Estrella (@sgestrella) on CodePen.

What about the future?

There is a new CSS rule called @counter-style which will allow us more easily to create custom counter styles for ordered lists, specifying the symbols to be used, the range of the list, and lots of other options. The CSS Counter Styles Level 3 specification is now a Candidate Recommendation at the W3C but as of May 2017 only FireFox supports it (with some issues). I would expect that Chrome, Edge, and Safari will add support sometime soon but the final version of Internet Explorer (version 11) will likely never have it. So if you have to support that browser, you will be stuck with tricks like the one described on this post until people stop using IE11 (perhaps the year 2020?).

Note that the @counter-style rule does not provide any way to style the counter symbol using CSS. So even when it is adopted by all browsers, there may be use cases for alternative solutions like the one presented here. You can read more about @counter-style on MDN. Here is a pen with a demonstration.

Be sure to use FireFox to see the effect:

See the Pen @counter-style demo (FireFox only as of May 2017) by Steven Estrella (@sgestrella) on CodePen.

On the shoulders of giants

We all learn from the work of others and I wish to credit the work of several writers whose articles I found informative when preparing this post.

Here is a Pen with the unordered list above using several different icon styles!

See the Pen List of Credits with Unicode Bullets by Steven Estrella (@sgestrella) on CodePen.


Ordered Lists with Unicode Symbols is a post from CSS-Tricks

CSS Custom Properties and Theming

Post pobrano z: CSS Custom Properties and Theming

We posted not long ago about the difference between native CSS variables (custom properties) and preprocessor variables. There are a few esoteric things preprocessor variables can do that native variables cannot, but for the most part, native variables can do the same things. But, they are more powerful because of how they are live-interpolated. Should their values ever change (e.g. JavaScript, media query hits, etc) the change triggers immediate change on the site.

Cool, right? But still, how actually useful is that? What are the major use cases? I think we’re still seeing those shake out.

One use case, it occurred to me, would be theming of a site (think: custom colors for elements around a site). Rather than writing different CSS for a bunch of different themes, or writing JavaScript that targets all the elements we intend to change and changing them), we just write one base set of CSS that utilizes variables and set those variables to the theme colors.

Imagine we allow the header and footer background of our site to be customized.

header {
  background: var(--mainColor);
}

...

footer {
  background: var(--mainColor);
}

Maybe there is a subheader with a darker variation of that color. Here’s a little trick to lay a transparent layer of color over another:

.subheader {
  background: 
    /* Make a bit darker */
    linear-gradient(
      to top,
      rgba(0, 0, 0, 0.25),
      rgba(0, 0, 0, 0.25)
    )
    var(--mainColor);
}

Where does --mainColor come from?

With theming, the idea is that you ask the user for it. Fortunately we have color inputs:

<input type="color" />

And you could store that value in a database or any other storage mechanism you want. Here’s a little demo where the value is stored in localStorage:

See the Pen Theming a site with CSS Custom Properties by Chris Coyier (@chriscoyier) on CodePen.

The value is plucked out of localStorage and used when the page loads. A default value is also set (in CSS), in case that doesn’t exist.

What makes the above demo so compelling, to me, is how little code it is. Maintaining this as a a feature on a site is largely a CSS endeavour and seems flexible enough to stand the test of time (probably).

Not unusually, I was way behind on this one.

Lots of people think of theming as one of the major use-cases for CSS Custom Properties. Let’s look at some other folks examples.

Giacomo Zinetti has the same kind of color-picker implementation

On his site:

Examples and advice from Harry Roberts

He wrote „Pragmatic, Practical, and Progressive Theming with Custom Properties”, in which he pointed to apps like Twitter and Trello that offer theming directly to users:

Harry does a lot of consulting, and to my surprise, finds himself working with companies that want to do this a lot. He warns:

Theming, the vast majority of the time, is a complete nice-to-have. It is not business critical or usually even important. If you are asked to provide such theming, do not do so at the expense of performance or code quality.

In Sass / In React

In a real-world application of theming through Custom Properties, Dan Bahrami recounts how they did it on Geckoboard, the product he works on:

It’s a React product, but they aren’t using any styles-in-JavaScript stuff, so they opted to do the theming with Custom Properties, through Sass.

@mixin variable($property, $variable, $fallback) {
  #{$property}: $fallback;
  #{$property}: var($variable);
}

So they can do:

.dashboard {
  @include variable(background, --theme-primary-color, blue);
}

Which compiles to having a fallback:

.dashboard {
  background: blue;
  background: var(--theme-primary-color);
}

They also created react-custom-properties which all about applying Custom Properties to components, taking advantage of the fact that you can set Custom Properties as inline styles:

<div style="--theme-primary-color: blue;">

</div>

More than one color and property

It’s not only colors that can change, a Custom Property can be any valid value. Here’s Keith Clark with a demo with multiple colors as well as font size:

See the Pen Using CSS custom properties for theme previews by Keith Clark (@keithclark) on CodePen.

And David Darnes with theming built into a Jekyll site:

Experimenting with CSS Custom Properties with my @jekyllrb theme, allowing people to customise it https://t.co/SP9lhxdcoD (WIP) pic.twitter.com/7QAzKtD5n7

— David Darnes (@DavidDarnes) April 27, 2017

Microsoft Demo

Greg Whitworth created this demo:

Which uses color modifiers within color functions themselves:

.distant-building__window {
  fill: rgb(
    calc(111 + (111 * var(--building-r-mod))),
    calc(79 + (79 * var(--building-g-mod))),
    calc(85 + (85 * var(--building-b-mod)))
  );
}

Which is not supported in all browsers.

Greg also pointed out that CSS4 color functions (which we’ve covered before), will make all this theming stuff even more powerful.

The Polymer Project themes through Custom Properties

At least it did in the v1 docs. The idea is that you’d have a web compontent, like:

<iron-icon icon="[[toggleIcon]]">
</iron-icon>

That had smart defaults, but was specifically built to allow styling via theming:

<style>
  iron-icon {
    fill: var(--icon-toggle-color, rgba(0,0,0,0));
    stroke: var(--icon-toggle-outline-color, currentcolor);
  }
  :host([pressed]) iron-icon {
    fill: var(--icon-toggle-pressed-color, currentcolor);
  }
</style>

Which meant that you could set those variables and have the component take on new colors.

Support and fallbacks

Support has gotten pretty good recently:

Green indicates full support at the version listed (and above). Yellow indicates partial support. Red indicates no support. See Caniuse for full browser support details.

Desktop

Chrome Opera Firefox IE Edge Safari
49 36 31 No 15 9.1

Mobile / Tablet

iOS Safari Opera Mobile Opera Mini Android Android Chrome Android Firefox
9.3 37 No 56 57 52

Opera Mini and IE are notably missing. We already covered the idea of a fallback through setting a valid non-variable property before the one using a Custom Property.

Like many modern CSS features, you can use @supports to test for support before using:

@supports (--color: red) {
  :root {
    --color: red;
  }
  body {
    color: var(--color);
  }
}

It always depends on the situation, but just putting fallbacks on a previous declaration is probably the most useful way to deal with non-support in CSS. There are also edge cases.

Michael Scharnagl documents a JavaScript method for testing:

if (window.CSS && window.CSS.supports && window.CSS.supports('--a', 0)) {
  // CSS custom properties supported.
} else {
  // CSS custom properties not supported
}

Colors and Accessibility

When setting colors for text, and the color behind that text, the contrast between those colors is an accessibility issue. Too little contrast, too hard to read.

One somewhat common solution to this is to choose whether the text should be light or dark (white or black) based on the color behind it.

David Halford has a demo calculating this with JavaScript:

See the Pen JS function for accessible color contrast by David Halford (@davidhalford) on CodePen.

And Brendan Saunders with Sass:

See the Pen Sass text-contrast mixin by Brendan Saunders (@bluesaunders) on CodePen.


CSS Custom Properties and Theming is a post from CSS-Tricks

Using Fetch

Post pobrano z: Using Fetch

Whenever we send or retrieve information with JavaScript, we initiate a thing known as an Ajax call. Ajax is a technique to send and retrieve information behind the scenes without needing to refresh the page. It allows browsers to send and retrieve information, then do things with what it gets back, like add or change HTML on the page.

Let’s take a look at the history of that and then bring ourselves up-to-date.

Another note here, we’re going to be using ES6 syntax for all the demos in this article.

A few years ago, the easiest way to initiate an Ajax call was through the use of jQuery’s ajax method:

$.ajax('some-url', {
  success: (data) => { /* do something with the data */ },
  error: (err) => { /* do something when an error happens */}
});

We could do Ajax without jQuery, but we had to write an XMLHttpRequest, which is pretty complicated.

Thankfully, browsers nowadays have improved so much that they support the Fetch API, which is a modern way to Ajax without helper libraries like jQuery or Axios. In this article, I’ll show you how to use Fetch to handle both success and errors.

Support for Fetch

Let’s get support out of the way first.

Green indicates full support at the version listed (and above). Yellow indicates partial support. Red indicates no support. See Caniuse for full browser support details.

Desktop

Chrome Opera Firefox IE Edge Safari
42 29 39 No 14 10.1

Mobile / Tablet

iOS Safari Opera Mobile Opera Mini Android Android Chrome Android Firefox
10.3 37 No 56 57 52

Support for Fetch is pretty good! All major browsers (with the exception of Opera Mini and old IE) support it natively, which means you can safely use it in your projects. If you need support anywhere it isn’t natively supported, you can always depend on this handy polyfill.

Getting data with Fetch

Getting data with Fetch is easy. You just need to provide Fetch with the resource you’re trying to fetch (so meta!).

Let’s say we’re trying to get a list of Chris’ repositories on Github. According to Github’s API, we need to make a get request for api.github.com/users/chriscoyier/repos.

This would be the fetch request:

fetch('https://api.github.com/users/chriscoyier/repos');

So simple! What’s next?

Fetch returns a Promise, which is a way to handle asynchronous operations without the need for a callback.

To do something after the resource is fetched, you write it in a .then call:

fetch('https://api.github.com/users/chriscoyier/repos')
  .then(response => {/* do something */})

If this is your first encounter with Fetch, you’ll likely be surprised by the response Fetch returns. If you console.log the response, you’ll get the following information:

{
  body: ReadableStream
  bodyUsed: false
  headers: Headers
  ok : true
  redirected : false
  status : 200
  statusText : "OK"
  type : "cors"
  url : "http://some-website.com/some-url"
  __proto__ : Response
}

Here, you can see that Fetch returns a response that tells you the status of the request. We can see that the request is successful (ok is true and status is 200), but a list of Chris’ repos isn’t present anywhere!

Turns out, what we requested from Github is hidden in body as a readable stream. We need to call an appropriate method to convert this readable stream into data we can consume.

Since we’re working with GitHub, we know the response is JSON. We can call response.json to convert the data.

There are other methods to deal with different types of response. If you’re requesting an XML file, then you should call response.text. If you’re requesting an image, you call response.blob.

All these conversion methods (response.json et all) returns another Promise, so we can get the data we wanted with yet another .then call.

fetch('https://api.github.com/users/chriscoyier/repos')
  .then(response => response.json())
  .then(data => {
    // Here's a list of repos!
    console.log(data)
  });

Phew! That’s all you need to do to get data with Fetch! Short and simple, isn’t it? 🙂

Next, let’s take a look at sending some data with Fetch.

Sending data with Fetch

Sending data with Fetch is pretty simple as well. You just need to configure your fetch request with three options.

fetch('some-url', options);

The first option you need to set is your request method to post, put or del. Fetch automatically sets the method to get if you leave it out, which is why getting a resource takes lesser steps.

The second option is to set your headers. Since we’re primarily sending JSON data in this day and age, we need to set Content-Type to be application/json.

The third option is to set a body that contains JSON content. Since JSON content is required, you often need to call JSON.stringify when you set the body.

In practice, a post request with these three options looks like:

let content = {some: 'content'};

// The actual fetch request
fetch('some-url', {
  method: 'post',
  headers: {
    'Content-Type': 'application/json'
  },
  body: JSON.stringify(content)
})
// .then()...

For the sharp-eyed, you’ll notice there’s some boilerplate code for every post, put or del request. Ideally, we can reuse our headers and call JSON.stringify on the content before sending since we already know we’re sending JSON data.

But even with the boilerplate code, Fetch is still pretty nice for sending any request.

Handling errors with Fetch, however, isn’t as straightforward as handling success messages. You’ll see why in a moment.

Handling errors with Fetch

Although we always hope for Ajax requests to be successful, they can fail. There are many reasons why requests may fail, including but not limited to the following:

  1. You tried to fetch a non-existent resource.
  2. You’re unauthorized to fetch the resource.
  3. You entered some arguments wrongly
  4. The server throws an error.
  5. The server timed out.
  6. The server crashed.
  7. The API changed.

Things aren’t going to be pretty if your request fails. Just imagine a scenario you tried to buy something online. An error occured, but it remains unhandled by the people who coded the website. As a result, after clicking buy, nothing moves. The page just hangs there… You have no idea if anything happened. Did your card go through? 😱.

Now, let’s try to fetch a non-existent error and learn how to handle errors with Fetch. For this example, let’s say we misspelled chriscoyier as chrissycoyier

// Fetching chrissycoyier's repos instead of chriscoyier's repos
fetch('https://api.github.com/users/chrissycoyier/repos')

We already know we should get an error since there’s no chrissycoyier on Github. To handle errors in promises, we use a catch call.

Given what we know now, you’ll probably come up with this code:

fetch('https://api.github.com/users/chrissycoyier/repos')
  .then(response => response.json())
  .then(data => console.log('data is', data))
  .catch(error => console.log('error is', error));

Fire your fetch request. This is what you’ll get:

Fetch failed, but the code that gets executed is the second `.then` instead of `.catch`

Why did our second .then call execute? Aren’t promises supposed to handle errors with .catch? Horrible! 😱😱😱

If you console.log the response now, you’ll see slightly different values:

{
  body: ReadableStream
  bodyUsed: true
  headers: Headers
  ok: false // Response is not ok
  redirected: false
  status: 404 // HTTP status is 404.
  statusText: "Not Found" // Request not found
  type: "cors"
  url: "https://api.github.com/users/chrissycoyier/repos"
}

Most of the response remain the same, except ok, status and statusText. As expected, we didn’t find chrissycoyier on Github.

This response tells us Fetch doesn’t care whether your AJAX request succeeded. It only cares about sending a request and receiving a response from the server, which means we need to throw an error if the request failed.

Hence, the initial then call needs to be rewritten such that it only calls response.json if the request succeeded. The easiest way to do so to check if the response is ok.

fetch('some-url')
  .then(response => {
    if (response.ok) {
      return response.json()
    } else {
      // Find some way to get to execute .catch()
    }
  });

Once we know the request is unsuccessful, we can either throw an Error or reject a Promise to activate the catch call.

// throwing an Error
else {
  throw new Error('something went wrong!')
}

// rejecting a Promise
else {
  return Promise.reject('something went wrong!')
}

Choose either one, because they both activate the .catch call.

Here, I choose to use Promise.reject because it’s easier to implement. Errors are cool too, but they’re harder to implement, and the only benefit of an Error is a stack trace, which would be non-existent in a Fetch request anyway.

So, the code looks like this so far:

fetch('https://api.github.com/users/chrissycoyier/repos')
  .then(response => {
    if (response.ok) {
      return response.json()
    } else {
      return Promise.reject('something went wrong!')
    }
  })
  .then(data => console.log('data is', data))
  .catch(error => console.log('error is', error));
Failed request, but error gets passed into catch correctly

This is great. We’re getting somewhere since we now have a way to handle errors.

But rejecting the promise (or throwing an Error) with a generic message isn’t good enough. We won’t be able to know what went wrong. I’m pretty sure you don’t want to be on the receiving end for an error like this…

Yeah… I get it that something went wrong… but what exactly? 🙁

What went wrong? Did the server time out? Was my connection cut? There’s no way for me to know! What we need is a way to tell what’s wrong with the request so we can handle it appropriately.

Let’s take a look at the response again and see what we can do:

{
  body: ReadableStream
  bodyUsed: true
  headers: Headers
  ok: false // Response is not ok
  redirected: false
  status: 404 // HTTP status is 404.
  statusText: "Not Found" // Request not found
  type: "cors"
  url: "https://api.github.com/users/chrissycoyier/repos"
}

Okay great. In this case, we know the resource is non-existent. We can return a 404 status or Not Found status text and we’ll know what to do with it.

To get status and statusText into the .catch call, we can reject a JavaScript object:

fetch('some-url')
  .then(response => {
    if (response.ok) {
      return response.json()
    } else {
      return Promise.reject({
        status: response.status,
        statusText: response.statusText
      })
    }
  })
  .catch(error => {
    if (error.status === 404) {
      // do something about 404
    }
  })

Now we’re getting somewhere again! Yay! 😄.

Let’s make this better! 😏.

The above error handling method is good enough for certain HTTP statuses which doesn’t require further explanation, like:

  • 401: Unauthorized
  • 404: Not found
  • 408: Connection timeout

But it’s not good enough for this particular badass:

  • 400: Bad request.

What constitutes bad request? It can be a whole slew of things! For example, Stripe returns 400 if the request is missing a required parameter.

Stripe’s explains it returns a 400 error if the request is missing a required field

It’s not enough to just tell our .catch statement there’s a bad request. We need more information to tell what’s missing. Did your user forget their first name? Email? Or maybe their credit card information? We won’t know!

Ideally, in such cases, your server would return an object, telling you what happened together with the failed request. If you use Node and Express, such a response can look like this.

res.status(400).send({
  err: 'no first name'
})

Here, we can’t reject a Promise in the initial .then call because the error object from the server can only be read after response.json.

The solution is to return a promise that contains two then calls. This way, we can first read what’s in response.json, then decide what to do with it.

Here’s what the code looks like:

fetch('some-error')
  .then(handleResponse)

function handleResponse(response) {
  return response.json()
    .then(json => {
      if (response.ok) {
        return json
      } else {
        return Promise.reject(json)
      }
    })
}

Let’s break the code down. First, we call response.json to read the json data the server sent. Since, response.json returns a Promise, we can immediately call .then to read what’s in it.

We want to call this second .then within the first .then because we still need to access response.ok to determine if the response was successful.

If you want to send the status and statusText along with the json into .catch, you can combine them into one object with Object.assign().

let error = Object.assign({}, json, {
  status: response.status,
  statusText: response.statusText
})
return Promise.reject(error)

With this new handleResponse function, you get to write your code this way, and your data gets passed into .then and .catch automatically

fetch('some-url')
  .then(handleResponse)
  .then(data => console.log(data))
  .catch(error => console.log(error))

Unfortunately, we’re not done with handling the response just yet 🙁

Handling other response types

So far, we’ve only touched on handling JSON responses with Fetch. This already solves 90% of use cases since APIs return JSON nowadays.

What about the other 10%?

Let’s say you received an XML response with the above code. Immediately, you’ll get an error in your catch statement that says:

Parsing an invalid JSON produces a Syntax error

This is because XML isn’t JSON. We simply can’t return response.json. Instead, we need to return response.text. To do so, we need to check for the content type by accessing the response headers:

.then(response => {
  let contentType = response.headers.get('content-type')

  if (contentType.includes('application/json')) {
    return response.json()
    // ...
  }

  else if (contentType.includes('text/html')) {
    return response.text()
    // ...
  }

  else {
    // Handle other responses accordingly...
  }
});

Wondering why you’ll ever get an XML response?

Well, I encountered it when I tried using ExpressJWT to handle authentication on my server. At that time, I didn’t know you can send JSON as a response, so I left it as its default, XML. This is just one of the many unexpected possibilities you’ll encounter. Want another? Try fetching some-url 🙂

Anyway, here’s the entire code we’ve covered so far:

fetch('some-url')
  .then(handleResponse)
  .then(data => console.log(data))
  .then(error => console.log(error))

function handleResponse (response) {
  let contentType = response.headers.get('content-type')
  if (contentType.includes('application/json')) {
    return handleJSONResponse(response)
  } else if (contentType.includes('text/html')) {
    return handleTextResponse(response)
  } else {
    // Other response types as necessary. I haven't found a need for them yet though.
    throw new Error(`Sorry, content-type ${contentType} not supported`)
  }
}

function handleJSONResponse (response) {
  return response.json()
    .then(json => {
      if (response.ok) {
        return json
      } else {
        return Promise.reject(Object.assign({}, json, {
          status: response.status
          statusText: response.statusText
        }))
      }
    })
}
function handleTextResponse (response) {
  return response.text()
    .then(text => {
      if (response.ok) {
        return json
      } else {
        return Promise.reject({
          status: response.status,
          statusText: response.statusText,
          err: text
        })
      }
    })
}

It’s a lot of code to write/copy and paste into if you use Fetch. Since I use Fetch heavily in my projects, I create a library around Fetch that does exactly what I described in this article (plus a little more).

Introducing zlFetch

zlFetch is a library that abstracts away the handleResponse function so you can skip ahead to and handle both your data and errors without worrying about the response.

A typical zlFetch look like this:

zlFetch('some-url', options)
  .then(data => console.log(data))
  .catch(error => console.log(error));

To use zlFetch, you first have to install it.

npm install zl-fetch --save

Then, you’ll import it into your code. (Take note of default if you aren’t importing with ES6 imports). If you need a polyfill, make sure you import it before adding zlFetch.

// Polyfills (if needed)
require('isomorphic-fetch') // or whatwg-fetch or node-fetch if you prefer

// ES6 Imports
import zlFetch from 'zl-fetch';

// CommonJS Imports
const zlFetch = require('zl-fetch');

zlFetch does a bit more than removing the need to handle a Fetch response. It also helps you send JSON data without needing to write headers or converting your body to JSON.

The below the functions do the same thing. zlFetch adds a Content-Type and converts your content into JSON under the hood.

let content = {some: 'content'}

// Post request with fetch
fetch('some-url', {
  method: 'post',
  headers: {'Content-Type': 'application/json'}
  body: JSON.stringify(content)
});

// Post request with zlFetch
zlFetch('some-url', {
  method: 'post',
  body: content
});

zlFetch also makes authentication with JSON Web Tokens easy.

The standard practice for authentication is to add an Authorization key in the headers. The contents of this Authorization key is set to Bearer your-token-here. zlFetch helps to create this field if you add a token option.

So, the following two pieces of code are equivalent.

let token = 'someToken'
zlFetch('some-url', {
  headers: {
    Authorization: `Bearer ${token}`
  }
});

// Authentication with JSON Web Tokens with zlFetch
zlFetch('some-url', {token});

That’s all zlFetch does. It’s just a convenient wrapper function that helps you write less code whenever you use Fetch. Do check out zlFetch if you find it interesting. Otherwise, feel free to roll your own!

Here’s a Pen for playing around with zlFetch:

See the Pen zlFetch demo by Zell Liew (@zellwk) on CodePen.

Wrapping up

Fetch is a piece of amazing technology that makes sending and receiving data a cinch. We no longer need to write XHR requests manually or depend on larger libraries like jQuery.

Although Fetch is awesome, error handling with Fetch isn’t straightforward. Before you can handle errors properly, you need quite a bit of boilerplate code to pass information go to your .catch call.

With zlFetch (and the info presented in this article), there’s no reason why we can’t handle errors properly anymore. Go out there and put some fun into your error messages too 🙂


By the way, if you liked this post, you may also like other front-end-related articles I write on my blog. Feel free to pop by and ask any questions you have. I’ll get back to you as soon as I can.


Using Fetch is a post from CSS-Tricks

Focus Styles on Non-Interactive Elements?

Post pobrano z: Focus Styles on Non-Interactive Elements?

Last month, Heather Migliorisi looked at the accessibility of Smooth Scrolling. In order to do smooth scrolling, you:

  1. Check if the clicked link is #jump link
  2. Stop the browser default behavior of jumping immediately to that element on the page
  3. Animate the scrolling to the element the #jump link pointed to

Stopping the browser default behavior is the part that is problematic for accessibility. No longer does the #jump link move focus to element the #jump link pointed to. So Heather added a #4: move focus to the element the #jump link pointed to.

But moving focus through JavaScript isn’t possible on every element. Sometimes you need to force that element to be focusable, which she did through setting tabindex="-1".

We since updated our snippet to do this more-accessible handling of focus. Since then, we’ve heard from quite a few folks about a new side effect to the updated snippet:

Notice the glowing blue outline of the headers that were scrolled to.

After the smooth scrolling, the headers that were scrolled to now have the default blue glowing outline that links have by default. Even if we don’t always love the blue glowing outline (the style varies by user agent, it might be a dotted outline, for example) we know better to remove it.

There is even a website dedicated to that sentiment:

http://www.outlinenone.com/

You can change the focus style if you like, but it’s good accessibility to have a distinct focus style for elements that are in focus. I can even imagine an argument for leaving the focus styles alone.

But but but

Headers aren’t focusable elements.

They aren’t „interactive” elements. We aren’t used to seeing focus styles on non-interactive elements. But now, all the sudden, because we used a smooth scrolling technique from the internet, we’re getting them. That tabindex="-1" technique to allow focus is causing it.

I reached out to Heather to ask her about this.

The :focus styling for headings and other non-interactive elements can be removed/left off. It’s really up to the folks behind the creative site if they want it or not there. In some cases, I’ve removed it, in others I’ve styled it. It just depends.

To my surprise, it’s OK to remove focus styles in the case that the element you’re force-focusing isn’t interactive. That last point is important, and Heather clarified:

As long as the headings are not links… 😉

So if you really hated the focus styles, you could do:

h1:focus,
h2:focus, 
h3:focus,
h4:focus,
h5:focus,
h6:focus {
  outline: 0;
}

You’re safe there. Even in the cases of <a><h3></h3></a> or <h3><a></a></h3>, the link still has focus styles.

It’s not just headers

Jump links can point to any element, and there are lots of non-focusable-by-default elements. Another classic technique in this situation is the „yellow fade” technique. Let’s say instead of linking to headers, we were linking to <section>s. When any section comes into focus, we could style it like this:

section:focus {
  outline: 0;
  animation: yellowFade 3s forwards;
}
@keyframes yellowFade {
  from { background: lightYellow; }
  to   { background: white; }
}

Which gives us:

Which is an adaptation of something that was often used for :target.


Focus Styles on Non-Interactive Elements? is a post from CSS-Tricks

The Many Tools for Shape Morphing

Post pobrano z: The Many Tools for Shape Morphing

To no one’s surprise, I’m sure, there are lots of different ways to do the same thing on the web. Shape morphing, being a thing on the web, is no different. There are some native technologies, some libraries that leverage those, and some libraries that do things all on their own. Let’s look at some of the options (with demos) and weigh the advantages and disadvantages.

SMIL

The original, native technology for shape morphing is SMIL. We have both a guide to SMIL on CSS-Tricks, and an article talking about replacements for it, since it doesn’t work in Microsoft browsers and Blink threatened to yank it at one point.

I wouldn’t suggest doing important work in SMIL but it is OG shape morphing.

See the Pen Sitepoint Challenge #1 in SVG and SMIL by Noah Blon (@noahblon) on CodePen.

Our article How SVG Shape Morphing Works covers SMIL shape morphing in detail, and the demo above is from Noah Blon’s An Intro to SVG Animation with SMIL.

To get a feel for the must have same # of points thing, you might enjoy playing with Shape Shifter:

MorphSVG (Greensock GSAP Plugin)

Moving right along to probably the most robust possible option, Greensock’s MorphSVG is a powerhouse. Bear in mind:

MorphSVGPlugin is a bonus plugin for Club GreenSock members („Shockingly Green” and „Business Green” levels). It’s our way of showing our gratitude to those who are fueling innovation at GreenSock.

Worth it. Just MorphSVG alone is amazing. Unlike almost any other shape morphing method, it can tween between shapes of any number of points. It does so performantly, in a safe cross-browser fashion, and gives you more fine grain control over how the animation goes down.

See the complex morphing happening here:

See the Pen Morphing SVG Slider – 20th Century Women by Sullivan Nolan (@nolakat) on CodePen.

If you’d like to play with MorphSVG, I created a drag-and-drop Pen to morphing between any two shapes (best results with SVG’s with viewBox="0 0 100 100" SVGs with just one <path>):

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

If you’re a user of Adobe Muse, you might be interested in the Muse Morph widget which combines Illustrator, Muse, and Greensock MorphSVG.

SnapSVG

SnapSVG’s animate() function will animate an SVG element’s properties, including path data. Codrops has excellent examples of this in action. Here’s a little movie showing some of them off:

SnapSVG is, in a sense, Raphaël’s older brother, which could do things like this:

anime.js

The newer anime.js library has shape morphing built in.

CSS

It’s a little hard to believe, but CSS is getting in on the shape morphing action! Eric Willigers, a Chrome developer, emailed me last year:

’d’ has become a presentation attribute. This allows SVG path elements to be animated using CSS animations and Web Animations, with path(’…’) keyframes.

I assume this is a spec change, so browsers other than Chrome will, presumably, start allowing this. For now, this works great in Chrome:

See the Pen Simple Path Examples by Chris Coyier (@chriscoyier) on CodePen.

SVG Morpheus

SVG Morpheus is a JavaScript lib entirely devoted to shape morphing. Here’s a great demo of it in action:

See the Pen Mobiltelefonens Evolution (SVG Shape Morphing) by Noel Delgado (@noeldelgado) on CodePen.

KUTE.js

There is an SVG plugin for Kute.js that allows for the animation of SVG properties, including shape morphing.

See the Pen Morph SVG with KUTE.js by thednp (@thednp) on CodePen.

The API gives you some control over the morphing, like how precise you want it to be and the ability to reverse the draw direction so different points match up to tween.

d3

d3, probably the biggest library out there for data viz folks, can also do shape morphing. Here’s a GIF recording of a demo by Mike Bostock:

There is also a d3 plugin called d3-interpolate-path that helps make it better:

Interpolates path `d` attribute smoothly when A and B have different number of points.

mo.js

„Motion graphics for the web” is the mo.js tagline, another newer library. Oleg Solomka (@LegoMushroom) has some incredible demos of what is is capable of:

See the Pen Mole :: property curves example by LegoMushroom (@sol0mka) on CodePen.

bodymovin

If you happen to be a video person before you became a web person (or you’re still both) perhaps you have experience working in Adobe After Effects, which is all about creating „incredible motion graphics and visual effects”. The bodymovin library exports After Effects into SVG, including plenty of hot morphing action. Here’s a great demo:

See the Pen svg jou jou monster by kittons (@airnan) on CodePen.


The Many Tools for Shape Morphing is a post from CSS-Tricks

Think you know the top web browsers?

Post pobrano z: Think you know the top web browsers?

If I had to blindly guess about global marketshare, I would have gotten it wrong. I probably would have forgotten about UC browser (kind of the point of Peter O’Shaughnessy’s article) that’s so huge in Asia. I would have guessed Firefox has a slight edge on Safari (turns out Firefox is half the share of Safari), and that Edge would be outpacing IE by now (also only half).

This is good dinner party conversation fodder, but I wouldn’t base any major decision making on it. The only stats that matter at your websites stats.

Here’s this sites, in the last 7 days.

There is always the chicken-or-egg conundrum though. If you support a browser that you didn’t before, doesn’t it stand to reason the numbers would go up for it? The time-on-site and bounce rate stuff would get better, anyway.

Direct Link to ArticlePermalink


Think you know the top web browsers? is a post from CSS-Tricks

Now that CSS Custom Properties are a Thing, All Value Parts Can Be Changed Individually

Post pobrano z: Now that CSS Custom Properties are a Thing, All Value Parts Can Be Changed Individually

In CSS, some properties have shorthand. One property that takes separated values. Syntactic sugar, as they say, to make authoring easier. Take transition, which might look something like:

.element {
  transition: border 0.2s ease-in-out;
}

We could have written it like this:

.element {
  transition-property: border;
  transition-duration: 0.2s;
  transition-timing-function: ease-in-out;
}

Every „part” of the shorthand value has its own property it maps to. But that’s not true for everything. Take box-shadow:

.element {
  box-shadow: 0 0 10px #333;
}

That’s not shorthand for other properties. There is no box-shadow-color or box-shadow-offset.

That’s where Custom Properties come to save us!

We could set it up like this:

:root {
  --box-shadow-offset-x: 10px;
  --box-shadow-offset-y: 2px;
  --box-shadow-blur: 5px;
  --box-shadow-spread: 0;
  --box-shadow-color: #333;
}

.element {
  box-shadow:
    var(--box-shadow-offset-x)
    var(--box-shadow-offset-y)
    var(--box-shadow-blur)
    var(--box-shadow-spread)
    var(--box-shadow-color);
}

A bit verbose, perhaps, but gets the job done.

Now that we’ve done that, remember we get some uniquely cool things:

  1. We can change individual values with JavaScript. Like:

    document.documentElement.style.setProperty("--box-shadow-color", "green");
  2. Use the cascade, if we need to. If we set --box-shadow-color: blue on any selector more specific than the :root, we’ll override that color.

Fallbacks are possible too, in case the variable isn’t set at all:

.element {
  box-shadow:
    var(--box-shadow-offset-x, 0)
    var(--box-shadow-offset-y, 0)
    var(--box-shadow-blur, 5px)
    var(--box-shadow-spread, 0)
    var(--box-shadow-color, black);
}

How about transforms? They are fun because they take a space-separated list of values, so each of them could be a custom property:

:root {
  --transform_1: scale(2);
  --transform_2: rotate(10deg);
}

.element{
  transform: var(--transform_1) var(--transform_2);
}

What about elements that do have individual properties for their shorthand, but also offer comma-separated multiple values? Another great use-case:

:root {
  --bgImage: url(basic_map.svg);
  --image_1_position: 50px 20px;
  --image_2_position: bottom right;
}

.element {
  background: 
    var(--bgImage) no-repeat var(--image_1_position),
    var(--bgImage) no-repeat var(--image_2_position);
}

Or transitions?

:root {
  --transition_1_property: border;
  --transition_1_duration: 0.2s;
  --transition_1_timing_function: ease;
  
  --transition_2_property: background;
  --transition_2_duration: 1s;
  --transition_2_timing_function: ease-in-out;
}

.element {
  transition: 
    var(--transition_1_property) 
    var(--transition_1_duration) 
    var(--transition_1_timing_function),
    var(--transition_2_property) 
    var(--transition_2_duration) 
    var(--transition_2_timing_function),
}

Dan Wilson recently used this kind of thing with animations to show how it’s possible to pause individual animations!


Here’s browser support:

Green indicates full support at the version listed (and above). Yellow indicates partial support. Red indicates no support. See Caniuse for full browser support details.

Desktop

Chrome Opera Firefox IE Edge Safari
49 36 31 No 15 9.1

Mobile / Tablet

iOS Safari Opera Mobile Opera Mini Android Android Chrome Android Firefox
9.3 37 No 56 57 52

Now that CSS Custom Properties are a Thing, All Value Parts Can Be Changed Individually is a post from CSS-Tricks

PWA Directory

Post pobrano z: PWA Directory

The other day I was watching an interview with Ade Oshineye where he discussed his work on the PWA Directory at Google, a showcase of progressive web apps. And it’s pretty neat!

It lists a whole bunch of PWAs out there and you can filter them by Lighthouse metrics – that’s the auditing tool from Google that scores a web app and gives us developers the ability to improve them.

Direct Link to ArticlePermalink


PWA Directory is a post from CSS-Tricks