74 | ```
75 |
76 | Don't create elements inside elements. If you find yourself needing this, consider converting your element into a block.
77 |
78 | We _don't_ do this:
79 | ```css
80 | .c-alert-box__close__button
81 | ```
82 |
83 | Choose your modifiers wisely. These two rules have very different meaning:
84 | ```css
85 | .c-block--modifier .c-block__element { color: red; }
86 | .c-block__element--modifier { color: red; }
87 | ```
88 |
89 | Don't nest class names when using a preprocessor. Here are a few reasons why:
90 |
91 | 1. It prevents from being able to find the class names easily
92 | 2. It hinders developers understanding the context that they are working on
93 | 3. When reviewing a pull request, it requires extra effort to see the actual
94 | selector and to do a proper review
95 |
96 | We _do_ this:
97 |
98 | ```css
99 | .c-block { padding: 24px; }
100 |
101 | .c-block--modifier { padding: 12px; }
102 |
103 | .c-block__element { color: white; }
104 |
105 | .c-block__element--modifier { color: black }
106 | ```
107 |
108 | We _don't_ do this:
109 |
110 | ```css
111 | .c-block {
112 | padding: 24px;
113 |
114 | &--modifier {
115 | padding: 12px;
116 | }
117 |
118 | &__element {
119 | color: white;
120 |
121 | &--modifier {
122 | color: black;
123 | }
124 | }
125 | }
126 | ```
127 |
--------------------------------------------------------------------------------
/css/config/.stylelintrc:
--------------------------------------------------------------------------------
1 | {
2 | "rules": {
3 | "at-rule-empty-line-before": [ "always", {
4 | "except": ["blockless-group"]
5 | } ],
6 | "block-closing-brace-newline-after": "always",
7 | "block-closing-brace-newline-before": "always-multi-line",
8 | "block-closing-brace-space-before": "always-single-line",
9 | "block-no-empty": true,
10 | "block-opening-brace-newline-after": "always-multi-line",
11 | "block-opening-brace-space-after": "always-single-line",
12 | "block-opening-brace-space-before": "always",
13 | "color-hex-case": "lower",
14 | "color-hex-length": "short",
15 | "color-no-invalid-hex": true,
16 | "comment-empty-line-before": [ "always", {
17 | "except": ["first-nested"]
18 | }],
19 | "declaration-bang-space-after": "never",
20 | "declaration-bang-space-before": "always",
21 | "declaration-block-semicolon-newline-after": "always-multi-line",
22 | "declaration-block-semicolon-space-after": "always-single-line",
23 | "declaration-block-semicolon-space-before": "never",
24 | "declaration-block-single-line-max-declarations": 0,
25 | "declaration-colon-newline-after": "always-multi-line",
26 | "declaration-colon-space-after": "always-single-line",
27 | "declaration-colon-space-before": "never",
28 | "function-calc-no-unspaced-operator": true,
29 | "function-comma-newline-after": "always-multi-line",
30 | "function-comma-space-after": "always-single-line",
31 | "function-comma-space-before": "never",
32 | "function-parentheses-newline-inside": "always-multi-line",
33 | "function-parentheses-space-inside": "never-single-line",
34 | "function-whitespace-after": "always",
35 | "indentation": "tab",
36 | "max-empty-lines": 1,
37 | "media-feature-colon-space-after": "always",
38 | "media-feature-colon-space-before": "never",
39 | "media-feature-range-operator-space-after": "always",
40 | "media-feature-range-operator-space-before": "always",
41 | "media-query-list-comma-newline-after": "always-multi-line",
42 | "media-query-list-comma-space-after": "always-single-line",
43 | "media-query-list-comma-space-before": "never",
44 | "media-query-parentheses-space-inside": "never",
45 | "no-eol-whitespace": true,
46 | "no-missing-eof-newline": true,
47 | "number-leading-zero": "always",
48 | "number-no-trailing-zeros": true,
49 | "number-zero-length-no-unit": true,
50 | "rule-no-shorthand-property-overrides": true,
51 | "rule-non-nested-empty-line-before": "always-multi-line",
52 | "rule-trailing-semicolon": "always",
53 | "selector-combinator-space-after": "always",
54 | "selector-combinator-space-before": "always",
55 | "selector-list-comma-newline-after": "always",
56 | "selector-list-comma-space-before": "never",
57 | "string-quotes": "single",
58 | "value-list-comma-newline-after": "always-multi-line",
59 | "value-list-comma-space-after": "always-single-line",
60 | "value-list-comma-space-before": "never"
61 | }
62 | }
--------------------------------------------------------------------------------
/css/house-style.md:
--------------------------------------------------------------------------------
1 | # CSS style guide
2 |
3 | We namespace our CSS as detailed in our [how we write CSS](how-we-write-css.md) guide. For the purposes of the examples here, we will use the `component` namespace.
4 |
5 | - [General principles](#general-principles)
6 | - [Code style](#code-style)
7 | - [Linting](#linting)
8 | - [Preprocessors](#preprocessors)
9 | - [Nesting](#nesting)
10 |
11 | ## General principles
12 |
13 | We write our CSS using design patterns that aim to maximise maintainability and reuse; See our [house style document](../practices/house-style.md) to understand the rationale behind enforcement of style.
14 |
15 | ## Code style
16 |
17 | Avoid using HTML tags in CSS selectors. And always prefer using a class over HTML tags (with some exceptions)
18 |
19 | We _don't_ do this
20 | ```scss
21 | div {}
22 | div.c-modal {}
23 | ```
24 |
25 | We do this:
26 | ```scss
27 | .c-modal {}
28 | ```
29 |
30 | Don't use [ids in selectors](http://csswizardry.com/2011/09/when-using-ids-can-be-a-pain-in-the-class/)
31 |
32 | We _don't_ do this:
33 | ```scss
34 | #header {}
35 | ```
36 |
37 | We do this:
38 | ```scss
39 | .c-header {}
40 | ```
41 |
42 | Avoid using `margin-top`. Vertical margins [collapse](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Box_Model/Mastering_margin_collapsing). Always prefer `padding-top` or `margin-bottom` on preceding elements
43 |
44 | We _don't_ do this:
45 | ```scss
46 | .c-list__item {
47 | margin-top: 10px;
48 | }
49 | ```
50 |
51 | We do this:
52 | ```scss
53 | .c-list__item {
54 | padding-top: 10px;
55 | }
56 |
57 | /* or */
58 |
59 | .c-list__item {
60 | margin-bottom: 10px;
61 | }
62 | ```
63 |
64 | Avoid shorthand properties, if you aren't setting all the values in the property. This applies to all properties with a shorthand: border, margin, padding, font, etc. Use your judgement on this, as there are exceptions.
65 |
66 | We _don't_ do this:
67 | ```scss
68 | .c-modal {
69 | // overrides other values encapsulated by the shorthand property.
70 | // In this case, background-image and its associative properties are set to “none”
71 | background: $white;
72 | border: 1px;
73 | }
74 | ```
75 |
76 | We do this:
77 | ```scss
78 | .c-modal {
79 | background-color: $white;
80 | border-width: 1px;
81 | }
82 | ```
83 |
84 | Don't use `!important`. If you must, leave a comment, and prioritise resolving specificity issues before resorting to `!important`.
85 |
86 | ### Linting
87 |
88 | Static analysis tools like linters can flag programming errors, bugs and stylistic errors, making your code more robust, readable and maintainable.
89 |
90 | CSS code (not compiled) should be linted with [styleLint](https://github.com/stylelint/stylelint). You can find _an example_ config file in the [config directory](config).
91 |
92 | Sass code should be linted with [Stylelint](https://stylelint.io/) using the [Springer Nature
93 | `stylelint-config`](https://github.com/springernature/stylelint-config-springernature). This configuration allows us to maintain consistency between different projects.
94 |
95 | You can check the [README](https://github.com/springernature/sasslint-config-springernature/blob/main/README.md) for details about installing and configuring the tools.
96 |
97 | ## Preprocessors
98 |
99 | Our preferred CSS preprocessor is [Sass](https://sass-lang.com) using the SCSS syntax. Find out about [how we write CSS](how-we-write-css.md).
100 |
101 | ### Nesting
102 |
103 | Nesting selectors increases specificity, meaning that overriding any CSS set therein needs to be targeted with an even more specific selector. This quickly becomes a significant maintenance issue, which makes excessive nesting [a bad idea](http://www.sitepoint.com/beware-selector-nesting-sass/). It can easily be avoided by using smart class naming. Avoid nesting selectors more than **3 levels** deep, and prefer using nesting as a convenience to extend the parent selector over targeting nested elements.
104 |
105 | If possible, try and avoid using nesting for anything other than:
106 |
107 | **Pseudo selectors and state selectors**. We do this:
108 | ```scss
109 | a {
110 | &:hover {
111 | text-decoration: underline;
112 | }
113 | &:focus {
114 | outline: 1px dashed #000;
115 | }
116 | }
117 |
118 | span {
119 | &::before {
120 | content: '\2022';
121 | }
122 | }
123 | ```
124 |
125 | **Javascript-only style enhancements**. We do this:
126 | ```scss
127 | .c-class {
128 | display: block;
129 |
130 | .js & {
131 | display: flex;
132 | }
133 | }
134 | ```
135 | > _Read more about [how to add the `.js` class](../practices/javascript-styling.md)_
136 |
137 | **Inline html tags within other elements**. We do this:
138 | ```scss
139 | .c-class {
140 | span {}
141 | em {}
142 | small {}
143 | /* etc */
144 | }
145 | ```
146 |
147 | **Media queries**. We nest media queries and position the media queries after the CSS declarations for that block.
148 |
149 | We _don't_ do this:
150 | ```scss
151 | .c-header__journal-title {
152 | @include media-query('md') {
153 | font-size: 1.25rem;
154 | }
155 |
156 | @include media-query('lg') {
157 | font-size: 1.5rem;
158 | }
159 |
160 | font-size: 1rem;
161 | color: #000;
162 | }
163 | ```
164 |
165 | We do this:
166 | ```scss
167 | .c-header__journal-title {
168 | font-size: 1rem;
169 | color: #000;
170 |
171 | @include media-query('md') {
172 | font-size: 1.25rem;
173 | }
174 |
175 | @include media-query('lg') {
176 | font-size: 1.5rem;
177 | }
178 | }
179 | ```
180 |
181 | **Breakpoints**
182 | These should be nested within the relevant parent using `@include`.
183 |
184 | One exception to these rules is targeting a BEM element from within a nested block rule. See the [BEM documentation](bem-css.md) for more information on BEM and nesting.
185 |
--------------------------------------------------------------------------------
/git/README.md:
--------------------------------------------------------------------------------
1 | # git
2 |
3 | We use git as a our version control system.
4 |
5 | * [git](git.md)
6 | * [Semver](semver.md)
7 |
8 | [Main table of contents](../README.md#table-of-contents)
9 |
--------------------------------------------------------------------------------
/git/git.md:
--------------------------------------------------------------------------------
1 | # Git
2 |
3 | - [Repository names](#repository-names)
4 | - [Working with branches](#working-with-branches)
5 | - [Commit messages](#commit-messages)
6 | - [Pull requests](#pull-requests)
7 | - [Versioning](#versioning)
8 |
9 | ## Repository names
10 |
11 | We use a standard naming format for our Git repositories. Repository names are _lowercase-hyphenated_ (all lowercase, words separated by a hyphen), and begin with "frontend" followed by your project name.
12 |
13 | We _don't_ do this:
14 |
15 | ```
16 | front-end-project-name
17 | front-end-projectname
18 | project-name-front-end
19 | project-name-frontend
20 | ```
21 |
22 | We do this:
23 |
24 | ```
25 | frontend-project-name
26 | ```
27 |
28 | ## Working with branches
29 |
30 | Create a local branch based off the default branch. For this example, let's assume the default branch is called `main`.
31 |
32 | Follow [Continous Delivery](https://martinfowler.com/bliki/ContinuousDelivery.html) and [Continuous Integration](https://martinfowler.com/articles/continuousIntegration.html) principles as much as is reasonable (given the constraints of your team). Branches should be:
33 |
34 | * As short lived as possible.
35 | * _Atomic_, i.e. one unit of work that can't be sensibly subdivided.
36 | * They should contain their own tests.
37 | * They should be releasable independently.
38 | * As limited in scope as possible. Large pull requests are hard to review and can be painful to merge. Also, once merged & a bug is traced back to that commit, they are much harder to debug.
39 |
40 | When your work is almost complete, `git rebase main` or merge -- especially if other people are working on the same code. Avoid merge pain by;
41 |
42 | * _talking to your team_ to divide work across files sensibly & co-ordinate merges if required.
43 | * `git pull origin main` and rebase or merge often.
44 | * make sure branches are short-lived! (Did we mention that branches should be short-lived?)
45 |
46 | When the unit of work is complete and tests pass, stage your changes and commit them.
47 |
48 | ## Commit messages
49 |
50 | Your commit messages are your personal legacy. They are the record of what you've done to a codebase and more importantly, *why*. A good commit message is composed of a summary line or shortlog, and a description.
51 |
52 | * The summary line should be [50 characters or less](http://stopwritingramblingcommitmessages.com/), followed by a blank line.
53 | * Use present tense rather than past tense when referring to changes introduced by commit in question. For example, use "Update request library" instead of "Updated request library". Imagine your commit message has to make sense prefaced with _"If applied, this commit will..."_.
54 | * Summarize only the change itself in the summary line, not the bug or effects/benefits (that goes in description).
55 | * Unhelpful messages like "Update" or "Bugfix" are... _unhelpful_. Please explain a little more. Bear in mind that the commit message should allow you or anyone else to understand the changes, both now and in a year's time.
56 | * If your work is part of a ticket, include the ticket number in the commit message, but don't only use the ticket number as the commit message. Otherwise this just makes life hard for your colleagues to understand what the change was for. The git log should be all they need to read. You may also include a link to the bug after the description, separated by one blank line.
57 | * Add a description, if necessary, as detailed as you need. Make sure that lines wrap at 72 characters.
58 |
59 | A few blog posts on writing better commit messages:
60 |
61 | * [5 Useful Tips for a Better Commit Message](https://robots.thoughtbot.com/5-useful-tips-for-a-better-commit-message)
62 | * [A Note About Commit Messages](http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html)
63 | * [Git Commit](http://chris.beams.io/posts/git-commit/)
64 | * [Writing Good Commit Messages](https://github.com/erlang/otp/wiki/Writing-good-commit-messages)
65 | * [Better Commit Messages with a `.gitmessage` Template](https://robots.thoughtbot.com/better-commit-messages-with-a-gitmessage-template)
66 | * [GNOME project - Guidelines for Commit Messages](https://wiki.gnome.org/Git/CommitMessages)
67 |
68 | Once your work is committed, submit a [pull request](https://help.github.com/articles/using-pull-requests/).
69 |
70 | ## Pull requests
71 |
72 | We use pull requests to review code. [GitHub's pull request reviews feature](https://help.github.com/articles/about-pull-request-reviews/) blocks merging of code until it's been reviewed. It may or may not be enabled on a repository, at the discretion of the individual team. You should submit your pull requests for review regardless of whether or not this feature is enabled.
73 |
74 | 1. Ask for a code review in Slack.
75 | 2. A colleague (or multiple colleagues) other than the author will review the pull request. They will make comments and ask questions directly in the GitHub web interface. See the [Code review guide](../practices/code-review.md) to see what reviewers are looking for.
76 | 3. When satisfied, the reviewer(s) will approve the pull request, so that your code can be merged.
77 | 4. Give your code one last visual check in github.
78 | 5. Double-check the commit message -- and any commit message detail -- then **"Squash & Merge" commits via github**. We do not want lots of "work in progress" commits cluttering the commit history on the default branch. _One unit of work, one commit._
79 |
80 | Your work is now merged, good job! Delete your remote branch, and delete your local branch too, if you want.
81 |
82 | ## Versioning
83 |
84 | Our open source projects are versioned with [SemVer](semver.md). Check our [Open Source support](../practices/open-source-support.md) guide for details on how to version and release an update to an open source project.
85 |
86 | Closed source projects may use different versioning practices.
87 |
--------------------------------------------------------------------------------
/git/semver.md:
--------------------------------------------------------------------------------
1 | # SemVer
2 |
3 | * [What is SemVer](#what-is-semver)
4 | * [Why we use SemVer](#why-we-use-semver)
5 | * [Common concerns](#common-concerns)
6 | * [How can I trust that things aren’t going to break with a minor or patch release update?](#how-can-i-trust-that-things-arent-going-to-break-with-a-minor-or-patch-release-update)
7 | * [The version number is getting really big really quickly!](#the-version-number-is-getting-really-big-really-quickly)
8 | * [Find out more:](#find-out-more)
9 |
10 |
11 | ## What is SemVer
12 |
13 | SemVer is a way of versioning software in the format of MAJOR.MINOR.PATCH:
14 |
15 | * MAJOR version when you make breaking changes,
16 | * MINOR version when you add functionality in a backwards-compatible manner for any specific MAJOR version, and
17 | * PATCH version when you make backwards-compatible bug fixes to any specific MAJOR.MINOR version.
18 |
19 | This means that any time you release a new MAJOR release, the minor and patch values reset to 0, and the same is true of the patch value when making a MINOR release.
20 |
21 | For more information about how SemVer is defined, please see: http://semver.org/
22 |
23 | ## Why we use SemVer
24 |
25 | SemVer allows us to keep a consistent numbering scheme to ensure that going forward we can maintain compatibility with all system and platform components. It also allows us to upgrade dependencies with the confidence that things won’t break.
26 |
27 | SemVer enables us to ensure that once something is committed we can be confident that any version remains unique.
28 |
29 | ## Common concerns
30 |
31 | ### How can I trust that things aren’t going to break with a minor or patch release update?
32 |
33 | Like any practice, SemVer can be let down by people not using it correctly (like releasing a breaking change under a minor version rather than a major). It’s the responsibility of the person upgrading to ensure that the upgrade is appropriate and compatible.
34 |
35 | ### The version number is getting really big really quickly!
36 |
37 | When a piece of software under heavy development many major/minor releases may happen in quick succession, so your version might start to look like 23.2.0 or 3.34.1. THAT’S OKAY! If that’s a true representation of what has happened in the code, then it’s appropriate that the version number reflects that.
38 |
39 | What _might_ be a worry is if your version looked like 2.1.45 - did you really release 45 patches/bug fixes in a row without adding any new features?
40 |
41 | ## Find out more:
42 |
43 | * [Canonical source of info](http://semver.org/)
44 | * [How we version and release our open-source software](../practices/open-source-support.md)
45 | * [What is Semantic Versioning (SemVer)?](https://abdulapopoola.com/2015/10/26/what-is-semver/)
46 |
--------------------------------------------------------------------------------
/javascript/README.md:
--------------------------------------------------------------------------------
1 | # JavaScript
2 |
3 | We use JavaScript both in the client and on the server.
4 |
5 | * [House style](house-style.md)
6 |
7 | [Main table of contents](../README.md#table-of-contents)
8 |
--------------------------------------------------------------------------------
/learning/README.md:
--------------------------------------------------------------------------------
1 | # Learning resources
2 |
3 | In this section we offer curated lists of learning resources that people can use to get started or improve their knowledge of accessibility or web performance.
4 |
5 | * [Accessibility](web-accessibility.md)
6 | * [Web performance](web-performance.md)
7 |
8 | [Main table of contents](../README.md#table-of-contents)
9 |
--------------------------------------------------------------------------------
/learning/web-accessibility.md:
--------------------------------------------------------------------------------
1 | # Web accessibility
2 |
3 | This is a list of different resources that we offer to people interested in knowing more about web accessibility.
4 |
5 | Udacity have published an [excellent free course on Web Accessibility](https://www.udacity.com/course/web-accessibility--ud891) with Google engineers Alice Boxhall and Rob Dodson.
6 |
7 | The Financial Times have produced an [accessibility tip sheet](https://ft-interactive.github.io/accessibility/index.html).
8 |
9 | The Government Digital Service frequently publishes excellent resources. Some highlights are:
10 |
11 | * [We're making accessibility clearer and easier](https://gds.blog.gov.uk/2017/10/23/were-making-accessibility-clearer-and-easier/)
12 | * [Making your service accessible: an introduction](https://www.gov.uk/service-manual/helping-people-to-use-your-service/making-your-service-accessible-an-introduction)
13 |
--------------------------------------------------------------------------------
/learning/web-performance.md:
--------------------------------------------------------------------------------
1 | # Web performance
2 |
3 | This is a list of different resources that we offer to people interested in knowing more about web performance.
4 |
5 | ## Online courses
6 |
7 | For people wanting to learn about web performance we recommend to have a look at the following courses:
8 |
9 | * ["Lightning-fast web performance"](https://scottjehl.com/lfwp/) by Scott Jehl is an excellent short introductory course that has been recently made free.
10 | * ["Web Performance Fundamentals"](https://frontendmasters.com/courses/web-perf/) by Todd Gardner covers things in more detail. A subscription to Frontend Masters is required.
11 |
12 | ## Books
13 |
14 | The following books can be used as refererence. Some of them have been published for a while so not all advice may be applicable today, but they are still very useful to improve knowledge of a particular subject.
15 |
16 | * "High Performance Web Sites" by Steve Souders: https://learning.oreilly.com/library/view/high-performance-web/9780596529307/
17 | * "Even Faster Web Sites" by Steve Souders: https://learning.oreilly.com/library/view/even-faster-web/9780596803773/
18 | * "High Performance Browser Networking" by Ilya Grigorik: https://hpbn.co/
19 | * "HTTP/2 in Action" by Barry Pollard: https://learning.oreilly.com/library/view/http-2-in-action/9781617295164/
20 | * "Using WebPageTest" by Rick Viscomi, Andy Davies & Marcel Duran: https://learning.oreilly.com/library/view/using-webpagetest/9781491902783/
21 | * "Time Is Money" by Tammy Everts: https://learning.oreilly.com/library/view/time-is-money/9781491928783/
22 |
23 | ## Videos
24 |
25 | * Catchpoint frequently releases videos showcasing new features of WebPageTest, or Twitch streams of their performance auditing sessions:
26 | https://www.youtube.com/channel/UC5CqJ9V7cQddZDf1DKXcy7Q/featured
27 | * The London Web Performance Group has a youtube channel with most of their talks: https://www.youtube.com/user/ldnwebperf/videos
28 |
29 | ## Other resources
30 |
31 | * Google has three collections of web performance-related material available on their web.dev site: https://web.dev/learn/#collections
32 |
--------------------------------------------------------------------------------
/markup/README.md:
--------------------------------------------------------------------------------
1 | # Markup
2 |
3 | We utilise HTML5 for compiled markup.
4 |
5 | * [House style](house-style.md)
6 |
7 | [Main table of contents](../README.md#table-of-contents)
8 |
--------------------------------------------------------------------------------
/markup/house-style.md:
--------------------------------------------------------------------------------
1 | # Markup
2 |
3 | This document outlines the way we write markup and why. See our [house style document](../practices/house-style.md) to understand the rationale behind enforcement of style.
4 |
5 | - [HTML vs XHTML](#html-vs-xhtml)
6 | - [We author HTML 5](#we-author-html-5)
7 | - [Validation](#validation)
8 | - [Do not omit optional end tags](#do-not-omit-optional-end-tags)
9 | - [Implicitly close void elements](#implicitly-close-void-elements)
10 | - [Closing elements in embedded documents](#closing-elements-in-embedded-documents)
11 | - [Form submit controls](#form-submit-controls)
12 | - [Semantics](#semantics)
13 | - [Follow the HTML 4 outline model for heading levels](#follow-the-html-4-outline-model-for-heading-levels)
14 | - [Templating language](#templating-language)
15 |
16 | ## HTML vs XHTML
17 |
18 | HTML up to 3.2 was written with SGML syntax rules. HTML 4 could be written with either SGML syntax (HTML 4.01) or XML (XHTML 1.0). [HTML 5 breaks with SGML and has two serializations](https://www.w3.org/blog/2008/01/html5-is-html-and-xml/), a new one called "html" (which looks like SGML but is not an application of SGML) and again XML (XHTML).
19 |
20 | ### We author HTML 5
21 |
22 | When a document is transmitted with an XML MIME type, such as `application/xhtml+xml`, this is intended to instruct the client to render using an XML parser, and popular contemporary clients honour this. [See HTML vs XHTML on w3.org](https://www.w3.org/TR/html5/introduction.html#html-vs-xhtml).
23 |
24 | One of the benefits of XML is its strictness -- the flip-side of this benefit is that XML is not designed to fail safely. The internet, the web, and typical web clients are however designed to fail safely. This is a philosophical difference with practical implications.
25 |
26 | In professional web development, one typically has to rely on 3rd-party code which is executed in our domain, but under which we have no real control (advertisements, tracking code, resources served from 3rd-party CDNs, etc). Additionally accidents happen, and broken code goes live. So we must think defensively and cannot rely on the validity of our documents. When XHTML is served with an `application/xhtml+xml` MIME type, any errors introduce fatal errors in the document parser and completely unusable pages are the result.
27 |
28 | So for business purposes it is impractical to serve XHTML with anything other than a `text/html` MIME type. This means the client cannot leverage an XML parser and instead uses a regular HTML parser, so any XML benefits are lost to the client. Additionally it introduces cognitive dissonance (a document which is an application of XML not being treated as such), we are serving a heavier page over an HTML 5 equivalent for no client-side benefit, and we lose some HTML features with XHTML such as [NOSCRIPT](https://www.w3.org/TR/html5/scripting-1.html#the-noscript-element) (which still appears in 3rd-party code).
29 |
30 | It is not impossible to imagine a back-end markup-generation system that only outputs XHTML, but as any valid XHTML document is essentially expressible in HTML (the reverse is not true) this should be seen as a shortcoming in the markup generator, at least as far as the client is concerned.
31 |
32 | As such it seems beneficial to choose HTML 5 over XHTML.
33 |
34 | ### Validation
35 |
36 | Do what is reasonable to ensure your documents [validate](https://validator.w3.org/).
37 |
38 | Invalid markup results in authors relying on all clients to do what they intended, not what they instructed. Clients regularly disagree on how to interpret our instructions, yet alone our intentions, so to promote consistency of execution you must do what you can to ensure your HTML is valid.
39 |
40 | Additionally, invalid HTML violates WCAG 2.1 Success Criterion [4.1.1 Parsing](https://www.w3.org/TR/WCAG21/#parsing) (Level A), and areas where your product falls short must be noted on your product's VPAT, if it has one. It's probably easier just to make sure your HTML is valid in the first place.
41 |
42 | ### Do not omit optional end tags
43 |
44 | While the HTML 4 & 5 specs allow some end tags to be omitted for _some_ non-[void elements](https://www.w3.org/TR/html5/syntax.html#void-elements), it's unreasonable to expect authors to remember which elements this applies to. Additionally this kind of inconsistency can play havok with text editors, any indentation policy, and impairs our ability to spot bugs that would otherwise offend our pattern-recognition powers.
45 |
46 | We do this:
47 |
48 | ```html
49 |
50 | foo
51 | bar
52 |
53 | ```
54 |
55 | We *don't* do this:
56 |
57 | ```html
58 |
59 | foo
60 | bar
61 |
62 | ```
63 |
64 | ### Implicitly close void elements
65 |
66 | Explicitly closing void elements (e.g. `
`) is not invalid in HTML 5. However, explicitly closing void elements is an artifact of XML serialization, not HTML 5's "html" serialization, so may introduce cognitive dissonance in authors given that we are authoring HTML 5. Additionally, explicitly closing void elements was invalid in older versions of HTML.
67 |
68 | Conversely, it may be the case that their omission impacts authors more used to writing XML, or HTML with an XML serialization. However as far as machines are concerned, they increase page weight with zero benefit.
69 |
70 | We do this:
71 |
72 | ```html
73 |
74 | ```
75 |
76 | We *don't* do this:
77 |
78 | ```html
79 |
80 | ```
81 |
82 | #### Closing elements in embedded documents
83 |
84 | Sometimes we need to embed content from different markup languages in HTML, such as
85 | [SVG](https://developer.mozilla.org/en-US/docs/Web/SVG) or
86 | [MathML](https://developer.mozilla.org/en-US/docs/Web/MathML/).
87 |
88 | When embedding these markup languages in HTML, there is no need to specify an namespace on the root element as it will be provided by the HTML parser. See also the [SVG specs](https://svgwg.org/svg2-draft/struct.html#Namespace) and [Using MathML](https://developer.mozilla.org/en-US/docs/Web/MathML/Authoring#using_mathml).
89 |
90 | Because the namespace is provided by the HTML parser, we still do not need to explicitly close void elements.
91 |
92 | We do this:
93 |
94 | ```html
95 |
96 |
97 |
98 | ```
99 |
100 | We *don't* do this:
101 |
102 | ```html
103 |
104 |
105 |
106 | ```
107 |
108 | Conversely, if you were authoring for an XML document (including XHTML, EPUB) you would include the namespace and would therefore have to explicitly close void elements.
109 |
110 | ### Form submit controls
111 |
112 | In modern browsers, `button type="submit"` provides a superset of functionality when compared to `input type=submit`.
113 |
114 | `button` elements are much easier to style than `input` elements. You can add
115 | inner HTML content (think `
`, ``, or even ` `), and use
116 | `::after` and `::before` pseudo-elements to achieve complex rendering while
117 | `input` only accepts a textual value attribute.
118 |
119 | **Note**: Submitting is `button` default behaviour, but we want to "code for
120 | humans". Therefore do not ommit `type="submit"`.
121 |
122 | Make sure to specify `name` and `value` attributes to maximize browsers
123 | compatibility ([See IE11-Only Submit Bug on Stack
124 | Overflow](https://stackoverflow.com/a/22703881/9461391)).
125 |
126 | We do this:
127 |
128 | ```html
129 |
132 | ```
133 |
134 | We *don't* do this:
135 |
136 | ```html
137 |
140 | ```
141 |
142 | and
143 |
144 | We *don't* do this:
145 |
146 | ```html
147 |
150 | ```
151 |
152 | **Caution**: There is a shortcoming for Internet Explorer when using the `button`
153 | element. Indeed it submits the text within the `button` element as its value in
154 | the form data rather than the value of its `value` attribute.
155 | This becomes problematic when using multiple submit buttons in a single form with each a different value and purpose.
156 |
157 | Here are some suggestions to work around these:
158 |
159 | - Redesign the interface so multiple submit buttons are not required.
160 | - (Preferred) Use a multiple pages form as recommended by GOV.UK in [Structuring forms,
161 | Start with one thing per
162 | page](https://www.gov.uk/service-manual/design/form-structure#start-with-one-thing-per-page).
163 | - Replace them with radio buttons and a single submit button (requires an
164 | extra click from the user though);
165 | - Use a separate form for each instance, with a hidden `input` providing
166 | the data the submit `button` would normally carry. This can be a good
167 | solution when you have a simple “Delete this row” problem.
168 | - Last resort solution: Hide the value inside the name of the control. A loop
169 | over the names from the form data is needed in the business logic then. Please
170 | avoid as much as you can as this adds complexity to code and may degrade
171 | performance.
172 |
173 | ## Semantics
174 |
175 | ### Follow the HTML 4 outline model for heading levels
176 |
177 | When HTML 5 was first announced, it brought with it a plethora of new semantic elements and an entirely new document outline model which leveraged them to provide meaning. This was intended to supplant the HTML 4 model in which the heading level (h1 - h6) was used to imply the structure of the HTML document. See [Using HTML sections and outlines](https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/Using_HTML_sections_and_outlines) for more information.
178 |
179 | Unfortunately, this new document outline model was never well supported by browsers or assistive technologies. We considered sticking with the HTML 5 document outline model used in conjunction with setting ARIA attributes (`role="heading" aria-level="3"`) but this rather defeated any benefit from using the more localised heading levels, and was also poorly supported in some key assistive technologies.
180 |
181 | The HTML 5 document outline algorithm specification has been removed in HTML 5.1. You should continue to use the older HTML 4 style heading levels in conjunction with the new HTML 5 semantic elements. Do not use multiple H1 headings on a single page.
182 |
183 | See the HTML specification for [the current recommendation for use in all HTML 5 documents](https://www.w3.org/TR/html5/sections.html#the-h1-h2-h3-h4-h5-and-h6-elements).
184 |
185 | We do this:
186 |
187 | ```html
188 | Page title
189 |
190 |
191 | Article title
192 | Article subtitle
193 |
194 |
195 |
198 | ```
199 |
200 | We *don't* do this:
201 |
202 | ```html
203 | Page title
204 |
205 |
206 | Article title
207 | Article subtitle
208 |
209 |
210 |
213 | ```
214 |
215 | ## Templating language
216 |
217 | Templates should be written using [Handlebars](http://handlebarsjs.com/).
218 |
219 | Handlebars works in the browser, Node, and has been ported to the JVM-based languages we use server-side.
220 |
221 | This enables us to share the same templates across the variety of environments we commonly use. Also Handlebars is a well-documented, stable technology with "good enough" compatibility between implementations (although handlebars helpers are an exception).
222 |
--------------------------------------------------------------------------------
/performance/README.md:
--------------------------------------------------------------------------------
1 | # Performance
2 |
3 | Performance refers to the speed in which web pages are downloaded and displayed on the user's browser.
4 |
5 | Faster page speeds have been shown to increase visitor retention and user satisfaction, especially for users with slow internet connections and those on mobile devices. Improved web performance also leads to less data travelling across the web, which in turn lowers a website's power consumption and environmental impact.
6 |
7 | - [Advertising](advertising.md)
8 | - [Browser caching](browser-caching.md)
9 | - [Font loading](font-loading.md)
10 | - [Images](images.md)
11 | - [Performance checklist](performance-checklist.md)
12 |
13 | [Main table of contents](../README.md#table-of-contents)
14 |
--------------------------------------------------------------------------------
/performance/advertising.md:
--------------------------------------------------------------------------------
1 | # Advertising
2 |
3 | - [Ethical](#ethical)
4 | - [Accessibility](#accessibility)
5 | - [Performance](#performance)
6 | - [References](#references)
7 |
8 | These guidelines are based on ethical, [accessibility](../accessibility/README.md) and performance recommendations and best practices.
9 |
10 | ## Ethical
11 |
12 | * Do use clear, intelligible, and unambiguous information.
13 | * Don't use ads that are misleading. For example, "trick banners" that look like part of the operating system UI.
14 | * Don't use ads that advertise businesses that participate in spammy or scammy practices.
15 | * Don't use images that convey a false sense of urgency.
16 | * Don't advertise products with obvious exaggerations or dubious claims that are impossible to prove.
17 | * Don't advertise "free" products or services that have hidden costs or charges.
18 | * Don't advertise gambling, alcohol and tobacco.
19 | * Don't use [pop-under ads](https://en.wikipedia.org/wiki/Pop-up_ad#Pop-under_ads).
20 | * Adverts must not contain spyware, malware or any software that results in an unexpected or deceptive experience. This includes links to sites containing these products.
21 |
22 | ## Accessibility
23 |
24 | * Don't use ads that make use of fast animations or flashing content.
25 | * The ad content must have clearly defined borders and not be confused with normal page content.
26 | * Audio or video in ads must be user initiated. A control must be included in order to allow for audio/video initiation and stop.
27 |
28 | All advertising must also comply with the rest of our [accessibility guidelines](../accessibility/06-accessibility-checklist.md).
29 |
30 | ## Performance
31 |
32 | * Do load ads asynchronously.
33 | * Don't use ads that add a significant size to the page.
34 | * Do use a maximum of 15 file requests for initial file load, as per the [IAB display advertising guidelines](https://www.iab.com/guidelines/iab-display-advertising-guidelines/).
35 | * All assets must be packaged together for delivery. All assets should be delivered in compressed format (e.g. GZIP).
36 |
37 | ## References
38 |
39 | * IAB Display Advertising Guidelines
40 | [https://www.iab.com/guidelines/iab-display-advertising-guidelines/](https://www.iab.com/guidelines/iab-display-advertising-guidelines/)
41 |
42 | * UK Code of Non-broadcast Advertising and Direct & Promotional Marketing (CAP Code) [https://www.asa.org.uk/codes-and-rulings/advertising-codes/non-broadcast-code.html](https://www.asa.org.uk/codes-and-rulings/advertising-codes/non-broadcast-code.html)
43 |
44 | * Advertising Standards Authority (ASA)
45 | [https://www.asa.org.uk/](https://www.asa.org.uk/)
46 |
47 | * Facebook Advertising Policies
48 | [https://www.facebook.com/policies/ads](https://www.facebook.com/policies/ads)
49 |
50 | * Pinterest Advertising Standards
51 | [https://about.pinterest.com/en/advertising-standards](https://about.pinterest.com/en/advertising-standards)
52 |
53 | * LinkedIn Advertising Guidelines
54 | [https://www.linkedin.com/legal/sas-guidelines](https://www.linkedin.com/legal/sas-guidelines)
55 |
--------------------------------------------------------------------------------
/performance/browser-caching.md:
--------------------------------------------------------------------------------
1 | # Browser caching
2 |
3 | - [HTML Markup](#html-markup)
4 | - [CSS, JS and Images](#css-js-and-images)
5 | - [General](#general)
6 | - [Further resources](#further-resources)
7 |
8 | ## HTML Markup
9 |
10 | * Serve these with a `Cache-Control: no-cache` header. This will instruct the browser to cache locally but only after checking with the server that the content hasn’t changed. Note that `no-cache` does NOT mean "don’t cache", rather it tells the browser to always revalidate when the resource is requested. `no-store` tells the browser not to cache at all, which isn’t usually desirable.
11 | * See [Caching best practices](https://jakearchibald.com/2016/caching-best-practices/) for more information.
12 |
13 | ## CSS, JS and Images
14 |
15 | * Set a long `max-age` eg: `Cache-Control: max-age: 31536000` (one year). The `max-age` directive states the maximum amount of time in seconds that fetched responses are allowed to be used again (from the time when a request is made) and because content on these URLs typically don't change, it is safe to cache them for really long periods.
16 | * Use a [cache-busting](https://www.keycdn.com/support/what-is-cache-busting) mechanism for versioning assets to ensure that the browser caches each version as a different URL. Example: `sncss-29d48c7.css` or `sncss.js?v=29d48c7` where “_29d48c7_” is an auto-generated number unique to every version of the file. Frameworks like [Shunter](https://github.com/springernature/shunter) use the filename version style which is preferred.
17 |
18 | ## General
19 |
20 | * If it is under your control, ensure the server provides an Entity Tag (`ETag`) header. The `ETag` header is an additional identifier for a specific version of a resource, typically comprised of the modified time and file size. (On older systems the ETag may also include an inode portion, but this is problematic.) The `Etag` header is especially useful to prevent simultaneous updates overwriting each other. If you use a CDN, it is likely this header will already be provided and properly configured. Learn more:
21 | * [MDN ETag](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/ETag)
22 | * [Express options for 'ETag' setting](https://expressjs.com/en/api.html#etag.options.table)
23 | * You no longer need to use [`Expires` headers](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Expires) as it has been superseded by `Cache-Control` header with `max-age`, which is [supported by modern browsers](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control#Browser_compatibility).
24 |
25 | It’s important to note that there isn’t a one-size-fits-all approach to caching, so always decide a caching strategy based on your needs.
26 |
27 | ## Further resources
28 |
29 | * [Web Fundamentals: HTTP Caching](https://developers.google.com/web/fundamentals/performance/optimizing-content-efficiency/http-caching)
30 | * [HTTP Cache Headers: A Complete Guide](https://www.keycdn.com/blog/http-cache-headers)
31 |
--------------------------------------------------------------------------------
/performance/font-loading.md:
--------------------------------------------------------------------------------
1 | # Font loading
2 |
3 | - [When to use webfonts](#when-to-use-webfonts)
4 | - [Implementation](#implementation)
5 | - [Quick tips](#quick-tips)
6 | - [Understand the different user experiences in font loading: FOIT, FOUT and FOFT](#understand-the-different-user-experiences-in-font-loading-foit-fout-and-foft)
7 | - [Understand the different implementations available](#understand-the-different-implementations-available)
8 | - [WOFF and WOFF2 font formats](#woff-and-woff2-font-formats)
9 | - [font-display CSS](#font-display-css)
10 | - [Loading fonts with JavaScript](#loading-fonts-with-javascript)
11 | - [Preloading webfonts](#preloading-webfonts)
12 | - [Self host webfonts if possible](#self-host-webfonts-if-possible)
13 |
14 | ## When to use webfonts
15 |
16 | Webfonts allow us to bring emotion, personality and tone to our sites - which can make them more successful.
17 |
18 | However, the task of choosing a webfont and implementing it on your site should be approached cautiously. Webfonts have the potential to impact aspects of your sites such as accessibility and page speed. For example:
19 |
20 | - Certain webfonts may reduce the readability of the site, for example for people with dyslexia, or low vision.
21 | - Webfonts can negatively impact page performance (additional http requests and increased page weight) especially in markets of strategic importance for Springer Nature like China. This will in turn impact usage numbers.
22 |
23 | Our recommendation is that you prioritise a [system font](https://css-tricks.com/snippets/css/system-font-stack/) over a webfont. System fonts are extensively tested, and incur no performance penalty.
24 |
25 | If a webfont is needed then close collaboration between user experience, accessibility, and web performance specialists must be sought to ensure the choice is satisfactory from typographic, accessibility, and performance perspectives.
26 |
27 | As a Frontend Developer, it's your role to provide technical guidance and feedback, not to choose the font.
28 |
29 | ## Implementation
30 |
31 | We do not prescribe a particular implementation. Each team should determine which implementation is best suited for them. However, before selecting an implementation a team should be mindful of our working practices such as:
32 |
33 | - [Graded Browser Support](https://github.com/springernature/frontend-playbook/blob/main/practices/graded-browser-support.md)
34 | - Is the implementation supported by all "enhanced" browsers? If not, is there a good justification for selecting it anyway?
35 | - Does the implementation work in conjunction with the Cut The Mustard technique?
36 | - [Progressive Enhancement](https://github.com/springernature/frontend-playbook/blob/main/practices/progressive-enhancement.md)
37 | - This is not meant to force you to choose a non-js implementation, but rather for you to ensure you consider what will happen for users in varying circumstances from the beginning.
38 | - [Our Performance Goals](https://github.com/springernature/frontend-playbook/blob/main/performance/performance-checklist.md)
39 | - What impact will the implementation have on the page performance of your site?
40 |
41 | ## Quick tips
42 |
43 | Here are some quick suggestions for techniques that may prove useful:
44 |
45 | ### Understand the different user experiences in font loading: FOIT, FOUT and FOFT
46 |
47 | - FOIT means _flash of invisible text_. Text on the page is hidden while webfonts are loading, so users will see a page with images but no text. We only show the text when webfonts are loaded.
48 | - FOUT means _flash of unstyled text_. When webfonts are loading, we show users a system font. When the webfont gets loaded, we change the text back to the desired webfont.
49 | - FOFT means _flash of faux text_. Only load the roman character set initially and load the others later for less page render blocking. "Faux" refers to the fact the browser fakes italics and bold before those character sets have loaded.
50 |
51 | We believe that FOIT should be avoided as it is the worst experience for the user.
52 |
53 | ### Understand the different implementations available
54 |
55 | We highly recommend reading [Zach Leat's comprehensive guide](https://www.zachleat.com/web/comprehensive-webfonts/) to get a good understanding of the different techniques available. There is also a good [follow-up article](https://css-tricks.com/the-best-font-loading-strategies-and-how-to-execute-them/) that summarises Zach's findings.
56 |
57 | ### WOFF and WOFF2 font formats
58 |
59 | WOFF2 has a superior compression, and [is supported by all of our Enhanced browsers](https://caniuse.com/woff2), so there's no need to serve fonts in WOFF format.
60 |
61 | ### [font-display CSS](https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display)
62 |
63 | [`font-display`](https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display) is useful and has the benefit of being a technique that does not require JavaScript and is easy and straight forward to implement.
64 |
65 | We recommend reading this [comprehensive analysis of font-display](https://calendar.perfplanet.com/2020/a-font-display-setting-for-slow-connections/) values when deciding which value is best for you.
66 |
67 | ### Loading fonts with JavaScript
68 |
69 | Consider using [FontFaceObserver](https://github.com/bramstein/fontfaceobserver) instead of the [CSS Font Loader API](https://drafts.csswg.org/css-font-loading/), as the latter does not have support for all our Enhanced browsers.
70 |
71 | ### Preloading webfonts
72 |
73 | If you have to load a font the conventional way using a ` ` then consider using the [preload technique](https://web.dev/preload-critical-assets/) to ensure the font is requested as early on in the page load process as possible.
74 |
75 | ` `
76 |
77 | ### Self host webfonts
78 |
79 | Any webfonts you use must be self-hosted - avoid using a font-hosting service.
80 |
81 | Every major browser now implements HTTP cache partitioning in order to prevent leaking of the users' browser history, and avoid cross-site tracking and cross-site search attacks. This means that there's no performance benefit from using an external service to host our webfonts.
82 |
83 | Using an external font-hosting service can actually worsen performance in important markets like China, as opening a connection to a new host can sometimes be very slow, or even fail completely, due to the filtering done by the Great Firewall.
84 |
85 | But most importantly, using external font-hosting services we risk passing personally identifiable information (PII) from your users to those font-hosting services, increasing the risk of litigation.
86 |
--------------------------------------------------------------------------------
/performance/images.md:
--------------------------------------------------------------------------------
1 | # Images
2 |
3 | - [Introduction](#introduction)
4 | - [Picking the right image format](#picking-the-right-image-format)
5 | - [Image formats](#image-formats)
6 | - [SVG images](#svg-images)
7 | - [JPEG images](#jpeg-images)
8 | - [PNG images](#png-images)
9 | - [Optimisation of images](#optimisation-of-images)
10 | - [Serving images](#serving-images)
11 | - [Comparing the quality of images](#comparing-the-quality-of-images)
12 |
13 | This document describes best practices for the use of images on the web at Springer Nature.
14 |
15 | ## Introduction
16 |
17 | In a frontend workflow we typically deal with two different categories of images:
18 |
19 | * **User interface images**. These include icons, logos, buttons, and any other image that is part of the user. Usually managed by the frontend, these are stored with other client-side resources such as templates, CSS and JS. Like those resources, they may be shared between many different pages.
20 |
21 | * **Content images**. These are unique to a page, or a handful of pages. They will usually be provided from a database or a content management system.
22 |
23 | Most best practices described in this document apply to both categories unless otherwise indicated.
24 |
25 | ## Picking the right image format
26 |
27 | * Use [SVG](https://en.wikipedia.org/wiki/Scalable_Vector_Graphics) for icons, logos, and other images with sharply defined edges.
28 | * Use [JPEG](https://en.wikipedia.org/wiki/JPEG) for still images, photographs, and in any other cases where using a PNG would result in an image too large to be delivered over the network effectively.
29 | * Use [PNG](https://en.wikipedia.org/wiki/Portable_Network_Graphics) for illustrations, graphs, flat-colour graphics, images containing transparency (which JPEG doesn't support), and images containing text.
30 | * Use [MP4](https://en.wikipedia.org/wiki/MPEG-4_Part_14) for any kind of animated images.
31 | * Do not use [GIFs](https://en.wikipedia.org/wiki/GIF). The file size of animated GIF images is usually an order of magnitude bigger than MP4s of similar quality. They can be a barrier that prevents users from accessing our content, especially in markets where slower connections and low performing devices are more common. For static images with transparency, an 8-bit PNG can be used to deliver an indexed colour image, with binary transparency, [at a smaller size than a GIF](https://helpx.adobe.com/photoshop-elements/using/optimizing-images-gif-or-png.html).
32 |
33 | A number of more modern image formats can also be used to deliver images:
34 |
35 | * [WebP](https://en.wikipedia.org/wiki/WebP) is a replacement for JPEG, PNG, and GIFs, but improvements to encoders like [mozjpeg](https://github.com/mozilla/mozjpeg) means that [WEBP file sizes are only marginally smaller than JPEG](https://siipo.la/blog/is-webp-really-better-than-jpeg). It's supported by almost all major browsers ([Safari supports it partially](https://caniuse.com/webp)) and must be used only as an enhancement to another better supported format.
36 | * [AVIF](https://en.wikipedia.org/wiki/AVIF) is suitable for static and animated images, and supports both lossy and lossless compression with better compression efficiency and better detail preservation than other formats. It's [supported by Chrome and Firefox](https://caniuse.com/avif), and can be used only as an enhancement to another better supported format. Compression (encoding) of images can be significantly slower than with other formats.
37 | * [JPEG-XL](https://en.wikipedia.org/wiki/JPEG_XL) supports both lossy and lossless compression. It's [more efficient than other formats while being usually faster](https://cloudinary.com/blog/how_jpeg_xl_compares_to_other_image_codecs) both when compressing and decompressing than JPEG. Unfortunately, as of November 2022 [no browser officially supports it](https://caniuse.com/jpegxl) and [Google has announced that it's removing preliminary support from Chrome](https://www.theregister.com/2022/10/31/jpeg_xl_axed_chrome/), in favour of AVIF.
38 |
39 | ## Image formats
40 |
41 | ### SVG images
42 |
43 | Always minify your SVGs using [SVGO](https://github.com/svg/svgo) or a similar tool.
44 |
45 | ### JPEG images
46 |
47 | When encoding JPEG images:
48 |
49 | * Use progressive encoding. [Progressive JPEGs provide a better user experience and, most of the time, are smaller than baseline](https://github.com/yeoman/yeoman/issues/810).
50 | * Use [4:2:0](https://en.wikipedia.org/wiki/Chroma_subsampling#4:2:0) [chroma subsampling](https://en.wikipedia.org/wiki/Chroma_subsampling) whenever possible. This encodes the colour information at half the resolution of the luma, usually generating smaller images. It may however result in a perceptible loss of colour accuracy, so we suggest to create both 4:4:4 and 4:2:0 versions of an image and compare them for any quality loss. See [Comparing the quality of images](#comparing-the-quality-of-images) below for tools that can help you with this.
51 | * Use encoders like [Mozilla's mozjpeg](https://github.com/mozilla/mozjpeg) that can create images with the same visual quality as other encoders but a much smaller file size.
52 |
53 | ### PNG images
54 |
55 | Always use the maximum compression level (9).
56 |
57 | ## Optimisation of images
58 |
59 | Images can contribute significantly to the size of a page, so it's important to optimise them before they are delivered to the user. This helps ensure that our sites stay performant and we're not preventing anyone from accessing them due to increased page weight. Common optimisations include:
60 |
61 | * Making sure that you save images using an [sRGB](https://en.wikipedia.org/wiki/SRGB) ICC profile. Although modern browsers support images with ICCv2 profiles like [Adobe RGB](https://en.wikipedia.org/wiki/Adobe_RGB_color_space) and even [ProPhoto RGB](https://en.wikipedia.org/wiki/ProPhoto_RGB_color_space), colour space issues are extremely difficult to debug. Saving the images as sRGB and removing the colour profile is encouraged.
62 | * Stripping the metadata from the image. This includes things like EXIF data, Copyright information (unless required), GPS data, colour profiles, thumbnails (in JPEGs), comments, and others.
63 | * [Setting appropriate cache headers for the images](#serving-images).
64 |
65 | For images that are going to be included in a repository, tools like [ImageOptim](https://imageoptim.com/mac) can be used to optimise them and strip the metadata before committing them to your codebase. There's also an [ImageOptim-CLI](https://github.com/JamieMason/ImageOptim-CLI) that can be integrated with CI systems.
66 |
67 | If an image is still too big after following all these optimisations, other options can be used that will require editing the image. These can be used to generate images with a much smaller size than otherwise would be possible:
68 |
69 | * Reducing or completely eliminating noise and other complexity from the image, which makes it easier to compress.
70 | * Blurring unimportant areas will also make the image easier to compress.
71 | * Finally, decreasing the export quality may be required if the image is still too big.
72 |
73 | ## Serving images
74 |
75 | We work under the assumption that images are encoded only once but decoded many times. Therefore, increased encoding times, while undesirable, are usually secondary to other concerns like making the image easier to decompress, or having a smaller file size.
76 |
77 | When optimising non-content images that are going to be committed to a repo, make sure you always use the maximum settings if you're using lossless optimisations.
78 |
79 | For content images, we encourage using an on-premise or cloud-based image server in order to:
80 |
81 | * Ensure that all images are optimised automatically.
82 | * Ensure that the appropriate cache headers are always set.
83 |
84 | As an additional benefit, changes to these tools may result in improvements to the images being served automatically, without the images having to be manually re-encoded.
85 |
86 | ## Comparing the quality of images
87 |
88 | When comparing the output of two different image compression formats, algorithms, or quality settings, [tools that calculate the similarity between images](https://github.com/kornelski/dssim) with algorithms like [SSIM](http://en.wikipedia.org/wiki/Structural_similarity) and [DSSIM](https://github.com/kornelski/dssim) can be used to get an objective idea of the trade-off between quality and byte size.
89 |
--------------------------------------------------------------------------------
/performance/performance-checklist.md:
--------------------------------------------------------------------------------
1 | # A simple performance checklist
2 |
3 | Web performance is an important consideration in everything that we build, from the early design stages, until a product has reached end-of-life.
4 |
5 | This checklist aims to help you and your team create performant products.
6 |
7 | Remember that, for most of these rules, there's always the chance that following them may impact performance in a negative way. Always use [any of the tools below](#tooling) to run before/after comparisons.
8 |
9 | - [HTTP Requests](#http-requests)
10 | - [Page weight](#page-weight)
11 | - [Render blocking resources](#render-blocking-resources)
12 | - [The critical rendering path](#the-critical-rendering-path)
13 | - [Post launch](#post-launch)
14 | - [Tooling](#tooling)
15 | - [Further resources](#further-resources)
16 |
17 | ## HTTP Requests
18 |
19 | A lower number of requests is directly related to better performance and higher user engagement. Make sure that the [number of HTTP requests is as small as possible](https://learning.oreilly.com/library/view/high-performance-web/9780596529307/ch03.html) by:
20 |
21 | * Ensuring that there are [no redirects](https://learning.oreilly.com/library/view/high-performance-web/9780596529307/ch13.html) on the page itself or in any of the first party resources.
22 | * Concatenating first party CSS and JS, when suitable. **This is true even when using HTTP2**.
23 | * Ensuring that no first party resources are returning HTTP 4xx or 5xx errors.
24 | * Serve first party resources from as few different domains as possible in order to [reduce DNS lookups](https://www.oreilly.com/library/view/high-performance-web/9780596529307/ch11.html).
25 |
26 | ## Page weight
27 |
28 | Another important factor that impacts user engagement is [the size of the resources](https://blog.chriszacharias.com/page-weight-matters). On low performing networks or devices, the size of the resources being loaded can delay the loading of the page by several seconds and increase power consumption significantly.
29 |
30 | * [Minify all text resources](https://learning.oreilly.com/library/view/high-performance-web/9780596529307/ch12.html) over 1500 bytes.
31 | * Ensure that all text resources over 1500 bytes use Brotli or [GZip compression](https://learning.oreilly.com/library/view/high-performance-web/9780596529307/ch06.html).
32 | * [Choose the right format for images, and optimise images and SVGs](images.md).
33 | * Set an [appropriate expiry date or a maximum age](browser-caching.md#css-js-and-images) for all static resources.
34 | * For resources that change rarely, consider [fingerprinting them](https://developers.google.com/web/fundamentals/performance/optimizing-content-efficiency/http-caching) and setting a expiry date [far in the future](https://developers.google.com/web/tools/lighthouse/audits/cache-policy).
35 |
36 | ## Render blocking resources
37 |
38 | CSS and JS resources can be [render blocking](https://developers.google.com/web/tools/lighthouse/audits/blocking-resources), meaning that the browser will pause rendering of a page while a CSS file or a synchronous JS file or script are being loaded. On slow connections this can delay the page load by several seconds. Ensure there are as few render blocking resources as possible by:
39 |
40 | * Using [`async` or, when possible, `defer` attributes](https://www.growingwiththeweb.com/2014/02/async-vs-defer-attributes.html) in all JavaScript files.
41 | * Only loading synchronously the smallest amount of CSS needed to render the page. [Load the rest of the CSS asynchronously](https://www.filamentgroup.com/lab/load-css-simpler/).
42 |
43 | ## The critical rendering path
44 |
45 | The [critical rendering path](https://developers.google.com/web/fundamentals/performance/critical-rendering-path/analyzing-crp) is made up by the resources that are required in order for the browser to complete rendering the current view. By optimizing the critical rendering path you can improve the time to first render of our pages.
46 |
47 | * Study the waterfall and find out which resources are in the critical path. Make them load earlier by using [`rel="dns-prefetch"` and `rel="preconnect"`](https://www.keycdn.com/blog/resource-hints) resource hints as appropriate.
48 | * Ensure that resources [like CSS](https://web.dev/defer-non-critical-css/) that are _not_ in the critical path are loaded asynchronously or lazy-loaded when possible.
49 |
50 | ## Post launch
51 |
52 | * Add the site to [SpeedCurve](https://speedcurve.com) for continuous performance monitoring and alerting.
53 |
54 | ## Tooling
55 |
56 | The following tools can be used to run performance tests on one or more pages:
57 |
58 | * [WebPageTest](https://www.webpagetest.org/): The standard tool for synthetic web performance testing.
59 | * [SpeedCurve](https://speedcurve.com/): A tool that automates running tests on WebPageTest and provides graphs, trends, and alerts.
60 | * A private WebPageTest instance is available to help with use cases not covered by the two previous tools.
61 |
62 | Contact the Frontend Enablement team if you need access to any of these three tools.
63 |
64 | ## Further resources
65 |
66 | * [MDN web docs: Web performance](https://developer.mozilla.org/en-US/docs/Learn/Performance)
67 |
--------------------------------------------------------------------------------
/practices/README.md:
--------------------------------------------------------------------------------
1 | # Practices
2 |
3 | Development of products at Springer Nature is informed by two primary constraints:
4 |
5 | * The products that Springer Nature produce are used in an enormous variety of contexts, by an enormous variety of users, all of them spread across the planet. We have no way of knowing the situation that any given user could be in. We must deal with:
6 | * The variety of technical conditions: Device; operating system; network connection; CPU; browser; screen size; interface; institutional network policies; browser extensions; ISP-injected scripts.
7 | * The infinite variety of the human experience: User context; user disabilities; user time limits; user financial status.
8 | * We have a number of obligations to ensure our products conform to the WCAG 2.1 guidelines, to the “AA” level of Success Criteria.
9 |
10 | * [Code reviews](code-review.md)
11 | * [(Graded) Browser support](graded-browser-support.md)
12 | * [House style](house-style.md)
13 | * [Javascript dependent styling](javascript-styling.md)
14 | * [Managing node projects](managing-node-projects.md)
15 | * [Managing static assets](managing-static-assets.md)
16 | * [Open source support](open-source-support.md)
17 | * [Progressive enhancement](progressive-enhancement.md)
18 | * [Structured data](structured-data.md)
19 |
20 | [Main table of contents](../README.md#table-of-contents)
21 |
--------------------------------------------------------------------------------
/practices/code-review.md:
--------------------------------------------------------------------------------
1 | # Code reviews
2 |
3 | * [Why do them?](#why-do-them)
4 | * [What to look out for](#what-to-look-out-for)
5 |
6 | Code Review, or Peer Code Review, is the act of having your code checked by others for mistakes, errors, and omissions (e.g. missing tests). Like pair-programming (which we also support), it accelerates and streamlines software development.
7 |
8 | While we can support "traditional" Code Reviews, [we routinely review via **pull requests**](../git/git.md#pull-requests). These are communicated in the `#frontend-pr` Slack channel, and managed via GitHub. Discussion should happen in the GitHub comments, not Slack.
9 |
10 | Requesters merge their own changes when they're ready. Keep your fingers off that tempting green merge button.
11 |
12 |
13 | ## Why do them?
14 |
15 | **PR reviews are cross-team, thereby helping to foster discussion and feedback**
16 |
17 | 1. Knowledge sharing and transfer within and between teams:
18 | * Allows everyone to learn from their colleagues.
19 | * Allows greater visibility and familiarity of other team's work.
20 | * Helps prevent knowledge silos or domain-specific codebases.
21 | * Allows FEDs to share expertise.
22 | 1. Standards compliance across teams:
23 | * Aids the ability for developers to easily move between teams.
24 | * Ensures changes to codebase conforms to the same standards and guidelines.
25 | * Helps identify areas where code re-use are beneficial ("should that be a component?").
26 | * Helps identify areas of compliance, which are missed during development.
27 | * Fosters caution and code quality over temporary hacks.
28 | 1. Prepares people for work on [open source software projects](https://github.com/springernature/open-source-directory).
29 | 1. Generally aids onboarding and training.
30 |
31 |
32 | ## What to look out for
33 |
34 | * **Accessibility**
35 |
36 | * [Accessibility](../accessibility/06-accessibility-checklist.md) problems. Suggest testing with [pa11y](https://github.com/pa11y) and/or other tools.
37 | * [pa11y dashboard](http://pa11y.springernature.com/) _(link only works if inside the Springer Nature VPN)_
38 |
39 | * **Complexity**
40 |
41 | * [Overly complex code](https://www.codesimplicity.com/post/what-is-overengineering/): code that solves problems we don't have, or makes things more complex instead of less.
42 | * Code that introduces [out-of-date](https://docs.npmjs.com/cli/outdated) or unnecessary dependencies into the project.
43 | * Changes which may have wider ramifications than the author anticipated. Double check they are aware which can of worms they have just opened :)
44 |
45 | * **Performance**
46 |
47 | * [Premature](http://wiki.c2.com/?PrematureOptimization) and/or micro optimisations.
48 | * Non-performant code. Suggest testing with [Lighthouse](https://developers.google.com/web/tools/lighthouse/), [SpeedCurve](https://speedcurve.com), [WebPageTest](https://www.webpagetest.org/) and/or other tools.
49 |
50 | * **Scope**
51 |
52 | * [PRs which are non-atomic](https://medium.com/@fagnerbrack/one-pull-request-one-concern-e84a27dfe9f1) and should be split into separate PRs, e.g. a new UI feature combined with an unrelated configuration change.
53 | * Code which could be split up into reusable modules.
54 |
55 | * **Security**
56 |
57 | * Code that adds dependencies that contain known vulnerabilities. Suggest testing with tools like [npm audit](https://docs.npmjs.com/cli/v8/commands/npm-audit), [Snyk](https://snyk.io) (for open source repos) and/or [White Source](https://www.whitesourcesoftware.com/) (for private repos).
58 |
59 | * **Syntax**
60 | * Syntactic inconsistencies the [linter](https://github.com/springernature/frontend-playbook/blob/main/practices/house-style.md#linting) did not catch.
61 |
--------------------------------------------------------------------------------
/practices/graded-browser-support.md:
--------------------------------------------------------------------------------
1 | # Browser support
2 |
3 | This page describes the way that we support different browsers and browser versions when building sites at Springer Nature.
4 |
5 | * [Our criteria for browser support](#our-criteria-for-browser-support)
6 | * [Rationale](#rationale)
7 | * [Browser support list](#browser-support-list)
8 | * [Grey area browsers](#grey-area-browsers)
9 | * [Implementing browser support](#implementing-browser-support)
10 | * [Implementation details](#implementation-details)
11 | * [.browserslist](#browserslist)
12 | * [Caveats](#caveats)
13 | * [Browsers without TLS 1.2 support](#browsers-without-tls-12-support)
14 |
15 | ## Our criteria for browser support
16 |
17 | We follow the principles of [Progressive Enhancement](progressive-enhancement.md) and implement it using a variant of [Yahoo's Graded Browser support](https://github.com/yui/yui3/wiki/Graded-Browser-Support) (a concept originally conceived by [Nate Koechley](https://web.archive.org/web/20060304042737/http://developer.yahoo.net/yui/articles/gbs/gbs.html)).
18 |
19 | Our approach to browser support works by classifying all versions of all browsers into one of two levels:
20 |
21 | * **"Core"** is our universal support level. We serve all browsers at this level server-side rendered semantic HTML and minimal CSS. Essential user journeys must be accessible at this level.
22 | * **"Enhanced"** is our support level for modern and/or [evergreen browsers](https://www.techopedia.com/definition/31094/evergreen-browser). As well as the Core HTML and CSS, we serve these browsers JavaScript and more advanced CSS, giving them a more interactive and visually pleasing product experience.
23 |
24 | ### Rationale
25 |
26 | There are two motivators for approaching browser support like we do:
27 |
28 | * We must support all users. No matter their device, browser, or network condition, the user should find a working and robust product.
29 | * We should apply effort efficiently. It is both impractical _and_ counterproductive [making advanced CSS and JavaScript work in older browsers](https://en.wikipedia.org/wiki/Pareto_principle#In_software). Attempting to do so results in fragile sites, code bloat, and no benefit for users.
30 |
31 | ## Browser support list
32 |
33 | This is the current list of browser versions and their corresponding support level:
34 |
35 | | Browser | Enhanced | Core |
36 | | --------------- |:------------------:| ------------------:|
37 | | Chrome | 76+ | < 76 |
38 | | Edge | 79+ | < 79 |
39 | | Firefox | 67+ | < 67 |
40 | | Opera | 62+ | < 62 |
41 | | Safari iOS | 13+ | < 13 |
42 | | Safari MacOS | 12.1+ | < 12.1 |
43 | | Android Webview | 91+ | < 91 |
44 | | Internet Explorer | N/A | all |
45 |
46 | ### Grey area browsers
47 |
48 | Nightly or developer versions of evergreen browsers exist in the grey area outside Enhanced and Core levels. We serve these grey area browsers the Enhanced version of a site, so they will receive the full experience. Due to resourcing limitations we do not specifically test our products against them - however we do expect them to work (because, for example, [we strive to provide compatible CSS via Autoprefixer](#browserslist)). Over time, analysis of errors and usage patterns may cause some browsers in this grey area to be deliberately changed to either Enhanced or Core, to allow for better support.
49 |
50 | ## Implementing browser support
51 |
52 | Our primary approach to classifying a browser support level is the "[Cutting the Mustard (CTM)](https://responsivenews.tumblr.com/post/18948466399/cutting-the-mustard)" progressive enhancement technique, based upon the principles developed by the BBC.
53 |
54 | This approach works by using feature detection in order to determine which browsers will receive the full Enhanced experience (i.e. they "[cut the mustard](https://en.wiktionary.org/wiki/cut_the_mustard)") and which ones will receive only the Core experience.
55 |
56 | ### Implementation details
57 |
58 | All browser versions load a basic stylesheet that contains only [normalisation](https://necolas.github.io/normalize.css/) and a few small enhancements to the user-agent stylesheet (typically max-width layout and colour and logo branding).
59 |
60 | We then use CSS media queries to detect capable browsers. Unlike the approach described by the BBC, we don't use a JavaScript-based featured detection. We want users to have the best possible experience even if JavaScript is not available.
61 |
62 | To load the full experience only in Enhanced browsers we implement logic in the media attribute of the ` ` element that identifies the main stylesheet, loading the stylesheet only in browsers that recognise the properties of that media query:
63 |
64 | ```html
65 |
66 | ```
67 |
68 | This technique is documented in [Cutting the Mustard with Media queries](https://www.sitepoint.com/cutting-the-mustard-with-css-media-queries/). The specific media queries we use are based upon [CSS Only Mustard Cut](https://github.com/Fall-Back/CSS-Mustard-Cut), with a preference towards combining them into one rather than separating them out into multiple ` ` elements. Note that you **cannot** add line breaks to the media query if they are combined.
69 |
70 | We couple the loading of JavaScript to the loading of the enhanced CSS. We use the [window.matchMedia](https://developer.mozilla.org/en/docs/Web/API/Window/matchMedia) API to detect when the browser loads the CSS within the media query. Once the enhanced CSS loads, this will cause the JavaScript code to load too.
71 |
72 | ```javascript
73 | (function() {
74 | var linkEl = document.getElementById('enhanced-stylesheet');
75 | if (window.matchMedia && window.matchMedia(linkEl.media).matches) {
76 | var script = document.createElement('script');
77 | script.src = 'enhanced-script.js';
78 | script.async = true;
79 | document.body.appendChild(script);
80 | }
81 | })();
82 | ```
83 |
84 |
85 | ### .browserslist
86 |
87 | While we do not test [grey-area browsers](#grey-area-browsers), we still work towards the best experience for all our users. CSS for grey-area browsers should therefore be prefixed using [Autoprefixer](https://github.com/postcss/autoprefixer). Automatically adding vendor prefixes allows us to increase support for these browsers with little extra effort.
88 |
89 | The following `.browserslistrc` file ([a standard way of sharing target browser data](https://github.com/browserslist/browserslist)) should cover all browsers that receive Enhanced CSS according to our [Browser Support list](#browser-support-list).
90 |
91 | ```nanorc
92 | defaults
93 | not ie 11
94 | ff > 66
95 | chrome > 75
96 | safari > 11
97 | edge > 78
98 | opera > 61
99 | ```
100 |
101 | ## Caveats
102 |
103 | ### Browsers without TLS 1.2 support
104 |
105 | As of June 2018, all our sites are served through HTTPS using the [TLS 1.2 cryptographic protocol](https://en.wikipedia.org/wiki/Transport_Layer_Security#TLS_1.2) or newer. This means that users of browsers that don't support TLS 1.2 (e.g. Safari on iOS 4) will not be able to access our sites. Browsers that have support for TLS 1.2 not enabled by default (e.g. Internet Explorer on Windows 7) will not be able to access our sites, unless they change their default settings. We consider that this is required in order to keep our users secure.
106 |
107 | The way that we restrict the connection to our sites when not using TLS 1.2 doesn't impact the way that we design and build our sites and our commitment to an approach based on progressive enhancement techniques.
108 |
--------------------------------------------------------------------------------
/practices/house-style.md:
--------------------------------------------------------------------------------
1 | # House style guide
2 |
3 | This document outlines the reasons for our having a house style, and generally-applicable principles. It's a living styleguide – it will grow as our practices do.
4 |
5 | - [Rationale](#rationale)
6 | - [General Principles](#general-principles)
7 | - [Linting](#linting)
8 | - [Accessibility](#accessibility)
9 | - [Progressive enhancement and browser support](#progressive-enhancement-and-browser-support)
10 | - [Code review](#code-review)
11 | - [Written communications](#written-communications)
12 | - [Making changes to the house style](#making-changes-to-the-house-style)
13 |
14 | ## Rationale
15 |
16 | The benefits of choosing one house style outweigh the benefits of allowing people free rein with code style. Personal preference is outweighed by the greater good. This isn't to say that we shouldn't constantly be looking to improve our ways of working. We aim to reduce friction for ourselves as we move between teams, and we do this by maintaining a general house style, linting, and agreeing on common practices.
17 |
18 | Read this excellent [article by Nicholas C. Zakas](https://www.smashingmagazine.com/2012/10/why-coding-style-matters/) to understand why having a house style is important.
19 |
20 | ## General principles
21 |
22 | Read the [markup guide](../markup/house-style.md), the [JavaScript guide](../javascript/house-style.md) and the [CSS guide](../css/house-style.md) to understand our house style in these technologies. You should also familiarise yourself with our [Git](../git/git.md) strategies. The team you're deployed to may also have its own strategies in addition to these.
23 |
24 | ### Indentation
25 |
26 | With regards to accessibility, we favour using `tab`s for indentation, rather than `space`s. Using `tab`s, every person can define their preferred _render width_ as they like. This also means that we discourage `tab width` settings in any shared configuration files, as that's a display thing, not a code thing.
27 | Please be aware that visually impaired people might depend on either a large indentation width for being able to easily detect code blocks, or on small indentation because they must use a very large font size. These examples are taken from [a comment on Reddit](https://www.reddit.com/r/javascript/comments/c8drjo/nobody_talks_about_the_real_reason_to_use_tabs/).
28 | At the same time, we must respect file types that demand the use of spaces for indentation, [for example YAML (`*.yml`) files](https://docs.fileformat.com/programming/yaml/#syntax), or Python with it's built-in linter.
29 |
30 | ### Linting
31 |
32 | We lint our CSS and JavaScript. This helps us to keep our different codebases consistent, avoid common logic and implementation errors, and lets us concentrate on solving problems instead of formatting.
33 |
34 | * For CSS linting, we use [StyleLint](https://github.com/stylelint/stylelint) and [sass-lint](https://github.com/sasstools/sass-lint). You can find our configuration and examples in our [CSS style guide](../css/house-style.md).
35 | * For JavaScript linting, we use [eslint](https://eslint.org/) with our own [eslint configuration](https://github.com/springernature/eslint-config-springernature). You can find our principles and best practices in the [JavaScript style guide](../javascript/house-style.md).
36 |
37 | ### Accessibility
38 |
39 | We care a great deal about accessibility. Our target standards for all of our products are [WCAG 2.1](https://www.w3.org/TR/WCAG21/) level AA, in line with the current EU legislation, [EN 301 549](https://eur-lex.europa.eu/legal-content/EN/TXT/?qid=1571662799042&uri=CELEX:32016L2102). *All first and third party web products and components published by Springer Nature must conform to WCAG 2.1 AA.*
40 |
41 | Civil and federal legislation worldwide is converging on WCAG. Meeting WCAG 2.1 AA will also bring us into alignment with federal regulations like [US Section 508](https://www.section508.gov/) and [UK Accessibility Regulations 2018](https://www.legislation.gov.uk/uksi/2018/952/introduction/made), and with civil rights legislation like the [UK Equality Act 2010](http://www.legislation.gov.uk/ukpga/2010/15/contents) and the [Americans with Disabilities Act](https://www.ada.gov/2010_regs.htm).
42 |
43 | Read our [Accessibility guide](../accessibility/README.md) to understand how we meet these aims.
44 |
45 | ### Progressive enhancement and browser support
46 |
47 | We support *all* browsers to different degrees of functionality. "Support" does *not* mean that everybody gets the same thing. Read our [browser support page](../practices/graded-browser-support.md) to understand our approach and where to aim your efforts.
48 |
49 | Our approach to browser support means that you MUST practice progressive enhancement when building sites for Springer Nature, not graceful degradation. See the [progressive enhancement guide](../practices/progressive-enhancement.md) to understand what this means.
50 |
51 | ### Code review
52 |
53 | We practice code review to safeguard the quality of what we produce. Code review aims to catch inadvertent mistakes, errors, and omissions (e.g. missing tests), and to act as a learning exercise for reviewers and reviewees.
54 |
55 | Everyone is expected to review code submissions; your level of experience as a developer or with the codebase in question doesn't matter. When submitting code for review, be prepared to explain your thinking. When reviewing code, don't be afraid to ask the submitter to explain!
56 |
57 | Read the [code review guide](../practices/code-review.md) for details on how we manage code reviews, and what to look for when reviewing.
58 |
59 | ### Written communications
60 |
61 | Not all written communications need to follow house style - for e.g. we don't expect you to follow any rules in Slack, beyond what's expected of you as a professional. If you write for any of our open source repositories (including documentation), [Cruft.io](http://cruft.io/), or any of our [social media accounts](../writing/social-media.md), please familiarise yourself with the [Language guide](../writing/house-style.md). Always use [inclusive language](../writing/inclusive-language.md).
62 |
63 | ## Making changes to the house style
64 |
65 | The playbook outlines our _current_ agreed house style. It's not written in stone, everybody has the opportunity to contribute and make changes. However, it's easy to [waste time and effort](https://en.wikipedia.org/wiki/Law_of_triviality) discussing code style. We use a process to make these discussions structured and productive.
66 |
67 | If you would like to propose a change to house style, follow these steps:
68 |
69 | 1. Read the relevant page in the playbook (assuming it exists).
70 | 2. Understand that you SHOULD NOT deviate from this style unless there are valid reasons in particular circumstances when the particular behaviour is acceptable or even useful.
71 | 3. If you believe that your situation or case meets the criteria in point 2, detail to the rest of the team the benefits of making an exception or a change.
72 | 4. If the team agrees that your exception (or change) is acceptable and useful, submit a PR to the playbook, detailing the exception (or change) to the world.
73 |
--------------------------------------------------------------------------------
/practices/javascript-styling.md:
--------------------------------------------------------------------------------
1 | # Javascript dependent styling
2 |
3 | A class name of `.js` on the document root element (normally `html`) is used to target JS-dependent visual styles via CSS.
4 |
5 | ## Scripts
6 |
7 | The `.js` class must be added via a micro—but blocking—script, placed as far up in the `` of the document as possible.
8 |
9 | The blocking nature of the script prevents any visual flickering or browser reflows, unlike other techniques where JavaScript may cause styles to be applied after the page has rendered.
10 |
11 | ```html
12 |
16 | ```
17 |
18 | ## Styles
19 |
20 | All UI elements MUST be usable and visually-acceptable when Javascript is not present. Enhancements can be made when Javascript is present by nesting those styles underneath the `.js` class.
21 |
22 | Following the principles of [Progressive Enhancement](./progressive-enhancement.md), consider building and releasing your core unenhanced version first. Then build and deliver the Javascript enhanced version in a subsequent iteration.
23 |
24 | ```scss
25 | // Define core styles
26 | .c-component {
27 | color: black;
28 | padding-bottom: 1rem;
29 | }
30 |
31 | // Add and override declarations when JS is present
32 | .js .c-component {
33 | height: 200px;
34 | padding-bottom: 0; // overridden now that JS is present
35 | background-color: #e4e4e4;
36 | margin: 10px;
37 | }
38 | ```
39 |
--------------------------------------------------------------------------------
/practices/managing-static-assets.md:
--------------------------------------------------------------------------------
1 | # Managing static assets
2 |
3 | Static assets are files that don't need to be generated, modified or processed by an application before being delivered to the user. This typically includes CSS, JavaScript, images and web fonts. Static assets change rarely, and their content doesn't depend on user input or preferences.
4 |
5 | **We [MUST][rfc-2119] host these kinds of static resources on our own infrastructure and Content Delivery Network (CDN) instead of including them on our pages from a third-party CDN.**
6 |
7 | JavaScript files or libraries introduce security and data compliance risk. Resources related to fonts and videos also carry heightened data compliance risk on the basis of legal precedence.
8 |
9 | Self-hosting static assets has several advantages over relying on third parties for their delivery:
10 |
11 | * **Data protection.** When a user requests a resource from a third party service via a site we control, we are responsible for sharing their Personally Identifiable Information - such as user IP addresses - with the third party. We have a commitment to treating our users personal data with proper care, and a responsibility to the company to follow local privacy laws.
12 | * **Robustness.** As long as our site is up, the static resource will be up too. We don't depend on third party servers or additional CDNs besides our own, and we won't be affected by their outages, or closure of the service.
13 | * **Consistency.** Static assets are cached and served like the rest of our resources, and use the same CDN. As a result, resource timings and user experience are more consistent all around the world.
14 | * **Security.** Reduces our front-end [attack surface](https://en.wikipedia.org/wiki/Attack_surface) as the resources will enjoy the same level of security as the rest of first party content, and we don't have to trust the security of third parties. Self-hosting the asset makes it easier for us to use [Subresource Integrity (SRI)](https://developer.mozilla.org/en-US/docs/Web/Security/Subresource_Integrity) for an additional layer of security.
15 | * **Control.**
16 | If we serve the asset we also have more control of how it's cached across the internet and by clients - so in the event of a compliance or security issue, we are able to react and protect our users and the company more quickly.
17 | * **Performance.** Self-hosting may save the users the cost of the DNS request, TCP connection and TLS negotiation for each CDN-hosted request, which in slow connections may make a big difference. This can also be mitigated with [`rel=dns-prefetch`](https://developer.mozilla.org/en-US/docs/Learn/Performance/dns-prefetch) and [`rel=preconnect`](https://developer.mozilla.org/en-US/docs/Web/HTML/Link_types/preconnect), but self-hosting the assets eliminates that penalty completely.
18 | * **Filtering.** Some CDNs are filtered by the [Great Firewall of China (GFW)](https://en.wikipedia.org/wiki/Great_Firewall). This can slow down the loading of certain resources, or even make them fail to load completely. Self-hosting static assets helps mitigate this, as all of the 1st party resources on a page will be served from the same place.
19 |
20 | [rfc-2119]: https://tools.ietf.org/html/rfc2119
21 |
--------------------------------------------------------------------------------
/practices/open-source-support.md:
--------------------------------------------------------------------------------
1 | # Open source support
2 |
3 | - [Versioning](#versioning)
4 | - [Release process](#release-process)
5 | - [CI tests](#ci-tests)
6 | - [Node versions](#node-versions)
7 | - [Security](#security)
8 | - [Support for old versions](#support-for-old-versions)
9 |
10 |
11 | ## Versioning
12 |
13 | Our open source projects are versioned with [SemVer](../git/semver.md). You should read through the [SemVer documentation](http://semver.org) if you're going to release new versions.
14 |
15 |
16 | ## Release process
17 |
18 | To publish a *new* version of one of our open source projects:
19 |
20 | * Switch to the default branch. Version commits are the only ones that shouldn't be committed to a feature branch.
21 | * Consider what type of release this is: `major`, `minor` or `patch` according to SemVer. If you're unsure which, check with the rest of the team or re-read the [SemVer docs](https://semver.org/). Also verify if there are any references to the old version in the `README.md` or any other files, and update them too.
22 | * Add an entry to the `HISTORY.md` file outlining the changes in the new version. Take your time, this log should be useful to developers who use this project - it should help them make decisions about whether they can or should upgrade. If there are additional commits on the default branch since the last version, be sure to include a description of what they do in your history update - talk to the developers who committed them, if necessary.
23 | * Run `npm version` depending on the SemVer type of release - e.g. `npm version minor` for a minor release. This will:
24 | * increment the version in your `package.json`, based on the type of release.
25 | * commit this version bump.
26 | * create a tag for the current release in your local repository.
27 | * You can also use the above command to conveniently publish a release candidate, e.g. `npm version 4.0.0-rc1`. Once you are finished with the release candidates and ready for a major release, use `npm version major`.
28 | * It's possible to do those three steps manually - and you will need to do that for a first OSS release - but using the convenience method of `npm version` reduces human error and increases consistency.
29 | * Before publishing to NPM for real, run `npm publish --dry-run` ([docs](https://docs.npmjs.com/cli/v9/commands/npm-publish#dry-run)) to see what will happen.
30 | * Push both the commit and the new tags to origin: `git push && git push --tags`.
31 | * Depending on how the project is set up, the build system may automatically publish your new version based on the tag. Otherwise you may have to run `npm publish` to publish the package in [npm](https://www.npmjs.com/). If you don't have permission yet, request it from one of the existing collaborators.
32 |
33 |
34 | ## CI tests
35 |
36 | We aim for every project to run its unit tests automatically every time a change is committed to its repo.
37 |
38 | At the moment we recommend [GitHub Actions](https://docs.github.com/en/actions/use-cases-and-examples/building-and-testing/building-and-testing-nodejs) for our projects but other options are available.
39 |
40 | The default branch should be protected so other branches can't be merged unless the tests have passed on those branches.
41 |
42 |
43 | ## Node versions
44 |
45 | On [node-based projects](https://nodejs.org) we aim to support every version that the Node foundation offers [Long-term support (LTS)](https://github.com/nodejs/Release) for. That means that we won't offer support for odd versions like Node 19 and 21.
46 |
47 | Dropping support for a node version from the test matrix must be only done as part of a major release, as we consider it a breaking change.
48 |
49 |
50 | ## Security
51 |
52 | Whenever possible, we'll use automated tools and alerts in order to check for vulnerabilities in our projects or their dependencies.
53 |
54 |
55 | ## Support for old versions
56 |
57 | We aim to support old versions for 6 months after the next major version has been released. Support for old versions will be usually limited to security issues or important bugfixes.
58 |
59 |
--------------------------------------------------------------------------------
/practices/progressive-enhancement.md:
--------------------------------------------------------------------------------
1 | # Progressive enhancement
2 |
3 | * [What is it?](#what-is-it)
4 | * [Why we use it](#why-we-use-it)
5 | * [Implementation](#implementation)
6 | * [Common concerns](#common-concerns)
7 | * [How many users turn JavaScript off, anyway?](#how-many-users-turn-javascript-off-anyway)
8 | * [OK, so how often does JavaScript fail? How can we test for that?](#ok-so-how-often-does-JavaScript-fail-how-can-we-test-for-that)
9 | * [So you're saying I can't use JavaScript?](#so-youre-saying-i-cant-use-javascript)
10 | * [Find out more:](#find-out-more)
11 |
12 | ## What is it?
13 |
14 | Progressive enhancement is a design and development practice that focuses on delivering the basic essentials of a website as a primary concern, then building the various layers of refinement and niceties on top of that for those clients than can receive them. In practice this means that we start with developing a logical and semantic HTML application with all the key functionality, then we can enhance this with an aesthetic layer (CSS) and behavioural layer (JavaScript) as desired.
15 |
16 | There is a subtle but important difference in this approach vs the outdated approach of "graceful degradation" (or fault-tolerance) which it can often be confused with. Graceful degradation suggests a feature-complete "full-fat" application is designed and built, and is expected to be delivered wholesale to each client. Developers then attempt to build into the system fail safes so that when a client is unable to use the whole application, it can still get some value out of it.
17 |
18 | ## Why we use it
19 |
20 | Progressive Enhancement fits perfectly with the [Rule of Least Power](https://en.wikipedia.org/wiki/Rule_of_least_power).
21 |
22 | > In the web front-end stack — HTML, CSS, JS, and ARIA — if you can solve a problem with a simpler solution lower in the stack, you should. It’s less fragile, more foolproof, and just works.
23 | >
24 | > -- [Derek Featherstone, April 23rd 2014](https://web.archive.org/web/20220922175527/https://simplyaccessible.com/article/data-attributes/)
25 |
26 | By keeping the Rule of Least Power in mind you can create software that's fault tolerant by design - a key consideration for writing software for the web which will be downloaded and interpreted/executed in an incomprehensibly diverse plethora of devices and environments.
27 |
28 | Unlike graceful degradation, this fault tolerance is built in *from the start* and so is much less likely to be skipped out in the interests of hitting a deadline (or because it's less spangly than the next feature X).
29 |
30 | Developing software using progressive enhancement also encourages Lean thinking, by aligning development priorities with end-user priorities (people are likely here for your content, not for how pretty your buttons look). This is both very useful for prioritisation of features (and refinement of the fabled MVP) but also biases you towards delivery of software that can be tested early; so you can see if your core content and functionality is working before spending too much time on making it "cutting-edge".
31 |
32 | Finally by starting with just the most basic layer of content and moving on from there, progressive enhancement encourages a lighter, more performant delivery of software. For someone on a slow network, or with a device which can't support the layers of sophistication you've built into your site, they'll appreciate being able to access the content and basic functionality you've provided even while the bells and whistles are downloaded/parsed/executed (or none of the above).
33 |
34 | ## Implementation
35 |
36 | We enable progressive enhancement at every level of our products.
37 |
38 | On the broadest level our [browser support](graded-browser-support.md) approach lets us offer Core versions of our products that work for all users, in all situations, and which are then enhanced when the browser is deemed advanced enough.
39 |
40 | On the CSS level we build basic implementations first, using primitive CSS, and then enhance in more advanced browsers using the [cascade](https://developer.mozilla.org/en-US/docs/Web/CSS/Cascade), [specificity](https://developer.mozilla.org/en-US/docs/Web/CSS/Specificity), source order, and [feature queries](https://developer.mozilla.org/en-US/docs/Web/CSS/@supports).
41 |
42 | With JavaScript we acknowledge that, given our [browser support chart](graded-browser-support.md#graded-browser-support-list), we must support ES5 browsers, which we do so via transpiling from ES6/Next to ES5. However we can then use [feature detection](https://developer.mozilla.org/en-US/docs/Learn/Tools_and_testing/Cross_browser_testing/Feature_detection) to offer more capabilities as the browser supports them.
43 |
44 | ## Common concerns
45 |
46 | ### How many users turn JavaScript off anyway?
47 |
48 | Not very many, but this usually isn't the question you really need to be asking. A more useful, subtly different, question is "how many users don't have JavaScript available?" The reasons for JavaScript delivery failure are varied. In 2015, Stuart Langridge published an ["Everyone has JavaScript, right?" flowchart](https://www.kryogenix.org/code/browser/everyonehasjs.html). The web is a fast-moving environment, but as of writing in 2023, everything on the flowchart is still relevant. All users will have times when JavaScript fails, for all kinds of reasons, and mostly they're not in control of why and when it happens. The active choice to turn JavaScript off (which people still do), is fairly far down the list of reasons for not having working JavaScript.
49 |
50 | Progressive enhancement is not just a solution for clients who have deliberately deprived themselves of JavaScript, it's also a failsafe for EVERY client which guarantees your site/application is as useful as it can be to everyone all the time.
51 |
52 | ### OK, so how often does JavaScript fail? How can we test for that?
53 |
54 | Usually this question comes from the Extreme Programming thinking of "[You Ain't Gonna Need It](https://en.wikipedia.org/wiki/You_aren%27t_gonna_need_it)" - the desire to only implement features when they're necessary. However, as the previous section ("How many users turn JavaScript off anyway?") makes clear, JavaScript delivery failure happens to everyone, some of the time. Robustness is a core requirement for our websites and applications, not an optional feature. Stuart Langridge illustrates why you need to think in terms of [JavaScript failing for a % of _visits_, not _users_](https://www.kryogenix.org/code/browser/why-availability/).
55 |
56 | At this stage, you may be wondering why I've not answered the question directly. How many, exactly? That's because it's hard to test for - if there's no JavaScript, there's no tracking. For this reason, not very many people have tried it. Those who do include [Yahoo! back in 2010](https://web.archive.org/web/20130622121741/https://developer.yahoo.com/blogs/ydn/many-users-JavaScript-disabled-14121.html), and [the UK Government Digital Service in 2013](https://gds.blog.gov.uk/2013/10/21/how-many-people-are-missing-out-on-javascript-enhancement/). These groups found a failure rate of about 1.1% to 1.3% of requests. Again, this is across all users and devices, of all capacities and capabilities, not just "people who turned JavaScript off", or "people using old browsers".
57 |
58 | ### So you're saying I can't use JavaScript?
59 |
60 | No, that's a misrepresentation of the purpose of progressive enhancement. There are many situations where you will _need_ to use JavaScript to achieve certain objectives. One example is the use of ARIA - you can't meaningfully use the `aria-expanded` property to indicate that a component progressively discloses information without JavaScript, because you need to be able to update the DOM depending on user activity.
61 |
62 | Use JavaScript defensively, on the assumption that there will frequently be times where it's not available. And since we're on the subject, [ARIA should be a progressive enhancement too](https://developer.paciellogroup.com/blog/2018/06/short-note-on-progressive-aria/).
63 |
64 |
65 | ## Find out more
66 |
67 | * [A List Apart: Understanding Progressive Enhancement](http://alistapart.com/article/understandingprogressiveenhancement) October 07, 2008
68 | * [Progressive enhancement is a team sport](https://seesparkbox.com/foundry/Progressive_Enhancement_Is_A_Team_Sport)
69 | * [Progressive enhancement is still important](https://jakearchibald.com/2013/progressive-enhancement-still-important/) July 03, 2013
70 | * [Robustness and least power](https://adactio.com/journal/14327) September 10th, 2018
71 |
--------------------------------------------------------------------------------
/practices/structured-data.md:
--------------------------------------------------------------------------------
1 | # Structured data
2 |
3 | In the context of the web, structured data refers to information used to describe and classify the content of a webpage. For example; on a scientific article page, who the author is, what the article title is, and so on. Structured data contributes towards the vision of the [Semantic Web](https://en.wikipedia.org/wiki/Semantic_Web#Semantic_Web_solutions) and provides SEO benefit.
4 |
5 | There are 4 widely accepted ways to implement structured data:
6 | - [JSON-LD](https://en.wikipedia.org/wiki/JSON-LD) (a W3C Recommendation)
7 | - [RDFa](https://en.wikipedia.org/wiki/RDFa) (a W3C Recommendation)
8 | - [Microdata](https://en.wikipedia.org/wiki/Microdata_(HTML))
9 | - [Microformat](https://en.wikipedia.org/wiki/Microformat)
10 |
11 |
12 | ## How we implement structured data
13 |
14 | We primarily use JSON-LD. Information is defined in JSON using the [RDF](https://en.wikipedia.org/wiki/Resource_Description_Framework) format. You can add these inside `
58 | ```
59 |
60 | ## Why JSON-LD?
61 | Using JSON-LD instead of marking up HTML with one of the other techniques has benefits:
62 |
63 | - Separation of structured data and HTML. Provides information about the page without binding it to specific HTML elements. This improves the maintainability of both HTML and structured data.
64 | - Generally speaking, it will be easier to generate from the backend. This is especially true for apps that already deal with JSON data as part of their implementation.
65 | - Easier for client apps to consume as those apps no longer need to trawl through HTML to extract.
66 | - JSON-LD is an official [W3C Recommendation](https://en.wikipedia.org/wiki/World_Wide_Web_Consortium#W3C_recommendation_(REC)).
67 | - Google [recommends](https://developers.google.com/search/docs/guides/intro-structured-data) JSON-LD for structured data.
68 |
69 | ## Vocabulary
70 | A shared, standardised vocabulary ensures that structured data is interpreted consistently by people and machines. We use the vocabulary defined and maintained at [https://www.schema.org](https://www.schema.org). Since its creation in 2011 by Google, Bing, Yahoo! and Yandex this vocabulary has been widely adopted and is the most commonly implemented.
71 |
72 | Tip - after adding a new JSON-LD script to your website, be sure to validate your use of vocabulary by using [Google’s structured data test tool](https://search.google.com/structured-data/testing-tool).
73 |
--------------------------------------------------------------------------------
/security/README.md:
--------------------------------------------------------------------------------
1 | # Security
2 |
3 | All web developers should be aware of security risks related to web technologies.
4 |
5 | * The Open Worldwide Application Security Project ([OWASP](https://owasp.org/)) is a nonprofit foundation that works to improve the security of software. They maintain a [top 10 list of critical security risks in web applications](https://owasp.org/www-project-top-ten/), which is essential reading.
6 | * Mozilla's open-source infosec documentation contains an excellent [Web Security Cheat Sheet](https://infosec.mozilla.org/guidelines/web_security.html) we encourage you to read.
7 | * We publish a document to help you create [secure markup](secure-markup.md).
8 |
9 | [Main table of contents](../README.md#table-of-contents)
10 |
--------------------------------------------------------------------------------
/security/secure-markup.md:
--------------------------------------------------------------------------------
1 | # Secure Markup
2 |
3 | * [Scope of this document](#scope-of-this-document)
4 | * [Use UTF-8 and specify this in a `meta` tag](#use-utf-8-and-specify-this-in-a-meta-tag)
5 | * [Add `rel="noopener"` to outbound links in new windows](#add-relnoopener-to-outbound-links-in-new-windows)
6 | * [Use Subresource Integrity](#use-subresource-integrity)
7 | * [Use cautious form defaults](#use-cautious-form-defaults)
8 | + [A note on autofill](#a-note-on-autofill)
9 | * [Use the `sandbox` attribute for `iframe`s](#use-the-sandbox-attribute-for-iframes)
10 | * [Use the `type` attribute for `object`s](#use-the-type-attribute-for-objects)
11 |
12 | ## Scope of this document
13 | You should be aware of the security implications of your frontend code. This document outlines some steps you can take to reduce the risk of markup exposing us, or our users, to security flaws.
14 |
15 | Note: this document does not cover JavaScript or interactions which may touch the server, e.g. XSS or HTTP headers. (It is assumed security-related headers are set in the HTTP headers, not in `meta` tag equivalents.)
16 |
17 | Additionally, you're encouraged to familiarise yourself with the [OWASP HTML5 Security Cheat Sheet](https://github.com/OWASP/CheatSheetSeries/blob/master/cheatsheets/HTML5_Security_Cheat_Sheet.md).
18 |
19 | ## Use UTF-8 and specify this in a `meta` tag
20 |
21 | Do this: ` `.
22 |
23 | Not specifying the appropriate character set has historically been a source of [charset-related security problems](https://code.google.com/archive/p/doctype-mirror/wikis/ArticleUtf7.wiki) as well as a source of rendering bugs.
24 |
25 | Ideally this should be specified in both the HTTP header and a `meta` element, in case one breaks.
26 |
27 | ## Add `rel="noopener"` to outbound links in new windows
28 |
29 | Links leak the context of the opening window to the opened window, via the `window.opener` object. This allows the opened window to alter the opening window via JavaScript, regardless of whether the window is opened via JavaScript or simply a `target="_blank"` attribute. Exploiting this [context leaking is a security problem](https://mathiasbynens.github.io/rel-noopener/).
30 |
31 | As of 2020, recent versions of all major browsers treat `target=_blank` links as `noopener` by default. However, we still recommend including this attribute because as an HTML feature it will be served to older browsers, and is cheap to implement.
32 |
33 | ## Use Subresource Integrity
34 |
35 | Often we serve assets such as JavaScript or CSS files via [CDN](https://www.cloudflare.com/learning/cdn/what-is-a-cdn/)'s for performance reasons. But what if that resource is corrupted, either on the CDN or over the network?
36 |
37 | Files served via CDN's (or your own asset servers) are high-priority targets for attackers, because they enable attackers to inject [payloads](https://en.wikipedia.org/wiki/Payload_(computing)#Security) into many sites with just one breach.
38 |
39 | Subresource Integrity protects against corrupted resource files by instructing the browser to calculate a [hash](https://en.wikipedia.org/wiki/Cryptographic_hash_function) of the downloaded file's content, then compare that hash to one we previously computed for the known-good file. If the hashes don't match, the browser doesn't parse the loaded file.
40 |
41 | We tell the browser the hash of the known-good file by embedding the hash value in the HTML—using the `integrity` attribute on the corresponding `script` or `link` element.
42 |
43 | This may sound complicated but it's not too hard to do!
44 |
45 | Example markup (from the [MDN article on Subresource Integrity](https://developer.mozilla.org/en-US/docs/Web/Security/Subresource_Integrity)):
46 | ```
47 |
50 | ```
51 |
52 | (Use of the `crossorigin` attribute depends on [CORS](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS) support of the asset server.)
53 |
54 | Subresource Integrity can be used in conjunction with a [Content Security Policy](https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP) but does not require a CSP to work.
55 |
56 | As Subresource Integrity should be relatively easy to add to a frontend build tool chain, you should use it for any `script` or `link` element, especially as [browser support for Subresource Integrity](https://caniuse.com/#feat=subresource-integrity) is good.
57 |
58 | - [Gentle introduction to Subresource Integrity by keycdn.com](https://www.keycdn.com/support/subresource-integrity/)
59 | - [MDN article on Subresource Integrity](https://developer.mozilla.org/en-US/docs/Web/Security/Subresource_Integrity)
60 |
61 | ## Use cautious form defaults
62 |
63 | We must not write data that comes from the user into the DOM without first [sanitising](https://www.smashingmagazine.com/2011/01/keeping-web-users-safe-by-sanitizing-input-data/) that data. Input includes not only form data, but also things like user agent strings, request headers, URL parameters and cookies.
64 |
65 | Sanitising input is the responsibility of the server in most cases, but we must also sanitise input in rich JavaScript applications (e.g. URL fragments) at the risk of exposing our users to attacks like [DOM XSS/Client-Side XSS](https://www.owasp.org/index.php/Types_of_Cross-Site_Scripting#DOM_Based_XSS_.28AKA_Type-0.29).
66 |
67 | Such sanitisation is beyond the scope of this document, but as authors of HTML forms we can mitigate _some_ classes of client-side attack by specifying some form widget attributes. This is no substitute for sanitisation but constitutes part of a ["belt & braces"](https://www.collinsdictionary.com/dictionary/english/belt-and-braces) approach to security, as well as reducing common sources of bugs.
68 |
69 | - `form` — specify `accept-charset="utf-8"`. Charset issues are a common source of bugs generally. If a page has been parsed as UTF-8 the browser _should_ default to sending data as UTF-8, but it's easy to specify the `accept-charset` as extra protection in case something breaks, so why not do it?
70 | - `input` — if the value of the type attribute is `text`, `email`, `search`, `password`, `tel`, or `url`, specify the `maxlength` attribute.
71 | - `textarea` — specify the `maxlength` attribute.
72 | - `input type="file"` — use the `accept` attribute to specify which types of file can be uploaded (specify by extension or MIME type). Again this is no substitute for server validation but improves usability.
73 | - for non-essential "autocomplete" functionality, consider using a `datalist` element instead of JavaScript.
74 | - `keygen` is deprecated, don't use it.
75 |
76 | ### A note on autofill
77 |
78 | Whether the browser autofills input elements is controlled by the `autocomplete` attribute, for which there are a [large number of potential values](https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/autocomplete#Values).
79 |
80 | Firstly, while there are security concerns about autofill & Personally Identifiable Information (PII),
81 |
82 | > ...in-browser password management is generally seen as a net gain for security. Since users do not have to remember passwords that the browser stores for them, they are able to choose stronger passwords than they would otherwise.
83 | > For this reason, many modern browsers do not support autocomplete="off" for login fields
84 | > — [MDN - Turning off form autocompletion](https://developer.mozilla.org/en-US/docs/Web/Security/Securing_your_site/Turning_off_form_autocompletion)
85 |
86 | As such, while you can disable autofill for sensitive fields (see MDN article above) browser vendors feel it is not a good idea overall.
87 |
88 | Secondly,
89 |
90 | > User agents should verify that all fields with the autocomplete attribute are visible within the viewport before automatically entering data.
91 | > — [HTML 5.3 W3C Working Group Note](https://www.w3.org/TR/2021/NOTE-html53-20210128/sec-forms.html#sec-autofill)
92 |
93 | So to be sure, *avoid enabling autocomplete for elements which may be visually-hidden*.
94 |
95 |
96 | ## Use the `sandbox` attribute for `iframe`s
97 |
98 | Even if you control the content of the `iframe`, do use the `sandbox` attribute if you can. This attribute restricts the functionality of the framed document [(_why "sandbox"?_)](https://en.wikipedia.org/wiki/Sandbox_(computer_security)).
99 |
100 | Note the default sandbox is very strict (e.g. no JavaScript, forms cannot be submitted) so tailor the value of the attribute to your use case. Mike West has written [a great article about `iframe sandbox`](https://www.html5rocks.com/en/tutorials/security/sandboxed-iframes/) and MDN has [a lovely reference article on `sandbox`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe#attr-sandbox).
101 |
102 | ## Use the `type` attribute for `object`s
103 |
104 | Either the [`data`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLObjectElement/data)
105 | or [`type`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLObjectElement/type)
106 | attribute for the [`object` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/object)
107 | must be specified. You are encouraged to always ensure `type` is specified.
108 |
109 | The value should be a valid [MIME type](https://developer.mozilla.org/en-US/docs/Glossary/MIME_type), also know as a "content type".
110 |
111 | Embedded objects are generally not to be trusted -- security issues have arisen in the past from browsers being "tricked" into treating content as the wrong type, including [same-origin policy](https://developer.mozilla.org/en-US/docs/Web/Security/Same-origin_policy) violations.
112 |
113 | For more information please see the [W3C HTML Living Standard](https://html.spec.whatwg.org/multipage/iframe-embed-object.html#the-object-element).
114 |
--------------------------------------------------------------------------------
/writing/README.md:
--------------------------------------------------------------------------------
1 | # Writing
2 |
3 | We write for a variety of audiences, and we must therefore take that into account whenever we write.
4 |
5 | * [House style](house-style.md)
6 | * [Inclusive language](inclusive-language.md)
7 | * [Social media](social-media.md)
8 |
9 | [Main table of contents](../README.md#table-of-contents)
10 |
--------------------------------------------------------------------------------
/writing/house-style.md:
--------------------------------------------------------------------------------
1 | # Language style guide
2 |
3 | * [Writing style](#writing-style)
4 | * [Tone of voice](#tone-of-voice)
5 | * [Plain English](#plain-english)
6 | * [Technical writing](#technical-writing)
7 | * [Frontend or front-end](#frontend-or-front-end)
8 |
9 | ## Writing style
10 |
11 | We don't enforce strict standards on writing style as we want you to use your own words to express your own personality. That said, we have three general sets of guidelines - tone of voice, plain English, and technical writing.
12 |
13 | ### Tone of voice
14 |
15 | For a general audience, you should write like a human. Be professional, but conversational - we want our contributors and readers to feel comfortable joining in at any time.
16 |
17 | Be thankful to contributors and those who log issues. They're giving up their time to make our playbook better. Make sure they know we're grateful to them.
18 |
19 | Maintain the same friendly and professional standards across the entire repository - in documentation, issues, pull requests, and comments.
20 |
21 | Always use [inclusive language](inclusive-language.md).
22 |
23 | ### Plain English
24 |
25 | Follow [Plain English guidelines](http://www.plainenglish.co.uk/how-to-write-in-plain-english.html) to help safeguard the accessibility of your written content. You might find tools like [Hemingway App](http://www.hemingwayapp.com/) helpful when editing. In particular:
26 |
27 | * Be concise
28 | * Check any sentences with more than 25 words to see if you can split them to make them clearer.
29 | * Ideally no more than 1-2 points per sentence.
30 | * Use contractions (e.g. "can't", "it's").
31 | * Go straight to the point.
32 | * Avoid unnecessary words (e.g. There is, It is, very, really, pretty, just, actually).
33 | * Be specific
34 | - Prefer the active voice to the passive voice[\[1\]][active-passive] (e.g. "NPM will install the dependencies" instead of "the dependencies will be installed").
35 | * Address the reader as "you" where possible.
36 | * Avoid referring to "things" or "stuff".
37 | * Be direct. Avoid metaphor, simile, and slang.
38 | * Be informative
39 | * Consider your audience. General information may not look the same as information aimed at a technical audience.
40 | * Be as precise as you can usefully be - consider linking to high quality external resources where relevant.
41 |
42 | ### Technical writing
43 |
44 | When expressing technical concepts, you'll need to use technical language. This may be complex, contain jargon, or seem formal. That's ok! Technical writing isn't for a general audience. Your priorities must be clarity, brevity, and accuracy. If you think your reader may need additional context to understand a concept, link out to external resources.
45 |
46 | All of the advice in the [plain English](#plain-english) section applies. Additionally:
47 |
48 | * Expand acronyms the first time you use them, and limit their use thereafter e.g. "Avoid the use of TLAs (Three Letter Acronyms)".
49 | * When defining technical requirements, you may use the keywords defined in [RFC 2119](https://www.ietf.org/rfc/rfc2119.txt) for those requirement levels, e.g. "MUST", "SHOULD", "OPTIONAL", etc.
50 |
51 | ## Frontend or front-end
52 |
53 | Always use `frontend` regardless of the context. It's less confusing and error prone, and ensures consistency across all our documentation and portfolio of products.
54 |
55 | [active-passive]: https://oxfordediting.com/the-active-verb-form-makes-academic-writing-more-readable/
56 |
--------------------------------------------------------------------------------
/writing/inclusive-language.md:
--------------------------------------------------------------------------------
1 | # Inclusive language
2 |
3 | * [Non-discriminatory language](#non-discriminatory-language)
4 | * [Unacceptable language](#unacceptable-language)
5 | * [Language that excludes](#language-that-excludes)
6 | * [Gendered language](#gendered-language)
7 | * [Disability and accessibility](#disability-and-accessibility)
8 |
9 | ## Non-discriminatory language
10 |
11 | [Discrimination](https://en.wikipedia.org/wiki/Discrimination) is prohibited under law in the UK and many other countries.
12 |
13 | Language is our main form of communication and it plays a powerful role both in contributing to and in eliminating discrimination.
14 |
15 | Language influences thinking. For example, Hebrew uses gender markers, whereas Finnish doesn’t mark gender at all. A study done in the 1980s[\[1\]][wiley] found that kids who spoke Hebrew knew their own genders a year earlier than those who grew up speaking Finnish.
16 |
17 | Inclusive language is language that is free from words, phrases or tones that reflect prejudiced, stereotyped or discriminatory views of particular people or groups. It is also language that doesn't deliberately or inadvertently exclude people from being seen as part of a group[\[2\]][govau] .
18 |
19 | We're committed to using inclusive, non-discriminatory language in every written or verbal communication.
20 |
21 | ### Unacceptable language
22 |
23 | Inappropriate or unacceptable language highlights perceived or actual differences between people. The use of insensitive and inappropriate language can create a hostile environment for people who have protected characteristics, as outlined in the [Equality Act 2010](http://www.legislation.gov.uk/ukpga/2010/15/contents).
24 |
25 | Stereotyping means presuming a range of things about people based on their personal characteristics. These may include their appearance, apparent intelligence, personality or character, or their gender, sexual orientation, race, ethnicity, age, location, socioeconomic status or disability. We don't use language that reinforces stereotypes.
26 |
27 | ### Language that excludes
28 |
29 | Language matters. It remains a common practice in IT to use terminology like slave/master or blacklist/whitelist that reference slavery or segregation.
30 |
31 | There's always a better way to label the relationship between two entities. In the case of databases, choosing more descriptive terms like replica/primary, secondary/primary, follower/leader or standby/active instead of slave/master not only removes the reference to slavery, but also makes it easier to understand as it [avoids metaphor](https://github.com/springernature/frontend-playbook/blob/main/writing/house-style.md#plain-english).
32 |
33 | Similarly, in the case of blacklist/whitelist there are alternatives that better show their purpose to people not familiar with the terminology, like denylist/allowlist, blocklist/allowlist or block/permit. Choose a term that is appropriate and descriptive for your particular app or feature.
34 |
35 | ["Treat problematic terminology as technical debt. When you learn that you have it in your projects, make it a priority to remove it."](https://blog.carbonfive.com/problematic-terminology-in-open-source/)
36 |
37 | The [IETF has published a document (ietf.org)](https://tools.ietf.org/html/draft-knodel-terminology-01) that further describes the reasoning for avoiding this kind of language alongside further alternatives.
38 |
39 | ### Gendered language
40 |
41 | In most cases your writing will address the reader directly as "you", but if you do need to write about people in the abstract, avoid language that centers the male identity as the default. Try recasting your sentences as plural to make them more inclusive and concise. You can also use the [singular _they_](https://www.poynter.org/reporting-editing/2015/the-washington-post-will-allow-singular-they/) as per the Washington Post.
42 |
43 | Avoid "bro" language, even in verbal communication.
44 |
45 | We _don't_ say this:
46 | > Each student must complete his or her homework.
47 |
48 | > Server: Hello.
49 | >
50 | > Client: Hey _bro_, I have a message for you.
51 |
52 | > Hey guys!
53 |
54 | We say this:
55 | > All students must complete their homework
56 |
57 | > Server: Hello.
58 | >
59 | > Client: Hey server, I have a message for you.
60 |
61 | > Hey people!
62 | > Hey team!
63 |
64 | ### Disability and accessibility
65 |
66 | Using inclusive language is critical when writing about accessibility. Avoid references that dehumanise or 'other' people, or that cast them as helpless victims. Never use collective nouns like "the disabled" or "the blind" - these words are descriptors, not group labels.
67 |
68 | Use positive language that emphasises abilities rather than limitations. Consider whether you need to refer to a disability at all - for example, instead of writing about "users who are unable to use a mouse", perhaps you can be more precise with "keyboard users", or "users of alternative input devices".
69 |
70 | We _don't_ say this:
71 |
72 | > The disabled.
73 | > Dyslexics.
74 | > Susan is a victim of blindness.
75 | > People suffering from deafness.
76 | > Users who cannot see a screen.
77 |
78 | We say this:
79 |
80 | > Disabled people.
81 | > Dyslexic people.
82 | > Susan is blind.
83 | > Deaf people.
84 | > Screenreader users / blind users. [where relevant]
85 |
86 | The Special Interest Group on Accessible Computing (SIGACCESS) has published a [comprehensive guide to writing about disability](http://www.sigaccess.org/welcome-to-sigaccess/resources/accessible-writing-guide/) within the context of science and technology.
87 |
88 | You may also find the more general [gov.uk inclusive language guidance](https://www.gov.uk/government/publications/inclusive-communication/inclusive-language-words-to-use-and-avoid-when-writing-about-disability) helpful.
89 |
90 | [govau]: https://www.education.tas.gov.au/documentcentre/Documents/Guidelines-for-Inclusive-Language.pdf "Guidelines for Inclusive Language"
91 | [hemingway]: http://www.hemingwayapp.com/
92 | [wiley]: http://onlinelibrary.wiley.com/doi/10.1111/j.1467-1770.1982.tb00973.x/abstract "Language environment and gender identity attainment"
93 |
--------------------------------------------------------------------------------
/writing/social-media.md:
--------------------------------------------------------------------------------
1 | # Social media
2 |
3 | - [Cruft.io](#cruftio)
4 | - [Posting publicly](#posting-publicly)
5 |
6 | An important part of our work as developers is not only to create quality products, but also to raise awareness of accessibility, performance and progressive enhancement best practices. This includes promoting our work and our practices in open spaces like social media, conferences, talks and other events.
7 |
8 | For open-source projects, we aim to keep our projects up to date and fix any vulnerabilities in a timely fashion. Please see our [Open Source Support page](https://github.com/springernature/frontend-playbook/blob/main/practices/open-source-support.md) for details on how we do this.
9 |
10 | ## Cruft.io
11 |
12 | [Cruft.io](http://cruft.io) is a blog run by Springer Nature Technology. Anyone can post there and the instructions can be found in the [project's wiki (internal)](https://github.com/springernature/cruft/).
13 |
14 | ## Posting publicly
15 |
16 | Before publishing anything ensure that:
17 |
18 | * All the public communications follow our [language standards](house-style.md).
19 | * When reporting bugs or security issues, remember to use positive language instead of blaming.
20 | * Always use [inclusive language](inclusive-language.md).
21 |
22 | We do:
23 | > Released Shunter 1.2.3. Security upgrade of `nac` to 3.2.1 which addresses several vulns. https://github.com/springernature/shunter/blob/master/HISTORY.md#123-2017-03-08
24 |
25 | We _don't_ do:
26 | > Released Shunter 1.2.3. Fixes a vulnerability which was caused by a bug in `nac`, breaking our project. https://github.com/springernature/shunter/blob/master/HISTORY.md#123-2017-03-08
27 |
28 | * Always provide links where people can find further information if interested. E.g. a changelog for a software release, a blog article, a link to the frontend playbook, etc.
29 |
--------------------------------------------------------------------------------