diff --git a/.storybook/preview.jsx b/.storybook/preview.jsx index 2921adc6..a6cdd346 100644 --- a/.storybook/preview.jsx +++ b/.storybook/preview.jsx @@ -135,7 +135,6 @@ export const parameters = { 'Import CSS, assets and JavaScript', 'Configure components with JavaScript', 'Localise Gov IE DS', - 'Support Internet Explorer 8', 'JavaScript API Reference', 'Sass API Reference', 'Colours', diff --git a/README.md b/README.md index 1cc7662b..015bc04b 100644 --- a/README.md +++ b/README.md @@ -32,7 +32,6 @@ Using Frontend will help your service meet [level AA of WCAG 2.1](https://www.w3 You should also use: - [the JavaScript from Gov IE DS](https://ogcio.github.io/ogcio-ds/?path=/docs/docs-import-css-assets-and-javascript--docs) -- [a separate stylesheet](https://ogcio.github.io/ogcio-ds/?path=/docs/docs-support-internet-explorer-8--docs) if you support Internet Explorer 8 You can also read the [accessibility statement for Gov IE DS](https://www.design-system.ogcio.gov.ie/accessibility/) diff --git a/postcss.config.js b/postcss.config.js index f3e8f022..74e9adb3 100644 --- a/postcss.config.js +++ b/postcss.config.js @@ -1,15 +1,15 @@ -const { parse } = require('path') +const { parse } = require('path'); -const autoprefixer = require('autoprefixer') -const cssnano = require('cssnano') -const cssnanoPresetDefault = require('cssnano-preset-default') -const { minimatch } = require('minimatch') -const postcss = require('postcss') -const pseudoclasses = require('postcss-pseudo-classes') -const scss = require('postcss-scss') -const unmq = require('postcss-unmq') -const unopacity = require('postcss-unopacity') -const unrgba = require('postcss-unrgba') +const autoprefixer = require('autoprefixer'); +const cssnano = require('cssnano'); +const cssnanoPresetDefault = require('cssnano-preset-default'); +const { minimatch } = require('minimatch'); +const postcss = require('postcss'); +const pseudoclasses = require('postcss-pseudo-classes'); +const scss = require('postcss-scss'); +const unmq = require('postcss-unmq'); +const unopacity = require('postcss-unopacity'); +const unrgba = require('postcss-unrgba'); /** * PostCSS config @@ -18,58 +18,52 @@ const unrgba = require('postcss-unrgba') * @returns {import('postcss-load-config').Config} PostCSS config */ module.exports = (ctx) => { - const plugins = [] - const syntax = ctx.to?.endsWith('.scss') ? scss : postcss + const plugins = []; + const syntax = ctx.to?.endsWith('.scss') ? scss : postcss; // PostCSS 'from' (or webpack 'file') source path // https://github.com/postcss/postcss-load-config#options - const { dir, name } = parse(ctx.from || ctx.file || '') + const { dir, name } = parse(ctx.from || ctx.file || ''); // IE8 stylesheets - const isIE8 = name?.endsWith('-ie8') || name?.endsWith('-ie8.min') + const isIE8 = name?.endsWith('-ie8') || name?.endsWith('-ie8.min'); // Add vendor prefixes - plugins.push(autoprefixer({ - env: isIE8 ? 'oldie' : ctx.env - })) + plugins.push( + autoprefixer({ + env: isIE8 ? 'oldie' : ctx.env, + }), + ); // Add review app auto-generated 'companion' classes for each pseudo-class // For example ':hover' and ':focus' classes to simulate form label states if (minimatch(dir, '**/app/stylesheets')) { - plugins.push(pseudoclasses({ - allCombinations: true, - restrictTo: [ - ':link', - ':visited', - ':hover', - ':active', - ':focus' - ] - })) - } - - // Transpile CSS for Internet Explorer - if (isIE8) { plugins.push( - unmq(), - unopacity({ browsers: 'ie 8' }), - unrgba({ filter: true }) - ) + pseudoclasses({ + allCombinations: true, + restrictTo: [':link', ':visited', ':hover', ':active', ':focus'], + }), + ); } // Always minify CSS if (syntax !== scss) { - plugins.push(cssnano({ - preset: [cssnanoPresetDefault, { - // Sorted CSS is smaller when gzipped, but we sort using Stylelint - // https://cssnano.co/docs/optimisations/cssdeclarationsorter/ - cssDeclarationSorter: false - }] - })) + plugins.push( + cssnano({ + preset: [ + cssnanoPresetDefault, + { + // Sorted CSS is smaller when gzipped, but we sort using Stylelint + // https://cssnano.co/docs/optimisations/cssdeclarationsorter/ + cssDeclarationSorter: false, + }, + ], + }), + ); } return { syntax, - plugins - } -} \ No newline at end of file + plugins, + }; +}; diff --git a/postcss.config.unit.test.js b/postcss.config.unit.test.js index 0e945610..7fa0a0b4 100644 --- a/postcss.config.unit.test.js +++ b/postcss.config.unit.test.js @@ -1,210 +1,104 @@ -const Vinyl = require('vinyl') -const configFn = require('./postcss.config.js') +const Vinyl = require('vinyl'); +const configFn = require('./postcss.config.js'); describe('PostCSS config', () => { let env; - function getPluginNames ({ plugins }) { - return plugins.map(({ postcssPlugin }) => postcssPlugin) + function getPluginNames({ plugins }) { + return plugins.map(({ postcssPlugin }) => postcssPlugin); } beforeAll(() => { - env = 'production' - }) + env = 'production'; + }); describe('Browserslist', () => { describe('Default environment', () => { it('Uses default environment', () => { - const config = configFn({ env }) + const config = configFn({ env }); - expect(config.plugins) - .toEqual(expect.arrayContaining([ + expect(config.plugins).toEqual( + expect.arrayContaining([ expect.objectContaining({ postcssPlugin: 'autoprefixer', - options: { env } - }) - ])) - }) - - it.each( - [ - { path: 'example.css' }, - { path: 'example.scss' } - ] - )('Uses default environment for $path', ({ path }) => { - const input = new Vinyl({ path }) - const config = configFn({ env, file: input.basename }) - - expect(config.plugins) - .toEqual(expect.arrayContaining([ - expect.objectContaining({ - postcssPlugin: 'autoprefixer', - options: { env } - }) - ])) - }) - }) - - describe('IE8 only environment', () => { - it.each( - [ - { path: 'example-ie8.css' }, - { path: 'example-ie8.scss' }, - { path: 'example-ie8.min.css' }, - { path: 'example-ie8.min.scss' } - ] - )("Uses 'oldie' environment for $path", ({ path }) => { - const input = new Vinyl({ path }) - const config = configFn({ env, file: input.basename }) - - expect(config.plugins) - .toEqual(expect.arrayContaining([ - expect.objectContaining({ - postcssPlugin: 'autoprefixer', - options: { env: 'oldie' } - }) - ])) - }) - }) - }) + options: { env }, + }), + ]), + ); + }); + + it.each([{ path: 'example.css' }, { path: 'example.scss' }])( + 'Uses default environment for $path', + ({ path }) => { + const input = new Vinyl({ path }); + const config = configFn({ env, file: input.basename }); + + expect(config.plugins).toEqual( + expect.arrayContaining([ + expect.objectContaining({ + postcssPlugin: 'autoprefixer', + options: { env }, + }), + ]), + ); + }, + ); + }); + }); describe('Plugins', () => { describe('Default', () => { - it.each( - [ - { path: 'example.css' }, - { path: 'example.scss' } - ] - )('Adds plugins for $path', ({ path }) => { - const input = new Vinyl({ path }) - - // Confirm plugins for both file object and path - for (const file of [input, input.path]) { - const config = configFn({ env, file: file.basename }) + it.each([{ path: 'example.css' }, { path: 'example.scss' }])( + 'Adds plugins for $path', + ({ path }) => { + const input = new Vinyl({ path }); - expect(getPluginNames(config)) - .toEqual(['autoprefixer', 'cssnano']) - } - }) - }) - - describe('Default + IE8', () => { - it.each( - [ - { path: 'example-ie8.css' }, - { path: 'example-ie8.scss' } - ] - )('Adds plugins for $path', ({ path }) => { - const input = new Vinyl({ path }) + // Confirm plugins for both file object and path + for (const file of [input, input.path]) { + const config = configFn({ env, file: file.basename }); - // Confirm plugins for both file object and path - for (const file of [input, input.path]) { - const config = configFn({ env, file: file.basename ? file.basename : file }) - - expect(getPluginNames(config)) - .toEqual([ - 'autoprefixer', - 'postcss-unmq', - 'postcss-unopacity', - 'postcss-color-rgba-fallback', - 'cssnano' - ]) - } - }) - }) + expect(getPluginNames(config)).toEqual(['autoprefixer', 'cssnano']); + } + }, + ); + }); describe('Default + Minification', () => { - it.each( - [ - { path: 'example.min.css' }, - { path: 'example.min.scss' } - ] - )('Adds plugins for $path', ({ path }) => { - const input = new Vinyl({ path }) - - // Confirm plugins for both file object and path - for (const file of [input, input.path]) { - const config = configFn({ env, file: file.basename ? file.basename : file }) - - expect(getPluginNames(config)) - .toEqual([ - 'autoprefixer', - 'cssnano' - ]) - } - }) - }) - - describe('Default + Minification + IE8', () => { - it.each( - [ - { path: 'example-ie8.min.css' }, - { path: 'example-ie8.min.scss' } - ] - )('Adds plugins for $path', ({ path }) => { - const input = new Vinyl({ path }) - - // Confirm plugins for both file object and path - for (const file of [input, input.path]) { - const config = configFn({ env, file: file.basename ? file.basename : file }) - - expect(getPluginNames(config)) - .toEqual([ - 'autoprefixer', - 'postcss-unmq', - 'postcss-unopacity', - 'postcss-color-rgba-fallback', - 'cssnano' - ]) - } - }) - }) + it.each([{ path: 'example.min.css' }, { path: 'example.min.scss' }])( + 'Adds plugins for $path', + ({ path }) => { + const input = new Vinyl({ path }); + + // Confirm plugins for both file object and path + for (const file of [input, input.path]) { + const config = configFn({ + env, + file: file.basename ? file.basename : file, + }); + + expect(getPluginNames(config)).toEqual(['autoprefixer', 'cssnano']); + } + }, + ); + }); describe('Review app only', () => { - it.each( - [ - { path: 'app/assets/scss/app.scss' }, - { path: 'app/assets/scss/app-legacy.scss' } - ] - )('Adds plugins for $path', ({ path }) => { - const input = new Vinyl({ path }) + it.each([ + { path: 'app/assets/scss/app.scss' }, + { path: 'app/assets/scss/app-legacy.scss' }, + ])('Adds plugins for $path', ({ path }) => { + const input = new Vinyl({ path }); // Confirm plugins for both file object and path for (const file of [input, input.path]) { - const config = configFn({ env, file: file.basename ? file.basename : file }) - - expect(getPluginNames(config)) - .toEqual([ - 'autoprefixer', - 'cssnano' - ]) - } - }) - }) - - describe('Review app only + IE8', () => { - it.each( - [ - { path: 'app/assets/scss/app-ie8.scss' }, - { path: 'app/assets/scss/app-legacy-ie8.scss' } - ] - )('Adds plugins for $path', ({ path }) => { - const input = new Vinyl({ path }) + const config = configFn({ + env, + file: file.basename ? file.basename : file, + }); - // Confirm plugins for both file object and path - for (const file of [input, input.path]) { - const config = configFn({ env, file: file.basename ? file.basename : file }) - - expect(getPluginNames(config)) - .toEqual([ - 'autoprefixer', - 'postcss-unmq', - 'postcss-unopacity', - 'postcss-color-rgba-fallback', - 'cssnano' - ]) + expect(getPluginNames(config)).toEqual(['autoprefixer', 'cssnano']); } - }) - }) - }) -}) \ No newline at end of file + }); + }); + }); +}); diff --git a/src/govie/all-ie8.scss b/src/govie/all-ie8.scss deleted file mode 100644 index e3f0913f..00000000 --- a/src/govie/all-ie8.scss +++ /dev/null @@ -1,6 +0,0 @@ -// By setting $govie-is-ie8 to true, we create a version of the stylesheet that -// targets IE8 – e.g. conditionally including or excluding styles, and -// rasterizing media queries. -$govie-is-ie8: true; - -@import 'all'; diff --git a/src/govie/all-storybook-ie.scss b/src/govie/all-storybook-ie.scss deleted file mode 100644 index 469f8ddd..00000000 --- a/src/govie/all-storybook-ie.scss +++ /dev/null @@ -1,10 +0,0 @@ -// By setting $govie-is-ie8 to true, we create a version of the stylesheet that -// targets IE8 – e.g. conditionally including or excluding styles, and -// rasterizing media queries. -$govie-is-ie8: true; -// By setting $govie-is-storybook to true, we create a version of the stylesheet that -// targets Storybook – e.g. conditionally including or excluding styles. -$govie-is-storybook: true; - -@import 'storybook/all'; -@import 'all'; diff --git a/src/govie/components/button/_index.scss b/src/govie/components/button/_index.scss index 4b74a151..3269fbd0 100644 --- a/src/govie/components/button/_index.scss +++ b/src/govie/components/button/_index.scss @@ -192,11 +192,6 @@ $govie-tertiary-button-text-colour: govie-colour('black') !default; @include govie-not-ie8 { outline: $govie-focus-width solid transparent; } - // Since Internet Explorer does not support `:not()` we set a clearer focus style to match user-agent outlines. - @include govie-if-ie8 { - border-color: $govie-focus-colour; - background-color: $govie-focus-colour; - } box-shadow: inset 0 0 0 1px transparent; } diff --git a/src/govie/components/icon-button/_index.scss b/src/govie/components/icon-button/_index.scss index 518e1807..e9f25aca 100644 --- a/src/govie/components/icon-button/_index.scss +++ b/src/govie/components/icon-button/_index.scss @@ -101,11 +101,6 @@ $govie-icon-button-hover-background-colour: govie-colour('mid-grey') !default; @include govie-not-ie8 { outline: $govie-focus-width solid transparent; } - // Since Internet Explorer does not support `:not()` we set a clearer focus style to match user-agent outlines. - @include govie-if-ie8 { - border-color: transparent; - background-color: $govie-icon-button-background-colour; - } box-shadow: inset 0 0 0 1px transparent; } diff --git a/src/govie/helpers/_media-queries.scss b/src/govie/helpers/_media-queries.scss index e5a39adc..bb87d0bf 100644 --- a/src/govie/helpers/_media-queries.scss +++ b/src/govie/helpers/_media-queries.scss @@ -24,9 +24,6 @@ $mq-show-breakpoints: (); // 'rasterize' any media queries. $mq-responsive: true; -@if variable-exists(govie-is-ie8) and $govie-is-ie8 { - $mq-responsive: false; -} // This is a horrible, horrible hack to prevent the 'dev mode' CSS to display // the current breakpoint from being included multiple times. diff --git a/src/govie/helpers/media-queries.test.js b/src/govie/helpers/media-queries.test.js index a1029afd..96f08245 100644 --- a/src/govie/helpers/media-queries.test.js +++ b/src/govie/helpers/media-queries.test.js @@ -152,52 +152,4 @@ describe('@mixin govie-media-query', () => { '@media aural and (max-width: 40em){.foo{color:red}}', ); }); - - describe('when compiling a rasterized stylesheet for IE8', () => { - it('only outputs static breakpoint styles', async () => { - const sass = ` - $govie-is-ie8: true; - - $govie-breakpoints: ( - mobile: 320px, - tablet: 740px, - desktop: 980px, - wide: 1300px - ); - - @import "helpers/media-queries"; - - .foo { - @include govie-media-query($until: tablet) { - color: #{lawngreen}; - } - @include govie-media-query($from: desktop) { - color: #{forestgreen}; - } - }`; - - const results = await compileSassString(sass, sassConfig); - - expect(results.css.toString().trim()).toBe('.foo{color:forestgreen}'); - }); - - it('does not rasterize print queries', async () => { - const sass = ` - ${sassBootstrap} - $govie-is-ie8: true; - - @import "helpers/media-queries"; - - .foo { - color: blue; - @include govie-media-query($media-type: 'print') { - color: red; - } - }`; - - const results = await compileSassString(sass, sassConfig); - - expect(results.css.toString().trim()).toBe('.foo{color:blue}'); - }); - }); }); diff --git a/src/govie/helpers/typography.test.js b/src/govie/helpers/typography.test.js index a2b46d6c..27a20a51 100644 --- a/src/govie/helpers/typography.test.js +++ b/src/govie/helpers/typography.test.js @@ -91,26 +91,6 @@ describe('@mixin govie-typography-common', () => { expect(resultsString).toContain('font-family: "Lato"'); expect(resultsString).toContain('font-family: "Lato"'); }); - - it('should not output a @font-face declaration when the browser is IE8', async () => { - const sass = ` - $govie-is-ie8: true; - - @import "settings/all"; - @import "helpers/all"; - @import "tools/ie8"; - - :root { - @include govie-typography-common; - } - `; - - const results = await compileSassString(sass, sassConfig); - const resultsString = results.css.toString(); - - expect(resultsString).not.toContain('@font-face'); - expect(resultsString).toContain('font-family: "Lato"'); - }); }); describe('@function _govie-line-height', () => { diff --git a/storybook/stories/api-reference/sass-api-reference.mdx b/storybook/stories/api-reference/sass-api-reference.mdx index 08ee1072..7c3e4c21 100644 --- a/storybook/stories/api-reference/sass-api-reference.mdx +++ b/storybook/stories/api-reference/sass-api-reference.mdx @@ -261,29 +261,6 @@ Whether to style paragraphs (>p<) and links (>a<) without explicitly $govie-global-styles: false; ``` -### Internet explorer 8 - -#### $govie-is-ie8 - -Whether the stylesheet being built is targeting Internet Explorer 8. - -#### Default value - -```css -$govie-is-ie8: false; -``` - -#### $govie-ie8-breakpoint - -The name of the breakpoint to use as the target when rasterizing media -queries. - -#### Default value - -```css -govie-ie8-breakpoint: desktop; -``` - ### Measurements #### $govie-page-width diff --git a/storybook/stories/get-started/support-ie-8.mdx b/storybook/stories/get-started/support-ie-8.mdx deleted file mode 100644 index d0692084..00000000 --- a/storybook/stories/get-started/support-ie-8.mdx +++ /dev/null @@ -1,109 +0,0 @@ -import { Canvas, Meta } from '@storybook/blocks'; -import { Link } from '../components/Link.jsx'; - - - -# Support Internet Explorer 8 - -Follow these extra steps if your service needs to support Internet Explorer 8 (IE8): - -1. Include an HTML5 shiv. -2. Generate an IE8-specific stylesheet. -3. Transform the IE8 stylesheet using oldie. -4. Include the IE8 stylesheet in your project. - -Once you have completed these steps, you will be able to write CSS that targets IE8 in your own application styles. - -If you installed using precompiled files, you can include the IE8-specific stylesheet in your project, allowing you to skip steps 2 and 3. - -## 1. Include an HTML5 shiv - -You will need to to include an [HTML5 shiv](https://github.com/aFarkas/html5shiv) which allows the 'semantic' HTML elements introduced in HTML5 to be used in older browsers which do not natively support them. - -These elements include `article`, `aside`, `figcaption`, `figure`, `footer`, `header`, `main`, `mark`, `nav`, `section`, and `time`. - -To improve performance for users of modern browsers, you can wrap the shiv include with conditional comments that target only the browsers that need it: - -```html - -``` - -Note that some libraries such as Modernizr may already include html5shiv. - -## 2. Generate an IE8-specific stylesheet - -Setting the `$govie-is-ie8` variable to `true` when generating the stylesheet will create a version that targets IE8. For example, it will: - -- flatten media queries to create a 'desktop only' version -- include any conditional styles that target IE8 -- exclude any conditional styles that target browsers other than IE8 - -You must set the variable before importing Gov IE DS. - -In most scenarios you should be able to create a separate stylesheet for IE8, set the `$govie-is-ie8` variable to true and then import your main application stylesheet without having to redefine anything else. - -```sass -// application.scss -@import "@ogcio/ogcio-ds/govie/all"; -.example { - // example application style -} - -// application-ie8.scss -$govie-is-ie8: true; -@import "application"; -``` - -## 3. Transform the generated stylesheet using 'oldie' - -You should use the [oldie plugin](https://github.com/jonathantneal/oldie) for [postcss](https://github.com/postcss/postcss) to further transform the stylesheet: - -- replacing opacity properties with compatible filter properties -- swapping `::` selectors with compatible `:` selectors for pseudo-elements -- swapping rgba colours with compatible hex colours and filter properties - -The oldie plugin is also able to flatten media queries, but this will already have been done as part of the stylesheet compilation in step 1. - -Doing this as a separate step allows us to keep the source of Gov IE DS simple, without having to wrap syntax that would need to be transformed in mixins or functions. - -## 4. Include the IE8 stylesheet in your project - -Now that you have an IE8 compatible stylesheet you should include it using [conditional comments](https://www.quirksmode.org/css/condcom.html): - -```html -{/*[if !IE 8]> -{/* - - -``` - -