Tags: frontend

2091

sparkline

Friday, September 30th, 2022

Supporting logical properties

I wrote recently about making the switch to logical properties over on The Session.

Initially I tried ripping the band-aid off and swapping out all the directional properties for logical properties. After all, support for logical properties is green across the board.

But then I got some reports of people seeing formating issues. These people were using Safari on devices that could no longer update their operating system. Because versions of Safari are tied to versions of the operating system, there was nothing they could do other than switch to using a different browser.

I’ve said it before and I’ll say it again, but as long as this situation continues, Safari is not an evergreen browser. (I also understand that problem lies with the OS architecture—it must be incredibly frustrating for the folks working on WebKit and/or Safari.)

So I needed to add fallbacks for older browsers that don’t support logical properties. Or, to put it another way, I needed to add logical properties as a progressive enhancement.

“No problem!” I thought. “The way that CSS works, I can just put the logical version right after the directional version.”

element {
  margin-left: 1em;
  margin-inline-start: 1em;
}

But that’s not true in this case. I’m not over-riding a value, I’m setting two different properties.

In a left-to-right language like English it’s true that margin-inline-start will over-ride margin-left. But in a right-to-left language, I’ve just set margin-left and margin-inline-start (which happens to be on the right).

This is a job for @supports!

element {
  margin-left: 1em;
}
@supports (margin-inline-start: 1em) {
  element {
    margin-left: unset;
    margin-inline-start: 1em;
  }
}

I’m doing two things inside the @supports block. I’m applying the logical property I’ve just tested for. I’m also undoing the previously declared directional property.

A value of unset is perfect for this:

The unset CSS keyword resets a property to its inherited value if the property naturally inherits from its parent, and to its initial value if not. In other words, it behaves like the inherit keyword in the first case, when the property is an inherited property, and like the initial keyword in the second case, when the property is a non-inherited property.

Now I’ve got three CSS features working very nicely together:

  1. @supports (also known as feature queries),
  2. logical properties, and
  3. the unset keyword.

For anyone using an up-to-date browser, none of this will make any difference. But for anyone who can’t update their Safari browser because they can’t update their operating system, because they don’t want to throw out their perfectly functional Apple device, they’ll continue to get the older directional properties:

I discovered that my Mom’s iPad was a 1st generation iPad Air. Apple stopped supporting that device in iOS 12, which means it was stuck with whatever version of Safari last shipped with iOS 12.

Wednesday, September 21st, 2022

Will Serving Real HTML Content Make A Website Faster? Let’s Experiment! - WebPageTest Blog

Spoiler: the answer to the question in the title is a resounding “hell yeah!”

Scott brings receipts.

Remix Icon - Open source icon library

I love how easy it is to use these icons: you can copy and paste the SVG or even get it encoded as a data URL.

Tuesday, September 20th, 2022

Web UI Engineering Book - toheeb.com

I like the way this work-in-progress is organised—it’s both a book and a personal website that’ll grow over time.

Monday, September 19th, 2022

CSS { In Real Life } | Web Sustainability and the Ethical Dilemma

But is it always the case that faster websites are greener websites? We reluctantly have to consider another facet: if making a website for a car manufacturer faster leads to an increase in the number of cars sold, can we really say that our website is greener?

This is very timely for me, given that Clearleft is currently engaged on a project that’s making me decidedly queasy for this exact reason—the success metrics of the project would be net negative for the world.

Saturday, September 17th, 2022

A long-term plan for logical properties? | Miriam Eric Suzanne

Well, now I’m really glad I wrote that post about logical properties!

We’re not there yet. So how do we get there?

Well, I don’t know for sure – but articles like this are very helpful as we try to work it out!

Thursday, September 15th, 2022

Let’s get logical

I was refactoring some CSS on The Session over the weekend. I thought it would be good to switch over to using logical properties exclusively. I did this partly to make the site more easily translatable into languages with different writing modes, but mostly as an exercise to help train me in thinking with logical properties by default.

All in all, it went pretty smoothly. You can kick the tyres by opening up dev tools on The Session and adding a writing-mode declaration to the body or html element.

For the most part, the switchover was smooth. It mostly involved swapping out property names with left, right, top, and bottom for inline-start, inline-end, block-start, and block-end.

The border-radius properties tripped me up a little. You have to use shorthand like border-start-end-radius, not border-block-start-inline-end-radius (that doesn’t exist). So you have to keep the order of the properties in mind:

border-{{block direction}}-{{inline-direction}}-radius

Speaking of shorthand, I also had to kiss some shorthand declarations goodbye. Let’s say I use this shorthand for something like margin or padding:

margin: 1em 1.5em 2em 0.5em;

Those values get applied to margin-top, margin-right, margin-bottom, and margin-left, not the logical equivalents (block-start, inline-end, block-end, and inline-start). So separate declarations are needed instead:

margin-block-start: 1em;
margin-inline-end: 1.5em;
margin-block-end: 2em;
margin-inline-start: 0.5em;

Same goes for shorthand like this:

margin: 1em 2em;

That needs to be written as two declarations:

margin-block: 1em;
margin-inline: 2em;

Now I’ve said it before and I’ll say it again: it feels really weird that you can’t use logical properties in media queries. Although as I said:

Now you could rightly argue that in this instance we’re talking about the physical dimensions of the viewport. So maybe width and height make more sense than inline and block.

But along comes the new kid on the block (or inline), container queries, ready to roll with container-type values like inline-size. I hope it’s just a matter of time until we can use logical properties in all our conditional queries.

The other place where there’s still a cognitive mismatch is in transforms and animations. We’ve got a translateX() function but no translate-inline(). We’ve got translateY() but no translate-block().

On The Session I’m using some JavaScript to figure out the details of some animation effects. I’m using methods like getBoundingClientRect(). It doesn’t return logical properties. So if I ever want to adjust my animations based on writing direction, I’ll need to fork my JavaScript code.

Oh, and one other thing: the aspect-ratio property takes values in the form of width/height, not inline/block. That makes sense if you’re dealing with images, videos, or other embedded content but it makes it really tricky to use aspect-ratio on elements that contain text. I mean, it works fine as long as the text is in a language using a top-to-bottom writing mode, but not for any other languages.

Wednesday, September 14th, 2022

The self-fulfilling prophecy of React - Josh Collinsworth blog

Matcalfe’s Law in action:

Companies keep choosing React because they know there’s a massive pool of candidates who know it; candidates keep learning React because they know companies are hiring for it. It’s a self-sustaining cycle.

But the problem is:

React isn’t great at anything except being popular.

Sunday, September 11th, 2022

Giving your future self a little credit with progressive enhancement - Blog - Pixo | Apps, websites, and software development

We often talk about technical debt — the costs we’ll need to pay in the future when we make short-term compromises. Progressive enhancement is the opposite of that — a sort of technical credit that will make things easier for us in the future.

A good explanation of how progressive enhancement works perfectly with the idea of a minimal viable product:

We focus first on a core experience that delivers what your users are looking for, and then we start adding enhancements that will delight them.

Thursday, September 8th, 2022

How To Improve Largest Contentful Paint for Faster Load Times - Calibre

A no-nonsense checklist of good performance advice from Karolina.

as days pass by — Farmbound, or how I built an app in 2022

Stuart writes up the process up making a mobile game as a web app—not a native app. The Wordle effect reverberates.

It’s a web app. Works for everyone. And I thought it would be useful to explain why it is, why I think that’s the way to do things, and some of the interesting parts of building an app for everyone to play which is delivered over the web rather than via app stores and downloads.

TIL: You Can Access A User’s Camera with Just HTML

The capture attribute is pretty nifty—and I just love that you get so much power in a declarative way:

<input type="file" accept="image/*" capture="environment">

Tuesday, September 6th, 2022

Why your website should work without Javascript. | endtimes.dev

The obvious answer to why you should build a website that doesn’t need js is… because some people don’t use js. But how many?!

Thursday, September 1st, 2022

Complex conditional width using flex-basis with clamp: Every Layout

Okay, combining flex-basis and clamp() is pretty cool!

Tuesday, August 30th, 2022

Bring Focus to the First Form Field with an Error :: Aaron Gustafson

A handy little script from Aaron to improve the form validation experience.

html energy

Can you feel the energy?

Wednesday, August 24th, 2022

Lean Web Club

New from Mr. Vanilla JS himself, Chris Ferdinandi:

A learning space for people who hate the complexity of modern web development.

It’ll be $29 a month or $299 a year (giving you two months worth for free).

Monday, August 22nd, 2022

Using :has() as a CSS Parent Selector and much more | WebKit

A terrific tour of just some of the fantastic ways you can use :has() in CSS.

The section on using it with sibling selectors blew my mind:

How often have you wanted to adjust the margins on a headline based on the element following it? Now it’s easy. This code allows us to select any h2 with a p immediately after it.

h2:has(+ p) { margin-bottom: 0; }

Amazing.

The web is a harsh manager - daverupert.com

Dave laments the increasing number of complex jobs involved in front-end (or “full-stack”) development.

But whereas I would just leave at that, Dave does something constructive and points to a potential solution—a corresponding increase of more thinsliced full-time roles like design engineering, front-end ops, and CSS engineering.

Thursday, August 18th, 2022

system.css | A design system for building retro Apple-inspired interfaces

A stylesheet for when you’re nostalgic for the old Mac OS.