Web Standards

A Boilerform Idea

Css Tricks - Tue, 10/03/2017 - 6:02am

This is just a random idea, but I can't stop it from swirling around in my head.

Whenever I need to style a form on a fresh project where the CSS and style guide stuff is just settling in, the temptation to reach for a mini form framework is strong. Form elements are finicky, have little cross-browser issues, and are sometimes downright hard to wrassle away styling control.

This idea, which I'm just now managing to write about, but haven't actually done any work toward, would be this mini-form framework. Maybe something like "Boilerform", as Dave jokingly suggested on an episode of ShopTalk.

I imagine it going something like this:

  • It would have basic form-styling to organize form elements, not unlike something like Foundation forms;
  • Account for cross browser issues, not unlike normalize.css;
  • Strong-arm styling control over form elements, not unlike WTF, forms?; and
  • Include native browser form validation stuff, including UX improvements via native JavaScript API's, not unlike Validate.js.

I think there is value in combining those things into one thing, but doing so with...

  1. A light touch, and without any more opinion about the final styling as possible, and with
  2. Flexibility, perhaps showing off a gallery of different form types with varied styling.

I probably don't have time to head up a project like this, but I wouldn't mind helping connect humans who also see value here and wanna give it a shot.

A Boilerform Idea is a post from CSS-Tricks

eBay’s Font Loading Strategy

Css Tricks - Tue, 10/03/2017 - 3:57am

Senthil Padmanabhan documents how:

  1. Both FOUT and FOIT are undesirable.
  2. The best solution to that is font-display.
  3. Since font-display isn't well supported, the path to get there is very complicated.
  4. They open sourced it.

They went with replicating font-display: optional, my favorite as well.

Direct Link to ArticlePermalink

eBay’s Font Loading Strategy is a post from CSS-Tricks

A Five Minutes Guide to Better Typography

Css Tricks - Mon, 10/02/2017 - 11:09am

Pierrick Calvez with, just maybe, a bunch of typographic advice that you've heard before. But this is presented very lovingly and humorously.

Repeating the basics with typography feels important in the same way repeating the basics of performance does. Gzip your stuff. Make your line length readable. Set far expires headers. Make sure you have hierarchy. Optimize your images. Align left.

Let's repeat this stuff until people actually do it.

Direct Link to ArticlePermalink

A Five Minutes Guide to Better Typography is a post from CSS-Tricks

Help Your Users `Save-Data`

Css Tricks - Mon, 10/02/2017 - 3:59am

The breadth and depth of knowledge to absorb in the web performance space is ridiculous. At a minimum, I'm discovering something new nearly every week. Case in point: The Save-Data header, which I discovered via a Google Developers article by Ilya Grigorik.

If you're looking for the tl;dr version of how Save-Data works, let me oblige you: If you opt into data savings on the Android version of Chrome (or the Data Saver extension on your desktop device), every request that Chrome sends to a server will contain a Save-Data header with a value of On. You can then act on this header to change your site's content delivery in such a way that conserves data for the user. This is a very open-ended sort of opportunity that you're being given, so let's explore a few ways that you could act on the Save-Data header to send less bytes down the wire!

Change your image delivery strategy

I don't know if you've noticed, but images are often the largest chunk of the total payload of any given page. So perhaps the most impactful step you can take with Save-Data is to change how images are delivered. What I settled on for my blog was to rewrite requests for high DPI images to low DPI images. When I serve image sets like this on my site, I do so using the <picture> element to serve WebP images with a JPEG or PNG fallback like so:

<picture> <source srcset="/img/george-and-susan-1x.webp 1x, /img/george-and-susan-2x.webp 2x"> <source srcset="/img/george-and-susan-1x.jpg 1x, /img/george-and-susan-2x.jpg 2x"> <img src="/img/george-and-susan-1x.jpg" alt="LET'S NOT GET CRAZY HERE" width="320" height="240"> </picture>

This solution is backed by tech that's baked into modern browsers. The <picture> element delivers the optimal image format according to a browser's capabilities, while srcset will help the browser decide what looks best for any given device's screen. Unfortunately, both <picture> and srcset lacks control over which image source to serve for users who want to save data. Nor should they! That's not the job of srcset or <picture>.

This is where Save-Data comes in handy. When users visit my site and send a Save-Data request header, I use mod_rewrite in Apache to serve low DPI images in lieu of high DPI ones:

RewriteCond %{HTTP:Save-Data} =on [NC] RewriteRule ^(.*)-2x.(png|jpe?g|webp)$ $1-1x.$2 [L]

If you're unfamiliar with mod_rewrite, the first line is a condition that checks if the Save-Data header is present and contains a value of on. The [NC] flag merely tells mod_rewrite to perform a case-insensitive match. If the condition is met, the RewriteRule looks for any requests for a PNG, JPEG or WebP asset ending in -2x (the high DPI version), and redirects such requests to an asset ending in -1x (the low DPI version).

Now comes the weird part: What happens if a user visits with Data Saver enabled, but turns it off and returns later on an unmetered (i.e., Wi-Fi) connection? Because we've surreptitiously rewritten the request for a -2x image to a -1x one, the browser will serve up the low quality version of the image from the browser cache rather than requesting the high quality version from the server. In this scenario, the user is lashed to a low quality experience until they empty their browser cache (or the cached entries expire).

So how do we fix this? The answer lies in the Vary response header. Vary instructs the browser how and if it should use a cached asset by aligning cache entries to specific header(s). Values for Vary are simply other header names (e.g., Accept-Encoding, User-Agent, et cetera). If we want the browser to cache content based on the existence of the Save-Data header, all we need to do is configure the server to send a Vary response header with a value of Save-Data like so:

<FilesMatch "\.(gif|png|jpe?g|webp)$"> Header set Vary "Save-Data" </FilesMatch> <FilesMatch "\.svg$"> Header set Vary "Accept-Encoding, Save-Data" </FilesMatch>

In this example, I'm sending a Vary response header with a value of Save-Data any time GIF, PNG, JPEG or WebP images are requested. In the case of SVGs, I send a Vary header with a value of Accept-Encoding, Save-Data. The reason for this is because SVGs are compressible text assets. Therefore, I want to ensure that the browser (and any intermediate cache, such as a CDN) takes the value of the Accept-Encoding header into consideration in addition to the Save-Data header when deciding how to retrieve entries from the cache.

Image delivery with Data Saver on vs. off

For our trouble, we now have an image delivery strategy that helps users conserve data, and will populate the browser cache with images that won't persist if the user turns off Data Saver later on.

Of course, there are other ways you could change your image delivery in the presence of Save-Data. For example, Cory Dowdy wrote a post detailing how he uses Save-Data to serve lower quality images. Save-Data gives you lots of room to devise an image delivery strategy that makes the best sense for your site or application.

Opt out of server pushes

Server push is good stuff if you're on HTTP/2 and can use it. It allows you send assets to the client before they ever know they need them. The problem with it, though, is it can be weirdly unpredictable in select scenarios. On my site, I use it to push CSS only, and this generally works well. Although, I do tailor my push strategy in Apache to avoid browsers that have issues with it (i.e., Safari) like so:

<If "%{HTTP_USER_AGENT} =~ /^(?=.*safari)(?!.*chrome).*/i"> Header add Link "</css/global.5aa545cb.css>; rel=preload; as=style; nopush" </If> <Else> Header add Link "</css/global.5aa545cb.css>; rel=preload; as=style" </Else>

In this instance, I'm saying "Hey, I want you to preemptively push my site's CSS to people, but only if they're not using Safari." Even if Safari users come by, they'll still get a preload resource hint (albeit with a nopush attribute to discourage my server from pushing anything).

Even so, it would behoove us to be extra cautious when it comes to pushing assets for users with Data Saver turned on. In the case of my blog, I decided I wouldn't push anything to anyone who had Data Saver enabled. To accomplish this, I made the following change to the initial <If> header:

<If "%{HTTP:Save-Data} == 'on' || %{HTTP_USER_AGENT} =~ /^(?=.*safari)(?!.*chrome).*/i">

This is the same as my initial configuration, but with an additional condition that says "Hey, if Save-Data is present and set to a value of on, don't be pushing that stylesheet. Just preload it instead." It might not be a big change, but it's one of those little things that could help visitors to avoid wasted data if a push was in vain for any reason.

Change how you deliver markup

With Save-Data, you could elect to change what parts of the document you deliver. This presents all sorts of opportunities, but before you can embark on this errand, you'll need to check for the Save-Data header in a back end language. In PHP, such a check might look something like this:

$saveData = (isset($_SERVER["HTTP_SAVE_DATA"]) && stristr($_SERVER["HTTP_SAVE_DATA"], "on") !== false) ? true : false;

On my blog, I use this $saveData boolean in various places to remove markup for images that aren't crucial to the content of a given page. For example, one of my articles has some animated GIFs and other humorous images that are funny little flourishes for users who don't mind them. But they are heavy, and not really necessary to communicate the central point of the article. I also remove the header illustration and a teeny tiny thumbnail of my book from the nav.

Image markup delivery with Data Saver on and off

From a payload perspective, this can certainly have a profound effect:

The potential effects of Data Saver on page payload

Another opportunity would be to use the aforementioned $saveData boolean to put a save-data class on the <html> element:

<html class="<?php if($saveData === true) : echo("save-data"); endif; ?>">

With this class, I could then write styles that could change what assets are used in background-image properties, or any CSS property that references external assets. For example:

/* Just a regular ol' background image */ body { background-image: url("/images/bg.png"); } /* A lower quality background image for users with Data Saver turned on */ .save-data body { background-image: url("/images/bg-lowsrc.png"); }

Markup isn't the only thing you could modify the delivery of. You could do the same for videos, or even do something as simple as delivering fewer search results per page. It's entirely up to you!

Conclusion

The Save-Data header gives you a great opportunity to lend a hand to users who are asking you to help them, well, save data. You could use URL rewriting to change media delivery, change how you deliver markup, or really just about anything that you could think of.

How will you help your users Save-Data? Leave a comment and let your ideas be heard!

Jeremy Wagner is the author of Web Performance in Action, available now from Manning Publications. Use promo code sswagner to save 42%.

Check him out on Twitter: @malchata

Help Your Users `Save-Data` is a post from CSS-Tricks

CSS font-variant tester

Css Tricks - Mon, 10/02/2017 - 3:58am

From small caps and ligatures to oldstyle and ordinal figures, the font-variant-* CSS properties give us much finer control over the OpenType features in our fonts. Chris Lewis has made a tool to help us see which of those font-variant features are supported in our browser of choice and I could definitely see this helpful for debugging in the future.

Direct Link to ArticlePermalink

CSS font-variant tester is a post from CSS-Tricks

safe-area-inset values on iOS11

QuirksBlog - Mon, 10/02/2017 - 2:12am

With the iPhone X’s notch came viewport-fit=cover and safe-area-inset, as explained here. It turns out that safe-area-inset is 0 on iOS11 devices that are not the iPhone X. This may sound logical, but I wonder if it is. Also, the value remains static, even when you zoom in.

Note: testing for this article was done exclusively on Apple’s simulator.

To recap briefly:

  • viewport-fit=cover, when added to the meta viewport, ensures the site takes over the entire screen, even the space below the notch, if applicable.
  • safe-area-inset-dir (where dir is left, right, top, or bottom) gives the safe areas you should apply if you want enough margin or padding to prevent your site from being obscured by the notch.
viewport-fit

Let’s treat viewport-fit=cover first. When applied on the iPhone X, your sites now stretches into the space below the notch, as advertised. When applied on any other device with iOS11, nothing happens. That’s logical: the viewport is already stretched to its maximum and there is no notch to avoid or stretch under.

In other words, viewport-fit=cover can be added to any site and will fire only when applicable. Keep that in mind.

The safe area

safe-area-inset should be added as a padding (or, I suppose, a margin) to elements or the entire page. Its value on the iPhone X, in case you’re wondering, is 44px. This value could conceivably be different on future models where the notch is larger or smaller, so using a constant that may change from model to model is a good idea.

But what is its value on iOS11 devices that are not the iPhone X and have no notch? It turns out it’s 0px. This may sound logical as well, since there is no notch and thus no safe area, but is it?

My problem is the following. Suppose I have this:

element { padding-left: 10px; padding-left: constant(safe-area-inset-left); }

What I want to do here is give the element a padding-left of 10px, except when a notch is present, then I want to give it a pading-left equal to the safe area (44px). This works absolutely fine on the iPhone X and in non-iOS browsers. In the former the initial 10px values is overwritten by the safe area, while the latter don’t understand the safe area and ignore the second rule.

Problem is: on iOS11 devices other than the iPhone X this misfires and gives the element a padding-left of 0. Thus, safe-area-inset fires even when it’s not applicable. I do not find this logical at all. As far as I can see, safe-area-inset should simply be absent when there is no safe area to describe. And 0 is not the same as absent.

As far as I’m concerned Apple should remove safe-area-inset entirely from devices that do not need it. Thus we web developers do not need to worry about the notch. We write a tiny bit of CSS for the notch, and can rest assured that the CSS will not fire when it’s absent.

The official post notes that you should use the following instead, but also notes that max() is not supported by the current Safari/iOS version, which makes the advice a bit pointless:

element { padding-left: max(10px,constant(safe-area-inset-left)); }

So they kind-of admit there might be a problem, but offer an as-yet-unavailable solution. Also, as far as I’m concerned this tip-toes around the fundamental problem of having a safe area of 0 where none is needed.

Zoom

There’s another problem as well: safe-area-inset is not adjusted when the user zooms, even though, at high zoom levels, the safe area becomes comically large. Even when I’m zoomed in to the maximum level on an iPhone X, the safe area is still 44px, though that now means about one-third of the screen.

I can understand why Apple did this. If safe-area-inset would become zoom-dependent, the browser would have to run re-layouts every time the user zooms, changing the calculated padding-left on every applicable element. This is likely to be a costly operation.

Still, the conclusion must be that safe-area-inset also misfires whenever the user zooms in.

Notch detection

So we have to write a notch detection script. Fortunately it’s quite simple: create a test element, apply the safe-area-inset and see if its value is larger than 0. If so, a notch is present.

function hasNotch() { if (CSS.supports('padding-left: constant(safe-area-inset-left)')) { var div = document.createElement('div'); div.style.paddingLeft = 'constant(safe-area-inset-left)'; document.body.appendChild(div); var calculatedPadding = parseInt(window.getComputedStyle(div).paddingLeft); document.body.removeChild(div); if (calculatedPadding > 0) { return true; } } return false; }

Still, I would argue that the very need for such a script means safe-area-inset has not been implemented quite properly.

Template Literals are Strictly Better Strings

Css Tricks - Sun, 10/01/2017 - 9:24am

Nicolás Bevacqua wrote this a year ago, and I'd say with a year behind us he's even more right. Template literals are always better. You don't have to screw around with concatenation. You don't have to screw around with escaping other quotes. You don't have to screw around with multiline. We should use them all the time, and adjust our linting to help us develop that muscle memory.

Besides the few things you can't use them for (e.g. JSON), there is also the matter of browser support. It's good, but no IE 11 for example. You're very likely preprocessing your JavaScript with Babel anyway, and if you're really smart, making two bundles.

Direct Link to ArticlePermalink

Template Literals are Strictly Better Strings is a post from CSS-Tricks

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