Identity Is the Dark Matter & Energy of Our World

Defining identity is a notoriously difficult endeavor. Identity, in the technology industry, is the name of a business vertical that developers and software vendors use to describe a class of products and services they employ for managing users, authentication, and access control. But the average person doesn’t define identity in this way. They’re more likely to describe identity as how a person or thing defines itself and is known to the world around it. I have always thought it ironic that an industry vertical named ‘Identity’ rarely produces solutions that extend beyond a narrow sliver of what identity truly is. In this post, I will present a conceptual model for identity that defines it as an expansive, organic system, and my stretch goal is that it changes how you perceive your interactions in the world (at least a little).

Identity as a Cosmological Analog

According to Dark Matter & Energy theory, the atoms, particles, and energy people commonly believe are the sum total of the universe, is known as Baryonic matter. Interestingly, and in contrast with human perception, the theory postulates that this form of matter only makes up ~5% of total matter and energy in the universe. The vast majority of the universe is said to be composed of another form of matter and energy, Dark Matter and Dark Energy. I find it fascinating there can be so much beyond our perception that goes into producing the relatively tiny sliver of what we recognize as our world.

A visualization of Dark Matter – NASA, ESA, and E. Hallman (University of Colorado, Boulder)

I posit to you that your perception of the countless interactions and exchanges you participate in on a daily basis is the Baryonic equivalent of their true scope and depth – just 5% of what’s really happening. The 95% you don’t see – the organic, interconnected web that permeates everything you experience – is identity. In this way, identity can be described as the Dark Matter & Energy of our physical and digital lives.

Identity Transactions All Around Us

Every object on the planet (alive or inanimate) is a distinct entity, each with its own identity – this includes humans, organizations, devices, bots, VR objects, and countless other nouns. But the rabbit’s hole goes much deeper: this swirl of identities is constantly interacting with each other in ways you probably don’t recognize as identity transactions. What these identities generate, exchange, and experience during their interactions are transfers of identity-encoded data that augment their state, definition, and accrued provenance.

All identity interactions are generally based on the transfer of self-signed or multi-party proofs; attestations, as many in the industry refer to them. These identity-linked proofs are what form the basis of trust and auditability when interacting with other identities. Here are just a few examples of identity transactions in our world:

  • Text, vocal, or visual communications – identity-encoded message transmissions
  • Licenses, permits, certificates, etc. – identity-signed declarations of privilege
  • Blogs, reviews, comments, etc. – self-signed attestations about other identities
  • Music, paintings, novels, photos. etc. – identity-encoded asset authorship proofs
  • Sales, ads, bids, asks, etc. – identity-signed signals of offer or intent
  • Supply chains, ownership histories, etc. – a trail of identity-signed proofs

As you can see, almost everything you do in life is an identity-encoded transaction, but much like Dark Matter & Energy, they are currently difficult to capture and record. In the identity technology sphere, we lack a good technical system for processing and storing these exchanges in a way that is precise, self-sovereign, discoverable, and universally interoperable. Most of these interactions are either never recorded or are captured by a sea of apps and services that lock them in silos and walled gardens, often sharing the resulting data with unintended third-parties.

Enter The Blockchain

We talk about identity, proofs, and signatures as the fundamental building blocks of every interaction between entities, but what technical options are best suited for this? In my early work at Mozilla, and more serious development now at Microsoft and the Decentralized Identity Foundation, we found that decentralized blockchains provide a solid foundation for anchoring Decentralized Identifiers and DPKI operations. By using decentralized blockchains as a root of trust for anchoring identifiers and their association with cryptographic keys and off-chain personal datastores, you can create a system with just the right mix of attributes and features to support these kinds of identity interactions. Here’s a graphic that shows what the system looks like from a high level:

With this layered approach, most interactions are able to be done off-chain by simply signing data and Verifiable Credentials with keys that are linked to blockchain-anchored identifiers. In many cases, the time-state of these identity interactions can also be important, so the identities involved may want to create a chain-anchored proof that captures the state of what they exchanged, when they exchanged it.

The Breathtaking Scale of Identity

Given the scope of identity, it is important to think about its scale. As alluded to above, each person, organization, device, bot, etc., singularly generates hundreds, if not thousands – and in some cases, millions – of transactions per day. Hopefully you are starting to realize the staggering scale required from any system or technology that seeks to support a world of identity transactions.

The canonical scaling goal you often hear about in blockchain land is “Look Ma, I can do 3000 transactions per second, just like Visa!”. While this would be a laudable goal if Visa-type payments accounted for a majority of transactional demand, it’s a drop in the ocean of demand-reality – and a tsunami is coming. All other demand sources aside, identity transactions + streaming micropayments, deployed at world-scale, would reach into the trillions of transactions per day.

Preview of Part 2

Blockchains, as decentralized, distributed systems that rely on broadcast transmission and consensus synchronization, are implicitly difficult to scale compared to traditional systems. Some blockchain communities have turned to what is known as on-chain scaling, versus intelligent off-loading of demand to secure, chain-anchored, Layer 2 systems. In the next post, I will break down the quantitative scale of demand blockchains will face if they intend to support decentralized identity, and provide an assessment of the various approaches to meeting that demand.

Demythstifying Web Components

The following is an attempt to stomp out the seemingly endless FUD that circulates about Web Components, most of which is purely manufactured by attacking tangential, opinionated choices of frameworks that happen to use Web Components in a way that differs from the opinions of other frameworks.

Level Setting

Don’t let me catch you claiming a Web Component is anything but the following, or I’ll send Kam Chancellor to lay you out:

Web Components are an amalgam of APIs from two W3C specs (Custom Elements and Shadow DOM) that enable the creation of encapsulated, declarative, custom elements, which serve as standard, reusable, interoperable vehicles of discrete, stateless functionality.

Myth 1: “Web Components are at odds with Framework X”

This is probably the most fallacious statement about Web Components.

As long as a framework writes to the DOM (which all major ones do), there is no reason it can’t include Web Components or update a Custom Element with data and state changes (as opposed to an amorphous tree of rando divs).

Let’s say I have a single page React app that’s a clock, where you select a timezone and the clock UI reflects the right time – here’s what I would do:

Write the actual clock element as a Web Component. All this <x-clock> element needs to do is understand one attribute, for example data-zone, that specifies which timezone to display, and print out a clock UI showing the correct time. It shouldn’t be aware of anything else about the app – this shit just tells time, yo. From here you can Reactify the living hell out of everything else (your route handling, how you save the state of the selected timezone, etc.) without ever having to hard-bind the <x-clock> element’s definition code to a framework.

When you follow this pattern, you end up with elements of discrete functionality that can survive a change in framework, data/change management library, storage adapter, etc., and still develop your app with the framework or library of your choosing. Oh, and you also get to feel like a good Web Citizen, because that <x-clock> component you made is now available for use across the entire web, without requiring someone to have advanced programming experience or worship at the Church of Framework X.

Myth 2: “If I want to use Web Components, I have to use HTML Imports”

I’m not going to spend much time on this because it’s so blatantly false.

HTML Imports is a proposed standard for importing an HTML document and its includes into a parent context. If you want to bundle your JS and CSS files into an HTML Import, go ahead, but Web Components are just JS and CSS files that have no dependency on how you include them in an app.

Myth 3: “Web Components require me to change my packaging system”

As previously stated: Web Components simply provide you two JS APIs (Custom Elements and Shadow DOM) with which you can define new elements and register them for use in your app. This means all a Web Component requires is a JS and CSS file; for multiple components you can concatenate them together, like you would any other includes (note: if you choose write your CSS in JS, you obviously wouldn’t need a CSS file)

Because this is just regular ol’ JS and CSS, don’t go chasing new packaging waterfalls on account of Web Components, you can stick to the packaging rivers and lakes that you’re used to.

Myth 4: “Web Components aren’t declarative”

This is perhaps the most mythstifying of all, given Web Components literally enable the end user to write declarative HTML markup extended with Custom Element tags. Frameworks like React (w/ JSX) are great if you prefer them, but in terms of categorization, something like JSX is a non-native, pseudo-declarative DSL with embedded logic hooks, vs the native, purely declarative markup of Custom Element tags written in regular ol’ HTML.

Myth 5: “Web Components aren’t compatible with JSX, they only accept string values!”

If you’re using a DSL markup layer like JSX, there’s no technical reason why a system like that can’t interoperate with Web Components. A conversation on Twitter with various folks in the ecosystem prompted me to address this myth. During the conversation someone noted the basic flow of JSX to React imperative code and asked how it would look with a Web Component. Here’s the pure JSX/React we started with:

// This JSX Markup:


// Turns into this imperative React code:
React.createElement(Foo, { bar: 1 }),

The question was how the above code would look if JSX was to support and interoperate with Web Components. The key requirement is any object type must be able to be passed to a Web Component. This isn’t an issue, as Web Components (and HTML elements in general) natively support methods and getters/setters, in addition to attributes. This means that you could route any type of an object to a Web Component from a JSX context as follows:

// This JSX Markup:


// Turns into this imperative code:
var foo = document.createElement('x-foo');
foo.bar = 1;

Whether or not JSX is already written to detect and reflect data to Web Components via setters/methods is immaterial – the point is: it should be trivial to detect a Custom Element token in the JSX parser and pass data to its corresponding instance. I have inquired about where in the React/JSX lib code this data relay takes place, and I am willing to help modify the code so Web Components can be seamlessly included.

Myth Status: BUSTED

So now that we’ve got all that straight, I encourage you to never utter these myths again.

Scaling Decentralized Apps & Services via Blockchain-based Identity Indirection

Blockchain Scalability

Developers of apps and services, blockchain-based or not, must always consider efficiency and scalability in determining how to best serve the needs of their users. This is especially true when you add new or emerging technologies to the equation. In the realm of blockchain-based apps and services, scalability considerations are magnified by the distributed nature of the underlying system.

In order to maintain the unique guarantees of a blockchain, transactions must be processed with a mechanism that ensures consensus, then propagated across the network. These constraints introduce three major scalability challenges:

  1. Propagation over a distributed system
  2. Consensus processing of transactions
  3. Data duplication size and cost

Transaction Rate

Currently there are two main blockchains: Bitcoin and Ethereum. Neither of these large-scale blockchain implementations publicly exceed double digits in per-second transaction rates. While various members of the blockchain community are experimenting with Proof of Stake and Sharding, which could theoretically push transaction rates “into the millions per second”, these additions introduce new constraints and network characteristics that could impact how developers write apps and services.

But let’s assume blockchains could process millions of transactions per second – is that enough? The real question is: “How many transactions per second would we need for an on-chain world of people, apps, services, and devices?”

To answer that, imagine a world where organic and inorganic entities are generating frequent, on-chain transactions – here are a few examples of transaction sources:

  • Billions of people each generating transactions throughout the day
  • Hundreds of millions of IoT devices triggering transactions
  • Millions of apps, services, and bots performing background transactions

When you consider the breathtaking enormity of the scale, it’s hard to precisely quantify a lower bound, but BILLIONS of transactions per second may be conservative.

Dr Evil

Transaction-related Computation

Another scalability consideration is the fact that transactions on some blockchains trigger consensus-based computation of programmatic ‘contracts’. While this is a neat feature, it also incurs a significant cost that must be borne by nodes on the network.

Ethereum devs themselves are open about the fundamental performance limitations of these contract computations:

“Clearly Ethereum is not about optimizing efficiency of computation. Its parallel processing is redundantly parallel. This is to offer an efficient way to reach consensus on the system state without needing trusted third parties, oracles or violence monopolies. But importantly they are not there for optimal computation. The fact that contract executions are redundantly replicated across nodes, naturally makes them expensive, which generally creates an incentive not to use the blockchain for computation that can be done off-chain.”

(I want you to remember the word off-chain, it’s going to come up a lot)

Data Storage

Blockchains do not allow much data to be embedded within their transactions, and rightly so, because duplicating  data across a significant number of nodes is a non-starter when you’re talking about billions of transactions per second. In fact, at those transactional rates – even with strict transactional data limits, pruning,  and aggressive transaction aggregation – the network would still generate hundreds of petabytes of data annually. This would likely reduce the number of full nodes in the network, and the widespread replication of blockchain transactional data that goes with it.

Consider the Following

The most common way of developing decentralized apps and services with blockchain tech is to create a digital record of source data, link it to an on-chain blockchain transaction via a hash of the data + timestamp, then store the source data off-chain somewhere. Let’s call this method the Blockchain Transactional Model.

But what does this model really provide?

  1. The on-chain transaction provides a rough timestamp based on when it is added to the chain.
  2. The hash embedded in the transaction records the state of off-chain data, but does not provide storage of that data.
  3. Both 1 and 2 are synced to the global ledger, and off-chain data can be validated against the embedded hash.

What if I told you blockchain-anchored identity could provide a more efficient means to achieve the majority of off-chain use-cases? I submit the following for your consideration:

Most non-monetary blockchain use-cases can be accomplished off-chain using a combination of blockchain-anchored identity, cryptographic signatures, and traditional storage systems – all while retaining the features developers desire and avoiding the scalability issues of on-chain transactions.

Identity – The Red Pill

There are known choke points in the transmission, computation, and storage of on-chain transactions that make the Blockchain Transactional Model prohibitive at high levels of transactional load. But what does that mean for the promise of decentralized apps and services – is blockchain still the solution?

The answer is yes, but you’ll need to free your mind.

red-pill-blue-pill

We are currently working on an open source system that will enable cross-blockchain registrations of identifiers for self-sovereign identities. Think of it like a transparent, open source, blockchain-based naming and identity layer for the world. Users will own their identities and can prove ownership based on control of a private key linked to a known identifier.

A blockchain-based identity can be used to represent any type of entity, including: people, apps, services, companies, government agencies, etc.

Regardless of the non-monetary decentralized app or service use-case – rental agreement, supply chain system, car title transfer, or any other attestation – it all boils down to three key features:

  1. Capturing the state of data
  2. Logging time of occurrence
  3. Verifying the participation of all parties involved

It turns out we can accomplish all three of these by having various parties to an action sign a payload comprised of source data, the state of that data, the time of occurrence (if relevant), and proof of participation using their globally verifiable, blockchain-based identity.

Use-Case: Renting an Apartment

Let’s compare how non-monetary, blockchain-based use-cases are handled under the Blockchain Transactional Model, vs handling them entirely off-chain via the Blockchain Identity Model. Imagine Jane wants to rent an apartment from Bill – here’s how that plays out under each model:

Blockchain Transactional Model (On-Chain)

rental-agreement-flow

Result:

  • A blockchain is used to record a hash of a rental agreement document and meta data – a scale bottleneck at higher transaction rates.
  • You must be online to commit a transaction to a blockchain – a blocker for many use-cases that demand quick resolution.
  • Bill and Jane have forced a huge, distributed consensus system to store a hash of the rental agreement only they are interested in – introduces scale problems without providing a clear benefit.
  • Bill and Jane still must save and maintain the original rental agreement document if it is ever needed for verification or inspection, because a hash alone is just a proof of state – it doesn’t escape off-chain data maintenance.
  • Bill and Jane are still required to prove that they each signed the rental document, which either requires traditional means of verification or a system of verifiable, digital identity – identity is an ever-present issue.

Blockchain Identity Model (Off-Chain):

identity-rental-agreement-flow

Result:

  • Use of a blockchain is only required once for each participant to register their identity, which can happen prior to this entire use-case taking place, yay, it scales!
  • Bill and Jane don’t have to worry about the cost, hassle, and delay in broadcasting a transaction to a huge, distributed consensus system, while retaining all the features they wanted from the on-chain model – less blockchain is more in many cases.
  • Bill and Jane still save their agreement payload off-chain, just as with the Blockchain Transactional Model, but instead the payload contains everything they need: the source document, data state hash, and identity signatures for verification — fewer moving parts and no added burden.
  • Bill and Jane can now complete this entire use-case with standard, scalable systems, even while offline, then sync the payload to the secure storage services of their choice – more flexibility with less complexity.

Implications

Blockchain-based identity should cause you to question core assumptions around modeling and implementation of decentralized app and service use-cases. As a result, you should ask whether or not your use-case truly requires on-chain transactions. Here are a few important points to take away from this post:

  1. The scalability issues with blockchains are an irrelevant mirage for the majority of decentralized app and service use-cases.
  2. Hashes or Merkle Roots stored on the blockchain may be valuable in certain unique situations where no combination of identity signatures can be trusted and there is no viable third-party witness, like a Notary Public or a government agency.
  3. We can build scalable, decentralized apps and services today by enabling entities to sign off-chain payloads with blockchain-based identities.

Determining On-Chain vs Off-Chain

Here is a little pseudo-code test to help you determine whether to use the off-chain Blockchain Identity Model or the on-chain Blockchain Transactional Model:


if (selfAsserted || groupSigsAreTrusted || canBeAttestedByNeutralParty) {
  useOffChainIdentitySignatures();
}
else {
  anchorItOnChain();
}

Feature Comparison

Last but not least, here’s a feature breakdown of the two models:

FeaturesTraditional(On-Chain)Identity(Off-Chain)
~Unlimited scalability
Eliminates the need for off-chain storage 
Transactions are verifiable without middlemen 
Solves identity verification 
Reuses existing systems and tools 
Doesn't require learning new languages
Not tied to any one blockchain 

Recapping the W3C Blockchain Standardization Workshop @ MIT

I had the opportunity to both co-chair and present at the W3C’s blockchain workshop at MIT in Boston this week. More than 100 of the best and brightest from the standards and blockchain worlds met to discuss potential Web standards opportunities for blockchain tech.

I have been working toward the establishment of a large-scale, user-sovereign, blockchain identity system for many years, and with an initiative now underway at Microsoft, this event was instrumental in better understanding the views of other organizations we intend to work with in bringing this system to users, companies, and governments across the globe.

CmOUQitWMAA0YZR

There were many areas of standardization discussed that touched on blockchain-based identity systems, but perhaps the most specific, actionable area of standardization the group identified was extension of the existing Web Auth spec to include the APIs, features, and flows necessary to enable blockchain-based identity authentication in browsers. This is something I will begin to explore with other implementers and interested organizations from the W3C workshop who committed to do so with us.

The workshop was a great opportunity to start an important discussion about systems that could move the Web far beyond what it is today. I look forward to reporting back on the progress of our explorations as we move forward!

The Nickelback Persistence Conjecture

“The Hammer’s Coming Down”

In my work with open source blockchains, distributed hash tables, and peer-to-peer systems in the area of identity, I have run across people making this statement from time to time, often in an effort to minimize open source, decentralized, distributed systems vs their centralized or proprietary counterparts:

“The data on these decentralized, distributed systems will only be persistently available if people continue to run them.”

These folks often add:

“This is a serious concern because the people running these systems must have an economic incentive to keep them running.”

I’ve never spent more than an eye-roll of my time on people who make these statements because they’re pure fallacy, but a random assault committed on my eardrums (Britney Spears – Oops I Did it Again) in the admission line at Google I/O 2016 inspired me to finally drop the hammer on this FUD. I’m sure you’re wondering how Britney Spears, Nickelback, and fallacious statements about decentralized, distributed systems are all related: slow your roll, I’ll get there.

“Believe It, or Not”

Let me channel my inner-@pmarca for a moment:

“I am hearing disturbing rumors that a system’s data won’t be unavailable if no one is running it.”

Wow, what a profound thought! While that is technically true, it’s also the Least Plausible Hypothesis for why data on a decentralized, distributed system with any traction, scale, or utility would suddenly become irrecoverable.

“Remind Me”

The craziest part about these statements is how absolutely backwards they are when used to target decentralized, distributed systems vs others. Perhaps the folks who emit this brand of truthiness need a reminder about the reality of their claim: A centralized or proprietary system is just as likely to go dark for any number of reasons.

yahoo-geocities-homepage

Disturbingly (not really), you can no longer access these systems (though some have been archived by various sites):

  • GeoCities
  • AltaVista
  • Yahoo Auctions
  • Friendster
  • Google Wave
  • etc. etc. ad infinitum

For whatever reason, a person might be inclined to gravitate toward centralized or proprietary systems because they believe them to be more trustworthy, secure, or permanent, but that is far from a reliable truth. In fact, centralized or proprietary systems can be worse for many reason, including:

  • Shutdown can happen more abruptly, sometimes without notice
  • Proprietary system shutdown is often permanent
  • Centralized and proprietary systems usually have a single arbiter that decides their fate
  • Almost without exception they are driven by revenue, sometimes at the expense of users

In contrast, decentralized, distributed systems with significant traction, scale, or utility:

  • Are very difficult to shut down abruptly – most if not all nodes need to go dark
  • Can be restarted by anyone in the community with copies of the data
  • Are not subject to the shutdown whims of a single arbiter
  • May persist because parties have a principled or personal desire to ensure they do

The Nickelback Persistence Conjecture

nickelback-meme-31

Now we get to the fun part. How does one articulate to someone deeply skeptical of open source, decentralized, distributed systems, such as a blockchain, that their data will not vanish suddenly? How does one rebut the statement that these systems must rely on unsustainable economic interests for anyone to run them?

After hearing that Britney Spears song at Google I/O, I wondered: “Is this noise pollution still available on decentralized systems (torrents, etc.) after this long?” When I got home I decided to up the ante in my search for long-lasting, distributed trash, so I chose to base my conjecture on the poster child of musical eye-rolling: Nickelback. Not many people like Nickelback, and that’s great, because those who are circulating its songs on a peer network are probably doing so out of some unnatural affection for them or specific self-interest. As it turns out, I took a look and found that Nickelback’s songs are still available on peer networks 20 years after they first appeared. Herein lies the conjecture I present to you, without further delay:

The mean duration that data will remain persistently available on an open source, decentralized, distributed system that reaches at least the size, popularity, or acolyte following of Nickelback, is roughly equal to the time period from which Nickelback’s songs first became available to the day no peer nodes remain that circulate their ‘music’.

“It’s Over”

“Never Again” let one of these purveyors of persistence FUD keep you up “Into the Night” thinking about if “Today Was Your Last Day” to access the data you have stored on an open source, decentralized, distributed system.

S(GH)PA: The Single-Page App Hack for GitHub Pages

SPA woes

For some time now I have wanted the ability to route paths for a gh-pages site to its index.html for handling as a single-page app. This ability is table stakes for single-page apps because you need all requests to be routed to one HTML file, unless you want to copy the same file across all your routes every time you make a change to your project. Currently GitHub Pages doesn’t offer a route handling solution; the Pages system is intended to be a flat, simple mechanism for serving basic project content.

If you weren’t aware, GitHub does provide one morsel of customization for your project site: the ability to add a 404.html file and have it served as your custom error page. I took a first stab at doing an SPA hack by simply copying my index.html file and renaming the copy to 404.html. Turns out many folks have experienced the same issue with GitHub Pages and liked the general idea: https://twitter.com/csuwildcat/status/730558238458937344. The issue that some folks on Twitter correctly raised was that the 404.html page is still served with a status code of 404, which is no bueno for crawlers. The gauntlet had been thrown down, but I decided to answer, and answer with vigor!

One more time, with feeling

After sleeping on it, I thought to myself: “Self, we’re deep in fuck-it territory, so why don’t I make this hack even dirtier?!” To that end, I developed an even better hack that provides the same functionality and simplicity, while also preserving your site’s crawler juice – and you don’t even need to waste time copying your index.html file to a 404.html file anymore! The following solution should work in all modern desktop and mobile browsers (Edge, Chrome, Firefox, Safari), and Internet Explorer 10+.

Template & Demo: If you want to skip the explanation and get the goods, here’s a template repo (https://github.com/csuwildcat/sghpa), and a test URL to see it in action: https://csuwildcat.github.io/sghpa/foo/bar

That’s so META

The first thing I did was investigate other options for getting the browser to redirect to the index.html page. That part was pretty straight forward, you basically have three options: server config, JavaScript location manipulation, or a meta refresh tag. The first one is obviously a no-go for GitHub pages, and JavaScript is basically the same as a refresh, but arguably worse for crawler indexing, so that leaves us with the meta tag. Setting a meta tag with a refresh of 0 appears to be treated as a 301 redirect by search engines, which works out well for this use-case.

You’ll need to start by adding a 404.html file to your gh-pages repo that contains an empty HTML document inside it – but your document must total more than 512 bytes (explained below). Next put the following markup in your 404.html page’s head element:


<script>
  sessionStorage.redirect = location.href;
</script>
<meta http-equiv="refresh" content="0;URL='/REPO_NAME_HERE'"></meta>

This code sets the attempted entrance URL to a variable on the standard sessionStorage object and immediately redirects to your project’s index.html page using a meta refresh tag. If you’re doing a Github Organization site, don’t put a repo name in the content attribute replacer text, just do this: content="0;URL='/'"

Customizing your route handling

If you want more elaborate route handling, just include some additional JavaScript logic in the script tag shown above to tweak things like: the composition of the href you pass to the index.html page, which pages should remain on the 404 page (via dynamic removal of the meta tag), and any other logic you want to put in place to dictate what content is shown based on the inbound route.

512 magical bytes:

This is hands down one of the strangest quirks I have ever encountered in web development: You must ensure the total size of your 404.html page is greater than 512 bytes, because if it isn’t IE will disregard it and show a generic browser 404 page instead. When I finally figured this out, I had to crack a beer to help cope with the amount of time it took.

Let’s make history

In order to capture and restore the URL the user initially navigated to, you’ll need to add the following script tag to the head of your index.html page before any other JavaScript acts on the page’s current state:

 

This bit of JavaScript retrieves the URL we cached in sessionStorage over on the 404.html page and replaces the current history entry with it. However you choose to handle things from there is up to you, but I’d use popstate and hashchange if you can.


Well folks, that’s it – now go hug it out and celebrate by writing some single-page apps on GitHub Pages!

GIF

The Web Beyond: How blockchain identity will transform our world

Imagine

Jane wakes up to the sound of her alarm clock, it’s 6:13 AM. “Oh great, what am I in for today,” she thinks. Jane’s alarm clock is normally set for 6:30 AM, but her identity agent detected a traffic accident that is projected to add 17 minutes to her commute. Jane’s identity agent, acting on her behalf, changed her alarm while she was sleeping. All three, Jane’s identity, the identity of her alarm clock, and the identity of her agent, are connected via a self-sovereign, decentralized, blockchain-anchored identity system.

Jane gets ready and grabs a yogurt from the fridge as she heads out the door. The yogurt was delivered yesterday, after her fridge detected she was out. Her fridge’s identity has been granted limited access to initiate purchases for her. In this case, Jane has opted to be notified for confirmation of any purchases her fridge initiates; yesterday Jane swiped “Confirm” when the identity management app on her phone asked if the fridge could execute a purchase of some groceries. The fridge executed a payment over the blockchain using Jane’s identity-linked blockchain wallet and the wallet linked to the grocery store’s identity. That’s right, the grocery store has a blockchain-anchored identity as well. Starting to get the picture?

Jane needs to get to a downtown office building where she is scheduled to meet a contact on the 12th floor. Jane doesn’t have a car, so she asks her identity agent to fetch her one by leveraging the many identity crawlers dedicated to indexing sharing economy identity data. These crawlers are always hard at work, real-time indexing the (user allowed) blockchain identity data changes of every person, place, device, and intangible entity on Earth. In this case, there are hundreds of drivers in Jane’s general vicinity who have granted popular ride sharing identity agents access to read and update their identity’s ride sharing fields. Jane uses her preferred crawler’s app to send signed, encrypted requests directly to providers of sharing economy services. The crawler identifies a driver whose identity shows a ride sharing status of “Available,” with a geolocation value that indicates he is close to Jane. Jane taps “Request a Ride” on the app and it immediately sends a message to the communication endpoint listed on the driver’s blockchain identity. The driver’s blockchain sharing economy app alerts him that a new ride request was received and asks whether he wants to accept. The driver accepts and is sent Jane’s current geolocation.

Upon arriving at her destination, Jane authorizes a payment of her driver’s identity-linked blockchain wallet. She enters the office building and heads directly for the elevators, bypassing a lengthy check-in procedure in the ground floor lobby. Jane taps her phone against an NFC pad, which instantly identifies her via a challenge/response verification of her identity assertion. The elevator system’s blockchain-anchored identity has been given access to the appointment schedules of the various software systems used by the companies that reside in the building. It uses Jane’s identity datastore to locate the appointment entry, which was created by her contact. Within this entry is a signed directive to allow Jane’s identity to access the elevator and take it to the 12th floor. Jane enters the elevator and the button for the 12th floor is already lit up. Just for fun, Jane tries hitting other buttons. But alas, she was not granted access to other floors, so the buttons don’t light up and she isn’t able to access them.

Jane walks up to the front desk and alerts the attendant that she has arrived for her meeting. The attendant directs her to verify her identity once more, via the guest terminal. Jane is greeted by her contact and smiles at the thought of how efficient and interoperable the world has become, thanks to the universal blockchain-based identity system.

Understand

A blockchain is a decentralized, distributed ledger that accounts for and stores cryptographically verifiable token ownership proofs, synced to computers around the globe. Blockchains represent an unprecedented opportunity to create standard, decentralized systems that handle complex activities in a more efficient, automated, programmable way than ever before. One of the most interesting applications of blockchain tech is in the area of identity. Identity has never, ever, had a good solution. Humanity has built countless centralized systems, federation schemes, and every hybrid of the two you can imagine. With a worldwide, decentralized blockchain of identity, that all ends.

Each transaction on a blockchain allows for a small amount of data to be stored with it. For the purpose of identity, this data can be encoded with two things:

  1. A registration for an ID (a friendly or unfriendly name), that is verifiable and indexable
  2. A pointer to off-blockchain data that describes the identity attached to the ID

Whoever possesses the private key for one of these blockchain ID transactions controls the identity data attached to it. This allows us to do interesting things, like:

  • Lookup IDs on a cacheable index of the global ledger
  • CRUD identity data connected to an ID at real-time speed
  • Prove ownership of an ID, or verify data has been signed/sent by an ID’s owner, using standard cryptographic methods

Build

With a global blockchain of identity, we can dramatically transform almost every product or service that relies on interactions between living, non-living, and intangible things. Here are a few examples of what it will do:

  • Allows users to directly expose products or services to real-time crawlers and indexes, which can disintermediate centralized products/services in every vertical.
  • Provides a means to lookup and contact anyone on the planet via the exposure of public or private (access limited) communication endpoints
  • Simplifies service access and accounting schemes, like registering for API keys, leaky URL params, etc.
  • Provides better mechanisms for verifying access/ownership of digital goods
  • Solves the fundamental issues with provisioning, security, and access control for the IoT ecosystem

Here are a few developer-enabling features, APIs, and tools we can build into existing platforms to more rapidly realize this blockchain-based future:

  • Create a new protocol (chain:, bid: ?) that allows for CRUD and search of blockchain transactions/identities
  • Build cloud services that make blockchain identity agents, and their bots, as easy to develop as all the social/messaging bot frameworks of today
  • Develop new Web standards and browser features that integrate a more secure, more powerful blockchain-anchored system of authentication and identity into common flows, like login and request signing
  • We may want to reuse/augment some existing mechanism, like the FIDO flow, etc.

^ This is the future we deserve, a standard, generative, user-sovereign world of identity that will fundamentally change the way we interface with every person and object around us.

A Renewed Call for App-to-App Interaction APIs

Cow, come in cow

The battle ground of app-to-app interaction history is littered with abandoned ideas, half-solutions, and unimplemented APIs. The current, consumer/provider interaction paradigm for apps and services is a mess of one-off, provider-defined systems that each use their own transaction mechanisms and custom data structures. This makes it hard to do simple things across N providers, like save something to a user’s preferred storage service without jumping through provider-specific code and UX hoops.

I’d like to restart the conversation about bringing legit, app-to-app interaction APIs to the Web. There have been past spec attempts, namely Web Activities and Web Intents, but I’ll argue that while they get a lot right, they all fail to deliver an A+ solution.

Wait, what is an “App-to-App Interaction API”?

Have you ever wanted to open a programmatic connection within your app to the user’s preferred provider of a service or activity? Maybe you’ve wanted to check a user’s identity, store data to a user’s storage provider, or post to the user’s preferred social network, etc. If you’re saying to yourself, “Self, this is already solved, there are endless provider-specific social, identity, and storage includes to do just that” <– I would submit to you, that right there, sucks. There must be some way to provide a common API layer for consumption of these services that doesn’t require developers to know of, integrate, and manage specific bits of UI and code for every provider. Not having legit APIs to do this is a real problem, with significant consequences:

  • Pages are cluttered with code and UI includes for countless providers, many of which are left on pages to rot after a company discontinues support.
  • Developers must know of, include, maintain, and write code to juggle how and what providers respond with; which usually doesn’t share a semantic, even across the same type of service.
  • The performance cost is huge – social, login, and other provider-specific includes account for a staggering amount of memory and dramatically increase page load times.
  • Because developers are required to specifically include each provider, they often display only two or three options for a given service. This prevents users from leveraging different services that aren’t among those a developer has committed cycles to integrating.

So we know this is a serious issue that impacts countless uses-cases, degrades performance, and limits service mashability, but what does a serious solution look like?

Must-haves of an A+ solution:

  1. Ability for providers to be registered dynamically, or via manifest declaration, but not tied to any installable app model – the whole Web deserves this API.
  2. The user’s selection and preferences for servicing activities should be managed by the User Agent (browser, OS, etc.), within its trusted, chrome UI.
  3. The user should have the ability to pick a service/app to handle an activity per-use, as a default per-domain, or as a global default.
  4. The developer should be able to request handling of an activity via context switch to the provider app OR by establishing a silent, programmatic connection (connecting to another app/service in the background)
  5. The spec should provide both declarative and imperative entry points for UI hand-offs and programmatic connections – for instance: links for declarative hand-offs, and imperative interfaces for background connections.
  6. Imperative API connections to providers should be transactional – meaning a response sent back from a provider should be tied to a specific request instance (hopefully with a Promise).

How does current tech stack up?

Here’s a rundown of how the three existing mechanisms we have for app-to-app interaction fare when assessed against the base features and capabilities an A+ solution should include:

FeaturesWeb IntentsWeb ActivitiesCustom Protocols
Use is not limited to installable app model✔❌✔
Choice of dynamic or declarative registration❌❌✔
Activities types should not be whitelist-driven✔❌✔
Selection/prefs managed in trusted UI❌❌⁕
UI for selection/prefs shouldn't have asstastic UX❌❌❌
Per-use selection✔✔✔
Per-domain default option❌❌❌
Global default option✔✔✔
Global default != granting global permission✔✔❌
Requests to providers are handled transactionally✔✔✔
Handling via context switch or background connection⁕❌⁕
Implemented today by more than one browser vendor❌❌✔
Implemented today in any default, mobile browsers❌❌❌

Though Custom Protocols come closest – and could be enhanced to fill the gaps – none of these options meet the criteria of an A+ solution. To add insult to injury, no current option is supported by default mobile browsers (Android, iOS, or Windows Phone), which makes general use a non-starter for most developers. The inability of these APIs to cover significant developer use-cases is one reason implementation of the above APIs is so spotty. Neither IE nor Edge currently support these APIs, and I don’t blame them – before you commit significant time to implementing an API, you need to be sure it adequately solves the problems you face. That’s part of the reason I am starting this discussion; we want to create an open dialog to better understand your needs.

Experimenting with Protocol Handlers

I needed an app-to-app interaction API for something I’m working on at Microsoft, called Web Profile. The requirement was that any consuming app would be able to open a programmatic connection to a user’s preferred service provider and perform transactions without the consuming app having to know where to look, or include any provider specific code.

To build a working prototype, I needed an existing mechanism that worked across multiple browsers, so I took another look at something I had used in the past: Custom Protocol Handlers (MDN: navigator.registerProtocolHandler). Though they may not realize it, users and developers are already familiar with custom protocol handlers; the best example is probably mailto:. URLs prefixed with a custom protocol direct the browser to open the app or site the user selects to handle the request. This usually takes the form of a contextual switch: opening a new window or browser tab. For what I was looking to do, I needed a way to stay within my app while interacting over a programmatic connection with whatever provider the user selects. Custom protocol handlers can currently be registered in the desktop versions of these browsers:

  • Firefox 3+
  • Chrome 13+
  • Opera 11.6+

Meet ProtocolWorker

It turns out you can use custom protocols to create a programmatic, background connection for app-to-app interactions. How? By pairing them with an old friend: the iframe. I found that loading a custom protocol (any handler registered with the web+ prefix) in an iframe will redirect to the handler’s target page. With a bit of postMessage() magic handled by a prollyfill included on both sides (consumer and provider), you can create an active, two-way connection between your app and the user’s preferred service provider. Think of it as a cross between a Web Worker and Background Page (as they’re known in browser extension land). Here’s my Github repo with the JS file you’ll need to make it all work: https://github.com/csuwildcat/ProtocolWorker

Talk codey to me:

To show how this works I put together a simple demo built on the totally-100%-made-up web+whisper protocol. The hypothetical Web Whisper case I highlight in the code below lets a user store a text string (a whisper) with their provider, or retrieve the last text string the provider stored on their behalf. Any consuming app that desires to store or retrieve the user's whisper must first be permitted to do so via the browser's protocol selection UI. The whole demo uses localStorage to save the user's text string on the provider's domain, so don't expect persistence beyond that of your local machine.

Note: though this is a super simple demo, the system would be just as good for sending/retrieving things like: social posts, user profile info, or files from places like OneDrive, Dropbox, Box, etc.

Providers register a protocol handler

The first thing a site offering a Web Whisper service needs to do is register itself as a handler for the web+whisper protocol. Here's how you do that:

navigator.registerProtocolHandler('web+whisper', HANDLER_URL + '?%s', 'Whisper Demo Provider');

Protocol handlers point to a ProtocolWorker page

At the other end of that HANDLER_URL should be an HTML page that is not intended for display - we'll be treating it as more of a DOM-enhanced, Web Worker environment. In this page you will include event listeners and whatever code you need to deal with the requests you'll receive from consuming apps. Here's what the handler page looks like for our Web Whisper provider:

<script src="js/ProtocolWorker.js"></script>

<script></p>
<p>  window.addEventListener('protocolrequest', function(event){<br />
    if (event.detail['@type'] == 'Comment') {<br />
      localStorage.whisper = event.detail.comment;<br />
      event.detail.resolve();<br />
    }<br />
    if (event.detail['@type'] == 'Search') {<br />
      event.detail.resolve(localStorage.whisper);<br />
    }<br />
  });</p>
<p></script>

Consuming apps connect to providers via ProtocolWorker

After the user adds our Web Whisper provider as a handler for web+whisper requests, consuming apps can ask to open a connection to it. Below is a demo page of what it would look like for a consuming app to interact with the user's Web Whisper provider. Notice the consuming app creates a ProtocolWorker instance and sets up events in which it will attempt to send and retrieve data from the user's Web Whisper provider.

<input type="text" placeholder="Whisper something" /><button id="send">Send</button><button id="retrieve">Retrieve</button>

<script src="js/ProtocolWorker.js"></script>
<script></p>
<p>var retrieveButton = document.querySelector('#retrieve');<br />
var sendButton = document.querySelector('#send');<br />
var input = document.querySelector('input');</p>
<p>var whisperWorker = new ProtocolWorker('web+whisper');</p>
<p>sendButton.addEventListener('click', function(){</p>
<p>  var value = input.value.trim();<br />
  if (value) {<br />
    whisperWorker.request({<br />
      '@context': 'http://schema.org',<br />
      '@type': 'Comment',<br />
      comment: value<br />
    }).then(function(){<br />
      alert('Your message has been whispered to your provider!')<br />
    }).catch(function(){<br />
      alert('You either declined to whisper something to me or don\'t have a web+whisper provider :/')<br />
    });<br />
  }<br />
  else alert('You didn\'t whisper anything.');</p>
<p>});</p>
<p>retrieveButton.addEventListener('click', function(){</p>
<p>  whisperWorker.request({<br />
    '@context': 'http://schema.org',<br />
    '@type': 'Search'<br />
  }).then(function(data){<br />
    alert('You last whispered: ' + data);<br />
  }).catch(function(){<br />
    alert('You either decided not to let this app see your last whisper, or don\'t have a web+whisper provider :/')<br />
  });</p>
<p>});</p>
<p></script>

Transactions should follow shared semantics

As you may have noticed above, each ProtocolWorker request above is formatted in accordance with a matching data description from Schema.org. Schema.org is a great resource for semantic data descriptors, which I believe are a solid Lingua-franca upon which to transact custom protocol requests. Who knows, maybe browsers could validate and enforce these semantic data structures some day?

Just show me the demo, clown.

I have the demo code above running on a couple Github domains so you can test the interplay between providing and consuming apps – note: you need to be using a desktop version of Firefox, Chrome, or Opera. Here are the steps to follow:

  1. Add the demo provider as your Web Whisper handler by clicking the “Add Provider” button, and accepting the handler via the browser’s permission UI: http://web-protocols.github.io/provider-demo/
  2. Visit the consuming app demo page and whisper something to your provider by entering a message in the input and clicking the send button. It will prompt you to select a provider, make sure you pick the “Whisper Demo Provider” you just added: http://csuwildcat.github.io/ProtocolWorker/
  3. OPTIONAL: You’ll notice an option to make your provider choice the default when the browser selection UI is raised in the consuming app demo. If you select a provider as your default, all subsequent ProtocolWorker calls will happen instantly in the background, without bugging you to choose a handler.

Christian Heilmann was kind enough to shoot a quick screen cast of the steps above:

Where do we go from here?

As we’ve discussed, there are new and existing APIs and specs that could be modified to enable these use-cases – ServiceWorker could be a candidate, but regardless of what form the solution takes, let’s come together as a community of developers and platform implementers to move the web forward. I encourage you to submit your own requirements, technical feedback, and implementation ideas directly to this Github repo: https://github.com/csuwildcat/ProtocolWorker/issues/1

Element Queries, From the Feet Up

Everybody’s looking for Element Queries

What are Element Queries? At a high level, I’d describe them as pure, unfiltered, rocket fuel for hyper-responsive layouts and components. More technically, they are Media Queries scoped to individual elements. Element Queries would allow you to attach Media Query break-points based on the dimensions and characteristics of an element itself, instead of the page’s viewport.

Developers have wanted Element Queries for a long time. Here’s a list of articles that convey the need, along with a few attempts to make them real:

Visualizing the Problem

I’ve included a couple sketches from the Filament Group (with permission) that highlight the common layout issues we face in a world without Element Queries:

When the following schedule component is in its primary, full-width state, Media Queries work well for addressing different screen sizes/orientations
Responsive Calendar

Problems quickly arise when the same schedule component enters a secondary, partial-width state. Top-level viewport break-points are no longer relevant, and styling the component becomes extremely difficult.
Responsive Calendar

“So you’ve convinced me. Element Queries would be awesome, and developers want them – so why don’t browser vendors just give ’em the goods?” Well, there are a few tough problems to solve, chief among them is circularity. As Tab Atkins points out in his post, there is a problematic condition created if you apply the existing paradigm to Element Queries:

.container {
  float: left;
}
.child {
  width: 500px;
}
.container:min-width(450px) > .child {
  width: 400px;
}

See the issue? I’ll let Tab clarify the problem for us:

In this simple example, the container’s size is determined by the size of its contents, because it’s floating. By default, its only child is 500px wide. However, whenever the container is greater than 450px wide, the child is 400px wide.

In other words, if the child is 500px wide (thus making the container also 500px wide), then the child becomes 400px wide. But if the child is 400px wide (thus making the container also 400px wide), the child becomes 500px wide. Circular dependency!

Some Element Query hacks want to abuse you

Each of the posts I’ve linked to above adds to the chorus of developer need, and all are to be commended for highlighting the issues developers face. While there have been many attempts at creating something that resembles Element Queries, most rely on polling, observers, hacky resize listeners, hand-rolled measurement routines, and an assortment of odds and ends that simply fail to produce the same level of API fidelity and reliability that native Media Queries do. So what does this mean? Is all hope lost?

I’ve traveled the DOM and the HTML seas

After doing a ton of research and experimentation, I believe I have a better solution to Element Queries – in fact, it may be the best solution possible while we wait for some sort of native implementation of the feature. The mechanism I’ve derived not only avoids the issues highlighted above, it also provides the full Media Query API, scoped to individual elements. There are many factors to consider, but with a bit of out-side-the-box (literally) thinking, we’re giving Element Queries to everyone!

Oprah 'You Get' Element Queries Meme

Sweet Element Queries are made of this

Let’s talk about all the pieces we’ll need. I’ll start with the most basic ingredient: finding a way to associate a separate, scoped viewport with each of the elements we want to imbue with Element Query powers.

Picking a Viewport Surrogate

What are the options? There are basically two routes: you can either try arcane event juggling with resize listeners or DOM polling, or utilize something that creates its own browsing context. Tab Atkins highlights one classic element that does this: the iframe. Sure, I guess we could toss content into an iframe, but they are heavy elements (in terms of performance), and placing all your content into a separate browsing context brings with it its own lame set of hassles, like style/script boundaries, lack of auto-height content flexibility, and a host of others. But hey, let’s not give up yet, there are other candidates for the staring role in this Element Query thriller: embed and object.

The EMBED Element

The embed element can be used to, er, embed content within your pages. It was recently standardized in the HTML spec, and in my exploration of the spec, seems to be the ‘lightest’ (in terms of performance) of all the elements that create new browsing contexts. The flaw with embed elements, is the difficulty in accessing the content they contain from the parent document. For this reason, it’s a poor choice for this use-case. (here’s the embed element spec if you’re curious: http://www.w3.org/TR/html5/embedded-content-0.html#the-embed-element)

The OBJECT Element

Our other option, is the object tag. It can also be used to fetch and include content (or code) within your page, and still has a far ‘lighter’ create, load, and memory footprint than the iframe (closest to that of the img tag). This tag is interesting for a few reasons. Object tags create new browsing contexts, and most importantly, allow ownerDocument script access to their about:blank content. These suckers have been around for ages, here’s the spec: http://www.w3.org/TR/html5/embedded-content-0.html#the-object-element

The Conclusion: We’re going with option 2, the object element, for compatibility and (relative) ease in scripting its contents.

The Skinny on Performance

It’s widely recognized that the iframe element is a beast that consumes memory and ravages performance – this is true, they’re terrible. So how are object and embed elements different? Can’t you load things into them like an iframe? Sure, but their fundamental attributes and performance characteristics greatly differ from that of an iframe. To assure you that, in moderation, use of object elements is safe and will not get you burned at the stake for performance heresy, I’ve thrown together a perf test – you may find the results surprising: http://jsperf.com/element-create-load-footprint (Warning: some have stated the audio tag test – which has nothing to do with Element Queries – crashes Safari. This is inexplicable, as I am doing very basic create/load testing)

Basically, I wouldn’t use 1000 object elements in your app – but as the test above shows, I wouldn’t go putting a 1000 img elements into the DOM either. Use this Element Query code in a smart and deliberate way. Instead of putting an element query on 1000 li elements, put one on the ul – this is my official appeal to common sense, folks.

Bringing It All Together

Now you may be thinking “So put content in an object element? Wow, great advice Dan, that’s really original. Yawn.”, but here’s the trick: we’re not putting any content inside the object element! A few posts back I did a walk-through of how you can create a resize event sensor out of a few divs and well-placed scroll events – this is along those lines. I’ve created two distribution flavors for this mechanism: 1) a vanilla module that enables use without reliance on any additional dependencies, and 2) an easy-to-use Web Component created with the awesome X-Tag library.

UPDATE: I was contacted on Twitter by a fellow who suggested I use the addListener method of MediaQueryList objects to detect query matches on the object element sensors. I explored this route, but there are a few things that led me back to using dummy transitionend pings. I am happy to code up a version that uses MQL listeners, but here are a few things to consider:

  • It reduces browser support: you lose all of Android below version 4
  • MQL listeners are still shaky: https://bugs.webkit.org/show_bug.cgi?id=75903 – http://stackoverflow.com/questions/16694591/media-query-doesnt-change-css-when-maximizing-browser-and-switching-tabs/16844712#16844712
  • Hold on a bit longer!: They’ll be reliable soon, I’d estimate another 6-12 months

Both versions of the Element Query code work in any browser that supports CSS Transitions. This is a generous compatibility range that covers all “app-ready” browsers. Let me know if you encounter any issues using the GitHub issue areas under each of the repositories listed at the end of the article.

The Vanilla Module

The plain ol’ code module comes with the following features:

  • Two methods for manually attaching and detaching the Element Query object sensor – attachQuerySensor() and detachQuerySensor()
  • Automatic DOM ready attachment of all non-style/link elements that have a media="" attribute
  • Automatic bootstrapping of dynamically create elements when you add a media="" attribute
The HTML

Let’s imagine I have a section element that contains a ul. I want to style the list differently when the container becomes smaller than 300px. The HTML structure below is what this scenario would look like if the elements had already been parsed by the Element Query module (triggered by the presence of the media="" attribute):

  • One
  • Two
  • Three

So what’s that object element doing in there? How’s that going to help with anything? The media="" attribute on the section element is how you declare your Element Query rules. There are two arguments for the media attribute’s query() function syntax. The first is an identifying query name that will be added to the matched-media="" attribute when its corresponding CSSMediaRule is matched within the object sensor. As the user, all you need to worry about is adding queries to the media attribute, and styling based on the matched-media attribute, all the rest happens automatically.

The CSS

Once a query is matched, the name you gave the query will be added to the matched-media attribute. It’s a space separated list, so if multiple are matched, you would use it in CSS just like other attributes of this sort, class="" for instance. Here’s a post by Chris Coyier on all the ways you can style elements based on their attribute values: http://css-tricks.com/attribute-selectors/. Here’s an example of what writing CSS against an Element Query match looks like, based on the HTML example content above:

section[matched-media~="small-width"] {
  font-size: 50%; /* small text for a wee lil element! */
}

/*** Example for styling multiple matches: ***/

section[matched-media~="small-width medium-height"] {
  ...
}

A few caveats with this version:

  • If you set the innerHTML of an element, and that HTML contains an element that has the media="" attribute, it will not be element-quererized. This is something that is automatic when you use the Web Component version below. To augment the element with the query sensor, you’ll need to call the window method attachQuerySensor(ELEMENT_REF), passing the element as the first argument.
  • You must take care not to inadvertently remove the object element from the element-quererized parent. If you do this, it will no longer be able to sense changes and determine query matches. The most common ways this can occur are using innerHTML to blow-out content, or a DOM library method to empty an element. One strategy to avoid this, is always using a single child element inside the target element and using that for content CRUDing.

The Element Query Web Component

To make things even easier, I’ve created a Web Component Custom Element called x-querybox using X-Tag. This component utilizes the same mechanism described above, but also provides enhanced ergonomics, matched media listeners, and automatic retention of the object sensor when doing DOM manipulation – and since we’re using X-Tag, it’s actually smaller in size than the vanilla version! Let’s explore how it’s used:

The HTML (same as above, besides the custom element)
  • One
  • Two
  • Three

The CSS (also the same)
x-querybox[matched-media~="small-width"] {
  font-size: 50%; /* small text for a wee lil querybox! */
}
Moar goodies! The mediachange custom event
document.querySelector('x-querybox').addEventListener('mediachange', function(e){
  // the event detail property is an array of the active element queries
  if (e.detail.indexOf('small-width') > -1) {
    // the 'small-width' query is active, do some smally-widthy stuff!
  }
});

Element Queries want to be used by you

Checkout the demo, and go grab the code. Feel free to contribute to either of the repositories using their respective GitHub Issues area. Happy queryin’ folks!

Demo

The demo is based on the Web Component version of the code to show both the basic and extended features. It’s only meant to give you a general idea of what is possible. The shapes are style with percentage units, so you can resize the window to expand them, or grow them with a tap (via :hover CSS styles). As the shapes progress through their size changes, you’ll notice the text and background colors change to indicate they have hit a new break-point – this is all based on their individual, element-scoped queries. If you open the console, you will notice I am logging all the `mediachange` events that occur. The demo is more impressive on a larger screen, where you can test all the query changes: Element Queries Demo

Repos

I have two different repositories on my Github profile, one for the vanilla version, and one for the x-querybox X-Tag Web Component:

Cross-Browser, Event-based, Element Resize Detection

UPDATE: This post has seen a significant change from the first version of the code. It now relies on a much simpler method: a hidden object element that relays its resize event to your listeners.

DOM Elements! Y U No Resize Event?

During your coding adventures, you may have run into occasions where you wanted to know when an element in your document changed dimensions – basically the window resize event, but on regular elements. Element size changes can occur for many reasons: modifications to CSS width, height, padding, as a response to changes to a parent element’s size, and many more. Before today, you probably thought this was mere unicorn lore, an impossible feat – well buckle up folks, we’re about to throw down the gauntlet.

Eye of Newt, and Toe of Frog

The following is the script provides two methods that take care of everything. To enable our resize listening magic, we inject an object element into the target element, set a list of special styles to hide it from view, and monitor it for resize – it acts as a trigger for alerting us when the target element parent is resized. The first method the script provides is addResizeListener, it manages all your listeners and monitors the element for resize using the injected object element. The other method is removeResizeListener, and it ensures that your listeners are properly detached when you want them removed.

(function(){
  var attachEvent = document.attachEvent;
  var isIE = navigator.userAgent.match(/Trident/);
  console.log(isIE);
  var requestFrame = (function(){
    var raf = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame ||
        function(fn){ return window.setTimeout(fn, 20); };
    return function(fn){ return raf(fn); };
  })();
  
  var cancelFrame = (function(){
    var cancel = window.cancelAnimationFrame || window.mozCancelAnimationFrame || window.webkitCancelAnimationFrame ||
           window.clearTimeout;
    return function(id){ return cancel(id); };
  })();
  
  function resizeListener(e){
    var win = e.target || e.srcElement;
    if (win.__resizeRAF__) cancelFrame(win.__resizeRAF__);
    win.__resizeRAF__ = requestFrame(function(){
      var trigger = win.__resizeTrigger__;
      trigger.__resizeListeners__.forEach(function(fn){
        fn.call(trigger, e);
      });
    });
  }
  
  function objectLoad(e){
    this.contentDocument.defaultView.__resizeTrigger__ = this.__resizeElement__;
    this.contentDocument.defaultView.addEventListener('resize', resizeListener);
  }
  
  window.addResizeListener = function(element, fn){
    if (!element.__resizeListeners__) {
      element.__resizeListeners__ = [];
      if (attachEvent) {
        element.__resizeTrigger__ = element;
        element.attachEvent('onresize', resizeListener);
      }
      else {
        if (getComputedStyle(element).position == 'static') element.style.position = 'relative';
        var obj = element.__resizeTrigger__ = document.createElement('object'); 
        obj.setAttribute('style', 'display: block; position: absolute; top: 0; left: 0; height: 100%; width: 100%; overflow: hidden; pointer-events: none; z-index: -1;');
        obj.__resizeElement__ = element;
        obj.onload = objectLoad;
        obj.type = 'text/html';
        if (isIE) element.appendChild(obj);
        obj.data = 'about:blank';
        if (!isIE) element.appendChild(obj);
      }
    }
    element.__resizeListeners__.push(fn);
  };
  
  window.removeResizeListener = function(element, fn){
    element.__resizeListeners__.splice(element.__resizeListeners__.indexOf(fn), 1);
    if (!element.__resizeListeners__.length) {
      if (attachEvent) element.detachEvent('onresize', resizeListener);
      else {
        element.__resizeTrigger__.contentDocument.defaultView.removeEventListener('resize', resizeListener);
        element.__resizeTrigger__ = !element.removeChild(element.__resizeTrigger__);
      }
    }
  }
})();

Demo-licious!

Here’s a pseudo code usage of the method.

var myElement = document.getElementById('my_element'),
    myResizeFn = function(){
        /* do something on resize */
    };
addResizeListener(myElement, myResizeFn);
removeResizeListener(myElement, myResizeFn);

Cut to the chase, let’s see this resize thang in action: Demo of resize listeners

Resize ALL The Things!

Now that we’re equipped with a nifty, cross-browser element resize event, what would it be good for? Here’s a few possible uses:

  • Resize-proof Web Component UI development
  • Per-element responsive design
  • Size-based loading of content
  • Anything you can imagine!

© 2025 Back Alley Coder

Theme by Anders NorenUp ↑