Snippets

CSS Motion Path

Motion Path is a CSS module that allows authors to animate any graphical object along a custom path.

The idea is that when you want to animate an element moving along a path, you previously only had animating translation, position, etc. at your disposal, which wasn’t ideal and only allowed for simple movements. With offset-path you can define a specific path of any shape you want. You then animate it along that path by animating offset-distance, and can choose to rotate it at any point using offset-rotate.

Code language: CSS

#motion-demo {
  offset-path: path('M20,20 C20,100 200,0 200,100');
  animation: move 3000ms infinite alternate ease-in-out;
  width: 40px;
  height: 40px;
  background: cyan;
}
 
@keyframes move {
  0% {
    offset-distance: 0%;
  }
  100% {
    offset-distance: 100%;
  }
}

Brutalist Web Design

The term brutalism is often associated with Brutalist Architecture, however it can apply to other forms of construction, such as web design.

[…]

The term brutalism is derived from the French béton brut, meaning “raw concrete”. Although most brutalist buildings are made from concrete, we’re more interested in the term raw. Concrete brutalist buildings often reflect back the forms used to make them, and their overall design tends to adhere to the concept of truth to materials.

A website’s materials aren’t HTML tags, CSS, or JavaScript code. Rather, they are its content and the context in which it’s consumed. A website is for a visitor, using a browser, running on a computer [or mobile device] to read, watch, listen, or perhaps to interact. A website that embraces Brutalist Web Design is raw in its focus on content, and prioritization of the website visitor.

Brutalist Web Design is honest about what a website is and what it isn’t. A website is not a magazine, though it might have magazine-like articles. A website is not an application, although you might use it to purchase products or interact with other people. A website is not a database, although it might be driven by one.

They list the following principles:

In defence of boring UX

The Pale King, the late David Foster Wallace’s final novel, was published in 2011. It’s about IRS employees in Peoria, Illinois

And it’s incredibly boring.

I’m not being cruel — The Pale King contains an intricate description of a traffic jam, a long list of tax forms, and an entire chapter devoted to mundane office tasks. As Michael Pietsch, the book’s editor notes, “David set out to write a novel about some of the hardest subjects in the world — sadness and boredom.”

Defending boring UX is a slightly easier task. I just want to get you excited about the invisible, unsung work required to build useful and understandable digital products that truly satisfy user needs.

Boring defined

Boring user experience is clear and straightforward content, design, and code that solves key pain points. No surprise. No delight. It’s the non-design of IA Writer or the simple poetry of plain language.

Unboring is an error message that requires a PhD to unpack or Microsoft Word’s everything-plus-the-kitchen-sink approach to software.

[…]

Boring UX emerged in 2012 with the launch of GOV.UK, a government site that proved straightforward digital design can improve the lives of millions of people. As the jury who awarded the site Design of the Year 2013 put it, “It may not look particularly exciting or pretty, but that is not the point. This is design in the raw, providing vital services and information in the simplest, most logical way possible.”

[…]

Boring doesn’t always save lives, but it usually improves them. The titans of the web — Wikipedia, Reddit, Google, Amazon, Dropbox, GitHub — look boring when compared to Snapchat, The Outline, or Bejeweled. But boring companies have millions of repeat users because their products actually work.

[…]

“Only when a product is functional, reliable, and usable can users appreciate the delightful, pleasurable, or enjoyable aspects of the experience,” notes Fessenden. In other words, boring underpins delight — and sometimes boring is delightful. Popular apps like Pocket and Instapaper, along with Safari’s reader view, turn exciting into boring by rescuing content from the evil clutches of hyperactive design and indestructible retargeting ads.

[…]

If you’re truly user-centric, admit that the most meaningful life stuff happens beyond the borders of tiny glowing rectangles. UX folks are brokers and intermediaries, not rock stars or ninjas. Your job is to swallow some boredom so people can live better lives.

And if that sounds a bit dreary, remember the words of David Wallace in The Pale King: “If you are immune to boredom, there is literally nothing you cannot accomplish.”

When text truncation fails

I understand that it’s tough to get people excited about boring tools and approaches, especially invisible things like semantic HTML, edge cases, and truncation. But without foundational, behind-the-scenes work, products and features can break in terrible ways. Just ask Karen McGrane. She’s an accomplished digital strategist who has spent the past few years warning the UX community that truncation is not a content strategy. But people continue to ignore her, even though she’s written not one, but two great books.

Why? Because solving for truncation is low glory work. To be blunt, it’s a pain in the ass. But Karen is right. And when truncation fails, it can be far more painful:

Tags

Apple's subtle anti-competitive practices and the web

Apple has a history of stunting the web’s progress on its platforms. On iOS, Apple doesn’t allow fully independent third-party browsers, requiring all apps to leverage its Safari browser when rendering web-based content. While browsers like Chrome and Opera are available in the App Store, they must use Apple’s Safari browser behind the scenes to render web pages, rather than their own. That means Apple has a monopoly on how iPhone and iPad users access the web. To push developers toward building native apps on iOS rather than using web technologies, Apple ignores popular parts of the open web specification that other browsers implement, to its own benefit.

A technology called WebRTC, for example, allows video calling in a web browser without additional software. It powers tools like Google Meet. But Apple was incredibly slow to implement the specification, leaving out key pieces of functionality, and the technology didn’t work when embedded inside apps.

Apple also handicapped an emerging standard called Progressive Web Apps (PWAs) — which, like Electron, allows developers to build native-like apps for both desktop and mobile — by partially implementing it in a way that makes it too inconsistent to rely on. PWA doesn’t have the same problem if users open apps in Chrome or Firefox, but iPhone and iPad users can’t install third-party browsers, which makes PWA-based technology a non-starter.

[…]

Apple’s subtle, anti-competitive practices don’t look terrible in isolation, but together they form a clear strategy: Make it so painful to build with web-based technology on Apple platforms that developers won’t bother. Now that the App Store is not accepting apps built using Electron, developers will likely find creative ways to work around it, but Apple is setting up for a continual cat-and-mouse game as it plans to exert more control over which apps can run on the platform in the future.

Drupal Composer scaffold file prepending and appending

The file-mapping configuration setting consists of a map from the destination path of the file to scaffold to a set of properties that control how the file should be scaffolded.

The available properties are as follows:

  • mode: One of “replace”, “append” or “skip”.
  • path: The path to the source file to write over the destination file.
  • prepend: The path to the source file to prepend to the destination file, which must always be a scaffold file provided by some other project.
  • append: Like prepend, but appends content rather than prepends.
  • overwrite: If false, prevents a replace from happening if the destination already exists.

The mode may be inferred from the other properties. If the mode is not specified, then the following defaults will be supplied:

  • replace: Selected if a path property is present, or if the entry’s value is a string rather than a property set.
  • append: Selected if a prepend or append property is present.
  • skip: Selected if the entry’s value is a boolean false.

Examples:

"file-mapping": {
  "[web-root]/sites/default/default.settings.php": {
    "mode": "replace",
    "path": "assets/sites/default/default.settings.php",
    "overwrite": true
  },
  "[web-root]/sites/default/settings.php": {
    "mode": "replace",
    "path": "assets/sites/default/settings.php",
    "overwrite": false
  },
  "[web-root]/robots.txt": {
    "mode": "append",
    "prepend": "assets/robots-prequel.txt",
    "append": "assets/robots-append.txt"
  },
  "[web-root]/.htaccess": {
    "mode": "skip",
  }
}

Mike Taylor - A case for browser-engine diversity... - View Source 2019

Given the recent demise of Presto and EdgeHTML rendering engines, and dominant market share growth for Chrome (and its Chromium engine), can we make a case for browser engine diversity in a decreasingly diverse browser engine world? In this talk, we’ll talk about web compatibility, interoperability, the web standards process, and hopefully conclude that we should care about these things in 2019.

Equal height rows in CSS Grid Layout

Great answer by Michael_B on Stack Overflow:

Short Answer

If the goal is to create a grid with equal height rows, where the tallest cell in the grid sets the height for all rows, here’s a quick and simple solution:

  • Set the container to grid-auto-rows: 1fr

How it works

Grid Layout provides a unit for establishing flexible lengths in a grid container. This is the fr unit. It is designed to distribute free space in the container and is somewhat analogous to the flex-grow property in flexbox.

If you set all rows in a grid container to 1fr, let’s say like this:

grid-auto-rows: 1fr;

… then all rows will be equal height.

It doesn’t really make sense off-the-bat because fr is supposed to distribute free space. And if several rows have content with different heights, then when the space is distributed, some rows would be proportionally smaller and taller.

Except, buried deep in the grid spec is this little nugget:

7.2.3. Flexible Lengths: the fr unit

When the available space is infinite (which happens when the grid container’s width or height is indefinite), flex-sized (fr) grid tracks are sized to their contents while retaining their respective proportions.

The used size of each flex-sized grid track is computed by determining the max-content size of each flex-sized grid track and dividing that size by the respective flex factor to determine a “hypothetical 1fr size”.

The maximum of those is used as the resolved 1fr length (the flex fraction), which is then multiplied by each grid track’s flex factor to determine its final size.

So, if I’m reading this correctly, when dealing with a dynamically-sized grid (e.g., the height is indefinite), grid tracks (rows, in this case) are sized to their contents.

The height of each row is determined by the tallest (max-content) grid item.

The maximum height of those rows becomes the length of 1fr.

That’s how 1fr creates equal height rows in a grid container.


Why flexbox isn’t an option

As noted in the question, equal height rows are not possible with flexbox.

Flex items can be equal height on the same row, but not across multiple rows.

This behavior is defined in the flexbox spec:

6. Flex Lines

In a multi-line flex container, the cross size of each line is the minimum size necessary to contain the flex items on the line.

In other words, when there are multiple lines in a row-based flex container, the height of each line (the “cross size”) is the minimum height necessary to contain the flex items on the line.