Using Intersection Observers

With the Intersection Observer coming to Firefox, a nice article covering it appeared on Mozilla Hacks.

The IntersectionObserver interface of the Intersection Observer API provides a way to asynchronously observe changes in the intersection of a target element with an ancestor element or with a top-level document’s viewport.

To use it, create a new instance of IntersectionObserver, and then let it observe a given element (target):

let observer = new IntersectionObserver((entries, observer) => { /* … */});
observer.observe(target); // <-- Element to watch

Here's a demo pen:

See the Pen Hello IntersectionObserver by Dan Callahan (@callahad) on CodePen.

To not watch the target's relation to the viewport, but to another element, use the root option.

let observer = new IntersectionObserver((entries, observer) => { /* … */}, {
   root: parentElement,
});
observer.observe(target); // <-- Element to watch

Works in Edge 15, Chrome 51, and soon Firefox 55. For browsers that don't support it you can use a polyfill.

Intersection Observer comes to Firefox →
IntersectionObserver Polyfill →

Elsewhere , , Leave a comment

GridBugs – A Curated List of CSS Grid Interop Issues

Like Flexbugs, but then for CSS Grid Layout:

Inspired by Flexbugs this list aims to be a community curated list of CSS Grid Layout bugs, incomplete implementations and interop issues. Grid shipped into browsers in a highly interoperable state, however there are a few issues – let’s document any we find here.

By Rachel Andrew – who else?!of course.

GridBugs – A Curated List of CSS Grid Interop Issues →

Elsewhere , , , Leave a comment

Automatically rerun PHPUnit tests when source code changes with phpunit-watcher

Nice new package by Freek from Spatie.be. Think of it like Jest, but for PHP:

Wouldn’t it be great if your PHPUnit tests would be automatically rerun whenever you change some code? This package can do exactly that.

By default it will watch all files in the src, app and tests subdirectories in the directory where it is started.

Installation per Composer, of course:

composer global require spatie/phpunit-watcher

spatie/phpunit-watcher introductory blogpost →
spatie/phpunit-watcher (GitHub) →

Sidenote: If you’re new to PHPUnit, Sitepoint has got you covered with a newly released (re-)introduction to PHPUnit. Also, the folks over at CxSocial (former Engagor) have written a nice post on how to write better tests in PHPUnit

Elsewhere , , Leave a comment

Navigating on the next iPhone

Some folks have been poking around in the HomePod Firmware update. Doing so they’ve unearthed the existence of an upcoming face unlock feature using and infrared camera and face detection, the new iPhone’s bezel-less form factor, and its resolution of 1125 x 2436 (375 x 812 points rendered @3x).

Former Apple Software Engineer and now App Developer Allen Pike wonders how apps would render on this new iPhone, assuming the Home button being replaced with a virtual one (because it will disappear):

So, after ten years, the Home button is going virtual. Our beautiful new 812pt OLED display will have a function area carved out of the bottom, with Home in the middle. There are many things Apple could put on either side of the Home button – Android-like multitasking buttons I suppose – but iOS 11 gives us a giant clue.

Taking clues from the fact that the the navigation bar and the big bold titles in iOS11 are oddly positioned (see screenshot above) he suggests that the bottom 66pt of the new iPhone’s screen will be reserved for the virtual home button, and that the buttons of the navigation bar will move next to either side of it. This way the visual oddity is existent no more, and navigation is put within thumbs’ reach.

Developing for iPhone Pro →

Sidenote: If this were to be the case – which would make sense – I cannot help but wonder how Apple will tout this as their next great invention – which they tend to do – as Android phones have had their darn handy physical back button at said location for ages 😉

Elsewhere , , , Leave a comment

React, Relay and GraphQL: Under the Hood of the Times Website Redesign

The folks over at The New York Times have made change to using React, Relay and GraphQL for the new version of their website (which they are rolling out over the coming months):

We thought it would be nice if there was one place to add and retrieve data and one way to authenticate against it. It would also be helpful if there was a common language and repository for creating and reusing components. If a new developer joins our team, I want to point them at a single page of documentation that explains how to get up and running — and preferably start building apps the same day.

This is not at all a dream scenario. We are moving towards this reality. That future is Relay and GraphQL.

In case you – just like I was – are wondering if they’ll break the web with this, they won’t. In the comments the author mentions:

Isomorphism (rendering a full server response) is a first-class citizen in our architecture. Most of the challenges we have run into are around ensuring that our server responses and client responses have parity. By solving this problem, we don’t have to worry about the SEO hit. SEO is a top priority at the NYT.

React, Relay and GraphQL: Under the Hood of the Times Website Redesign →

Elsewhere , , , Leave a comment

Announcing Conduct AR!

The creators of “Conduct THIS!” are building an AR version of their game:

Lookin’ good!

Sidenote: If you want to follow iOS specific AR projects, be sure to follow @MadeWithARKit on Twitter. You’ll find some inspiring stuff on there.

Elsewhere , , , Leave a comment

Vertical margins/paddings and Flexbox, a quirky combination

In CSS, percentage-based paddings are – as per spec – calculated with respect to the width of an element. However, for flex items (e.g. items whose parent have display: flex; applied) that’s not always the case.

Depending on which browser you are using the percentage-based padding of a flex item will be resolved against its height instead of its width … and the spec is totally fine with that.

Until browser vendors agree on one behavior, be advised to not use vertical margins/paddings on flex items … and know that the CSS Aspect Ratio Hack won’t work on them.

As detailed in “Aspect Ratios in CSS are a Hack” we can use percentage-based padding to force a box to have a fixed aspect ratio.

However, In a recent project I was working on I noticed that my aspect ratio boxes weren’t working as expected in Firefox. Where other browsers would nicely render boxes with their set aspect ratio, Firefox would do render the box with a fixed height, independent of the box’s defined width.

Digging deeper into the problem – in order to flesh out what exactly triggers this rendering quirk – I knocked up a testcase in which it became clear to me that the CSS Aspect Ratio Hack didn’t seem to work on flex items (e.g. elements that are contained inside a parent element that has display: flex; applied) — Uh oh!

See the Pen Aspect-Ratio box inside flexboxed wrapper? by Bramus (@bramus) on CodePen.

~

Interpreting the results


The result in Chrome, yay 16:9


The result in Firefox, not 16:9

In Chrome/Edge/Safari the green box acts as expected, and has a 16:9 aspect ratio thanks to a 56.25% vertical padding. Firefox however renders the box with a height of 281.25px, independent of its width. Running some numbers this 281.25px turns out to be exactly 56.25% of 500px, which is the height of its parent.

This must be a bug, right?

~

Filing a bug

So I set out to file a bug report for Firefox. To my surprise the issue got closed, concluding that Firefox renders things correctly … as do all the other browsers.

Huh? How can two different results both be correct? Turns out there’s some wiggle room in the spec:

Percentage margins and paddings on flex items can be resolved against either:

  1. their own axis (left/right percentages resolve against width, top/bottom resolve against height)
  2. the inline axis (left/right/top/bottom percentages all resolve against width)

A User Agent must choose one of these two behaviors.

CSS Flexible Box Layout Module Level 1: 4.2. Flex Item Margins and Paddings.

Now letting browsers choose which behavior they want to implement of course isn’t ideal, and that’s also what spec writer Tab Atkins has added as a note:

Note: This behavior sucks, but it accurately captures the current state of the world. It is the CSSWG’s intention that browsers will converge on one of the behaviors, at which time the spec will be amended to require that.

~

Down the Rabbit Hole: How come Firefox behaves differently?

The “culprit” for this quirk is that an older version of the spec read this on margin/padding behavior for flex items:

Percentage margins and paddings on flex items are always resolved against their own axis: left and right margins resolve against the containing block’s width, and top and bottom margins resolve against the containing block’s height. Unlike blocks, block-axis margins do not resolve against the inline dimension of their containing block.

One might wonder why this initially specced behavior behaves different from what we are used to. As Tab Atkins put it:

The logic is that the behavior of percentage vertical padding in existing layout modes is document-focused, where width is *always* the dominant measurement; height is nearly never an input to anything. The newer layout modes (Flexbox and Grid) are different – in them, height and width are on a more equal playing field, and code written that uses percentage padding in the main axis of a flexbox should work equally well for row and column flexboxes. Similar arguments apply for Grid.

So Firefox had implemented this behavior from the start on, and kept in place as a change in the spec still accepted it.

Sidenote: In an archived mailing list message – again by Tab Atkins, the man truly is/was the thriving force behind this spec – I also found this note on the fact that speccing it in this way would nullify the existing aspect ratio hacks:

We recognize that there are some drawbacks, notably the inconsistency with existing document-focused display modes, and the loss of the ability to employ the common “aspect-ratio” hack involving vertical padding. We believe that the first is not too relevant […]. The second is unfortunate, but we plan to address aspect ratios directly in the future, and so consider the loss of this hack for now to be not significant enough to sway our opinion.

… but we plan to address aspect ratios directly in the future … — More on that in a later post 😉

~

Feeling Curious

But why was the original spec changed in the first place? Looking at one of the responses in my initial bug report the adjustment was made because Chrome refused to implement the spec-mandated behavior.

I can follow Chrom(e/ium)’s decision here, as us developers are already used to a vertical padding being calculated with respect to the width:

Part of the reason we’re arguing to change the spec is that all the developers we’ve heard from want the Blink/WebKit behavior because they want to do the aspect ratio hack. We’ve had no developers asking for the specced behavior.

On the other hand, one must admit that the behavior we’re used to is an acquired taste. The first time I ever set a vertical padding I thought it’d be resolved against the height and not the width.

The easy fix would be for Firefox to adjust its behavior to what other browsers do, right? In the long run however – given the history laid out here – I personally thing it might be better to follow the initially specced behavior. Why cling on to an acquired taste, and possibly limit our future possibilities?

That might explain why the spec authors didn’t just switch from one behavior to the other, but added a second behavior instead. By adding a second behavior, they left the door open for future decisions on the matter. For example: the day native aspect ratio methods arrive in browsers, this part of the spec can be reevaluated (and hopefully one of both behaviors can be chosen).

~

What now?

For now, be advised to not use percentage-based values paddings/margins when it comes to flex items as there’s still some ongoing discussion going on about this. This is also noted in the spec:

Advisement: Authors should avoid using percentages in paddings or margins on flex items entirely, as they will get different behavior in different browsers.

The fact that the bug reports on this are still open for both Chromium and Firefox tell me that there’s more to come concerning this. The longer they remain open though, the more sites that might break though once a consensus has been reached.

In case you do want to use any of the current hacks to creating aspect ratios with CSS in combination with flex items, don’t apply the styles on one and the same element but use separate elements for them.

See the Pen Flex Items + Aspect Ratios by Bramus (@bramus) on CodePen.

It’s things like this that make the simple thing called CSS not easy 😉

Update 2017/07/31: Today I came to discover that there’s an open issue on Flexbugs about this. I’ve appended my findings to said issue.

Elsewhere , , 1 Comment

Chromeless Playground: Chrome Automation Made Simple

With Chrome 59 came the ability to run a Headless Chrome. Controlling it via code isn’t that easy nor elegant. Enter Chromeless (not be confused with Mozilla’s Chromeless):

With Chromeless you can control Chrome (open website, click elements, fill out forms…) using an elegant API. This is useful for integration tests or any other scenario where you’d need to script a real browser.

Runs locally or headless on AWS Lambda. The API to control it is really elegant, as the code is very easy to understand:

const { Chromeless } = require('chromeless');

async function run() {
  const chromeless = new Chromeless();

  const screenshot = await chromeless
    .goto('https://www.google.com')
    .type('chromeless', 'input[name="q"]')
    .press(13)
    .wait('#resultStats')
    .screenshot();

  console.log(screenshot); // prints local file path or S3 url

  await chromeless.end();
}

run().catch(console.error.bind(console));

Chromeless Playground →
graphcool/chromeless GitHub →

Elsewhere , , , Leave a comment

Interacting with the iOS Simulator from the Command Line using simctl

Wasn’t aware of this, but turns out one can control (and interact with) the iOS Simulator straight from the command line.

There’s no need to install anything new though. The tool we’re going to be using is already on our Mac, hiding inside the xcrun command, which gets installed with Xcode.

It’s called simctl.

Here’s a few examples:

# open a URL
xcrun simctl openurl booted "https://littlebitesofcocoa.com"

# upload an image to the iOS Simulator
xcrun simctl addmedia booted ~/images/image1.png ~/images/image2.jpg

# Take a screenshot
xcrun simctl io booted screenshot ~/Desktop/screenshot.png

# Record a video
xcrun simctl io booted recordVideo --type=mp4 ~/Desktop/movie.mp4

Other commands include booting/stopping a device, clipboard operations, launching/terminating processes, installing/uninstalling apps, etc. — No touch events though, that would’ve been real fun.

Little bits of Cocoa: Interacting with the iOS Simulator using simctl

Sidenote: digging a bit deeper into this I stumbled upon fbsimctl. Their features are quite the same which makes me wonder if fbsimctl uses simctl underneath its hood, or if simctl came later and copied features from fbsimctl.

Elsewhere , , , Leave a comment

Better Error Handling in React 16 with Error Boundaries

The first beta React 16 has been released just yesterday. Next to it running on Fiber (speeeed!), and allowing one to return Arrays in the render() method (bye bye unnecessary wrapper divs!), it also introduces the concept of Error Boundaries:

Error boundaries are React components that catch JavaScript errors anywhere in their child component tree, log those errors, and display a fallback UI instead of the component tree that crashed. Error boundaries catch errors during rendering, in lifecycle methods, and in constructors of the whole tree below them.

A class component becomes an error boundary if it defines a new lifecycle method called componentDidCatch(error, info)

With Error Boundaries a JavaScript error will no longer break your whole app. An example Error Boundary would be:

class ErrorBoundary extends React.Component {
  constructor(props) {
    super(props);
    this.state = { hasError: false };
  }

  componentDidCatch(error, info) {
    // Display fallback UI
    this.setState({ hasError: true });
    // You can also log the error to an error reporting service
    logErrorToMyService(error, info);
  }

  render() {
    if (this.state.hasError) {
      // You can render any custom fallback UI
      return <h1>Something went wrong.</h1>;
    }
    return this.props.children;
  }
}

Just wrap this around your own component, and it will catch any JavaScript errors inside ‘m

<ErrorBoundary>
  <MyWidget />
</ErrorBoundary>

Here’s a demo pen:

Error Handling in React 16 →

Elsewhere , , Leave a comment