How to Use `@supports (display: contents)` Feature Query in Safari →

As CSS Grid adoption continues to rise, there are certain situations where a wrapping div prevents you from accessing the elements you want to use as grid items. In these cases, @supports (display: contents) becomes a particularly valuable feature query.

Safari has technically supported display: contents for a while now, but with one huge caveat — it only works with <slot> elements. This becomes problematic when you want to use the feature query outside of <slot> elements.

You can see it when we use this example by Rachel Andrew on Safari 11.0 and Safari 11.1 Technology Preview:

As you can see, @supports (display: contents) is activating as true on Safari 11.0 even though we wouldn't expect it to.

Thankfully, there's a workaround!

The upcoming release of Safari 11.1 also introduces a new CSS feature called caret-color, which we can pair display: contents together as a feature query to target only browsers that properly support display: contents.

So instead of this:

@supports (display: contents) {
  .container {
    display: contents;
  }
}

The best practice is to use this:

@supports (display: contents) and (caret-color: red) {
  .container {
    display: contents;
  }
}

Shout out to Pavel Kilmanshikin and Antti Koivisto for sharing!

How to Fix the Cloudflare WP-Admin Endless Redirect Loop Error with Wordpress

If you are using Cloudflare's free Flexible SSL feature on a Wordpress site and you're experiencing an endless redirect loop when trying to log into /wp-admin, try hardcoding the following into you wp-config.php file:

define('WP_SITEURL', 'https://www.domain.com');
define('WP_HOME', 'https://www.domain.com');
define('FORCE_SSL_ADMIN', true);
define('FORCE_SSL_LOGIN', true);
if( isset($_SERVER['HTTP_CF_VISITOR']) && strpos($_SERVER['HTTP_CF_VISITOR'], 'https') )
$_SERVER['HTTPS']='on';

Progressive Enhancement: Investing in the Future →

Rachel Andrew on teaching clients how to let go of "it must look the same in every single browser" and embrace progressive enhancement:

Your boss or client may be unaware of the way that browsers update. They may have been told by someone who knows about computers that it is important their site is compatible with all browsers. They have equated compatible with “looks the same”. You can challenge that. Look at your analytics data, look at browser release schedules and see what is going to land in the next releases. Check out the Can I Use stats for your location, and present the information to your boss or client.

Explain the benefits of using something new - whether that be performance, the ability to achieve a layout you couldn’t otherwise, or time-saving now and in the future. Explain how the ‘fallback’ is acceptable and that over time more users will grow into the newer design without you needing to ship any more code. This is the reality of design in a world of evergreen browsers. […]

Most clients would not like to think that their investment will be out of date in a year or two. [Emphasis mine.] You can use that to explain how quickly browsers move these days and that by having some features there that will very soon have widespread support will help in ensuring the site remains fresh and is still using modern methods in two years time. If your client is cost sensitive explain how these features can save money in terms of easing maintainability; if they worry about SEO explain how making sure the site is fast is one of the most important things you can do; if the visual design is key then you have plenty of things to show that just can’t be achieved without newer techniques.

Also, remember that you don’t need to throw everything out and only use a very new layout method such as Grid or even Flexbox. Start small, finesse your forms or navigation with these methods, add some little touches. Not every site needs all the new shiny throwing at it, most will benefit from some elements from newer specifications. You can learn just as much about Grid by using it to tighten up a floated UI, as you can by turning your whole site over to it.

Help your client understand that embracing @supports and other progressive enhancement techniques, you are investing in the future that will become more relevant over time instead of investing in browsers that get outdated every passing day.

For coworkers and managers, help them understand that we don't need to change the way we make an entire website; we can start off experimenting on small, specific components.

Using calc() in LESS →

If you ever try to use calc() in LESS, using the standard syntax will give you an unexpected result. For example, if we used this standard syntax:

width: calc(100% - 200px);

LESS will compile that as:

width: calc(-100%);

For the correct syntax for LESS, you have to use an escaped string, like this:

width: ~"calc(100% - 200px)";

Using Feature Queries in CSS →

Jen Simmons explains, when using feature queries, outdated browsers will not understand the @supports not clause:

@supports not (display: grid) {
    // code for older browsers
    // DO NOT COPY THIS EXAMPLE
}
@supports (display: grid) {
    // code for newer browsers
    // DID I SAY THIS IS REALLY BAD?
}

If you do, certain outdated browsers will not get the code they need.

Instead, here is the best practice:

// fallback code for older browsers

@supports (display: grid) {
    // code for newer browsers
    // including overrides of the code above, if needed
}

The Future of Loading CSS →

Jake Archibald of the Google Chrome team explains the upcoming, modern behavior for loading CSS that should replace lazy loading.

The current state-of-the-art of loading CSS:

<head>
  <script>
    // https://github.com/filamentgroup/loadCSS
    !function(e){"use strict"
    var n=function(n,t,o){function i(e){return f.body?e():void setTimeout(function(){i(e)})}var d,r,a,l,f=e.document,s=f.createElement("link"),u=o||"all"
    return t?d=t:(r=(f.body||f.getElementsByTagName("head")[0]).childNodes,d=r[r.length-1]),a=f.styleSheets,s.rel="stylesheet",s.href=n,s.media="only x",i(function(){d.parentNode.insertBefore(s,t?d:d.nextSibling)}),l=function(e){for(var n=s.href,t=a.length;t--;)if(a[t].href===n)return e()
    setTimeout(function(){l(e)})},s.addEventListener&&s.addEventListener("load",function(){this.media=u}),s.onloadcssdefined=l,l(function(){s.media!==u&&(s.media=u)}),s}
    "undefined"!=typeof exports?exports.loadCSS=n:e.loadCSS=n}("undefined"!=typeof global?global:this)
  </script>
  <style>
    /* The styles for the site header, plus: */
    .main-article,
    .comments,
    .about-me,
    footer {
      display: none;
    }
  </style>
  <script>
    loadCSS("/the-rest-of-the-styles.css");
  </script>
</head>
<body>
</body>

When all browsers adopt it, this will be the simpler, better way:

<head>
</head>
<body>
  <!-- HTTP/2 push this resource, or inline it, whichever's faster -->
  <link rel="stylesheet" href="/site-header.css">
  <header>…</header>

  <link rel="stylesheet" href="/article.css">
  <main>…</main>

  <link rel="stylesheet" href="/comment.css">
  <section class="comments">…</section>

  <link rel="stylesheet" href="/about-me.css">
  <section class="about-me">…</section>

  <link rel="stylesheet" href="/site-footer.css">
  <footer>…</footer>
</body>

Currently, Firefox and Edge/IE will load this progressively. Chrome will soon support this. The Safari team knows of this change and are expected to adopt it as well.