global-news
The Global News Repo!
Redesign
To get started developing any redesign templates, you will first need to download and install node
and npm
on your system. If you're using Windows, make sure both are included in your PATH
variable so they can be accessed from the command line.
Next, run an npm install
in the theme directory to locally install all dependencies.
Local Development
All JS, CSS, and static assets for our redesign templates can be found in the assets/src/
directory. To start development locally, run the command: npm run theme:dev
from the theme directory. This will compile all code into the assets/dist/
directory and set up a watch event to listen for any changes to files in assets/src/
.
When you are ready to deploy your changes, run the command npm run theme
. This will compile your code for production, as well as update any styleguide and js documentation changes.
Compilation is done using Webpack and all compilation scripts are in the compile/
directory.
CSS
ITCSS
Redesign styles are separated into SCSS
partials and stiched together using SASS. You'll notice that the CSS is split up into separate layers, each with their own folder. This follows Harry Robert's ITCSS model for organizing large stylesheets. Basically layers are ordered from low to high specificity to avoid having to overwrite styles as much as possible. A good talk explaining ITCSS can be found here. Here is an overview of the layers we are using:
- Settings: Globally-available settings or configuration switches for our project
- Tools: Globally-available mixins, functions, and tools that should make our development flow easier
- Base: Far-reaching low-specificity selectors that target elements directly, no classes
- Objects: Non-cosmetic design patterns, following Object Oriented CSS principles (prefix with
o-
) - Components: Re-usable UI components (prefix with
c-
) - Layout: Specific parts of the page layout made up of other components (e.g. header, footer, sidebar) (prefix with
l-
) - Overrides: Utility classes and overrides (e.g. a JS button click state)
When developing a feature you will need to put some thought into where your CSS will reside in this strucutre. To promote re-usability, try wrapping your CSS into a component. If your feature is complex, break it up into multiple components, potentially with a layout partial fit them together.
BEM
You will notice that the CSS in the objects, components, and layout layers follows a very specific naming convention. This is known as Block Element Modifier syntax or BEM. While it's more verbose that typical CSS syntax, it has a number of benefits:
- Better code organization
- It's easy to know just by looking at the class what the element does
- It allows for shorter more efficient CSS selectors
Stylguide
We're using KSS to generate a styleguide automatically based on comments included at the top of the file. The styleguide can be found in the styleguide/
directory. It will be regenerated every time you call npm run theme
or if you run npm run kss
. The styleguide comment syntax is best explained here. Styleguide configuation can be found in compile/kss-config.json
. If you need to override some styles specifically within the styleguide use compile/kss-overrides.css
.
Stylelint
We're using Stylelint to lint all css in assets/src
. If your IDE is able to visually flags linting issues as you code, you will want to set it up so that Stylelint issues are flagged. Rules are defined in .stylelintrc
config file. CSS files and directories can be set to bypass the linter via .stylelintignore
.
Critical vs Main
- Critical.scss: These styles are inlined directly into the page
<head>
. They are render-blocking and hence should be kept to an absolute minimum. Only include styles here if they are above the fold or otherwise need to be rendered initially on page load. - Main.scss: These styles are loaded asynchronously and hence are not render-blocking. When in doubt, load your styles in here.
There are other ways to improve the loading efficiency of CSS. We can break it up by media query and only load the appropriate media query for the appropriate screen-size. We can also include our <link>
tags in the body itself so CSS is loaded as the markup is parsed. We should test these strategies to see which works best.
PostCSS
Our CSS is also passed through the PostCSS preprocessor after being compiled by SASS. This will automatically add any browser-specific selector prefixes like -webkit-
and -moz-
when necessary. It also lets us use a basic version of the new CSS Grid layout. Grid is supported in all browsers we are supporting, but needs some adjustments to work in IE10 and IE11. Check out this article to see how to use CSS Grid in a way that works on IE, with the help of PostCSS Autoprefixer.
Animations
If you are animating an element with CSS transitions, CSS animation, or JS, it's best to only animate the transform
and opacity
properties, as these are handled most efficiently by the browser. You can accomplish pretty much any animation you can think of by some combination of transform
and opacity
. For an added performance benefit, convert your transform into a matrix3d
transform using this tool. This should ensure that your animation is handled on a separate thread by the GPU.
Javascript
Babel
We are using babel to transpile all scripts into syntax that will work across browsers (supporting the last two versions of most major browsers and IE10+). This means we can make use of ES6 features today, including ES6 modules, fat arrow functions, the spread operator, template literals and block scoping. It's worth reviewing the new ES6 language features before starting development on this project.
Airbnb Standards
We are following the Airbnb JavaScript Style Guide for this project. Rules are enforced using ESlint. We are making some small deviations from the style guide to match the coding style found in other parts of our project. These modifications can be found in the .eslintrc
file. JS files and directories can by set to bypass the linter via .estlintignore
. If you can, set up your IDE to flag ESLint issues automatically.
No jQuery
jQuery was created to provide a convenient interface for interacting with the DOM that smoothed over cross-browser compatibility issues. Today most of what is done with jQuery can be accomplished using plain JS without much difficulty. In order to reduce our reliance on this dependency, we won't be using jQuery for new JS written for the redesign. See youmightnotneedjquery.com for some helpful tips in replicating jQuery functionality with plain JS. We are not stripping jQuery from our existing code. It may be a while before we can fully remove this library as a dependency, but this will start us down that path.
Folder Structure
We are using ES6 modules to organize our code. Each module has its own file and should represent a clear, encapsulated function. There are 3 main folders in the js/
directory:
modules
: The place for all interactive components (e.g. MainMenu, LoadMore, Alerts, etc)polyfills
: The place for small polyfills that provide legacy browser support for newer featuresutils
: Any generic utility function you find helpful
Include the modules and code you are using in the main.js
file, which will be compiled by Webpack.
There is no penalty to having many files, in-fact it is actually preferable. Include each utility function and polyfill in its own module file (don't create a generic utilities.js
). This way we won't balloon the production JS by including utility functions and polyfills that are unused.
The js/
directory should not contain any 3rd party code. If you need use a 3rd party library, include it in the vendor/
directory and add it to the $vendors
array in includes/gnca-enqueue-redesign.php
. Be sure to include a minified version for production and a non-minified version for VIP code-review.
Documentation
We are using JSDoc to automatically document our code based on JS comments at the top of each module and function. The documenation can be found in the jsdoc/
directory. It will be regenerated every time you call npm run theme
or if you run npm run jsdoc
. Check out JSDoc website for an explanation of the JSDoc comment syntax. JSDoc configuation can be found in compile/jsdoc-config.json
.
Icons
We are using SVG icons instead of an icon font for all redesign templates. After adding or removing an SVG icon you will need to compile a new SVG sprite. See the following README for more information on how to do this.
Accessibility
All markup on redesign templates needs to conform to WCAG 2.0 AA accessibility guidelines. From a design perspective this means making sure that site is visually clear and that it won't confuse those with various forms of colorblindness. It also means ensuring that contrast ratios between foreground and background elements are sufficiently high. From a dev perspective this largely means making sure the site is accessible via a keyboard and screen reader. Here are some tips:
- Use the WAVE Browser Extension to automatically scan your pages for accessibility issues
- Make sure every element that can be clicked has a focus style that appears when you tab to it (and it can't just be a change of color)
- Make sure the whole page is easily accessible via a keyboard (
tab
to go forward,shift
+tab
to go back) - Use a screen reader like ChromeVox to test that the page is usable from a screen reader
- Use semantic markup wherever possible to help the screen reader parse your code
- Use WIA-ARIA attributes to provide additional screen reader hints when semantic markup is not enough
- Make sure every image has an
alt
tag oralt=""
if no alt text is required