Reading List
The most recent articles from a list of feeds I subscribe to.
What kind of ethics do front-end developers need?
Now that the technology sector of the world is rapidly transforming all of the world’s things into digital things, many have called for more ethics in our field. That is in many instances quite a vague goal, so let’s apply it to one part of digital: front-end development. How can we be more ethical as front-end developers, what kinds of things can we do? I thought I’d try and make a list.
I don’t know what is good for us. I mean, I have ideas about that, but this post is not about those ideas, it is about what kinds of things front-end developers can think about if they want to apply ethics to our field.
What and why
In my talk for Inclusive Design 24, I said that ethics is about how we want our world shaped. But ethics has many definitions, another one is that it answers the question ‘what should I do?’ In that question, note the word ‘should’. It’s about what you’re obliged to do. It also implies taking a moral stance and choosing between different paths. It is about coming up with reasons based on what is considered the right thing, based on a set of rules. An example of such a rule is ‘only act according to rules that you would want to apply to everyone’ (said Kant). And there is The Golden Rule: treat others as you would want to be treated.
The ethics described above is roughly what the literature would refer to as duty-based ethics, it is based on the idea of a moral obligation. There is also consequence-based ethics. Consequentialists look at the outcome of their decisions and actions. They consider how decisions or actions impact the world, for example whether they increase or decrease the total amount of happiness in the world. It doesn’t matter how you get to an increase of total happiness, it matters that you do.
When trying to apply ethics to technology, it should be fine to be pragmatic and combine both approaches. Do things because they are right and do (or leave) things because of their consequences.
The reason that ethics can make an important contribution to the web is its focus on why and how we do things rather than just what we are doing. That focus has the unique chance to make our choices more human, because arguably without ethics we could just leave our decision making to machines. It takes a human to make ethical decisions, said the awesome Laura Kalbag. Thinking ethically about decisions also makes them more human. It works both ways.
Tim Berners-Lee already talked about how ethics is important for the web at the first WWW conference in 1994. He describes this in his book Weaving the web (2000, 86):
I finished by pointing out that, like scientists, people in the Web development community had to be ethically and morally aware of what they were doing
This, about the origins of the Web, is recommended reading, by the way. Don’t judge it by its cover design…
Ethics is important for everyone who makes things for the web: people working on design, product and management. But also for front-end developers. We drive a lot of how modern web products are built and uniquely know of weird details and consequences of products decisions. If ethics is about consequences, we are part of it. So let’s worry about what decisions are made. Rather than just using our expertise to build products, we can think about decisions and then build products. Because it is also our duty and we can help increase (or not decrease) total happiness in the world.
Ok, so do I just npm install ethics
?
Admittedly, I’m stretching it a bit, but I would like to show what ethics is not. I should stress that ethics can’t be just added to something that exists, it has to be in the decision process before. Automating ethics won’t work either, trying to do it would also sort of miss the point of ethics. Package managers like npm
can install most things that a web project could possibly depend on, but it should be clear by now that ethics is not one of them. Computers can automatically foresee consequences sometimes, they can use statistical analysis see how big your JS bundle will be. Or, more real-world, use facial recognition to see that someone is cheating on their partner. But the point is, ethics is the assessment that can start after metrics like these. It requires humans.
There are plenty of situations in our jobs where we can apply ethical thinking to what we do. Let’s look at some real-world examples.
Front-end developer impact
Ensure accessibility
The web is accessible by default, but as a developer it’s easy to break that in the flow of getting features shipped. I sometimes do this myself, and I specialise in accessibility. There are ways to improve though, for example by focusing (part of) your personal development on learning about making accessible products. By being aware of how to meet the Web Content Accessibility Guidelines and generally accessibility good practices, you can directly contribute to letting more people enjoy the web through code.
Analytics with Do Not Track
You’re asked to implement trackers in a site. You are aware that technically, this will allow some megacorporation to spy on people. You are also aware that modern browsers support Do Not Track. It will likely be your choice to honour your user’s Do Not Track settings, and otherwise your duty to convince the people in the company who prefer more metrics over more valuing user preferences. Or maybe you research a way to completely anonomise the data. This combines duty and consequences.
Impact on society at large
This is a more general example, applying to what you work on and where you choose to work. There’s a degree of ‘but not everyone is so privileged that they have choice’ to this, but I still believe we can all choose to some degree. When working as a front-end developer, it is likely that what you work on will somehow shape the world, sometimes even disrupt it. Should you build the front-end for a product that ‘disrupts’ an industry, but also introduces more inequality and makes the lives of other people harder?
Code of conducts in open source
If you released some of your code as an open source project and it attracted a bit of a community around it, considering community values would make a huge difference. Things like how you want people to feel empowered to make suggestions, feel included in the community, participate and show empathy to each other. A Code of Conduct (for example, a CODE_OF_CONDUCT.MD
) could help make these values explicit, and heck, you could even npm install one (just note that this only adds value if you also have a plan for getting incidents reported and responding to them).
Diversity in hiring
As a front-end developer you may sometimes be involved in hiring new team members. This is also a great opportunity to influence how the world is shaped: be aware of possible biases in order to give good recommendations to HR.
Recognising dark patterns
If you don’t like to be tricked into buying services you don’t actually need or want, then your users likely feel the same. Learn to recognise dark patterns and start the discussion if you’re asked to implement one.
Keeping users secure
By being aware of common security risks we can ensure our users are safer online. Most of the responsibilities fall within front-end (and back-end) development scope. The Golden Rule applies here: if you surf the web as a consumer, you would also like the developer who has built the site to have done so securely.
These are all things where an ethical attitude and contemplating why and how we do things can be helpful in creating a better web. They’re not all easy things, some of them are hard to get right. But if we’re going to play a role in making all the things digital things, let’s do it responsibly.
Conclusion
As front-end devs, we can apply ethics to our work by having an ethical mindset when doing our work. Practically we could do this by applying the Golden Rule and thinking about consequences of our code for users and our colleagues, for example by ensuring accessibility, security and a safe and welcoming working environment.
Originally posted as What kind of ethics do front-end developers need? on Hidde's blog.
How I learned to stop worrying and love CSPs
To gain precise control over what styles, scripts and other assets do on your site, you can serve pages with a Content Security-Policy. What does that mean for the front-end, and for those of us building user interfaces in browsers? Well, it can be tricky to set up, but there are useful benefits.
Why CSPs?
CSPs basically work like a whitelist of asset domains that the browser will accept for your site. This is great, as browsers have no notion of benevolent or malicious assets. Only website owners do. By telling browsers where the good stuff is located, website owners can rest assured users of modern browsers won’t get bad assets executed. They are one out of many security headers.
CSPs have been around for ages (see for example the Twitter blog in 2011), but usage numbers seem to be quite low. It seems to me they have recently gained more traction though, as more people get interested into website safety and content integrity. See also how Mozilla Add-Ons did it.
How they work
Technically, a CSP is a string that contains key-value pairs, served as a header with the response (or via a meta
element in the page). They describe for each type of content how it can be used within your page. To be more precise: where it can be loaded from. Definitions for each type of asset are separated with semicolons, the definitions themselves have spaces in between.
Here’s an example:
script-src https://hidde-cdn.com; style-src https://hidde-cdn.com
This will only allow scripts or styles if they are served from https://hidde-cdn.com
.
There are also a number of keywords.
self
will allow assets from the same domain that the page is served fromunsafe-inline
will allow inline assets
See for example, this policy:
script-src 'self' https://hidde-cdn.com; style-src 'unsafe-inline' https://hidde-cdn.com
This allows scripts only from the current domain or from https://hidde-cdn.com
, and allows styles inline or when served from https://hidde-cdn.com
.
There are also directives: font-src
for fonts, img-src
for images,connect-src
for fetching/requests and default-src
if you want to set a default. Best set default-src to none, so that you already have a policy for any asset types you don’t or forget to define.
The unsafe-inline
directive is interesting: it has the word ‘unsafe’ in it, because inline assets are considered harmful. I should clarify: inline assets aren’t harmful because they are inline as such, but it is the case that whenever malicious scripts or stylesheets are injected, they are likely to be inline. Blocking their execution altogether mitigates their risk. If that feels like too much, it is also possible to allow some inline scripts: identify one script with a nonce (a number used once) and whitelist that nonce.
In summary, a CSP lets you whitelist locations to load assets from. Although these whitelists themselves are simple when you grasp the concept, their consequences can be unexpected and, for front-end devs, rather inconvenient.
Some side-effects
When I recently implemented a CSP in a project I was working on, I found a couple of surprises that were inconvenient, some of them related to disallowing inline assets. Note that those specific issues will be go away if your setup has a different, less stringent CSP locally.
Adding styles via Developer Tools
Sometimes when I’m working on some CSS, I’ll inject CSS via the Dev Tools, so that I can see what the effect of my changes are without actually making them just yet. If your CSP disallows inline styles, you are out of luck as this feature will stop working.
Browsersync
If your local development environment uses script to reload the browser when you’ve changed a file, this likely uses inline scripts that will be blocked when your policy forbids inline scripts.
Analytics
If you’re using external analytics scripts, don’t forget to add the domains that they load from, if they are different from your own domain. This is the case for Google’s Analytics and Tag Manager products, for example.
Polyfills that inject CSS
The inert
polyfill injects some CSS into the page in order to prevent user selection on inert elements. Injected CSS counts as inline CSS (obvs), so that will not work.
Inline styles in SVGs
Double-check that SVGs that you are including in your page do not contain style
attributes, as some browsers can deem those to be a violation of unsafe-inline
.
The good and the bad
What I love about CSPs
The great thing about CSPs is that, if implemented well, you know exactly where to expect attacks. Without a CSP, the ‘attack vector’ is unknown and likely big or of infinite size, with a CSP you know where it can come from.
If you work in a large organisation where the marketing team can insert scripts via Tag Manager(-like) solutions, which is quite common these days, CSPs are also a useful treshold. Scripts that are useful for gaining marketing insights could at the same time be risky from a security standpoint (not to mention privacy).
There are some design choices that make CSPs a joy to work with, for example the built-in report-uri
directive, that lets you specify a URL to report CSP violations to, which can be used to track violations using a service like Sentry.
What I slightly dislike
If your site is served over SSL and you sanitise all the things (in other words, you avoid Little Bobby Table scenarios), your CSP does not actually make it more secure. Note that this is a huge if. If you’re healthy, a health insurance isn’t going to make you more healthy, but it is extremely sensible to have one in place anyway. This is kind of the point of CSPs, they provide extra cover for if things like SSL and XSS protection aren’t (correctly) in place. Mistakes can be easy to make in the security space. So I’ve learned to love this: CSPs don’t harm if you can work around the side-effects.
Something else I don’t really like is the usability of error reports for CSP violations in browser Dev Tools. They will make clear that there is an error, but aren’t too helpful in pointing towards the right direction. Browsers could be clearer about which exact bit of your policy is stopping an asset from working.
TL;DR
CSPs can nullify what XSS attackers can do once they’ve managed to attack. This is great, although implementing it can make some things harder on the front-end. But that’s ok, it is our job after all. For help with implementing a CSP for your site, check out Mozilla’s Laboratory Add-On and Google’s Web Fundamentals page on CSP.
Originally posted as How I learned to stop worrying and love CSPs on Hidde's blog.
Vague, but exciting…
Last week I saw Sir Tim Berners-Lee, inventor of the web and receiver of the Turing Prize, give the ACM Turing Lecture. He spoke about redecentralising the web.
In less than an hour, Tim Berners-Lee talked us through the history of the web, its current state and what we need to do to have a healthy future for the web. Redecentralisation, he phrased this. The web was invented as a decentralised thing, but that model is currently under threat. Large portions of the web have become walled gardens from within which it is hard to exchange with others: data is kept within its own garden.
A universal and decentralised web
The decentralised web, Berners-Lee explained, started at CERN, a research institution that brings together lots of different people, from different universities, with different preferences for both natural and programming languages and, of course, lots of documentation that was stored on computers.
Berners-Lee worked at CERN as a software engineer and he had this idea for making documents easier to access by having unique identifiers for them. When talking about this idea at the coffee machine, a colleague said he should write it down. He did and when his boss read the proposal, he wrote the now so famous words ‘Vague, but exciting’ on the memo. When he later had some time in between projects, what an impactful coincidence, he started to develop this idea further.
URI vs UDI vs URL
A key component of the initial idea was that everything on the planet should be named so that it has something to be accessed by universally — or uniformly, there was plenty of debate around the distinction, he explained.
The universality of the web, Berners-Lee said, is that it works independent of:
- hardware and software, including browsers
- the type of network access (e.g. mobile or cable)
- whether you want the data to be publicly or privately available
- the polish of the content: it works equally well for polished publications and scribbled ideas (or Vengaboys fansites)
- language and culture
- disability
- whether the data is to be consumed by people, machines or a combination of both
A web that has the above independencies is one worth fighting for, Berners-Lee explained. The W3C famously does great work in this, but less well known is that Berners-Lee found another organisation: the World Wide Web Foundation. It wants to make the web a better place for more people. He argued that if people spend 98% of their time on the web, they might as well spend 2% defending it.
We might be going in the wrong direction
Berners-Lee first showed a virtuous circle: if all goes well the web lets people publish, which inspires conversation and more publications. This is the utopian scenario and we’ve seen a lot of this actually happen. The web community itself it s a great example of this, we teach each other stuff and good blogs inspire other people to start blogging, this very blog is an example of that effect.
The ideal web is a virtuous circle
However, if we’re not careful, Berners-Lee warned, there can also be a vicious circle, a dystopian scenario. This happens when algorithms cause people to meet more people like themselves, narrows down their circle and alienates them from people who are different. Or when websites are used to harvest people’s personal data that are then used for political gain. Or when falsehoods are presented as facts. These seem pretty much like the things that Mozilla identify as issues concerning internet health.
Towards more decentral web
There’s all sorts of things we can do to make better things for the web, and perhaps, consequently, make the web better. Berners-Lee urged us to build things that facilitate open dialogue and discussion, not flame wars. Human rights should be at the center of such things, and it would probably only work if it was not a centralised solution: we might need new (social) networks altogether in order to get what we need. Solid is an initiative led by Tim Berners-Lee aimed at building social websites that are not centralised and let people have control of your own profile and data.
It was an inspiring morning and great to see Berners-Lee speak in person (for what was my second time). The principles that the web was built on are strong and the lecture was a great reminder of how we can make better things on the web. We should make good things!
Originally posted as Vague, but exciting… on Hidde's blog.
More accessible markup with display: contents
CSS Grid Layout lets you turn an element into a grid, and place the element’s direct children onto it. Given that, it might be tempting to use flatter markup, but less meaning is usually less accessibility. With display: contents
, we can place grand children on a grid, which lets us have accessible markup and beautiful layout. Let’s dive into the details!
Below, I will explain in more detail what I mean by children and grand children, and then show how we can use display: contents
to improve this. Note: this caused an accessibility bug in all major browser engines, which has been addressed partially in all major engines since May 2022, with open issues, see below for details
Grid works on direct children
In Grid Layout, when a grid is defined on a given element, only direct children of that element become grid items and are layed out on it. To refresh for those not familiar with the syntax, let’s look at an example and write a recipe. With this HTML:
<div class="container">
<h1 class="item">Penne with tomato sauce</h1>
<p class="item">This simple recipe has few ingredients but tastes delicious.</p>
<div class="item ingredients">
<h2>You'll need</h2>
<ul>
<li>canned tomatoes</li>
<li>onions</li>
<li>garlic</li>
</ul>
</div>
</div>
we can have this CSS:
.container {
display: grid; /* element is now a grid container */
grid-template-columns: repeat( 4, 1fr ); /* grid now has 4 columns */
.item:nth-child(1) {
grid-columns: 1 / 2; /* Place item between grid line 1 and 2 */
}
.item:nth-child(2) {
grid-columns: 2 / 4; /* Place item between grid line 2 and 4 */
}
.item:nth-child(3) {
grid-columns: 4 / 5; /* Place item between line 4 and 5 */
}
I’ve used .container
and .item
as classnames, because that’s core to Grid Layout: there’s grid containers and grid items. Obviously, use any naming convention your projects require.
The reason we can position these items on the grid, is that they are direct children of the grid container. But look at what happens if we’d like to add a list of sponsors, like this:
We could add the list to our markup:
<div class="container">
<h1 class="item">Penne with tomato sauce</h1>
<p class="item">This simple recipe has few ingredients but tastes delicious.</p>
<div class="item ingredients">
<h2>You'll need</h2>
<ul>
<li>canned tomatoes</li>
<li>onions</li>
<li>garlic</li>
</ul>
</div>
<ul class="item sponsors">
<li>Supermarket 1</li>
<li>Supermarket 2</li>
</ul>
</div>
But we won’t be able to position each sponsor onto the grid. This is because only the <ul>
is a direct child of the container element and therefore a grid item. The <li>
s are not: because they are not direct children of our grid container, they don’t get to participate in its grid game. But what if we really want to align the sponsors onto the grid?
Flatter markup
One obvious method of making the sponsors participate is to remove the <ul>
and use a <div>
for each sponsor. But what we would then do, it ‘flatten’ our markup. That’s throwing away the baby with the bathwater.
The benefit of using the <ul>
(unordered list) element are plenty:
- it will stay a list outside the context of our page, for example in Safari Reader mode, it will show as a list
- when printed with stylesheet turned off, it will show as a list
- for people who use screenreaders, it is a list (screenreaders can announce things like ‘list, 3 items’).
If we would make our markup flatter, we lose those benefits.
display: contents
to the rescue
With display: contents
, we can have our markup and our grid placement. This property makes the element so that it no longer seems to exist. It does not generate a box, so backgrounds, borders and other box-related properties will no longer work on it. Grid placement properties will also no longer work. But all of these things will work for the element’s children. The spec says the element behaves ‘as if it had been replaced […] by its contents’. If that sounds weird, I can recommend Ire Aderinokun’s detailed explainer.
Effectively, for our purposes here, using display: contents
on an element does this: the element stops participating in the grid, and its contents start participating in it. It lets us specify our sponsors onto the grid, instead of the list they are contained in.
There’s some interesting edge cases listed in the spec, for if the property is used on elements like img
and video
.
Accessibility concerns with current browser implementations of display: contents
For people who use assistive technologies (AT), browsers expose accessibility properties, including the role
of elements on the page. This is so that their AT knows what’s what on the page. Many elements come with a built-in role
, for example lists have a role
of list
.
This is where it goes wrong in current browsers that support display: contents
. They do not interpret display: contents
as a lay-out thing only, they also derive meaning from it. This is problematic and a bug according to the spec’s comment on display affecting layout:
The display property has no effect on an element’s semantics: these are defined by the document language and are not affected by CSS. Aside from the none value, which also affects the aural/speech output and interactivity of an element and its descendants, the display property only affects visual layout: its purpose is to allow designers freedom to change the layout behavior of an element without affecting the underlying document semantics.
(emphasis mine)
Looking at our sponsor list example, it means that the item is no longer seen as a list, but as something else (test case in CodePen).
I’ve added my test results per browser below. In each of them, our <ul>
gets the correct role
without display: contents
, but once the property is set, it loses its role.
Firefox 61
The list gets a role
of text leaf
(Firefox bug). Update: this is now fixed; it will ship in Firefox 62 in August 2018
Chrome 66
The list shows as ‘accessibility node not exposed, element not rendered’ (Chromium bug). Update: this is now fixed; it has shipped in Chome 89 in March 2021
Safari
The list shows as ‘no accessibility information’ (Safari bug, Webkit bug #185679, Webkit bug #237834 that they did more work in)
Update 13 June 2022: this was reported fixed in Safari TP 144 / Safari 16
Update 9 July 2022: Adrian Roselli reports work is still needed in Safari
Related to this issue is that display
properties in CSS have impact on table semantics, as Adrian Roselli explains; see also Steve Faulkner’s explanation of where the responsibilities lie.
Conclusion
With display: contents
, you can place grand children of a grid container on the grid. This allows for more semantic mark-up, which is great for accessibility. The more meaningful your mark-up, the more detail an assistive technology can provide to its users. However, there is one caveat: none of the browsers that currently support display: contents
expose elements that have the property to the accessibility tree with their original role.
I believe the accessible roles should not disappear when setting display: contents
, as that defeats a lot of the purpose of display: contents
. I have filed bugs with Firefox, Chromium and Safari for this. I really hope we will be able to use display: contents
while keeping the accessible roles of elements intact, so that we can have great layouts and great accessibility. To be continued, I hope!
Originally posted as More accessible markup with display: contents on Hidde's blog.
For everyone
At accessibility talks, I love to show a photo of Sir Tim Berners-Lee and the words he made appear on enormous screens during the 2012 Olympics opening ceremony in London: ‘This is for everyone’.
Copyright: Martin Rickett/PA Wire, from The Guardian
With ‘this’, he meant the web, I assume. I like to ponder what the other bit means, ‘for everyone’. It’s probably a number of different things:
- Everyone can have a website. As in, you can register a domain, get hosting and put your site on. All at low cost and sometimes free. You do not need permission and are free to put whatever content on: your corporate mission statement or your love for the Vengaboys. Anything.
- Everyone can go to websites, there’s no entry fee or barrier to the web —although there is to some sites and in some countries— the web is open to access by default.
- Everyone can access the web, it is built to work for lots of different users, including those with visual, auditory or motor impairments, those with slow connections, those with new and those with old machines.
I think ‘this is for everyone’ refers for a large part to the universal accessibility of the platform. It is what makes the web awesome.
A different ‘for everyone’
During a meetup that took place at Uber Amsterdam’s offices this week, I learned about that company’s mission statement. Before I continue, it is very kind of them to host meetups, they are a great way for the web community to meet each other. I admire the hospitality that makes this possible.
Anyway, the statement:
Uber’s mission is to bring transportation — for everyone, everywhere.
I’m sorry, but it struck the wrong chord with me. Their everyone (and indeed their everywhere) means something else. Admittedly, this may come across as extreme cynicism, but let’s try and think about what it means for them. What Uber mean by making transport available to everyone, is that they want everyone’s transport transactions to run through their systems. So that they can get their financial cut.
This is, of course, a perfectly fine strategy and it is how economies work. It isn’t inherently wrong for companies to try and increase market share and profit, but it is definitely a different ‘for everyone’. It’s the same language with a different meaning. As the web-style ‘for everyone’ wouldn’t break sensible laws that protect vulnerable people, it wouldn’t monetise people in distress, it would not order fake rides to beat competitors, it would not deny users with guide dogs and it would not use its data to spy on ex-girlfriends, track one night stands and… well, the list goes on.
This is for themselves, not for everyone. Uber wouldn’t do those things if its for everyone was really about people and not about profits. They make Uber’s ‘for everyone’ sound hollow. And I don’t like that, because the web’s ‘for everyone’ is not hollow, it is built into how the platform technically works, in web standards, in all of that.
Conclusion
It appears ‘for everyone’ can have different meanings and I think it is important to see the difference between them, so that we are not fooled by for-profit companies that present themselves as charities. The web itself is a place where people are put first, and a place where power is not exercised on people, it is given to people.
Surely, it is great that so many companies are now using that platform for commercial purposes. Arguably that has helped with the platform’s popularity. It’s been pretty good for many of the world’ s economies too. But I can’t help but think about what the web could look like if we would make more things that really solve problems for everyone… let’s ask this: ‘what is the problem and who are we solving it for?’
Originally posted as For everyone on Hidde's blog.