FIX: The provider “cPanel (powered by Sectigo)” cannot currently accept incoming requests. The system will try again later.

A while back I noticed my cPanel/WHM server was struggling with renewing certificates through its AutoSSL feature. The error I got back was this:

The “cPanel (powered by Sectigo)” provider cannot currently accept incoming requests. The system will try again later.

Scouring the web for solutions I found some potential ones such as chmod’ing some directories and running autorepair scripts but none of that seemed to the trick.

The solution that eventually did the trick for me was to simply ditch Sectigo and use Let’s Encrypt™ instead. The switch is easy, as there’s a cPanel plugin which you can install pretty easily:

  1. Log in to the server as the root user.

  2. Run the following command:

    /usr/local/cpanel/scripts/install_lets_encrypt_autossl_provider
  3. Log in to WHM and navigate to the Manage AutoSSL interface (WHM » Home » SSL/TLS » Manage AutoSSL).

  4. In the Providers tab, select the Let’s Encrypt™ option. The interface will display the Terms of Service section.

  5. Review Let’s Encrypt’s terms of service. If you agree, select the I agree to these terms of service option.

  6. Click Save.

Once enabled, re-run AutoSSL and all should be fine again.

~

Did this help you out? Like what you see?
Thank me with a coffee.

I don't do this for profit but a small one-time donation would surely put a smile on my face. Thanks!

☕️ Buy me a Coffee (€3)

To stay in the loop you can follow @bramus or follow @bramusblog on Twitter.

Style a parent element based on its number of children using CSS :has()

In CSS it’s possible to style elements based on the number of siblings they have by leveraging the nth-child selector.

But what if you want to style the parent element based on the number of children? Well, that where the CSS :has() selector comes into play.

~

# The code

If you’re just here for the code, here it is. You can also see it in action in the demo below.

/* At most 3 (3 or less, excluding 0) children */
ul:has(> :nth-child(-n+3):last-child) {
	outline: 1px solid red;
}

/* At most 3 (3 or less, including 0) children */
ul:not(:has(> :nth-child(3))) {
	outline: 1px solid red;
}

/* Exactly 5 children */
ul:has(> :nth-child(5):last-child) {
	outline: 1px solid blue;
}

/* At least 10 (10 or more) children */
ul:has(> :nth-child(10)) {
	outline: 1px solid green;
}

/* Between 7 and 9 children (boundaries inclusive) */
ul:has(> :nth-child(7)):has(> :nth-child(-n+9):last-child) {
	outline: 1px solid yellow;
}

If you want to know how it works, keep on reading 🙂

~

# The selectors

The pattern of each selector built here is this:

parent:has(> count-condition) {
	…
}
  • By using parent:has() we can select the parent element that meets a certain condition for its children.
  • By passing > into :has(), we target the parent’s direct children.
  • The count-condition is something we need to come up with for each type of selection we want to do. Similar to Quantity Queries, we’ll leverage :nth-child() for this.

☝️ Although the :has() selector is often called the parent selector, it is way more than that.

At most x children

By using :nth-child with a negative -n it’s possible to select the first x children. If one of those is also the very last child, you can detect if a parent has up to x children

/* At most 3 (3 or less, excluding 0) children */
ul:has(> :nth-child(-n+3):last-child) {
	outline: 1px solid red;
}

This selector excludes parents that have no children. This is fine in most cases – as any element that only contains text would be matched – but if you do want to include use this selector instead:

/* At most 3 (3 or less, including 0) children */
ul:not(:has(> :nth-child(3))) {
	outline: 1px solid red;
}

Exactly x children

To select item x from a set you can use :nth-child without any n indication. If that child is also the last child, you know there’s exactly x children in the parent

/* Exactly 5 children */
ul:has(> :nth-child(5):last-child) {
	outline: 1px solid blue;
}

At least x children

To select a parent with a least x children, being able to select child x in it is enough to determine that. No need for :last-child here.

/* At least 10 (10 or more) children */
ul:has(> :nth-child(10)) {
	outline: 1px solid green;
}

Between x and y children

To do a between selection, you can combine two :has() conditions together. The first one selects all elements that have x or more children, whereas the second one cuts off the range by only allowing elements that have no more than y children. Only elements that match both conditions will be mathed:

/* Between 7 and 9 children (boundaries inclusive) */
ul:has(> :nth-child(7)):has(> :nth-child(-n+9):last-child) {
	outline: 1px solid yellow;
}

~

# Demo

See the Pen Styling parent elements based on the number of children with CSS :has() by Bramus (@bramus) on CodePen.

~

# Browser Support

These selectors are supported by all browsers that have :has() support. At the time of writing this does not include Firefox.

Flipping on the experimental :has() support in Firefox doesn’t do the trick either. Its implementation is still experimental as it doesn’t support all types of selection yet. Relative Selector Parsing (i.e. a:has(> b)) is one of those features that’s not supported yet – Tracking bug: #1774588

~

# Spread the word

To help spread the contents of this post, feel free to retweet its announcement tweet:

~

🔥 Like what you see? Want to stay in the loop? Here's how:

Scroll-Linked Animations with ScrollTimeline and ViewTimeline

In the latest episode of HTTP 203 I share my excitement with Jake about Scroll-Linked Animations with ScrollTimeline and ViewTimeline, a feature I’ve been tracking for almost two years now.

A lot has changed since I first wrote about it, as the specification has undergone a major rewrite. This episode should get you up to speed with everything:

Not covered in the episode – as it wasn’t ready back when it was recorded – is that Chrome 108 has experimental support for CSS scroll-timeline and view-timeline! It’s only a partial implementation at the time of writing, but nonetheless this is already very – VERY! – exciting news. The Firefox folks are also working on it.

~

The demo I’m still the most proud of, is this Cover Flow recreation using only HTML and CSS. I recently also gave a lightning talk about it at Full Stack Europe.

~

Here’s links to all demos (and more) shown in the episode, all hosted on CodePen:

I’ve also bundled all demos into two CodePen collections:

~

🔥 Like what you see? Want to stay in the loop? Here's how:

CSS Type Grinding: Casting Tokens (sm|md|etc) into Useful Values (aka Style Queries without Style Queries thanks to @property)

My favorite use case for Style Queries is the ability to change a bunch of styles based on the value of a so called “higher-order variable”. You use that variable as a switch to change a bunch of properties.

@container style(--theme: dark) {
  .card {
    background: royalblue;
    border-color: navy;
    color: white;
  }

  .card button {
    border-color: navy;
    background-color: dodgerblue;
    color: white;
  }
}

Current issue with Style Queries though is that:

  1. You need browser support (which is Chrome Canary only at the time of writing)
  2. Only parent elements can be containers that children can query. There is no way to have an element be both the container and the querying child targeting self (because: cycles)

While the first issue should get fixed over time, the second one never will …

~

Last week, Jane Ori surprised me a wonderful post that tackled the latter issue. Leveraging @property, they were able to implement Higher-Order Variables that work on the element itself! The technique is called Type Grinding:

Type Grinding allows your design tokens (keywords, or “<custom-ident>” values) written in your CSS to be transformed into any other values – like width, padding, color, etc – without relying on anything outside of CSS.

For example, you could have a --size Custom Property that accepts the values sm, md, or lg. Changing its value will act as a switch to change many other CSS properties, similar to Style Queries but without the need for Style Queries support!

The full code to achieve it is detailed in the post by Jane. It starts of with registering the --size with only its allowed values:

@property --size {
  syntax: "sm|md|lg";
  initial-value: md;
  inherits: true;
}

Based on the value of --size, it’s possible to have more properties that output a 1 or a 0:

@property --_sm-else-0 {
  syntax: "sm|";
  initial-value: 0;
  inherits: true;
}
@property --_if-sm-then-1-else-0 {
  syntax: "";
  initial-value: 1;
  inherits: true;
}

.type-grinding {
  --size: md;
  --_sm-else-0: var(--size);
  --_if-sm-then-1-else-0: var(--_sm-else-0);
}

With that at the base, Jane builds things up further, finally achieving the Type Grinding. Apart from being somewhat complicated, the only downside of the whole approach is that it needs @property support – a feature that’s only available in Chromium-based browsers at the time of writing.

If you happen to be visiting this site using Chrome, you can try it out yourself in the demo embedded below:

See the Pen CSS-Only Badge Component via the "Type Grinding" Trick! by Jane Ori 💜 (@propjockey) on CodePen.

CSS-Only Type Grinding: Casting Tokens (sm|md|etc) into Useful Values →

Container Queries: Style Queries

Did you know CSS Container Queries are more than “check the size of a container”? Also covered by the draft spec are Style Queries which allow querying computed values of the container. Let’s take a look at what that means …

~

👨‍🔬 Style Queries are still a work in progress and only have partial experimental support in Chrome. Style Queries are not part of the initial Container Queries implementation that landed in Chromium and WebKit earlier this year.

~

# Container Queries? Style Queries? What’s the difference?

Container Queries allow authors to style elements according to aspects of a Query Container. This Query Container – or Container for short – is always a parent element.

For Size-based Container Queries, children can look at the Container’s dimensions, and act upon that. This type of Container Query works similarly to how a @media query would resolve, except that the condition will be checked against a parent element instead of the Viewport.

For Style-based Container Queries – or Style Queries for short – you can look at the styles applied onto a Container. That means you can style children conditionally, based on the Computed (!) Value of a CSS property from that Container.

💡 This post only covers Style Container Queries. Read about Size Container Queries here.

~

# Basic Example

A basic example is this one below, which changes the style of i and em elements in case the parent already is italic.

@container style(font-style: italic) {
  i,
  em {
    background: lavender;
  }
}

Note that the font-style: italic matching is done against on the computed value of the parent container.

If you’re wondering how to define a style container: you don’t. All elements are style containers by default. You don’t need to manually activate this.

~

# Use Cases

My colleague Una has a great post up on her blog that gives an overview of Style Queries and its use cases.

My favorite use case is grouping styles with higher-order variables, where you can set a bunch of CSS property values based on a Custom Property Value – Yep, just like the Higher Level Custom Properties proposal I covered a long time ago.

@container style(--theme: dark) {
  .card {
    background: royalblue;
    border-color: navy;
    color: white;
  }

  .card button {
    border-color: navy;
    background-color: dodgerblue;
    color: white;
  }
}

~

# Browser Support

💡 Although this post was originally published in October 2022, the section below is constantly being updated. Last update: October 17, 2022.

This table below shows an up-to-date list of browser support:

Chromium (Blink)

🧪 Experimental partial support available in Chromium 107. To enable it, flip the “Experimental Web Platform Features” flag through chrome://flags/.

This partial support only encloses Style Queries through Custom Properties.

Firefox (Gecko)

🚫 No support

Safari (WebKit)

🚫 No support

At the time of writing only Chrome has partial support when activating the Experimental Web Platform Features feature flag. This partial support only encloses Style Queries through Custom Properties. When visiting using Chrome, the demo below will show you two different styled boxes, all controlled by the value of the --theme Custom Property:

See the Pen Style query test — card themes by Una Kravets (@una) on CodePen.

To stay up-to-date regarding browser support, you can follow these tracking issues:

~

# More Resources

At the time of writing there are not that many resources to find, but there are some:

~

# Spread the word

To help spread the contents of this post, feel free to retweet its announcement tweet:

~

🔥 Like what you see? Want to stay in the loop? Here's how:

Automatically ignore files and folders in Dropbox with dropboxignore

If you’re using Dropbox and would like to store Git repos in your Dropbox folder, this tool is useful:

This CLI shell script aims to take advantage of glob patterns and existing .gitignore files in order to exclude specific folders and files from dropbox sync.

Never sync node_modules or vendor to Dropbox again!

dropboxignore →

100 Days Of More Or Less Modern CSS

The great Manuel Matuzović:

It’s time to get me up to speed with modern CSS. There’s so much new in CSS that I know too little about. To change that I’ve started #100DaysOfMoreOrLessModernCSS. Why more or less modern CSS? Because some topics will be about cutting-edge features, while other stuff has been around for quite a while already, but I just have little to no experience with it.

100 Days Of More Or Less Modern CSS →

Upgrading colors to HD on the web

Colors on the web are on the rise. Soon, we’ll be able to escape the sRGB prison and use more colors than ever, by tapping into color spaces such as display-p3. Safari already supports most of the new color functions and spaces, and support in Chrome is on its way.

Say you want to use these richer colors on devices that support them? How exactly would you do that? Earlier today I whipped together two patterns to achieve this. Let’s take a look.

~

# Table of Contents

~

# Hotter than hotpink

My favorite color to debug is hotpink. But with display-p3 we can have an even hotter pink if we wanted, namely color(display-p3 1 0 0.87)

Screenshot of Safari’s Color Picker showing color(display-p3 1 0 0.87).

To make our dev-lives more easier, we could put it into a custom property:

--hotterpink: color(display-p3 1 0 0.87);

To use it, we simply need to refer to its name:

:root {
  --hotterpink: color(display-p3 1 0 0.87);
  background: var(--hotterpink);  /* 🟠 Nice, but no fallback value … */
}

But what about browsers that don’t support display-p3? How can we make those browsers fall back to our “plain” hotpink?

Using a fallback value with the var() function won’t work because CSS does not check the validity of the custom property that’s being referred to – it only checks if a value (other than the guaranteed invalid value initial) has been set or not. If one is set, it won’t use the fallback.

:root {
  background: var(--hotterpink, hotpink); /* ❌ Does not work */
}

So, what now?

~

# Possible Strategies

# Using @supports

A first approach I used was to use feature detection.

@supports(background: color(display-p3 1 1 1)) {
  :root {
    --hotterpink: color(display-p3 1 0 0.87);
  }
}

:root {
  --hotpink: var(--hotterpink, hotpink);
}

With this you can use var(--hotpink) throughout your code. It will either resolve to the color(display-p3 1 0 0.87) or to hotpink, depending on support:

When the browser has support for color(display-p3 1 1 1), the custom property --hotterpink will be declared and have a value of color(display-p3 1 0 0.87)

The extra Custom Property --hotpink refers to that --hotterpink. In browsers with display-p3, that --hotpink will take over the value of --hotterpink. In browsers that don’t support display-p3 that --hotterpink won’t exist, so it will fall back to a value of hotpink.

See the Pen Move over hotpink … by Bramus (@bramus) on CodePen.

~

# Using @property

An alternative approach is to use @property to register --hotpink as a type of <color> with an initial value of hotpink, and then set its value to color(display-p3 1 0 0.87).

@property --hotpink {
  syntax: '';
  initial-value: hotpink;
  inherits: true;
}

:root {
  --hotpink: color(display-p3 1 0 0.87);
}

In browsers that don’t understand display-p3, the override will not take place, thereby leaving --hotpink to its initial-value. In browsers that do speak display-p3 the value will be set as normal.

See the Pen Move over hotpink, redux … by Bramus (@bramus) on CodePen.

💡 Note that this will only work in browsers that support @property, which are Chromium-based browsers at the time of writing.

~

# Using a Space Toggle

UPDATE: reader Jane Ori commented with a third possible way: using a Space Toggle (also see this post by Lea Verou)

The code looks like this:

@supports (background: color(display-p3 1 1 1)) {
  :root {
    --supports-display-p3: ;
  }
}

body {
  --hotterpink: var(--supports-display-p3) color(display-p3 1 0 0.87);
  --hotpink: var(--hotterpink, hotpink);
  background: var(--hotpink);
}

If no support for display-p3 is detected, --hotterpink will be undefined and become the guaranteed invalid value initial. In that case, --hotpink will fall back to hotpink

See the Pen display-p3 Progressive Color Enhancement with CSS Space Toggles! by Jane Ori 💜 (@propjockey) on CodePen.

~

# Using @media

If you thought of using @media for this, you’re out of luck. The snippet below won’t work.

:root {
  --hotpink: hotpink;
}

@media (color-gamut: p3) {
  :root {
    --hotpink: color(display-p3 1 0 0.87); /* ❌ Will not work as one might expect … */
  }
}

Problem here is that @media (color-gamut: p3) queries hardware support, not browser support. On a MacBook Pro in a browser that does not understand display-p3 the condition will evaluate to true, this because the MacBook’s display is capable of showing p3 colors.

~

# Screenshots

Here’s a screenshot of Chrome 108 with the Experimental Web Platform Features turned on, which enables (experimental) support for display-p3:

Screenshot of Chrome 108, which has support for display-p3

And here’s a screenshot of stock Chrome 106 with no flags on, which does not support display-p3:

Screenshot of Chrome 106, which has no support for display-p3

~

# Automating things

# Automating things with PostCSS

If you want to automate things, you can use postcss’s color function. It will automatically convert richer colors to sRGB compatible ones. Using its preserve flag, you can keep both colors.

/* INPUT */
:root {
  --a-color: color(srgb 0.64331 0.19245 0.16771);
}


/* OUTPUT */
:root {
  --a-color: rgb(164,49,43);
}

@supports (color: color(srgb 0 0 0)) {
  :root {
    --a-color: color(srgb 0.64331 0.19245 0.16771);
  }
}
/* INPUT */
.color {
  color: color(display-p3 0.64331 0.19245 0.16771);
}


/* OUTPUT */
.color {
  color: rgb(179,35,35);
  color: color(display-p3 0.64331 0.19245 0.16771);
}

In that last example, browsers that don’t understand display-p3 will simply ignore that declaration, thereby falling back to the auto-converted RGB color.

# Automating things with a Sass mixin

Sparked by this post and a follow-up Twitter thread with Brandon McConnell, reader Josh Vickerson created a Sass mixin that lets you define multiple values in preference.

.background-hotter-pink {
  @prefer('background', color(display-p3 1 0 0.87), hotpink);
}

The cool thing is how simple it actually is: it applies the given values in the reverse order that you defined them.

/**
 * Generates a cascade of preferred values for a given CSS property
 * @param $property: css property name you wish to provide values for
 * @param $values: any number of values you'd like to use, in order of preference
 *
*/
@mixin prefer($property, $values...) {
  @for $i from length($values) to 0 {
    #{$property}: nth($values, $i);
  }
}

The output for the example above is this:

.background-hotter-pink {
  background: hotpink;
  background: color(display-p3 1 0 0.87);
}

Just like with the PostCSS plugin, browsers that don’t understand display-p3 will simply ignore the second declaration, thereby falling back to the hotpink.

# Automating things with native CSS

Reader Brandon McConnell also created an issue within the CSS Working Group asking for a native prefer() function that would work similarly to Josh’s function.

Turns out this already was on the radar of the Working Group, as Tab Atkins listed a similar issue two years ago.

The issue already underwent some discussion at the start of 2022, but it’s currently stalled. If you want to see this feature further evolve, feel free to chime in.

~

# Spread the word

To help spread the contents of this post, feel free to retweet the announcement tweet:

~

🔥 Like what you see? Want to stay in the loop? Here's how:

CSS in 2022 (and beyond) (2022.09.09 @ Fronteers Conf)

Me, in front of the big screen at Fronteers

On September 9, I was in Utrecht for Fronteers Conference 2022 – a conference I’ve been attending since back in 2009. This time – after a two year hiatus due to youknowwhat – I was very glad to be back! This time not as an attendee though, but as a speaker. In my talk I covered many of the new CSS features that have recently landed or – thanks to interop 2022 – will land in browsers later this year.

Things have been going hard for CSS the past few years, and there’s a bunch of new and exciting stuff on its way.

With this talk you’ll be up to speed on some very nice recent additions, and will get a glimpse of a lot of the features that will be landing across all browsers by the end of this year.

And oh, time permitting we’ll also take a look into the future of what’s to come next ….

As I had somewhat expected, we didn’t get round to the future stuff, as there were so many other things to talk about!

~

Slides

The slides are up on slidr.io:

~

Video

The talk was recorded and I expect it to get published in the coming weeks. Once that’s the case this post will get updated to include it.

This recording might be of more help, as the slides themselves lack some explanation and supporting animations to tell the whole story.

View from the side of the movie theatre

~

One-page Summary

Attendee Anke created this wonderful one-page sketchnote to summarize the talk. Excellent work I must say!

Sketchnote by Anke

~

Thanks!

The Fronteers Conf 2022 organisers and volunteers

I would like to thank the organisers and all volunteers for having me. Having organised events for almost a decade now, they know how to do it – even a totally new city+venue+format was no hurdle to them.

I especially liked how the organisers managed to create a well-balanced program. We got to hear about UX/research, HTTP/performance, fonts/design, CSS, Privacy, HTML/Progressive Enhancement … a very nice mixture imo! So with this, a big thank you to the other speakers as well for giving their talks – the quality, as per usual, was very high level.

Hopefully you all had fun attending my talk — I know I had making it (and whilst bringing it forward) — and perhaps you even learned something from it along the way 🙂

~

💁‍♂️ If you are a conference or meetup organiser, don't hesitate to contact me to come speak at your event.