April is upon us, and we have a most timely release for you — Firefox 88. In this release you will find a bunch of nice CSS additions including :user-valid
and :user-invalid
support and image-set()
support, support for regular expression match indices, removal of FTP protocol support for enhanced security, and more!
This blog post provides merely a set of highlights; for all the details, check out the following:
:user-valid and :user-invalid
There are a large number of HTML form-related pseudo-classes that allow us to specify styles for various data validity states, as you’ll see in our UI pseudo-classes tutorial. Firefox 88 introduces two more — :user-valid
and :user-invalid
.
You might be thinking “we already have :valid
and :invalid
for styling forms containing valid or invalid data — what’s the difference here?”
:user-valid
and :user-invalid
are similar, but have been designed with better user experience in mind. They effectively do the same thing — matching a form input that contains valid or invaid data — but :user-valid
and :user-invalid
only start matching after the user has stopped focusing on the element (e.g. by tabbing to the next input). This is a subtle but useful change, which we will now demonstrate.
Take our valid-invalid.html example. This uses the following CSS to provide clear indicators as to which fields contain valid and invalid data:
input:invalid {
border: 2px solid red;
}
input:invalid + span::before {
content: '✖';
color: red;
}
input:valid + span::before {
content: '✓';
color: green;
}
The problem with this is shown when you try to enter data into the “E-mail address” field — as soon as you start typing an email address into the field the invalid styling kicks in, and remains right up until the point where the entered text constitutes a valid e-mail address. This experience can be a bit jarring, making the user think they are doing something wrong when they aren’t.
Now consider our user-valid-invalid.html example. This includes nearly the same CSS, except that it uses the newer :user-valid
and :user-invalid
pseudo-classes:
input:user-invalid {
border: 2px solid red;
}
input:user-invalid + span::before {
content: '✖';
color: red;
}
input:user-valid + span::before {
content: '✓';
color: green;
}
In this example the valid/invalid styling only kicks in when the user has entered their value and removed focus from the input, giving them a chance to enter their complete value before receiving feedback. Much better!
Note: Previously to Firefox 88, the same effect could be achieved using the proprietary :-moz-ui-invalid
and :-moz-ui-valid
pseudo-classes.
image-set() support
The image-set()
function provides a mechanism in CSS to allow the browser to pick the most suitable image for the device’s resolution from a list of options, in a similar manner to the HTML srcset
attribute. For example, the following can be used to provide multiple background-image
s to choose from:
div {
background-image: image-set(
url("small-balloons.jpg") 1x,
url("large-balloons.jpg") 2x);
}
You can also use image-set()
as a value for the content
and cursor
properties. So for example, you could provide multiple resolutions for generated content:
h2::before {
content: image-set(
url("small-icon.jpg") 1x,
url("large-icon.jpg") 2x);
}
or custom cursors:
div {
cursor: image-set(
url("custom-cursor-small.png") 1x,
url("custom-cursor-large.png") 2x),
auto;
}
outline now follows border-radius shape
The outline
CSS property has been updated so that it now follows the outline shape created by border-radius
. It is really nice to see a fix included in Firefox for this long standing problem. As part of this work the non-standard -moz-outline-radius
property has been removed.
RegExp match indices
Firefox 88 supports the match indices feature of regular expressions, which makes an indices
property available containing an array that stores the start and end positions of each matched capture group. This functionality is enabled using the d
flag.
There is also a corresponding hasIndices
boolean property that allows you to check whether a regex has this mode enabled.
So for example:
const regex1 = new RegExp('foo', 'd');
regex1.hasIndices // true
const test = regex1.exec('foo bar');
test // [ "foo" ]
test.indices // [ [ 0, 3 ] ]
For more useful information, see our RegExp.prototype.exec() page, and RegExp match indices on the V8 dev blog.
FTP support disabled
FTP support has been disabled from Firefox 88 onwards, and its full removal is (currently) planned for Firefox version 90. Addressing this security risk reduces the likelihood of an attack while also removing support for a non-encrypted protocol.
Complementing this change, the extension setting browserSettings.ftpProtocolEnabled has been made read-only, and web extensions can now register themselves as protocol handlers for FTP.
About Chris Mills
Chris Mills is a senior tech writer at Mozilla, where he writes docs and demos about open web apps, HTML/CSS/JavaScript, A11y, WebAssembly, and more. He loves tinkering around with web technologies, and gives occasional tech talks at conferences and universities. He used to work for Opera and W3C, and enjoys playing heavy metal drums and drinking good beer. He lives near Manchester, UK, with his good lady and three beautiful children.
6 comments