CategoryWeb

All things Webby!

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.

Continue reading

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

Continue reading

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.

Continue reading

CSS Selector Listeners

The following article explores a new event mechanism that I like to call CSS Selector Listeners. Selector listeners are completely bad ass, and sufficiently indistinguishable from magic, as you will soon find out.

Rise of the Mutants

Developers recently were empowered with a new way to listen for changes in the DOM: DOM Level 4 Mutation Observers. Mutation Observers emit fairly general events that tell you basic things, like when a new element has entered the DOM, or an attribute has changed on an element or subtree you are observing.

As a result of their relatively low detail resolution, developers have created libraries to help make Mutation Observers more useful for developers. Rafael Weinstein of Google recently introduced a library called Mutation Summary, which lets you watch the DOM through the lens of a limited subset of CSS selectors using a combination of Mutation Observers and its own custom logic layer to filter and interpret mutation events. The concept of listening to selector matches is intriguing because selectors inherently require the parser to quickly assess complex DOM conditions and perform selector-related logic to check for matches. Having the ability to listen for when selector states become active would be a powerful tool indeed!

A Hidden World of Events

Mutation Summary is pretty cool, but what if I told you there was a hidden world of arcane CSS selector event magic living in your browser that offered unlimited, detailed insight into the state of the DOM? Well there is, and technically there always was, in every style sheet you’ve ever written. All we needed was the right key to access this world…well, a Keyframe, to be exact.

Piggybacking the Parser, with Keyframes

I recently posted a method for using CSS Animation Keyframes to detect node insertions via the animationstart event of a dummy keyframe animation. Now let’s take a second to realize what this hack really is at its core: the ability to listen for any selector-based matches the CSS parser makes anywhere in the DOM. The Selector Listener code I’ve developed provides two methods, addSelectorListener and removeSelectorListener. These methods are available at both document and element level, and allow you to listen for any selector match, regardless of complexity. Once the parser detects a matched selector, the event bubbles up the DOM from the matched target element to the element or document the selector listener is attached to. Here’s what it looks like in action:

// Some action to perform when a match occurs
var sequenceMatch = function(){
  alert("Selector listeners, they're easy as A, B, C!");
};

// Attaching your selector listener to the document or an element
document.addSelectorListener('.one + .two + .three', sequenceMatch);

// Remove the selector listener when it is no longer needed
document.removeSelectorListener('.one + .two + .three', sequenceMatch);

The Goods: Code & Demo

The code that provides all this new hotness, as well as more examples of what’s possible, is available on Github here: SelectorListener Code Repo

You can also play around a bit with this demo page: SelectorListener Demo

A Modal Cure in Pure CSS – No Wrappers, no JavaScript, no BS

Modals. They’ve been the subject of countless hacks over the years (I did a cross-browser one a while ago here), but due to cross-browser considerations, they usually are less than elegant in their implementation.

Well, if you don’t care about IE < 9, things are about to get much, much easier. This little trick is so simple it’s going to make you cry, in fact it’s so easy, it may cause you to audibly curse IE louder and more passionately than you ever have:


#modal {
    display: block;
    position: fixed;
    top: 50%;
    left: 50%;
    box-sizing: border-box;
    transform: translate(-50%, -50%);
}

Here’s a fiddle so you can see it in action:

Yeah I know, all those hours wasted on wrapper divs, tables, crazy CSS, and performance-robbing JS, all to get hoodwinked by some top/left positioning and a transform property, go figure.

I Want a DAMNodeInserted Event!

Have DOM Level 3 Mutation Events got you down?

There’s a long, sordid history behind DOM Level 3 Mutation Events. They’re basically the DOM Event equivalent of crack for developers: a ridiculous high of programmatic, dynamic handling of DOM manipulation, with a crash of endless, unavoidable, performance-destroying event evaluation.

John Resig detailed the plight of DOM Mutation Events in a mailing list thread, circa 2009:

Yes, DOM mutation events already exist (in Firefox and Opera – fairly reliably – and dicey in Safari). They have a huge problem, though:

They absolutely cripple DOM performance on any page which they’re enabled.

Firefox, for example, when it realizes that a mutation event has been turned on, instantly goes into an incredibly-slow code path where it has to fire events at every single DOM modification. This means that doing something like .innerHTML = “foo” where it wipes out 1000 elements would fire, at least 1000 + 1 events (1000 removal events, 1 addition event).

Mutation Events have since been deprecated, and browsers have not implemented any sort of replacement…but unknowingly, they actually have 😉

But wait! An epic hack emerges!

What I’m going to present below is a hack in the truest sense of the word, but damn, is it cool. The method I’ve devised provides the same functionality DOMNodeInserted offered, without requiring you to annihilate browser performance in the process – and it is very likely to work for a long, long time.

The Description

Basically what we’re going to do is setup a CSS keyframe sequence that targets (via your choice of CSS selector) whatever DOM elements you want to receive a DOM node insertion event for. I used a relatively benign and little used css property, clip I use outline-color in an attempt to avoid messing with intended page styles – the code once targeted the clip property, but it is no longer animatable in IE as of version 11. That said, any property that can be animated will work, choose whichever one you like.

Next I added a document-wide animationstart listener that I use as a delegate to process the node insertions. The animation event has a property called animationName on it that tells you which keyframe sequence kicked off the animation. Just make sure the animationName property is the same as the keyframe sequence name you added for node insertions and you’re good to go.

The Demo

That’s about it, pretty simple huh? Let’s see it in action – notice that the text in the divs isn’t added until their insertion into the DOM is detected:

Party time, excellent!

There you have it folks, a scope-able, performant, relatively simple method for DOM node insertion listeners in all browsers that support CSS3 Animations.

In related news: I will be accepting donations in the form of Jamba Juice gift cards, or pure gold bullion if you’re feeling especially generous.

© 2024 Back Alley Coder

Theme by Anders NorenUp ↑