Combining position: sticky; with overflow: scroll;

Figure: position: sticky; and overflow: scroll;, a quirky combination … but it can be fixed!

Dannie Vinther:

Say we want an overflowing table of columns and rows with sticky headings on a page. We want the headings to stick while scrolling on the document window, and we want to be able to scroll horizontally within the overflowing container.

When working with overflows you might find that your sticky element isn’t so sticky after all, which may cause some frustration. The browser doesn’t seem to be respecting position: sticky; once we add overflow to the mix.

The solution is to use two scroll containers and sync up their scrolling position using a tad of JavaScript:

See the Pen Position Sticky Table with overflow by Dannie Vinther (@dannievinther) on CodePen.

Let’s hope this quirky combination gets fixed in CSS itself. Until then we’ll need this JS-based solution.

position: stuck; — and a Way to Fix It →
syncscroll (GitHub) →

❓ Not familiar with position: sticky;? Check out this introduction then.

Aladdin Trailer

Disney’s Aladdin (1992) is getting a live-action remake. Today the trailer got released:

I was 9 when the original Aladdin came out. I can sing along to all of its songs by heart. So yeah, I’m quite the sucker for this re-make. The trailer looks quite promising so I’m starting to think that they won’t have f*cked it up too much (unlike what they did with that Beauty and the Beast remake).

Browse the web like it’s 1990: CERN 2019 WorldWideWeb Rebuild


Figure: WorldWideWeb, with the homepage of bram.us loaded

Today the web turned 30. Perfect time to mention that back in February a small team of people have worked on a rebuild of the original WorldWideWeb application – the world’s first browser – which was used to access the web back then.

In December 1990, an application called WorldWideWeb was developed on a NeXT machine at The European Organization for Nuclear Research (known as CERN) just outside of Geneva. This program – WorldWideWeb — is the antecedent of most of what we consider or know of as “the web” today.

In February 2019, in celebration of the thirtieth anniversary of the development of WorldWideWeb, a group of developers and designers convened at CERN to rebuild the original browser within a contemporary browser, allowing users around the world to experience the rather humble origins of this transformative technology.

Jeremy Keith, who was part of that team, has a nice writeup on their adventure and its result.

To me, this project has two very interesting parts:

  1. It’s recreated using web technologies, showing (some of) the power of what the web is capable of today.

  2. The application acts a litmus test to see whether your site is built in a timeless manner or not: If your site content can be consumed using WorldWideWeb, it means that a screen-reader, browsers with JS disabled, etc. will be able to read it too.

Nowadays I see a lot of sites that are built using a JS-first state of mind. The proven concept of Progressive Enhancement is nowhere to be found, and that’s sad. The fact that these sites don’t work in WorldWideWeb is a direct result from that, and that is – to me – a red flag.

The web is timeless, and so should the sites we build be. The fact that sites which I have built also are consumable in WorldWideWeb is something I take pride in.

WorldWideWeb →

A few tips on using WorldWideWeb:

  • Go to “Document” → “Open from full document reference” to open a URL
  • Links needed double clicking back then 😉

Using the <details> element to create modals and menus

The folks over at GitHub have been leveraging the <details> element to create modals and menus:

<details class=“dropdown”>
  <summary class=“btn” aria-haspopup=“menu”>…</summary>
  <ul class=“dropdown-content”>
    <li><a href="/muan">profile</a></li>
    …
  </ul>
</details>

Very clever, as <details> trumps the <modal> element in many ways:

  • Semantic
  • Accessible
  • No JavaScript

Next to that, they’ve also released a few custom elements that make use of this technique: a <details-menu> and a <details-dialog> custom element.

Details on <details>
Details on <details> (slides)
<details-menu> element →
<details-dialog> element →

Making sense of React’s useEffect

Today Dan Abramov published an extensive deep dive into useEffect. The issue that many devs (who, including me, have been using componentDidMount before) are having, is that they now need to unlearn a few things

It’s only after I stopped looking at the useEffect Hook through the prism of the familiar class lifecycle methods that everything came together for me.

This reply-tweet made resonated quite well:

The read is really extensive (40+ minutes), but totally worth your time.

~

A few days ago, Adam Rackis has posted a nice example on his blog in which he (re)wrote a component that contains a websocket. As the websocket connection would always be reinitialised with every render, he combined useEffect with useReducer

While we could add every piece of needed state to our useEffect dependency list, this would cause the web socket to be torn down, and re-created on every update.

If we look closer, however, we might notice something interesting. Every operation we’re performing is always in terms of prior state. […] This is precisely where a reducer shines; in fact, sending commands that project prior state to a new state is the whole purpose of a reducer.

const BookEntryList = props => {
  const [state, dispatch] = useReducer(scanReducer, initialState);

  useEffect(() => {
    const ws = new WebSocket(webSocketAddress("/bookEntryWS"));

    ws.onmessage = ({ data }) => {
      let packet = JSON.parse(data);
      dispatch([packet._messageType, packet]);
    };
    return () => {
      try {
        ws.close();
      } catch (e) {}
    };
  }, []);

  //...
};

~

A neat use-case for useEffect, detailed by Sebastian De Deyne, is to reset the page number when the search query changes:

Clever 😊

A Complete Guide to useEffect →
Hooks, State, Closures, and useReducer →

JavaScript “loose” comparison, step by step

This handy tool visualizes loose comparison (==) in JavaScript works:

Below you can provide two values to compare, and see which steps of the “Abstract Equality Algorithm” as defined in Section 7.2.14 of the ECMAScript specification are executed.

JavaScript “loose” comparison, step by step →

iTunes auto-rating all played tracks …

For more than a year it’s been bugging me that iTunes “sometimes” would auto-rate played tracks. It happened on some albums, yet not all albums. Back in May 2018 I posted this video on YouTube showing the behaviour:

As you can see iTunes here automatically rates “En Masse” (track 10) from the moment it starts playing.

~

Back then I couldn’t quite put my finger on it, yet today I found out when this behaviour occurs: it happens when you’ve rated the album itself. For whatever reason iTunes copies over the album rating onto each track when you start playing it.

I don’t like this behaviour, as it’s unwanted: an album can be 5 stars, yet that does not mean all individual tracks on it are 5 stars.

(*) For the “Nachtlicht” album (from the second video) I’d make an exception though … it’s an exceptionally great album by Eefje de Visser and would highly recommend it to all who speak Belgian/Dutch!

So, Apple, can you fix this?

php-timecop – A PHP extension providing “time travel” capabilities

Now this looks handy, especially when you’re writing/testing code that’s dependent on the system’s time:

php-timecop is a PHP extension providing “time travel” and “time freezing” capabilities

  • Freeze time to a specific point.
  • Travel back to a specific point in time, but allow time to continue moving forward from there.
  • Scale time by a given scaling factor that will cause time to move at an accelerated pace.
  • Override time-related PHP stock functions and methods, which supports freezing or traveling time.
var_dump(date("Y-m-d")); // todays date
timecop_freeze(0);
var_dump(gmdate("Y-m-d H:i:s")); // string(19) "1970-01-01 00:00:00"
var_dump(strtotime("+100000 sec")); // int(100000)

php-timecop
Stub PHP date() and the crew with php-timecop