w The Network week in review: Jan 20 - Jan 24 By newsroom.cisco.com Published On :: Fri, 24 Jan 2020 04:00:00 PST This week we go inside the World Economic Forum and we learn how smart manufacturers are using robots! Read below to learn more. More RSS Feed: newsroom.cisco.com/rss-feeds ... Full Article Government Federal & Cities Internet of Things Manufacturing Robotics Vertical Focus
w How 5G will change the game for medical practitioners By newsroom.cisco.com Published On :: Mon, 27 Jan 2020 04:00:00 PST How the technology will have a profound impact on healthcare delivery. More RSS Feed for Cisco: newsroom.cisco.com/rss-feeds ... Full Article 5G Healthcare Vertical Focus
w Twitter moments: Cisco at #wef20 By twitter.com Published On :: Mon, 27 Jan 2020 08:00:00 PST Highlights of tweets about Cisco at the World Economic Forum More RSS Feed for Cisco: newsroom.cisco.com/rss-feeds ... Full Article Government Federal & Cities Vertical Focus
w Entrepreneurial trees, watered by philanthropy, bears fruit By www.philanthropyroundtable.org Published On :: Mon, 27 Jan 2020 08:00:00 PST the Harambe Entrepreneur Allianceis hastening the development of Africa by promoting smaller and more daring actions. More RSS Feed for Cisco: newsroom.cisco.com/rss-feeds ... Full Article Corporate Social Responsibility
w The key to integrating retail systems? The Network By blogs.cisco.com Published On :: Mon, 27 Jan 2020 08:00:00 PST Retailers rely on applications and analytics engines to interpret the data and deliver engaging experiences and key business outcomes More RSS Feed for Cisco: newsroom.cisco.com/rss-feeds ... Full Article Analytics & Automation Enterprise Networking Retail Vertical Focus
w Cisco's new Cybersecurity Co-Innovation Center in Milan By blogs.cisco.com Published On :: Mon, 27 Jan 2020 12:00:00 PST Our newest Co-Innovation Center is focused on cybersecurity, privacy, digital skills and social impact. More RSS Feed for Cisco: newsroom.cisco.com/rss-feeds ... Full Article EMEAR Security
w How do you accelerate your hybrid applications? By blogs.cisco.com Published On :: Tue, 28 Jan 2020 23:30:00 PST When apps are from Mars and infrastructure is from Venus, how do you accelerate your Hybrid Applications? More RSS Feed for Cisco: newsroom.cisco.com/rss-feeds ... Full Article Cloud
w Cisco ushers in a bright new age of bridges By newsroom.cisco.com Published On :: Wed, 29 Jan 2020 08:00:00 PST Our dependence on apps is reaching its technical limits. But don't worry: Cisco is solving the issue. More RSS Feed for Cisco: newsroom.cisco.com/rss-feeds ... Full Article Cloud Software
w #CLEUR: Here's how we can build the future internet By www.wired.co.uk Published On :: Thu, 30 Jan 2020 08:00:00 PST The future internet will open new opportunities for remotely training and reskilling workers in a smoother and more effective way. More RSS Feed for Cisco: newsroom.cisco.com/rss-feeds ... Full Article Developers & Ecosystem Education Innovation Vertical Focus
w Online tests well received by schoolchildren in Tiruvannamalai By www.thehindu.com Published On :: Fri, 08 May 2020 19:37:58 +0530 District Collector K.S. Kandasamy said the tests were a joint effort of the District Education Department and National Informatics Centre to keep students engaged during the lockdown. Full Article Tamil Nadu
w Coronavirus | Chennai-based ayurvedic pharmacist dies after drinking concoction of his own preparation By www.thehindu.com Published On :: Fri, 08 May 2020 20:01:12 +0530 Managing Director of the firm faints after tasting the chemical Full Article Tamil Nadu
w Four doctors, two nurses of Rajah Muthiah hospital test positive By www.thehindu.com Published On :: Fri, 08 May 2020 20:36:31 +0530 Efforts on to trace other health workers who were in contact with them Full Article Tamil Nadu
w KKCTH treats a child with atypical symptoms for COVID-19 infection By www.thehindu.com Published On :: Fri, 08 May 2020 21:20:08 +0530 “COVID-19 is a respiratory disease but world over we see children coming with diarrhoea and abdominal pain,” says a doctor Full Article Tamil Nadu
w Sand lorry owners seek exemption from quarterly tax payment By www.thehindu.com Published On :: Fri, 08 May 2020 21:42:35 +0530 Most lorries were not operated during the lockdown which resulted in loss, they say Full Article Tamil Nadu
w Tapping expertise — how T.N. is handling the crisis By www.thehindu.com Published On :: Fri, 08 May 2020 23:44:57 +0530 Multiple panels with senior bureaucrats constituted to address issues arising out of the pandemic Full Article Tamil Nadu
w Cine industry welcomes govt.’s decision allowing post-production work By www.thehindu.com Published On :: Fri, 08 May 2020 23:55:27 +0530 The announcement by the Tamil Nadu government allowing post-production work on films and television projects to resume from May 11 was welcomed by the Full Article Tamil Nadu
w New COVID case at Kuchipalayam By www.thehindu.com Published On :: Fri, 08 May 2020 23:57:00 +0530 A person from Kuchipalayam tested positive for COVID-19 even as Mahe became COVID-free with the sole patient testing negative for the infection and ge Full Article Tamil Nadu
w Come May 11, post-production work in films will resume By www.thehindu.com Published On :: Fri, 08 May 2020 23:58:14 +0530 CM takes decision following representations from industry Full Article Tamil Nadu
w Coronavirus | Tamil Nadu tally goes past 6,000 with 600 new cases By www.thehindu.com Published On :: Sat, 09 May 2020 17:05:03 +0530 Chennai adds 399 patients to its total Full Article Tamil Nadu
w HC warns State of being imposed with costs By www.thehindu.com Published On :: Sat, 09 May 2020 00:07:34 +0530 The Madras High Court on Friday warned the State government of being imposed with costs if it fails to file a counter affidavit by Tuesday to a public Full Article Tamil Nadu
w Second train with migrant workers leaves for Ranchi By www.thehindu.com Published On :: Sat, 09 May 2020 05:22:35 +0530 The second Shramik special train with 1,131 passengers left Kadpadi junction for Ranchi on Friday at 7.40 p.m. The passengers were brought to the stat Full Article Tamil Nadu
w [ASAP] Low-Threshold Lasing up to 360 K in All-Dielectric Subwavelength-Nanowire Nanocavities By dx.doi.org Published On :: Tue, 07 Apr 2020 04:00:00 GMT ACS PhotonicsDOI: 10.1021/acsphotonics.0c00166 Full Article
w [ASAP] White Light Emission from a Zero-Dimensional Lead Chloride Hybrid Material By dx.doi.org Published On :: Thu, 09 Apr 2020 04:00:00 GMT ACS PhotonicsDOI: 10.1021/acsphotonics.9b01817 Full Article
w [ASAP] Plasmon-Mediated Coherent Superposition of Discrete Excitons under Strong Exciton–Plasmon Coupling in Few-Layer MoS<sub>2</sub> at Room Temperature By dx.doi.org Published On :: Fri, 10 Apr 2020 04:00:00 GMT ACS PhotonicsDOI: 10.1021/acsphotonics.0c00233 Full Article
w [ASAP] Room Temperature Graphene Mid-Infrared Bolometer with a Broad Operational Wavelength Range By dx.doi.org Published On :: Fri, 10 Apr 2020 04:00:00 GMT ACS PhotonicsDOI: 10.1021/acsphotonics.0c00028 Full Article
w [ASAP] Size, Ligand, and Defect-Dependent Electron–Phonon Coupling in Chalcogenide and Perovskite Nanocrystals and Its Impact on Luminescence Line Widths By dx.doi.org Published On :: Mon, 13 Apr 2020 04:00:00 GMT ACS PhotonicsDOI: 10.1021/acsphotonics.0c00034 Full Article
w [ASAP] Large Wavelength Response to Pressure Enabled in InGaN/GaN Microcrystal LEDs with 3D Architectures By dx.doi.org Published On :: Tue, 14 Apr 2020 04:00:00 GMT ACS PhotonicsDOI: 10.1021/acsphotonics.0c00251 Full Article
w [ASAP] Colloidal Quantum-Dots/Graphene/Silicon Dual-Channel Detection of Visible Light and Short-Wave Infrared By dx.doi.org Published On :: Fri, 17 Apr 2020 04:00:00 GMT ACS PhotonicsDOI: 10.1021/acsphotonics.0c00247 Full Article
w [ASAP] Update to Our Reader, Reviewer, and Author Communities—April 2020 By dx.doi.org Published On :: Wed, 22 Apr 2020 04:00:00 GMT ACS PhotonicsDOI: 10.1021/acsphotonics.0c00628 Full Article
w [ASAP] Terahertz Spectroscopy of Gas Mixtures with Dual Quantum Cascade Laser Frequency Combs By dx.doi.org Published On :: Thu, 23 Apr 2020 04:00:00 GMT ACS PhotonicsDOI: 10.1021/acsphotonics.9b01758 Full Article
w [ASAP] Near-Field Radiative Heat Transfer between Dissimilar Materials Mediated by Coupled Surface Phonon- and Plasmon-Polaritons By dx.doi.org Published On :: Fri, 24 Apr 2020 04:00:00 GMT ACS PhotonicsDOI: 10.1021/acsphotonics.0c00404 Full Article
w [ASAP] Exciton-Polaritons with Magnetic and Electric Character in All-Dielectric Metasurfaces By dx.doi.org Published On :: Thu, 30 Apr 2020 04:00:00 GMT ACS PhotonicsDOI: 10.1021/acsphotonics.0c00063 Full Article
w [ASAP] Colored Radiative Cooling Coatings with Nanoparticles By dx.doi.org Published On :: Fri, 01 May 2020 04:00:00 GMT ACS PhotonicsDOI: 10.1021/acsphotonics.0c00513 Full Article
w [ASAP] Probing the Radiative Electromagnetic Local Density of States in Nanostructures with a Scanning Tunneling Microscope By dx.doi.org Published On :: Wed, 06 May 2020 04:00:00 GMT ACS PhotonicsDOI: 10.1021/acsphotonics.0c00264 Full Article
w [ASAP] Line-Scan Hyperspectral Imaging Microscopy with Linear Unmixing for Automated Two-Dimensional Crystals Identification By dx.doi.org Published On :: Wed, 06 May 2020 04:00:00 GMT ACS PhotonicsDOI: 10.1021/acsphotonics.0c00050 Full Article
w Twelve Days of Front End Testing By feedproxy.google.com Published On :: Mon, 02 Dec 2019 12:00:00 +0000 Amy Kapernick sings us through numerous ways of improving the robustness and reliability of our front end code with a comprehensive rundown of ideas, tools, and resources. The girls and boys won’t get any toys until all the tests are passing. Anyone who’s spoken to me at some point in November may get the impression that I’m a bit of a grinch. But don’t get me wrong, I love Christmas, I love decorating my tree, singing carols, and doing Christmas cooking - in December. So for me to willingly be humming the 12 days of Christmas in October, it’s probably for something that I think is even more important than banning premature Christmas decorations, like front end testing. On the 12th day of Christmas, my front end dev, she gave to me, 12 testing tools, 11 optimised images, 10 linting rules, 9 semantic headings, 8 types of colour blindness, 7(.0) contrast ratio, 6 front end tests, 5 browser types, 4 types of tests, 3 shaken trees, 2 image types, and a source controlled deployment pipeline. Twelve Testing Tools axe does automated accessibility testing. Run as part of your development build, it outputs warnings to your console to let you know what changes you need to make (referencing accessibility guides). You can also specify particular accessibility standard levels that you’d like to test against, eg. best-practice, wcag2a or wcag2aa, or you can pick and choose individual rules that you want to check for (full list of rules you can test with axe). aXe Core can be used to automate accessibility testing, and has a range of extensions for different programming languages and frameworks. BackstopJS runs visual regression tests on your website. Run separately, or as part of your deployment/PR process, you can use it to make sure your code changes aren’t bleeding into other areas of the website. By default, BackstopJS will set you up with a bunch of configuration options by running backstop init in your project to help get you started. BackstopJS compares screenshots of your website to previous screenshots and compares the visual differences to see what’s changed. Website Speed Test analyses the performance of your website specifically with respect to images, and the potential size savings if they were optimised. Calibre runs several different types of tests by leveraging Lighthouse. You can run it over your live website through their web app or through the command line, it then monitors your website for performance and accessibility over time, providing metrics and notifications of any changes. Calibre provides an easy to use interface and dashboard to test and monitor your website for performance, accessibility and several other areas. Cypress is for end-to-end testing of your website. When visual regression testing may be a bit much for you, Cypress can help you test and make sure elements are still on the page and visible (even if they’re not pixel for pixel where they were last time). pa11y is for automated accessibility testing. Run as part of your build process or using their CLI or dashboard, it tests your website against various Web Content Accessibility Guidelines (WCAG) criteria (including visual tests like colour contrast). While axe is run as part of your dev build and gives you an output to the console, it can be combined with pa11y to automate any changes as part of your build process. whocanuse was created by Corey Ginnivan, and it allows you to view colour combinations as those with colour blindness would (as well as testing other visual deficiencies, and situational vision events), and test the colour contrast ratio based on those colours. Colour contrast assessment of my brand colours, testing them for issues for people with various vision deficiencies, and situational vision events. Colour Blindness Emulation was created by Kyo Nagashima as an SVG filter to emulate the different types of colour blindness, or if you’re using Gatsby, you can use a plugin based off of gatsby-plugin-colorblind-filters. Accessible Brand Colors tests all your branding colours against each other (this is great to show designers what combinations they can safely use). Accessible Brand Colors tests all colour combinations of background and text colours available from your branding colours, and checks them for compliance levels at various font sizes and weights. Browser dev tools - Most of the modern browsers have been working hard on the features available in their dev tools: Firefox: Accessibility Inspector, Contrast Ratio testing, Performance monitoring. Chromium: (Chrome, Edge Beta, Brave, Vivaldi, Opera, etc) - Accessibility Inspector, Contrast Ratio testing, Performance Monitoring, Lighthouse Audits (testing performance, best practices, accessibility and more). Edge: Accessibility Inspector, Performance monitoring. Safari: Accessibility Inspector, Performance monitoring. Firefox (left), Chrome, and Edge Beta (right) Dev Tools now analyse contrast ratios in the colour picker. The Chromium-based browsers also show curves on the colour picker to let you know which shades would meet the contrast requirements. Linc is a continuous delivery platform that makes testing the front end easier by automatically deploying a version of your website for every commit on every branch. One of the biggest hurdles when testing the front end is needing a live version of the site to view and test against. Linc makes sure you always have one. ESLint and Stylelint check your code for programmatic and stylistic errors, as well as helping keep formatting standard on projects with multiple developers. Adding a linter to your project not only helps you write better code, it can reduce simple errors that might be found during testing time. If you’re not writing JavaScript, there are plenty of alternatives for whatever language you’re writing in. If you’re trying to run eslint in VS Code, make sure you don’t have the Beautify extension installed, as that will break things. Eleven Optimised Images When it comes to performance, images are where we take the biggest hit, with images accounting for over 50% of total transfer size for websites. Many websites are serving excessively large images “just in case”, but there’s actually a native HTML element that allows us to serve different image sizes based on the screen size or serve better image formats when the browser supports it (or both). <!-- Serving different images based on the width of the screen --> <picture> <source srcset="/img/banner_desktop.jpg" media="(min-width: 1200px)" /> <source srcset="/img/banner_tablet.jpg" media="(min-width: 700px)" /> <source srcset="/img/banner_mobile.jpg" media="(min-width: 300px)" /> <img src="/img/banner_fallback.jpg"> </picture> <!-- Serving different image formats based on browser compatibility --> <picture> <source srcset="/banner.webp" type="image/webp" /> <img src="/img/banner_fallback.jpg"> </picture> Ten Linting Rules A year ago, I didn’t use linting. It was mostly just me working on projects, and I can code properly right? But these days it’s one of the first things I add to a project as it saves me so much time (and has taught me a few things about JavaScript). Linting is a very personal choice, but there are plenty of customisations to make sure it’s doing what you want, and it’s available in a wide variety of languages (including linting for styling). // .eslintrc module.exports = { rules: { 'no-var': 'error', 'no-unused-vars': 1, 'arrow-spacing': ['error', { before: true, after: true }], indent: ['error', 'tab'], 'comma-dangle': ['error', 'always'], // standard plugin - options 'standard/object-curly-even-spacing': ['error', 'either'], 'standard/array-bracket-even-spacing': ['error', 'either'], }, } // .stylelintrc { "rules": { "color-no-invalid-hex": true, "indentation": [ "tab", { "except": [ "value" ] } ], "max-empty-lines": 2, } } Nine Semantic Headings No, I’m not saying you should use 9 levels of headings, but your webpage should have an appropriate number of semantic headings. When your users are accessing your webpage with a screen reader, they rely on landmarks like headings to tell them about the page. Similarly to how we would scan a page visually, screen readers give users a list of all headings on a page to allow them to scan through the sections and access the information faster. When there aren’t any headings on a page (or headings are being used for their formatting rather than their semantic meaning), it makes it more difficult for anyone using a screen reader to understand and navigate the page. Make sure that you don’t skip heading levels on your page, and remember, you can always change the formatting on a p tag if you need to have something that looks like a heading but isn’t one. <h1>Heading 1 - Page Title</h2> <p>Traditionally you'll only see one h1 per page as it's the main page title</p> <h2>Heading 2</h2> <p>h2 helps to define other sections within the page. h2 must follow h1, but you can also have h2 following another h2.</p> <h3>Heading 3</h3> <p>h3 is a sub-section of h2 and follows similar rules to h2. You can have a h3 after h3, but you can't go from h1 to h3.</p> <h4>Heading 4</h4> <p>h4 is a sub-section of h3. You get the pattern?</p> Eight Types of Colour Blindness Testing colour contrast may not always be enough, as everyone perceives colour differently. Take the below colour combination (ignoring the fact that it doesn’t actually look nice). It has decent colour contrast and would meet the WCAG colour contrast requirements for AA standards – but what if one of your users was red-green colour blind? Would they be able to tell the difference? http://colorsafe.co/ empowers designers with beautiful and accessible colour palettes based on WCAG Guidelines of text and background contrast ratios. Red-green colour blindness is the most common form of colour blindness, but there are 8 different types affecting different parts of the colour spectrum, all the way up to complete colour blindness. Protanopia Inability to see red end of the colour spectrum. Protanomaly Difficulty seeing some shades of red. Deuteranopia Inability to see the green portion of the colour spectrum. Deuteranomaly Difficulty seeing some shades of green. Tritanopia Inability to see blue end of the colour spectrum. Tritanomaly Difficulty seeing some shades of blue. Achromatopsia Inability to see all parts of the colour spectrum, only able to perceive black, white and shades of grey. Achromatomaly Difficulty seeing all parts of the colour spectrum. Seven (.0) Contrast Ratio Sufficient colour contrast is perhaps one of the best steps to take for accessibility, as it benefits everyone. Having adequate contrast doesn’t just make the experience better for those with vision impairments, but it also helps those with situational impairments. Have you ever been in the sun and tried to read something on your screen? Whether you can view something when there’s glare could be as easy as making sure there’s enough contrast between the text and its background colour. The WCAG have defined a contrast ratio of at least 4.5:1 for normal text (18.5px) and 3:1 for large text (24px) to meet AA accessibility standards, but this should be an absolute minimum and isn’t always readable. All four below examples have sufficient contrast to pass AA standards, but you might be hard pressed to read them when there’s glare or you have a dodgy monitor (even more so considering most websites use below 18.5px for their base font size). Examples of 4.5:1 colour contrast To meet the AAA standard you need to have a ratio of 7:1 for normal text and 4.5:1 for large text, which should be sufficient for those with 20/80 vision to read. Six Front End Tests Adding default axe-core testing to Gatsby: //gatsby-config.js { resolve: 'gatsby-plugin-react-axe', options: {}, }, Running pa11y tests on homepage at various screen sizes: // tests/basic-a11y_home.js const pa11y = require('pa11y'), fs = require('file-system') runTest() async function runTest() { try { const results = await Promise.all([ pa11y('http://localhost:8000', { standard: 'WCAG2AA', actions: [], screenCapture: `${__dirname}/results/basic-a11y_home_mobile.png`, viewport: { width: 320, height: 480, deviceScaleFactor: 2, isMobile: true, }, }), pa11y('http://localhost:8000', { standard: 'WCAG2AA', actions: [], screenCapture: `${__dirname}/results/basic-a11y_home_desktop.png`, viewport: { width: 1280, height: 1024, deviceScaleFactor: 1, isMobile: false, }, }), ]) fs.writeFile('tests/results/basic-a11y_home.json', JSON.stringify(results), err => { console.log(err) }) } catch (err) { console.error(err.message) } } Running pa11y tests on a blog post template at various screen sizes: // tests/basic-a11y_post.js const pa11y = require('pa11y'), fs = require('file-system') runTest() async function runTest() { try { const results = await Promise.all([ pa11y('http://localhost:8000/template', { standard: 'WCAG2AA', actions: [], screenCapture: `${__dirname}/results/basic-a11y_post_mobile.png`, viewport: { width: 320, height: 480, deviceScaleFactor: 2, isMobile: true, }, }), pa11y('http://localhost:8000/template', { standard: 'WCAG2AA', actions: [], screenCapture: `${__dirname}/results/basic-a11y_post_desktop.png`, viewport: { width: 1280, height: 1024, deviceScaleFactor: 1, isMobile: false, }, }), ]) fs.writeFile('tests/results/basic-a11y_post.json', JSON.stringify(results), err => { console.log(err) }) } catch (err) { console.error(err.message) } } Running BackstopJS on a homepage and blog post template at various screen sizes: // backstop.json { "id": "backstop_default", "viewports": [ { "label": "phone", "width": 320, "height": 480 }, { "label": "tablet", "width": 1024, "height": 768 }, { "label": "desktop", "width": 1280, "height": 1024 } ], "onBeforeScript": "puppet/onBefore.js", "onReadyScript": "puppet/onReady.js", "scenarios": [ { "label": "Blog Homepage", "url": "http://localhost:8000", "delay": 2000, "postInteractionWait": 0, "expect": 0, "misMatchThreshold": 1, "requireSameDimensions": true }, { "label": "Blog Post", "url": "http://localhost:8000/template", "delay": 2000, "postInteractionWait": 0, "expect": 0, "misMatchThreshold": 1, "requireSameDimensions": true } ], "paths": { "bitmaps_reference": "backstop_data/bitmaps_reference", "bitmaps_test": "backstop_data/bitmaps_test", "engine_scripts": "backstop_data/engine_scripts", "html_report": "backstop_data/html_report", "ci_report": "backstop_data/ci_report" }, "report": [ "browser" ], "engine": "puppeteer", "engineOptions": { "args": [ "--no-sandbox" ] }, "asyncCaptureLimit": 5, "asyncCompareLimit": 50, "debug": false, "debugWindow": false } Running Cypress tests on the homepage: // cypress/integration/basic-test_home.js describe('Blog Homepage', () => { beforeEach(() => { cy.visit('http://localhost:8000') }) it('contains "Amy Goes to Perth" in the title', () => { cy.title().should('contain', 'Amy Goes to Perth') }) it('contains posts in feed', () => { cy.get('.article-feed').find('article') }) it('all posts contain title', () => { cy.get('.article-feed') .find('article') .get('h2') }) }) Running Cypress tests on a blog post template at various screen sizes: // cypress/integration/basic-test_post.js describe('Blog Post Template', () => { beforeEach(() => { cy.visit('http://localhost:8000/template') }) it('contains "Amy Goes to Perth" in the title', () => { cy.title().should('contain', 'Amy Goes to Perth') }) it('has visible post title', () => { cy.get('h1').should('be.visible') }) it('has share icons', () => { cy.get('.share-icons a').should('be.visible') }) it('has working share icons', () => { cy.get('.share-icons a').click({ multiple: true }) }) it('has a visible author profile image', () => { cy.get('.author img').should('be.visible') }) }) describe('Mobile Blog Post Template', () => { beforeEach(() => { cy.viewport('samsung-s10') cy.visit('http://localhost:8000/template') }) it('contains "Amy Goes to Perth" in the title', () => { cy.title().should('contain', 'Amy Goes to Perth') }) it('has visible post title', () => { cy.get('h1').should('be.visible') }) it('has share icons', () => { cy.get('.share-icons .share-link').should('be.visible') }) it('has a visible author profile image', () => { cy.get('.author img').should('be.visible') }) }) Five Browser Types Browser testing may be the bane of our existence, but it’s gotten easier, especially when you know the secret: Not every browser needs to look the same. Now, this may differ depending on your circumstances, but your website doesn’t have to match pixel for pixel across all browsers. As long as it’s on-brand and is useable across all browsers (this is where a good solid HTML foundation is useful), it’s ok for your site to look a little different between browsers. While the browsers you test in will differ depending on your user base, the main ones you want to be covering are: Chrome/Chromium Firefox Safari Internet Explorer Edge Make sure you’re testing these browsers on both desktop and mobile/tablet as well, sometimes their level of support or rendering engine will differ between devices – for example, iOS Chrome uses the Safari rendering engine, so something that works on Android Chrome may not work on iOS Chrome. Four Types of Test When it comes to testing the front end, there are a few different areas that we can cover: Accessibility Testing: doing accessibility testing properly usually involves getting an expert to run through your website, but there are several automated tests that you can run against various standard levels. Performance Testing: performance testing does technically bleed into the back end as well, but there are plenty of things that can be done from a front end perspective. Making sure the images are optimised, our code is clean and minified, and even optimising fonts using features like the font-display property. No amount of optimising the server and back end will matter if it takes forever for the front end to appear in a browser. Visual Regression Testing: we’ve all been in the position where changing one line of CSS somewhere has affected another section of the website. Visual regression testing helps prevent that. By using a tool that compares before and after screenshots against one another to flag up what’s changed, you can be sure that style changes won’t bleed into unintended areas of the site. Browser/device testing: while we all want our users to be running the most recent version of Chrome or Firefox, they may still be using the inbuilt browser on their DVD player – so we need to test various browsers, platforms and devices to make sure that our website can be accessed on whatever device they use. Three Shaken Trees Including (and therefore requiring your users to download) things that you’re not using affects the performance of your application. Are you forcing them to download the entire lodash library when you’re only using 2 functions? While a couple of unused lines of code may not seem like a huge performance hit, it can greatly affect users with slower devices or internet connections, as well as cluttering up your code with unused functions and dependencies. This can be set up on your bundler – Webpack and Parcel both have guides for tree shaking, and Gatsby has a plugin to enable it. Two Image Types While there are several different types of images, most of the time they fall into one of two categories: Informative The image represents/conveys important information that isn’t conveyed by the content surrounding it. Decorative The image only adds visual decoration to a page. From these two categories, we can then determine if we need to provide alternative text for an image. If an image is purely decorative, then we add alt="" to let screen readers know that it’s not important. But if an image is informative, then we need to be supplying a text alternative that describes the picture for anyone who’s using a screen reader or isn’t able to see the image (remember the days when a standard internet connection took a long time to load a page and you saw alt text before an image loaded). <img src="./nice-picture.jpg" alt="" /> <img src="./important-graphic.png" alt="This is a picture of something important to help add meaning to the text around me" /> If you have a lot of images with missing alt text, look into services that can auto-generate alt text based on image recognition services. One Source Controlled Deployment Pipeline While front end tests are harder to automate, running them through a source control and deployment pipeline helps track changes and eliminates issues where “it works on my computer”. Whether you’re running tests as part of the PR process, or simply against every commit that comes through, running tests automatically as part of your process makes every developer’s life easier and helps keep code quality at a high standard. We already knew that testing was important, and your project can’t be run unless all your unit and integration tests are written (and pass), but often we forget about testing the front end. There are so many different tests we need to be running on the front end, it’s hard to work out what your need to test for and where to start. Hopefully this has given you a bit of insight to front end testing, and some Christmas cheer to take you into the holidays. About the author Amy wears many hats as a freelance developer, business owner and conference addict. She regularly shares her knowledge with her peers and the next generation of developers by mentoring, coaching, teaching and feeding into the tech community in many ways. Amy can be found volunteering her time with Fenders, ACS, SheCodes (formerly Perth Web Girls) and MusesJS (formerly NodeGirls). She also works as an evangelist for YOW! Conferences, is a Twilio Champion and has been nominated for the WiTWA awards for the last 2 years. In her spare time Amy shares her knowledge and experience on her blogs and speaking at conferences. She has previously given keynotes at multiple events as well as speaking at several international conferences in the US and Europe. More articles by Amy Full Article Code testing
w Future Accessibility Guidelines—for People Who Can’t Wait to Read Them By feedproxy.google.com Published On :: Tue, 03 Dec 2019 12:00:00 +0000 Alan Dalton uses this, the International Day of Persons with Disabilities, to look back at where we’ve come from, to evaluate where we are, and to look forward to what’s coming next in the future of accessibility guidelines. Happy United Nations International Day of Persons with Disabilities! The United Nations have chosen “Promoting the participation of persons with disabilities and their leadership: taking action on the 2030 Development Agenda” for this year’s observance. Let’s see how the World Wide Web Consortium (W3C)’s Web Accessibility Initiative (WAI) guidelines of accessibility past, present, and yet-to-come can help us to follow that goal, and make sure that the websites—and everything else!—that we create can include as many potential users as possible. Guidelines of Accessibility Past The W3C published the Web Content Accessibility Guidelines (WCAG) 1.0 on 5th May 1999, when most of us were playing Snake on our Nokia 3210s’ 1.5” monochrome screens…a very long time ago in technology terms. From the start, those guidelines proved enlightening for designers and developers who wanted to avoid excluding users from their websites. For example, we learned how to provide alternatives to audio and images, how to structure information, and how to help users to find the information they needed. However, those guidelines were specific to the web technologies of the time, resulting in limitations such as requiring developers to “use W3C technologies when they are available […]”. Also, those guidelines became outdated; I doubt that you, gentle reader, consult their technical documentation about “directly accessible applets” or “Writing for browsers that do not support FRAME” in your day-to-day work. Guidelines of Accessibility Present The W3C published the Web Content Accessibility Guidelines (WCAG) 2.0 on 11th December 2008, when most of us were admiring the iPhone 3G’s innovative “iPhone OS 2.0” software…a long time ago in technology terms. Unlike WCAG 1, these guidelines also applied to non-W3C technologies, such as PDF and Flash. These guidelines used legalese and future-proofed language, with terms such as “time-based media” and “programmatically determined”, and testable success criteria. This made these guidelines more difficult for designers and developers to grasp, but also enabled the guidelines to make their way into international standards (see EN 301 549 — Accessibility requirements suitable for public procurement of ICT products and services in Europe and ISO/IEC 40500:2012 Information technology — W3C Web Content Accessibility Guidelines (WCAG) 2.0) and even international law (see EU Directive 2016/2102 … on the accessibility of the websites and mobile applications of public sector bodies). More importantly, these guidelines enabled designers and developers to create inclusive websites, at scale. For example, in the past 18 months: Intercom made their web Messenger accessible, achieving Level-AA conformance; Vimeo made accessibility updates to their video player to achieve Level-AA conformance; Stripe designed a new accessible colour system to conform with success criterion 1.4.3 (“Contrast (Minimum)”). The updated Web Content Accessibility Guidelines (WCAG) 2.1 arrived on 5th June last year—almost a 10-year wait for a “.1” update!—and added 17 new success criteria to help bring the guidelines up to date. Those new criteria focused on people using mobile devices and touchscreens, people with low vision, and people with cognitive and learning disabilities. (If you need to get up to speed with these guidelines, take 36 minutes to read “Web Content Accessibility Guidelines—for People Who Haven’t Read Them” and Web Content Accessibility Guidelines 2.1—for People Who Haven’t Read the Update.) Guidelines of Accessibility Yet to Come So, what’s next? Well, the W3C hope to release another minor update (WCAG 2.2) in November 2020. However, they also have a Task Force working on produce major new guidelines with wider scope (more people, more technologies) and fewer limitations (easier to understand, easier to use) in November 2022. These next guidelines will have a different name, because they will cover more than “Web” and “Content”. Andrew Kirkpatrick (Adobe’s Head of Accessibility) named the Task Force “Silver” (because the initials of “Accessibility Guidelines” form the symbol of the silver element). The Silver Task Force want the next major accessibility guidelines to: take account of more disabilities; apply to more technologies than just the web, including virtual reality, augmented reality, voice assistants, and more; consider all the technologies that people use, including authoring tools, browsers, media players, assistive technologies (including screen readers and screen magnifiers), application software, and operating systems. That’s quite a challenge, and so the more people who can help, the better. The Silver Task Force wanted an alternative to W3C’s Working Groups, which are made up of employees of organisations who are members of the W3C, and invited experts. So, they created a Silver Community Group to allow everyone to contribute towards this crucial work. If you want to join right now, for free, just create a W3C account. Like all good designers, the Silver Task Force and Silver Community Group began by researching. They examined the problems that people have had when using, conforming to, and maintaining the existing accessibility guidelines, and then summarised that research. From there, the Silver Community Group drafted ambitious design principles and requirements. You can read about what the Silver Community Group are currently working on, and decide whether you would like to get involved now, or at a later stage. Emphasise expertise over empathy Remember that today’s theme is “Promoting the participation of persons with disabilities and their leadership: taking action on the 2030 Development Agenda”. (The United Nations’ 2030 Development Agenda is outside the scope of this article, but if you’re looking to be inspired, read Alessia Aquaro’s article on Public Digital’s blog about how digital government can contribute to the UN’s Sustainable Development Goals.) In line with this theme, if you don’t have a disability and you want to contribute to the Silver Community Group, resist the temptation to try to empathise with people with disabilities. Instead, take 21 minutes during this festive season to enjoy the brilliant Liz Jackson explaining how empathy reifies disability stigmas, and follow her advice. Choose the right route I think we can expect the next Accessibility Guidelines to make their way into international standards and international law, just like their predecessors. We can also expect successful companies to apply them at scale. If you contribute to developing those guidelines, you can help to make sure that as many people as possible will be able to access digital information and services, in an era when that access will be crucial to every aspect of people’s lives. As Cennydd Bowles explained in “Building Better Worlds”, “There is no such thing as the future. There are instead a near-infinity of potential futures. The road as-yet-untravelled stretches before us in abundant directions. We get to choose the route. There is no fate but what we make.” About the author Alan Dalton worked for Ireland’s National Disability Authority for 9½ years, mostly as Accessibility Development Advisor. That involved working closely with public sector bodies to make websites, services, and information more accessible to all users, including users with disabilities. Before that, he was a consultant and trainer for Software Paths Ltd. in Dublin. In his spare time, he maintains StrongPasswordGenerator.com to help people stay safe online, tweets, and takes photos. More articles by Alan Full Article Code accessibility
w Interactivity and Animation with Variable Fonts By feedproxy.google.com Published On :: Thu, 05 Dec 2019 12:00:00 +0000 Mandy Michael turns the corner on our variable font adventure and stumbles into a grotto of wonder and amazement. Not forgetting the need for a proper performance budget, Mandy shows how variable fonts can free your creativity from bygone technical constraints. If you read Jason’s introductory article about variable fonts, you’ll understand the many benefits and opportunities that they offer in modern web development. From this point on we’ll assume that you have either read Jason’s introduction or have some prior knowledge of variable fonts so we can skip over the getting started information. If you haven’t read up on variable fonts before jump over to “Introduction to Variable Fonts: Everything you thought you knew about fonts just changed” first and then come join me back here so we can dive into using variable fonts for interactivity and animations! Creative Opportunities If we can use variable fonts to improve the performance of our websites while increasing the amount of style variations available to us, it means that we no longer need to trade off design for performance. Creativity can be the driving force behind our decisions, rather than performance and technical limitations. Cookie text effect font: This Man is a Monster, by Comic Book Fonts. My goal is to demonstrate how to create interactive, creative text on the web by combining variable fonts with CSS and JavaScript techniques that you may already be familiar with. With the introduction of variable fonts, designs which would have previously been a heavy burden on performance, or simply impossible due to technical limitations, are now completely possible. Still I Rise Poem by Maya Angelou, Demo emphasising different words with variable fonts. View on Codepen. Variable fonts demo with CSS Grid using multiple weights and font sizes to emphasise different parts of the message. View on Codepen. The tone and intent of our words can be more effectively represented with less worry over the impacts of loading in “too many font weights” (or other styles). This means that we can start a new path and focus on representing the content in more meaningful ways. For example, emphasising different words, or phrases depending on their importance in the story or content. Candy Cane Christmas Themed Text Effect with FS Pimlico Glow by Font Smith. View on Codepen. Note: using variable fonts does not negate the need for a good web font performance strategy! This is still important, because after all, they are still fonts. Keep that in mind and check out some of the great work done by Monica Dinculescu, Zach Leatherman or this incredible article by Helen Homes. Variable Fonts & Animations Because variable fonts can have an interpolated range of values we can leverage the flexibility and interactive nature of the web. Rather than using SVG, videos or JavaScript to accomplish these effects, we can create animations or transitions using real text, and we can do this using techniques we may already be familiar with. This means we can have editable, selectable, searchable, copy-pastable text, which is accessible via a screenreader. Grass Variable Font Demo Growing Grass Variable Font Text. Demo on Codepen. This effect is achieved using a font called Decovar, by David Berlow. To achieve the animation effect we only need a couple of things to get started. First, we set up the font-family and make use of the new property font-variation-settings to access the different axes available in Decovar. h1 { font-family: "Decovar"; font-variation-settings: 'INLN' 1000, 'SWRM' 1000; } For this effect, we use two custom axis – the first is called “inline” and is represented by the code INLI and the second is “skeleton worm” represented by the code SWRM. For both axes, the maximum value is 1000 and the minimum value is 0. For this effect, we’ll make the most of the full axis range. Once we have the base set up, we can create the animation. There are a number of ways to animate variable fonts. In this demo, we’ll use CSS keyframe animations and the font-variation-settings property, but you can also use CSS transitions and JavaScript as well. The code below will start with the “leaves” expanded and then shrink back until it disappears. @keyframes grow { 0% { font-variation-settings: 'INLN' 1000, 'SWRM' 1000; } 100% { font-variation-settings: 'INLN' 1000, 'SWRM' 0; } } Once we have created the keyframes we can add the animation to the h1 element, and that is the last piece needed in order to create the animation. h1 { font-family: "Decovar"; font-variation-settings: 'INLN' 1000, 'SWRM' 1000; animation: grow 4s linear alternate infinite; } What this demonstrates is that typically, to accomplish effects like this, the heavy lifting is done by the font. We really only need a few lines of CSS for the animation, which if you think about it, is pretty incredible. There are all sorts of interesting, creative applications of variable fonts, and a lot of incredible fonts you can make the most of. Whether you want to create that “hand-writing” effect that we often see represented with SVG, or something a little different, there are a lot of different options. Duos Writer: Hand Writing Demo of hand writing variable font, Duos Writer by Underware. Decovar: Disappearing Text See the Pen CSS-only variable font demo using Decovar Regular by Mandy Michael (@mandymichael) on CodePen. Cheee: Snow Text Snow Text Effect - Text fills up with snow and gets “heavier” at the bottom as more snow gathers. Featuring “Cheee” by OhNoTypeCo. View on Codepen. Variable Fonts, Media Queries and Customisation It’s not that these are just beautiful or cool effects, what they demonstrate is that as developers and designers we can now control the font itself and that that means is that variable fonts allow typography on the web to adapt to the flexible nature of our screens, environments and devices. We can even make use of different CSS media queries to provide more control over our designs based on environments, light contrast and colour schemes. Though the CSS Media Queries Level 5 Spec is still in draft stages, we can experiment with the prefers-color-scheme (also known as dark mode) media query right now! Dark Mode featuring Oozing Cheee by OhNoTypeCo Oozing Dark Mode Text featuring “Cheee” by OhNoTypeCo. View Demo on Codepen. The above example uses a font called “Cheee” by OhNoTypeCo and demonstrates how to make use of a CSS Transition and the prefers-color-scheme media query to transition the axis of a variable font. h1 { font-family: “Cheee" font-variation-settings: "TEMP" 0; transition: all 4s linear; } @media (prefers-color-scheme: dark) { h1 { font-variation-settings: "TEMP" 1000; } } Dark mode isn’t just about changing the colours, it’s important to consider things like weight as well. It’s the combination of the weight, colour and size of a font that determines how legible and accessible it is for the user. In the example above, I’m creating a fun effect – but more practically, dark mode allows us to modify the contrast and styles to ensure better legibility and usability in different environments. What is even more exciting about variable fonts in this context is that if developers and designers can have this finer control over our fonts to create more legible, accessible text, it also means the user has access to this as well. As a result, users that create their own stylesheets to customise the experience to their specific requirements, can now adjust the pages font weight, width or other available axis to what best suits them. Providing users with this kind of flexibility is such an incredible opportunity that we have never had before! As CSS develops, we’ll have access to different environmental and system features that allow us to take advantage of our users unique circumstances. We can start to design our typography to adjust to things like screen width - which might allow us to tweak the font weight, width, optical size or other axes to be more readable on smaller or larger screens. Where the viewport is wide we can have more detail, when its smaller in a more confined space we might look at reducing the width of the font—this helps to maintain the integrity of the design as the viewport gets smaller or, to fit text into a particular space. See the Pen CSS is Awesome - Variable fonts Edition. by Mandy Michael (@mandymichael) on CodePen. We have all been in the situation where we just need the text to be slightly narrower to fit within the available space. If you use a variable font with a width axis you can slightly modify the width to adjust to the space available, and do so in a way that the font was designed to do, rather than using things like letter spacing which doesn’t consider the kerning of the characters. Variable Fonts, JavaScript and Interactive Effects We can take these concepts even further and mix in a little JavaScript to make use of a whole suite of different interactions, events, sensors and apis. The best part about this is whether you are using device orientation, light sensors, viewport resizes, scroll events or mouse movement, the base JavaScript doesn’t really change. To demonstrate this, we’ll use a straightforward example – we’ll match our font weight to the size of our viewport – as the viewport gets smaller, the font weight gets heavier. Demo: As the viewport width changes, the weight of the text “Jello” becomes heavier. We’ll start off by setting our base values. We need to define the minimum and maximum axis values for the font weight, and the minimum and maximum event range, in this case the viewport size. Basically we’re defining the start and end points for both the font and the event. // Font weight axis range const minAxisValue = 200 const maxAxisValue = 900 // Viewport range const minEventValue = 320px const maxEventValue = 1440px Next we determine the current viewport width, which we can access with something like window.innerWidth. // Current viewport width const windowWidth = window.innerWidth Using the current viewport width value, we create the new scale for the viewport, so rather than the pixels values we convert it to a range of 0 - 0.99. const windowSize = (windowWidth - minEventValue) / (maxEventValue - minEventValue) // Outputs a value from 0 - 0.99 We then take that new viewport decimal value and use it to determine the font weight based on viewport scale. const fontWeight = windowSize * (minAxisValue - maxAxisValue) + maxAxisValue; // Outputs a value from 200 - 900 including decimal places This final value is what we use to update our CSS. You can do this however you want – lately I like to use CSS Custom Properties. This will pass the newly calculated font weight value into our CSS and update the weight as needed. // JavaScript p.style.setProperty("--weight", fontWeight); Finally, we can put all this inside a function and inside an event listener for window resize. You can modify this however you need to in order to improve performance, but in essence, this is all you need to achieve the desired outcome. function fluidAxisVariation() { // Current viewport width const windowWidth = window.innerWidth // Get new scales for viewport and font weight const viewportScale = (windowWidth - 320) / (1440 - 320); const fontWeightScale = viewportScale * (200 - 900) + 900; // Set in CSS using CSS Custom Property p.style.setProperty("--weight", fontWeightScale); } window.addEventListener("resize", fluidAxisVariation); You can apply this to single elements, or multiple. In this case, I’m changing the paragraph font weights and different rates, but also reducing the width axis of the headline so it doesn’t wrap onto multiple lines. As previously mentioned, this code can be used to create all sorts of really amazing, interesting effects. All that’s required is passing in different event and axis values. In the following example, I’m using mouse position events to change the direction and rotation of the stretchy slinky effect provided by the font “Whoa” by Scribble Tone. See the Pen Slinky Text - WHOA Variable font demo by Mandy Michael (@mandymichael) on CodePen. We can also take the dark mode/colour schemes idea further by making use of the Ambient Light Sensor to modify the font to be more legible and readable in low light environments. This effect uses Tiny by Jack Halten Fahnestock from Velvetyne Type Foundry and demonstrates how we modify our text based by query the characteristics of the user’s display or light-level, sound or other sensors. It’s only because Variable fonts give us more control over each of these elements that we can fine-tune the font characteristics to maximise the legibility, readability and overall accessibility of our website text. And while these examples might seem trivial, they are great demonstrations of the possibilities. This is a level of control over our fonts and text that is unprecedented. Using device orientation to change the scale and weight of individual characters. View on Codepen. Variable Fonts offer a new world of interactivity, usability and accessibility, but they are still a new technology. This means we have the opportunity to figure out how and what we can achieve with them. From where I stand, the possibilities are endless, so don’t be limited by what we can already do – the web is still young and there is so much for us to create. Variable fonts open up doors that never existed before and they give us an opportunity to think more creatively about how we can create better experiences for our users. At the very least, we can improve the performance of our websites, but at best, we can make more usable, more accessible, and more meaningful content - and that, is what gets me really excited about the future of web typography with variable fonts. About the author Mandy is a community organiser, speaker, and developer working as the Front End Development Manager at Seven West Media in Western Australia. She is a co-organiser and Director of Mixin Conf, and the founder and co-organiser of Fenders, a local meetup for front-end developers providing events, mentoring and support to the Perth web community. Mandy’s passion is CSS, HTML and JS and hopes to inspire that passion in others. She loves the supportive and collaborative nature of the web and strives to encourage this environment through the community groups she is a part of. Her aim is to create a community of web developers who can share, mentor, learn and grow together. More articles by Mandy Full Article Code Design typography
w Beautiful Scrolling Experiences – Without Libraries By feedproxy.google.com Published On :: Fri, 06 Dec 2019 12:00:00 +0000 Michelle Barker appears as one of a heavenly host, coming forth with scroll in hand to pronounce an end to janky scrolljacking! Unto us a new specification is born, in the city of TimBL, and its name shall be called Scroll Snap. Sponsor: Order any Standard paperback(s) and get a surprise gift card in the box for YOU. While supplies last, from your pals at A Book Apart! One area where the web has traditionally lagged behind native platforms is the perceived “slickness” of the app experience. In part, this perception comes from the way the UI responds to user interactions – including the act of scrolling through content. Faced with the limitations of the web platform, developers frequently reach for JavaScript libraries and frameworks to alter the experience of scrolling a web page – sometimes called “scroll-jacking” – not always a good thing if implemented without due consideration of the user experience. More libraries can also lead to page bloat, and drag down a site’s performance. But with the relatively new CSS Scroll Snap specification, we have the ability to control the scrolling behaviour of a web page (to a degree) using web standards – without resorting to heavy libraries. Let’s take a look at how. Scroll Snap A user can control the scroll position of a web page in a number of ways, such as using a mouse, touch gesture or arrow keys. In contrast to a linear scrolling experience, where the rate of scroll reflects the rate of the controller, the Scroll Snap specification enables a web page to snap to specific points as the user scrolls. For this, we need a fixed-height element to act as the scroll container, and the direct children of that element will determine the snap points. To demonstrate this, here is some example HTML, which consists of a <div> containing four <section> elements: <div class="scroll-container"> <section> <h2>Section 1</h2> </section> <section> <h2>Section 2</h2> </section> <section> <h2>Section 3</h2> </section> <section> <h2>Section 4</h2> </section> </div> Scroll snapping requires the presence of two main CSS properties: scroll-snap-type and scroll-snap-align. scroll-snap-type applies to the scroll container element, and takes two keyword values. It tells the browser: The direction to snap Whether snapping is mandatory scroll-snap-align is applied to the child elements – in this case our <section>s. We also need to set a fixed height on the scroll container, and set the relevant overflow property to scroll. .scroll-container { height: 100vh; overflow-y: scroll; scroll-snap-type: y mandatory; } section { height: 100vh; scroll-snap-align: center; } In the above example, I’m setting the direction in the scroll-snap-type property to y to specify vertical snapping. The second value specifies that snapping is mandatory. This means that when the user stops scrolling their scroll position will always snap to the nearest snap point. The alternative value is proximity, which determines that the user’s scroll position will be snapped only if they stop scrolling in the proximity of a snap point. (It’s down to the browser to determine what it considers to be the proximity threshold.) If you have content of indeterminate length, which might feasibly be larger than the height of the scroll container (in this case 100vh), then using a value of mandatory can cause some content to be hidden above or below the visible area, so is not recommended. But if you know that your content will always fit within the viewport, then mandatory can produce a more consistent user experience. See the Pen Simple scroll-snap example by Michelle Barker (@michellebarker) on CodePen. In this example I’m setting both the scroll container and each of the sections to a height of 100vh, which affects the scroll experience of the entire web page. But scroll snapping can also be implemented on smaller components too. Setting scroll snapping on the x-axis (or inline axis) can produce something like a carousel effect. In this demo, you can scroll horizontally scroll through the sections: See the Pen Carousel-style scroll-snap example by Michelle Barker (@michellebarker) on CodePen. The Intersection Observer API By implementing the CSS above, our web page already has a more native-like feel to it. To improve upon this further we could add some scroll-based transitions and animations. We’ll need to employ a bit of Javascript for this, using the Intersection Observer API. This allows us to create an observer that watches for elements intersecting with the viewport, triggering a callback function when this occurs. It is more efficient than libraries that rely on continuously listening for scroll events. We can create an observer that watches for each of our scroll sections coming in and out of view: const sections = [...document.querySelectorAll('section')] const options = { rootMargin: '0px', threshold: 0.25 } const callback = (entries) => { entries.forEach((entry) => { if (entry.intersectionRatio >= 0.25) { target.classList.add("is-visible"); } else { target.classList.remove("is-visible"); } }) } const observer = new IntersectionObserver(callback, options) sections.forEach((section, index) => { observer.observe(section) }) In this example, a callback function is triggered whenever one of our sections intersects the container by 25% (using the threshold option). The callback adds a class of is-visible to the section if it is at least 25% in view when the intersection occurs (which will take effect when the element is coming into view), and removes it otherwise (when the element is moving out of view). Then we can add some CSS to transition in the content for each of those sections: section .content { opacity: 0: } section.is-visible .content { opacity: 1; transition: opacity 1000ms: } This demo shows it in action: See the Pen Scrolling with Intersection Observer by Michelle Barker (@michellebarker) on CodePen. You could, of course, implement some much more fancy transition and animation effects in CSS or JS! As an aside, it’s worth pointing out that, in practice, we shouldn’t be setting opacity: 0 as the default without considering the experience if JavaScript fails to load. In this case, the user would see no content at all! There are different ways to handle this: We could add a .no-js class to the body (which we remove on load with JS), and set default styles on it, or we could set the initial style (before transition) with JS instead of CSS. Position: sticky There’s one more CSS property that I think has the potential to aid the scroll experience, and that’s the position property. Unlike position: fixed, which locks the position of an element relative to the nearest relative ancestor and doesn’t change, position: sticky is more like a temporary lock. An element with a position value of sticky will become fixed only until it reaches the threshold of its parent, at which point it resumes relative positioning. By “sticking” some elements within scroll sections we can give the impression of them being tied to the action of scrolling between sections. It’s pretty cool that we can instruct an element to respond to it’s position within a container with CSS alone! Browser support and fallbacks The scroll-snap-type and scroll-snap-align properties are fairly well-supported. The former requires a prefix for Edge and IE, and older versions of Safari do not support axis values. In newer versions of Safari it works quite well. Intersection Observer similarly has a good level of support, with the exception of IE. By wrapping our scroll-related code in a feature query we can provide a regular scrolling experience as a fallback for users of older browsers, where accessing the content is most important. Browsers that do not support scroll-snap-type with an axis value would simply scroll as normal. @supports (scroll-snap-type: y mandatory) { .scroll-container { height: 100vh; overflow-y: scroll; scroll-snap-type: y mandatory; } section { height: 100vh; scroll-snap-align: center; } } The above code would exclude MS Edge and IE, as they don’t support axis values. If you wanted to support them you could do so using a vendor prefix, and using @supports (scroll-snap-type: mandatory) instead. Putting it all together This demo combines all three of the effects discussed in this article. Summary Spending time on scroll-based styling might seem silly or frivolous to some. But I believe it’s an important part of positioning the web as a viable alternative to native applications, keeping it open and accessible. While these new CSS features don’t offer all of the control we might expect with a fully featured JS library, they have a major advantage: simplicity and reliability. By utilising web standards where possible, we can have the best of both worlds: Slick and eye-catching sites that satisfy clients’ expectations, with the added benefit of better performance for users. About the author Michelle is a Lead Front End Developer at Bristol web agency Atomic Smash, author of front-end blog CSS { In Real Life }, and a Mozilla Tech Speaker. She has written articles for CSS Tricks, Smashing Magazine, and Web Designer Magazine, to name a few. She enjoys experimenting with new CSS features and helping others learn about them. More articles by Michelle Full Article UX css
w It All Starts with a Humble <textarea> By feedproxy.google.com Published On :: Sun, 08 Dec 2019 12:00:00 +0000 Andy Bell rings out a fresh call in support of the timeless concept of progressive enhancement. What does it mean to build a modern JavaScript-focussed web experience that still works well if part of the stack isn’t supported or fails? Andy shows us how that might be done. Those that know me well know that I make a lot of side projects. I most definitely make too many, but there’s one really useful thing about making lots of side projects: it allows me to experiment in a low-risk setting. Side projects also allow me to accidentally create a context where I can demonstrate a really affective, long-running methodology for building on the web: progressive enhancement. That context is a little Progressive Web App that I’m tinkering with called Jotter. It’s incredibly simple, but under the hood, there’s a really solid experience built on top of a minimum viable experience which after reading this article, you’ll hopefully apply this methodology to your own work. What is a minimum viable experience? The key to progressive enhancement is distilling the user experience to its lowest possible technical solution and then building on it to improve the user experience. In the context of Jotter, that is a humble <textarea> element. That humble <textarea> is our minimum viable experience. Let me show you how it’s built up, progressively real quick. If you disable CSS and JavaScript, you get this: This result is great because I know that regardless of what happens, the user can do what they needed to do when the loaded Jotter in their browser: take some notes. That’s our minimum viable experience, completed with a few lines of code that work in every single browser—even very old browsers. Don’t you just love good ol’ HTML? Now it’s time to enhance that minimum viable experience, progressively. It’s a good idea to do that in smaller steps rather than just provide a 0% experience or a 100% experience, which is the approach that’s often favoured by JavaScript framework enthusiasts. I think that process is counter-intuitive to the web, though, so building up from a minimum viable experience is the optimal way to go, in my opinion. Understanding how a minimum viable experience works can be a bit tough, admittedly, so I like to use a the following diagram to explain the process: Let me break down this diagram for both folks who can and can’t see it. On the top row, there’s four stages of a broken-up car, starting with just a wheel, all the way up to a fully functioning car. The car enhances only in a way that it is still mostly useless until it gets to its final form when the person is finally happy. On the second row, instead of building a car, we start with a skateboard which immediately does the job of getting the person from point A to point B. This enhances to a Micro Scooter and then to a Push Bike. Its final form is a fancy looking Motor Scooter. I choose that instead of a car deliberately because generally, when you progressively enhance a project, it turns out to be way simpler and lighter than a project that was built without progressive enhancement in mind. Now that we know what a minimum viable experience is and how it works, let’s apply this methodology to Jotter! Add some CSS The first enhancement is CSS. Jotter has a very simple design, which is mostly a full height <textarea> with a little sidebar. A flexbox-based, auto-stacking layout, inspired by a layout called The Sidebar is used and we’re good to go. Based on the diagram from earlier, we can comfortably say we’re in Skateboard territory now. Add some JavaScript We’ve got styles now, so let’s enhance the experience again. A user can currently load up the site and take notes. If the CSS loads, it’ll be a more pleasant experience, but if they refresh their browser, they’re going to lose all of their work. We can fix that by adding some local storage into the mix. The functionality flow is pretty straightforward. As a user inputs content, the JavaScript listens to an input event and pushes the content of the <textarea> into localStorage. If we then set that localStorage data to populate the <textarea> on load, that user’s experience is suddenly enhanced because they can’t lose their work by accidentally refreshing. The JavaScript is incredibly light, too: const textArea = document.querySelector('textarea'); const storageKey = 'text'; const init = () => { textArea.value = localStorage.getItem(storageKey); textArea.addEventListener('input', () => { localStorage.setItem(storageKey, textArea.value); }); } init(); In around 13 lines of code (which you can see a working demo here), we’ve been able to enhance the user’s experience considerably, and if we think back to our diagram from earlier, we are very much in Micro Scooter territory now. Making it a PWA We’re in really good shape now, so let’s turn Jotter into a Motor Scooter and make this thing work offline as an installable Progressive Web App (PWA). Making a PWA is really achievable and Google have even produced a handy checklist to help you get going. You can also get guidance from a Lighthouse audit. For this little app, all we need is a manifest and a Service Worker to cache assets and serve them offline for us if needed. The Service Worker is actually pretty slim, so here it is in its entirety: const VERSION = '0.1.3'; const CACHE_KEYS = { MAIN: `main-${VERSION}` }; // URLS that we want to be cached when the worker is installed const PRE_CACHE_URLS = ['/', '/css/global.css', '/js/app.js', '/js/components/content.js']; /** * Takes an array of strings and puts them in a named cache store * * @param {String} cacheName * @param {Array} items=[] */ const addItemsToCache = function(cacheName, items = []) { caches.open(cacheName).then(cache => cache.addAll(items)); }; self.addEventListener('install', evt => { self.skipWaiting(); addItemsToCache(CACHE_KEYS.MAIN, PRE_CACHE_URLS); }); self.addEventListener('activate', evt => { // Look for any old caches that don't match our set and clear them out evt.waitUntil( caches .keys() .then(cacheNames => { return cacheNames.filter(item => !Object.values(CACHE_KEYS).includes(item)); }) .then(itemsToDelete => { return Promise.all( itemsToDelete.map(item => { return caches.delete(item); }) ); }) .then(() => self.clients.claim()) ); }); self.addEventListener('fetch', evt => { evt.respondWith( caches.match(evt.request).then(cachedResponse => { // Item found in cache so return if (cachedResponse) { return cachedResponse; } // Nothing found so load up the request from the network return caches.open(CACHE_KEYS.MAIN).then(cache => { return fetch(evt.request) .then(response => { // Put the new response in cache and return it return cache.put(evt.request, response.clone()).then(() => { return response; }); }) .catch(ex => { return; }); }); }) ); }); What the Service Worker does here is pre-cache our core assets that we define in PRE_CACHE_URLS. Then, for each fetch event which is called per request, it’ll try to fulfil the request from cache first. If it can’t do that, it’ll load the remote request for us. With this setup, we achieve two things: We get offline support because we stick our critical assets in cache immediately so they will be accessible offline Once those critical assets and any other requested assets are cached, the app will run faster by default Importantly now, because we have a manifest, some shortcut icons and a Service Worker that gives us offline support, we have a fully installable PWA! Wrapping up I hope with this simplified example you can see how approaching web design and development with a progressive enhancement approach, everyone gets an acceptable experience instead of those who are lucky enough to get every aspect of the page at the right time. Jotter is very much live and in the process of being enhanced further, which you can see on its little in-app roadmap, so go ahead and play around with it. Before you know it, it’ll be a car itself, but remember: it’ll always start as a humble little <textarea>. About the author Andy Bell is an independent designer and front-end developer who’s trying to make everyone’s experience on the web better with a focus on progressive enhancement and accessibility. More articles by Andy Full Article UX craft
w Gift Giving to the World (Wide Web) By feedproxy.google.com Published On :: Wed, 11 Dec 2019 12:00:00 +0000 Frances Berriman asks us to give the gift of consideration to those who are using the web on constricted devices such as low-end smart phones or feature phones. Christmas is a time of good will to all, and as Bugsy Malone reminds us, you give a little love and it all comes back to you. If I was given the job of Father Christmas with all my human limitations, apparently it would take me something like 6 months at non-stop full speed to deliver gifts to every kid on the planet. The real Father Christmas has the luxury of magic when it comes to delivering millions of gifts in just one night, but the only magical platform at my disposal is the world wide web, so I propose switching to digital gift cards and saving the reindeer feed. 300 million people are set to come online for the very first time in 2020, and a majority of those will be doing so via mobile phones (smart- and feature-phones). If we want those new users to have a great time online, spending those gift cards, we need to start thinking about their needs and limitations. Suit up We might not be hopping on the sleigh for these deliveries, but let’s suit up for the journey and get the tools we need to start testing and checking how our online gift-receivers will be enjoying their online shopping experience. Of course, the variety of phones and OSs out there is huge and varied, but we have a few options out there to get a sense for the median. Here’s a few suggestions on where to start: Never has there been a better time to advocate at your workplace for a device testing suite or lab. You can also just pick up a low-end phone for a few bucks and spend some real time using it and getting a sense for how it feels to live with it every day. May I suggest the Nokia 2 or the Moto E6 - both very representative devices of the sort our new visitors will be on. You’ve also got WebPageTest.org at your disposal, where you can emulate various phones and see your sites rendered in real-time to get a sense of what an experience may look like for your users. You’ll also want to set yourself some goals. A performance budget, for example, is a good way to know if the code you’re shipping hits the mark in a more programmatic way. Gift wrap Many of us began our internet lives on desktop machines, and thanks to Moore’s law, these machines have been getting ever more powerful every year with more CPUs and memory at our disposal. The mobile phone landscape somewhat resets us on what hardware capacity is available on the client-side of our code, so it’s time to lighten the load. What we see in the landscape of phones today is a huge spread of capabilities and CPU speeds, storage capacity and memory. And the gap between the haves and the have-nots is widening, so we have a huge task to deal with in meeting the needs of such a varied audience. As far as possible, we should try to: Keep processing off the client - do anything you can server-side. Consider a server-side render (hold the <script>, thanks) for anything relatively static (including cached frequent queries and results) to keep client-side JavaScript to the minimum. This way you’re spending your CPU, not the user’s. Avoid sending everything you have to to the end user. Mobile-first access also means data-plan-first access for many, which means they may be literally paying in cold-hard cash for everything you send over the wire – or may be experiencing your site over a degraded “4G” connection towards the end of the month. Aggressively cache assets to prevent re-downloading anything you’ve sent before. Don’t make the user pay twice if they don’t have to. Progressively load additional assets and information as the user requests them, rather than a big upfront payload, that way you’re giving the end user a little more choice about whether they want or need that extra data set. This is all to say that as web developers, we have a lot more control over how and when we deliver the meat of our products - unlike native apps that generally send the whole experience down as one multi-megabyte download that our 4G and data-strapped users can’t afford. Make a wish Finally, it’s time for your gift recipients to go out onto the web and find whatever their greatest wish is. For many, that’s going to begin when they first turn on their phone and see all those enticing icons on their home screen. Opening a browser may not be their first port of call. They’ll be primed to look for sites and information through the icon-heavy menu that most mobile OSs use today, and they will be encouraged to find new experiences through the provided app store interface. The good news is that web experience can be found in many modern app-stores today. For example, if you build an app using Trusted Web Activities, the Google Play Store will list your web site right alongside native apps and allow users to install them on their phones. Samsung and Microsoft have similar options without the extra step of creating a TWA - they’ll list any Progressive Web App in their stores. Tools like Microsoft’s PWA Builder and Llama Pack are making this easier than ever. If your users are primed to search for new experiences via a search engine instead, then they’ll benefit from the work you’ve put in to list them in app stores regardless, as PWAs are first and foremost about making websites mobile-friendly, regardless of point of sale. A PWA will provide them with offline support, service works, notifications and much more. We do have a grinch in this story, however. Apple’s iOS explicitly does not allow your website to be listed in their app store, so sadly you’ll have a harder time reaching those users. But it is possible! Fortunately, iOS isn’t as all-dominating world wide as it is in the tech community, selling only around 10-15% of smartphones out in the world. The best present The WWW is a wonderful gift that we received over 30 years ago and, as web developers, we get to steward and share this truly global, open, platform with millions of people every day. Let’s take care of it by building and sharing experiences that truly meet the needs of everyone. About the author Frances Berriman is a San Francisco-based British-born designer and web developer who blogs at fberriman.com. She’s done all sorts of things, but has a special soft spot for public sector projects, and has worked for the Government Digital Service, building GOV.UK, Code for America, Nature Publishing and the BBC and is currently Head of UX and Product Design at Netlify. More articles by Frances Full Article Process mobile
w Making Distributed Working Work By feedproxy.google.com Published On :: Thu, 12 Dec 2019 12:00:00 +0000 Anna Debenham harnesses up the huskies and puts them to work to figure out how teams distributed across multiple locations can work effectively to all pull in the same direction. With modern workforces distributed from north pole to south, can they all be kept running in step? Four years ago, I started working at a small startup called Snyk that’s based in two locations – London and Tel Aviv. The founders made it clear they wanted to grow headcount in both locations at the same rate, and for the design and engineering skillsets between the two offices to be evenly spread. We’re now at over 200 people and we’re still staying true to that vision, but only by completely changing how we were used to working. The trend for fully distributed teams is on the rise – companies like InVision and GitLab have entirely remote employees. Snyk is somewhere in between, with small hubs of global team members in homes and shared offices globally alongside our main London, Tel Aviv, Boston, Ottawa and Bay Area offices. Our R&D teams are based entirely in London or Tel Aviv, with a few employees working around Europe. Rather than have Team A working in one office and Team B working in another, we’ve deliberately designed it so that no R&D team at Snyk has all its members in one location. We could design our teams to be all co-located so that everyone’s in the same room, but we don’t. When I explain this setup to people, I’ll often get a response of bewilderment – why do it this way? It sounds like a pain! Increasingly though, the reaction is positive – usually from people who’ve worked in a distributed team before where departments are split neatly between locations. They’ve experienced an “us vs them” culture, with work being thrown over the fence to designers or engineers in different timezones. They’ve been at the mercy of the decision makers who are all in the head office. This is exactly what we wanted to avoid. We wanted the company to feel like one team, across many locations. It’s not perfect – I do miss the things that working in the same location brings such as collaborating on a whiteboard, or having planning documents stuck on the wall for the team to refer to. Pre-distributed working, I used to sit next to a designer and we’d bounce ideas off each other. Now I have to make the extra effort to schedule something in. Managing people remotely is also tough – I can’t easily see that a team member is having a bad day and make them a cup of tea. But on the whole, it works pretty well for us. The time difference between London and Tel Aviv is a comfy 2 hours, and in Tel Aviv, the week runs from Sunday to Thursday, meaning there’s just a single day in the week when all our teams aren’t working. This makes the week feel like the ebb and flow of a tide – my Mondays are very busy, but on Fridays, half the team is off so there are barely any meetings – ideal for deep focus time. So how do we make this distributed-but-also-co-located hybrid thing work? Level the playing field Firstly, that “us vs them” mentality I mentioned is the key thing to avoid to maintain a positive distributed work culture. Avoid the term “remote team”, as that has a sense of otherness. Instead, refer to your team as “distributed”. It’s such a small change that has the effect of bringing everyone onto the same level. Also, consider your video conferencing etiquette – if you’ve got a large part of your team in one location, with just one or two members who are dialling in, you could end up with a very one-sided conversation. The room with the most people in it has a habit of forgetting the person they can’t easily see. Even if you’re in the same room, dial in individually so that everyones faces are the same size, and you’re addressing all the participants rather than just those in the same room as you. Invest in tools that help communication Early on, we invested in tools that would help make communication between locations as seamless as possible. I’m not talking about those screens with wheels that follow co-workers around a room to recreate a manager breathing down their neck (although now I think of it…). I’m talking about the familiar ones like Slack, Zoom and Notion. Use a single tool where possible to reduce friction between teams so there’s no confusion as to whether you’re having a call over Google Hangouts, Zoom, Skype or whatever else is fashionable to use this year. Same with meeting notes – keep them in one place rather than scattered across Dropbox, Email and Google Docs. Remote pair programming has also got a lot easier. We used ScreenHero before it got acquired and lost its remote control functionality – but there are some great alternatives out there like USE Together. You might also have collaboration tools built into your code editor, like Visual Studio’s Live Share, and Atom’s Teletype. If teams are complaining about bad audio, don’t skimp – invest in better microphones, speakers and sound-proofing. You won’t get the benefits of working as a distributed team if there’s a barrier between communication. Ensure the internet is stable in all locations. Also, it sounds basic but make sure teams have somewhere to take a call in the first place, particularly 1:1s which shouldn’t be done in the open. Previous places I’ve contracted at had people dialling into meetings in stairwells, shower rooms and even toilet cubicles. Take care not to make the experience of working in a distributed team end up harming the experience of working in an office. Open a window For as long as we’ve had offices, we’ve had a fixed camera and TV screen setup between them that acts as a “window” between locations. The camera is on all the time, and we turn the microphone on once a day for standup (or whenever someone wants to say hi). When I turn on the TV in the morning, I can see the Tel Aviv office already working. At midday, our Boston office comes online, followed shortly after by our Ottawa office. It’s incredible what a difference this has made to make us feel more like one office. We’ve positioned one of the cameras next to our dining area so we can eat together. Another camera is honed in on a dog bed in the corner of the office (sometimes there’s a dog in it!). Distributed meetings With the time differences and weekday shift, there’s a condensed timeframe in which we can collaborate. It’s not as bad as it could be (I pity my fellow Londoners who work for companies based in California), but the hours between 9am and 4pm Monday to Thursday for us are at a premium. This means the meetings we have need to be a good use of everyone’s time. When we can’t find a time that works for everyone, we record the meeting. But even if everyone can make it, we still take notes. The notebook brand Field Notes have a slogan “I’m not writing it down to remember it later, I’m writing it down to remember it now.”. This is a reminder that it’s not always the notes themselves that are useful, but the act of taking them. Where they’re really powerful is when you share them in real time. In Kevin Hoffman’s book ‘Meeting Design’, he recommends the notetaker shares their screen while taking notes so that everyone can participate in making sure those notes are accurate. Having the notes on the screen also helps focus the conversation – particularly if you have an agenda template to start with. It means you’ve got a source of truth for someone who mis-remembers a conversation, and you’ve got something to look back on in the next meeting so you don’t repeat yourselves. Another tip we’ve taken from Kevin’s book is to have a kanban board for standing meetings, where everyone can add a topic. That way, you always have a backlog of topics to discuss in the meeting. If there aren’t any, you can cancel the meeting! We use Notion’s kanban template for our sync meeting notes. Anyone can add a topic before (or during) the meeting and we go through each of them in order. We add notes and action points to the topic card. Don’t get into bad habits when you’re lucky enough to be sharing a single space – keep documenting conversations and decisions in the same way you would with a distributed team, so that future you can remember, and future team members can gather that context. Team bonding I always think the best way to bonding with people is over a meal – isn’t that what Christmas dinner is great for? As a distributed team, we can’t do that. We could try and recreate it (even just for the comedy value), but it’s really not the same. We have to try something different. Enter Eurovision. For those of you outside Europe, imagine a cheesy pop song contest where each country performs their own song and everyone votes for the winner. This year, it was held in Tel Aviv, so dozens of us sat down to watch the live stream. We set up a Eurovision Slack channel and shared our horror in real time. But Eurovision only happens ones a year, so we’ve extended shared experiences into multiple “hobby” Slack channels: we have one for food fans (#fun-foodies), football fans (#fun-footies), and even sourdough fans (#fun-sourdough). There’s also a weekly “drink and sync” where office-less team members join a video call and chat over a beer, coffee, or juice depending on the time of day for those that dial in. One team runs a movie club where they choose a video that’s relevant to their team’s work (such as a conference talk) and watch it together at the same time. Onboarding new team members can feel quite impersonal if their manager isn’t in the same office. Starting your first day in an office full of strangers, where the only interaction with your manager is over a video call can feel daunting. And as a manager, I get anxious about my new hire’s first day – was there someone there to greet them and show them where they sit? Was everything set up for them? Did they have someone to eat lunch with? So we’ve been rolling out an “onboarding buddy” scheme. This is someone local who can help the new hire settle in to their new surroundings. It’s someone to chat to, share a coffee with, and generally look out for them. We also use a Slack app called Donut which pairs employees up for informal chats to get to know each other. You get paired with someone random in the company and it helps you schedule a call with them. This is to encourage cross-pollination across teams and locations. What distributed teamwork has taught us There’s a lot that we’ve learnt about working well as a distributed team. We try and recreate the good things about sharing a physical space, and make them feel just as natural in the digital space, while also compensating for the lack of intimacy from being thousands of miles apart. Mel Choyce’s 24 ways article Surviving—and Thriving—as a Remote Worker stresses the value of remote working, and the long term benefits it has had. Working remotely has made me a better communicator largely because I’ve gotten into the habit of making written updates. I think in a lot of ways, the distance has brought us closer. We make more of an effort to check in on how each other is doing. We document as much as we can, which really helps new hires get up to speed quickly. By identifying what we find valuable about working in the same room, and translating that to work across locations, we find collaboration easier because we’re no longer strangers to each other. We might not be able to have those water-cooler moments in the physical realm, but we’ve done a good job of replicating that online. About the author Anna Debenham lives in London and is a Product Manager at Snyk. She’s the author of Front-end Style Guides, and when she’s not playing on them, she’s testing as many game console browsers as she can get her hands on. More articles by Anna Full Article Process productivity
w Art Direction and the New WordPress Editor By feedproxy.google.com Published On :: Fri, 13 Dec 2019 12:00:00 +0000 Mel Choyce explores how the new WordPress editor (also know as Gutenberg) can be used to create more carefully art directed posts. Like gifts carefully arranged beneath the Christmas tree, it’s the contents that matters but the presentation that sells. The New York Times release of Snowfall in 2012 took the web industry by storm. Media-rich and captivating, its design evoked wonder, fear, and desperation in the face of an avalanche. Snowfall was one of the first great art directed digital experiences in this era of the modern web (Space Jam, obviously, being one of the great experiences of the era prior). “Art direction combines art and design to evoke a cultural and emotional reaction. …Art direction is about evoking the right emotion, it’s about creating that connection to what you’re seeing and experiencing.” Art Direction and Design by Dan Mall Art direction isn’t a new concept. Pick up any magazine or print publication — designers have long been creating evocative media experiences. Then the web came and messed that up. Fonts and even colors were limited at first, especially if you wanted to create something using semantic HTML rather than Flash. Early HTML and CSS didn’t offer great ways to create dynamic layouts like you’d see in a magazine. Floats, am I right? A lot’s changed in the past decade. We have reliable ways to serve fonts, opening up vast typographic possibilities. CSS features like Flexbox and Grid allow for complex layouts. Plus, our hardware is getting better and better. We live in exciting times. Behind the curve But not everyone’s kept up. For most of its history, the WordPress editor was a text-first writing experience, shining with simple blogs but falling flat in the face of a complex website. Want some columns on your page? Well, there’s a plugin for that, it lets you write some pseudo-code WordPress called shortcodes, and yeah you just need to wrap your columns in this code in your editor… Or, uh, maybe you could hand-code a template for your theme that offers three columns of widget areas and put everything in there? Or maybe… You get the point. The new WordPress editor (codenamed “Gutenberg”) introduces the concept of blocks, like building blocks or bricks or LEGO. Rather than needing to hand-code anything, you have an interface for editing all sorts of content, even the aforementioned former nightmare of columns. Blocks can come with placeholders, so you can fill-in-the-blanks rather than having to build from scratch. The new WordPress block editor allows me to focus on the best way of presenting my content instead of focusing on how I’m going to technically enter the content. The block editor allows my designer brain to think more creatively. I can go about creating an appropriate emotional reaction for a site’s content, rather than focusing on implementation. Block it to me The building blocks of the new editor (text, media) are the same, but the new ways to combine and build upon those blocks makes for a better art direction experience. Your browser doesn’t support HTML5 video. Here is a link to the video instead. New to the WordPress editor is the Media and Text block, which combines — you guessed it — media and text into a new way to approach layouts. Your browser doesn’t support HTML5 video. Here is a link to the video instead. This is the foundation of the new WordPress editor. Take atomic pieces, and combine them to make whole sections and layouts. Best yet, no fumbling with floats if you want to put some text next to an image! Do you want to build a website? Let’s imagine I’m building a website for a non-profit that rescues black cats. They offer adoption services, run a fostering program, and take in abandoned, feral, or other cats in need. The primary goal of the site is to connect people to the rescue organization. Raising awareness and soliciting donations are secondary, but still important factors. Because so much of a person’s experience with WordPress is contingent on their particular setup — themes, plugins, and admin customizations — I’ve decided to keep this site pretty light. The Twenty Twenty Theme WordPress releases a new default theme pretty much every year. This year’s theme, Twenty Twenty, was built with Gutenberg in mind. It supports optional features like color schemes and wider block alignments. The design is clean and modern, and offers some additional customization options. I think it’s a good choice for this website. Columns While there’s no internal grid system in WordPress (yet!), the Columns block comes close to allowing complex layouts within a post or page. With it, you can start to break out of one column and think more like a print designer. The most straightforward layout we could do is a familiar pattern on the web — three feature columns consisting of a heading, some text, and a button. To accomplish this, I loaded up the editor and started planning. First, I added a group block to contain my columns, and provide a background color. (The columns block does not currently support background colors, but it might in the future.) I want my columns to stand out from the white background of the page, so I opt for a light grey. Within the group, I placed my Column block, which features a convenient placeholder to help me pick which layout I want: I opt for the three column option. From here, it’s easy to build out my section — headings, paragraphs, and buttons are all existing blocks I can plop right into my columns: It looks really good on the front-end of my site, too: This is all fairly straightforward, but by changing up a couple columns widths and some sizing, I can get something that looks more dynamic and draws attention to the adoption process, which is the most important feature: I could even add an image, change up my background color to match, and nest “Foster” and “Save” into another set of columns beneath “Adopt”: All of this from the same set of blocks, yet each variation strikes a different impact. …And, you know, feels a little less like this: which one of the two possible websites are you currently designing? pic.twitter.com/ZD0uRGTqqm— Jon Gold (@jongold) February 2, 2016 But if I wanted to start looking like that, uh, second example — I can! Media and Text The aforementioned Media and Text block is a great building block for some eye-catching, informational parts of my homepage. Galleries To break up all that text content and get my site looking less like it’s for a startup, how about adding even more cute cats in between? You can never have too many cat photos on the internet. CoBlocks is a fantastic plugin that adds new blocks to WordPress, among them the icon block I used above, as well as a couple of different gallery layouts. I think carousels are terrible when they’re used for showcasing features or content, but I think they’re a good gallery format, and having something horizontal means my cats aren’t taking up too much space (unlike my own black cat, who likes to hog all my leg room in bed). My favorite thing about this block is that, even though it’s fully-featured, it’s still 100x less of a chaotic mess than any other slider plugin I’ve experienced in WordPress. CoBlocks comes with Carousel, Collage, Masonry, Offest, and Stacked gallery blocks. The default Gallery block in WordPress is also pretty good — much better than it used to be. Buttons Alright, where am I? I have my intro columns featuring the primary information about site, some informational text, lots of cute cat photos, more informational text… I think my homepage is shaping up. I just need one final element: a donation section. Can’t take care of those kitties without some cash. The only way to integrate payments into WordPress is to either link to a third party platform, or use a plugin. I’ve used ActBlue quite a bit when making candidate websites, so I’m going to pretend that this site uses a third party service that, like ActBlue, lets me link to specific donation increments off-site. WordPress has a Buttons block underway that lets you add a row of buttons, without needing to rely on another block like Columns, but in the meantime, CoBlocks has an equivalent block I can use for now. Great. It’s got a bold color, and I can link to a couple different donation increments. But it could really use… something, you know, that draws the eye even more? Shape Divider CoBlocks has another great block, Shape Divider, which lets you add a decorative border that sits nicely above or below any container element, like the group block I’m using here. It comes with a variety of shape styles, like hills, rounded, and pointed. I settle on waves, which includes some overlapping transparencies along the top. It’s different from the rest of my page, but in a good way — it’s a subtle way for that section to stand out. With that final block, my homepage is almost done. I just want to touch on two more blocks that can be used to improve the design: the Separator block, and the Spacer block. Separator Separator inserts an <hr /> into the page, with some minimal styles to make it look nice. Themes can then add new styles, or restyle the default to get some fancy alternatives, like this: The Separator block is a great way to break up sections in a page. Spacer The Spacer block is an abomination, but I love it. It’s just an empty space. Think spacer gif, but spacer div. It’s terrible, but oh, oh so useful. I can increase space between elements without having to write any custom CSS. It empowers folks that are visual, but not technical. Combine it with Columns and you can almost pretend that you’re using a grid! (It is, at the very least, hidden from screen readers.) Okay but what does it look like? With those in place, let’s check out my homepage. Almost perfect. It’s bold, streamlined, and features plenty of cute cats. The only issue that caught my eye is the gap of white between the page content and the footer, which I can fix with some CSS added into WordPress’s Customizer tool: .home .footer-nav-widgets-wrapper { margin-top: 0; } Not too bad, considering this is the first bit of CSS I’ve had to write for my homepage layout. Much better. How about the old editor? Out of curiosity, I tried to recreate my homepage using the Classic Editor plugin, which restores the old WordPress editing interface. Since I used some of my favorite plugins on my block editor site, I decided it was only fair to leverage plugins on my classic site. I installed Shortcodes Ultimate, a plugin offering over 60 shortcodes to improve the WordPress editor. It has a good shortcode picking interface, great documentation, and in my opinion, is one of the best shortcode plugins the WordPress community has to offer. Your browser doesn’t support HTML5 video. Here is a link to the video instead. This wasn’t fun. No shortcode interface will make the experience worth it to me, when I could use Gutenberg. One misplaced bracket, and I’ve borked my site. It takes a whole lot of time. And, I almost always need to write a bunch of custom styles to get it to work with my theme. Yes, this is a LiveJournal icon I’ve had saved for like, 16 years. With our homepage complete, let’s move on to some interior pages. There are a couple other blocks, and combinations of blocks, that can help me build out the rest of my site. Cover Block One of the earliest complex blocks offered in the new WordPress editor was the “Cover” block, which can be used for banners and hero images: Originally, it only allowed you to add an image or video, headings, and paragraphs, but the requirements have recently been loosened so you can add whatever blocks you like. This can lead to some unique layout possibilities. Take, for example, a “Teams” section on our About page. We could use columns to make a simple layout, like this: But if we have better images, we could explore using Cover to create more visual impact: Let’s say we didn’t have any staff images, or they’re all poor quality and weirdly cropped, which is… not an usual occurrence! We can forego images altogether and instead, use the new gradient picker in Cover and use that to create visual impact: Explore third-party blocks Like CoBlocks’s gallery blocks, many third-party WordPress plugins can enhance your site and allow you to create a better experience for your visitors. Accordions Let’s say this rescue organization has some FAQs. Rather than creating a wall-of-text, we could use an accordion block to organize the content for easier browsing: Accordion Block from CoBlocks Grids If columns aren’t adequate for achieving the layout you’re looking to build, you could try the Grids plugin by Evolve, which comes with a “build your own grid” feature: I can use this block to make a more visually interesting landing page for the “Get Involved” section, which only exists to link out to its child pages: Typography You can also use plugins like CoBlocks and Kioken Blocks to customize your site’s typography, opening up the possibilities for a truly from-scratch site design. And I have to admit, as someone who makes web software, the idea of giving full typographic control to users terrifies me… but as a designer, I absolutely love this feature! ???? With these tools, it won’t take long to finish my website. Tons of new possibilities Mix and match to create beautiful, art-directed experiences using blocks. You can look for plugins that support and build on the new editor, or specifically download individual blocks in the new WordPress block directory (just beta launched!). Unsure of how to combine blocks to make an impact? A couple of plugins like Atomic Blocks, Kioken Blocks, and Ultimate Addons for Gutenberg include pre-curated layouts you can quickly add to your own sites. These layouts are already art directed, so you can choose the one that creates the biggest impact on your own audience. Explore, and share your results! About the author Mel Choyce is a wicked awesome product designer based in Boston, Massachusetts. Not only is Mel a WordPress Core Committer and former Release Lead, she is a regular core contributor and speaks frequently at WordCamps on design, typography, and user experience. When Mel isn’t designing products at Automattic, she enjoys cold brew coffee, craft beer, and rocking out in her band. Say hi to her on Twitter at @melchoyce, and visit her site at choycedesign.com. More articles by Mel Full Article Design design
w Microbrowsers are Everywhere By feedproxy.google.com Published On :: Sun, 15 Dec 2019 12:00:00 +0000 Colin Bendell gets into the minutia of microbrowsers - the small previews of your site that are pervasive all around the web and through social media apps and search engines whenever an item of content on your site is referenced. You’ve seen it everywhere - that little thumbnail preview of a website mentioned in a tweet, the expanded description in a Slack channel, or in WhatsApp group chat. Figure 1: The preview shown in a group chat provides a hint of what the real webpage looks like These link previews are so commonplace that we hardly pay any attention to how our site design might be impacting the generated preview. Yet, these previews can be the most influential part for attracting new audiences and increasing engagement - possibly more than SEO. Even more alarming is that most web analytics are blind to this traffic and can’t show you how these Microbrowsers are interacting with your site. As we close out the year, here are five essential questions and ideas that every web dev should know about Microbrowsers. 1. What are Microbrowsers? How are they different from “normal” browser? We are all very familiar with the main browsers like Firefox, Safari, Chrome, Edge and Internet Explorer. Not to mention the many new browsers that use Chromium as the rendering engine but offer unique user experiences like Samsung Internet or Brave. In contrast, Microbrowsers are a class of User-Agents that also visit website links, parse HTML and generate a user experience. But unlike those traditional browsers, the HTML parsing is limited and the rendering engine is singularly focused. The experience is not intended to be interactive. Rather the experience is intended to be representational - to give the user a hint of what exists on the other side of the URL. Creating link previews is not new. Facebook and Twitter have been adding these link previews in posts for nearly a decade. That used to be the primary use case. Marketing teams created backlog items to adopt different microdata - from Twitter Cards and Open Graph annotations for Facebook. LinkedIn likewise embraced both Open Graph and OEmbed tags to help generate the previews <meta name="description" content="seo description long"> <meta name="keywords" content="seo keyword list"> <link rel="shortcut icon" href="favicon.ico" type="image/x-icon"> <link rel="icon" href="favicon_32.png" sizes="32x32"> <link rel="icon" href="favicon_48.png" sizes="48x48"> <link rel="icon" href="favicon_96.png" sizes="96x96"> <link rel="icon" href="favicon_144.png" sizes="144x144"> <meta property="og:title" content="Short title here" /> <meta property="og:description" content="shortish description" /> <meta name="twitter:title" content="Short title here"> <meta name="twitter:description" content="shortish description"> <meta property="og:image" content="https://res.cloudinary.com/.../hero-img.png" /> <meta name="twitter:image:src" content="https://res.cloudinary.com/.../hero-img.png"> As group chats and other collaboration tools have become more prevalent, we have seen many features from the big social media platforms emerge. Particularly in recent years we’ve seen the adoption of the link unfurling behaviour in these chat platforms. Rather than reinventing the wheel, each platform looks for pre-existing microdata to generate the preview. But which data should be used? How should this be arranged? As it turns out, each platform behaves slightly differently; presenting information in slightly different ways. Figure 2: The same amazon link shared in iMessage (left), Hangouts and WhatsApp (right) 2. If Microbrowsers are everywhere, why don’t I see them in my analytics reports? It’s easy to miss the traffic from Microbrowsers. This is for a number of reasons: First, page requests from Microbrowsers don’t run JavaScript and they don’t accept cookies. The Google Analytics <script> block won’t be run or executed. And all cookie will be ignored by the rendering agent. Second, if you were to do a log analysis based on HTTP logs from your CDN or web stack, you would see a relatively small volume of traffic. That is assuming you can identify the User-Agent strings. Some of these Microbrowsers impersonate real browsers and others impersonate Facebook or twitter. For example, iMessage uses the same User-Agent string for all these requests and it hasn’t changed since iOS 9. User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_1) AppleWebKit/601.2.4 (KHTML, like Gecko) Version/9.0.1 Safari/601.2.4 facebookexternalhit/1.1 Facebot Twitterbot/1.0 Finally, many platforms - particularly Facebook Messenger and Hangouts use centralized services to request the preview layout. This, in contrast to WhatsApp and iMessage where you will see one request per user. In the centralized consumer approach your web servers will only see one request, but this one request might represent thousands of eyeballs. 3. Microbrowser are probably more important than google bot We all know the importance of having our web sites crawled by search engines like googlebot. These bots are the lifeblood for lead generation and for discovering new users. However, the real gold for marketers is from word-of-mouth discussions. Those conversations with your friends when you recommend a TV show, a brand of clothing, or share a news report. This is the most valuable kind of marketing. Last year when assembling the data for Cloudinary’s State of the Visual Media report, I discovered that there was a very prominent usage pattern over the USA holiday season. During thanksgiving, all the way to Black Friday, the rate of link sharing skyrocketed as group chats shared deals and insights. Zooming out (and normalizing for time-of-day), we can see that there is a daily cadence of link sharing and word of mouth referrals. It probably isn’t a shock to see that we predominantly share links in Slack between Monday and Friday, while WhatsApp is used all week long. Likewise, WhatsApp is most often used during our ‘break’ times like lunch or in the evening after we put the kids to bed. While the link preview is increasingly common, there are two user behaviours to balance: Users can be skeptical of links sent via SMS and other chats. We don’t want to be fooled into clicking a phishing links and so we look for other queues to offer validation. This is why most platforms use the preview while also emphasize the website url host name. Skimming. I’m sure you’ve had the experience coming out of a meeting or grocery store to find a group chat with 100 messages. As you scroll to catch up on the conversation, links can easily be skipped. In this way, users expect the preview to act as a summary to tell them how important it is to visit the link. Figure 4: Nielsen Norman Group summarizes the research in a dynamic image preview Figure 5: A mockup of how an ecommerce product could create compelling previews showcasing colors, stock and price in the preview 4. Microbrowsers are not real browsers (they just play one on TV) As I previously mentioned, Microbrowsers pretend to be a browser in that they send the right HTTP headers and often send impersonating User-Agent strings. Yet, there are several characteristics that a web dev should be aware of. First, Microbrowsers try to protect the User’s privacy. The user hasn’t decided to visit your site yet, and more importantly, the user is having a private conversation. The fact that your brand or website is mentioned should just make your ears burn, but you shouldn’t be able to listen in to the conversation. For this reason, all Microbrowsers: don’t execute JavaScript - so your react application won’t work ignore all cookies - so your A/B or red/green cookies will be ignored some will follow redirects, but will quickly time out after a few seconds and give up trying to expand the link. there won’t be a referer: HTTP header when the user clicks the link for the full browser. In fact, a new user will appear as ‘direct’ traffic - as though they typed in the url. Second, Microbrowsers have a very small brain and very likely don’t use an advanced network algorithm. Most browsers will use a tokenizer to parse the HTML markup and send requests to the network stack asynchronously. Better yet, browsers will do some analysis of the resources needed before sending the async request to the network. Based on observational experimentation, most platforms simply use a glorified for loop when parsing the HTML and often request the resources synchronously. This might be ok for fast wifi experiences, but it can cause inconsistent experiences on flaky wifi. For example, iMessage will discover and load all <link rel="icon" > favicon, all <meta property="og:image" images, and all <meta name="twitter:image:src" before deciding what to render. Many sites still advertise 5 or more favicon sizes. This means that iMessage will download all favicons regardless of size and then not use them if it decides to instead render the image. For this reason the meta markup that is included is important. The lighter the content, the more likely it will be to be rendered. 5. Markup Matters Since Microbrowsers are simple-brained browsers, it is all the more important to produce good markup. Here are a few good strategies: It’s almost 2020, you only need one favicon size. Remove all the other <link rel="shortcut icon" and <link rel="icon" references. Based on observational experimentation, the most commonly recognized microdata tags for preview are the Open-Graph tags. When the OG and twitter card tags are missing, the default SEO <meta name="description" is used. However, since the description is often nonsensical SEO optimized phrases, users’ eyes will likely glaze over. On that note, use good descriptive text Provide up to three <meta property="og:image" images. Most platforms will only load the first one, while others (notably iMessage) attempts to create a collage. Figure 6: Amazon uses User-Agent detection which results in many link previews using the description meta tag. Use <meta property="og:video* with progressive (not streaming) video experiences. <meta property="og:type" content="video.other"> <meta property="og:video:url" content="https://shoesbycolin.com/blue.mp4"> <meta property="og:video:secure_url" content="https://shoesbycolin.com/blue.mp4"> <meta property="og:video:type" content="video/mp4"> <meta property="og:video:width" content="1280"> <meta property="og:video:height" content="720"> Don’t use UA sniffing to hide the <meta> tags. Sites like Amazon do this to try and show only Facebook/Twitter the microdata annotated website. But this can cause problems for some Microbrowsers that don’t use the same impersonation convention. The result is a simple link without a preview. Use the opportunity to tell your product story or summarize your ideas. Summary As more of our conversations happen in group chats and slack channels, link previews are an important way for you to engage users before they start the journey on your site. Unfortunately, not all websites present good or compelling previews. (And now that you know what to look for, you won’t be able to unsee bad examples - I’m sorry). To help users take the leap and visit your site, we need to make sure that all our pages are annotated with microdata. Better yet, we can use these previews to create compelling visual summaries. About the author Colin is part of the CTO Office at Cloudinary and co-author of the O’Reilly book High Performance Images. He spends much of his time at the intersection of high volume data, media, browsers and standards. He recently helped the community effort writing chapters in the Web Almanac on Media and CDNs. You can find him on tweeting @colinbendell and at blogging at https://bendell.ca More articles by Colin Full Article Code performance
w A History of CSS Through Fifteen Years of 24 ways By feedproxy.google.com Published On :: Mon, 16 Dec 2019 12:00:00 +0000 Rachel Andrew guides us through a tour of the last fifteen years in CSS layout, as manifested in articles here on 24 ways. From the days when Internet Explorer 6 was de rigueur, right up to the modern age of evergreen browsers, the only thing you can be sure of is that the web never stands still for long. I’ve written nine articles in the 15 years of 24 ways, and all but one of those articles had something to do with CSS. In this last year of the project, I thought I would take a look back at those CSS articles. It’s been an interesting journey, and by reading through my words from the last 15 years I discovered not only how much the web platform has evolved - but how my own thinking has shifted with it. 2005: CSS layout starting points Latest web browser versions: Internet Explorer 6 (at this point 4 years old), IE5.1 Mac, Netscape 8, Firefox 1.5, Safari 2 Fifteen years ago, my contributions to 24 ways started with a piece about CSS layout. That article explored something I had been using in my own work. In 2005, most of the work I was doing was building websites from Photoshop files delivered to me by my design agency clients. I’d built up a set of robust, tried-and-tested CSS layouts to use to implement these. My starting point when approaching any project was to take a look at the static comps and figure out which layout I would use: Liquid, multiple column with no footer Liquid, multiple column with footer Fixed width, centred At that point, there were still many sites being shipped with table-based layouts. We had learned how to use floats to create columns some four years earlier, however layout was still a difficult and often fragile thing. By developing patterns that I knew worked, where I had figured out any strange bugs, I saved myself a lot of time. Of course, I wasn’t the only person thinking in this way. The two sites from which the early CSS for layout enthusiasts took most of their inspiration, had a library of patterns for CSS layout. The Noodle Incident little boxes is still online, glish.com/css is sadly only available at the Internet Archive. which one of the two possible websites are you currently designing? pic.twitter.com/ZD0uRGTqqm— Jon Gold (@jongold) February 2, 2016 This thinking was taken to a much greater extreme in 2011, when Twitter Bootstrap launched and starting with an entire framework for layout and much more became commonplace across the industry. While I understand the concern many folk have about every website ending up looking the same, back in 2005 I was a pragmatist. That has not changed. I’ve always built websites and run businesses alongside evangelizing web standards and contributing to the platform. I’m all about getting the job done, paying the bills, balancing that with trying to make things better so we don’t need to make as many compromises in the future. If that means picking from one of a number of patterns, that is often a very reasonable approach. Not everything needs to be a creative outpouring. Today however, CSS Grid Layout and Flexbox mean that we can take a much more fluid approach to developing layouts. This enables the practical and the creative alike. The need for layout starting points - whether simple like mine, or a full framework like Bootstrap - seems to be decreasing, however in their place comes an interest in component libraries. This approach to development partly enabled by the fact that new layout makes it possible to drop a component into the middle of a layout without blowing the whole thing up. 2006: Faster Development with CSS Constants Latest web browser versions: Internet Explorer 7, Netscape 8.1, Firefox 2, Safari 2 My article in 2006 was once again taken from the work I was doing as a developer. I’ve always been as much, if not more of a backend developer than a frontend one. In 2006, I was working in PHP on custom CMS implementations. These would also usually include the front-end work. Along with several other people in the industry I’d been experimenting with ways to use CSS “constants” as we all seemed to call them, by processing the CSS with our server-side language of choice. The use case was mostly for development, although as a CMS developer, I could see the potential of allowing these values to be updated via the CMS. Perhaps to allow a content editor to change a color scheme. Also in 2006, the first version of Sass was released, created by Hampton Catlin and Natalie Weizenbaum. Sass, LESS and other pre-processors began to give us a more streamlined and elegant way to achieve variables in CSS. In 2009, the need for pre-processors purely for variables is disappearing. CSS now has Custom Properties - something I did not foresee in 2006. These “CSS Variables” are far more powerful than swapping out a value in a build process. They can be changed dynamically, based on something changing in the environment, rather than being statically set at build time. 2009: Cleaner Code with CSS3 Selectors Latest web browser versions: Internet Explorer 8, Firefox 3.5, Safari 4, Chrome 3 After a break from writing for 24 ways, in 2009 I wrote this piece about CSS3 Selectors, complete with jQuery fallbacks due to the fact that some of these selectors were not usable in Internet Explorer 8. Today these useful selectors have wide browser support, we also have a large number of new selectors which are part of the Level 4 specification. The changes section of the Level 4 spec gives an excellent rundown of what has been added over the years. Browser support for these newer selectors is more inconsistent, MDN has an excellent list with the page for each selector detailing current browser support and usage examples. 2012: Giving Content Priority with CSS3 Grid Layout Latest web browser versions: Internet Explorer 10, Firefox 17, Safari 6, Chrome 23 My 2012 piece was at the beginning of my interest in the CSS Grid Layout specification. Earlier in 2012 I had attended a workshop given by Bert Bos, in which he demonstrated some early stage CSS modules, including the CSS Grid Layout specification. I soon discovered that there would be an implementation of Grid in IE10, the new browser shipped in September of 2012 and I set about learning how to use Grid Layout. This article was based on what I had learned. The problem of source versus visual order As a CMS developer I immediately linked the ability to lay out items and prioritize content, to the CMS and content editors. I was keen to find ways to allow content editors to prioritize content across breakpoints, and I felt that Grid Layout might allow us to do that. As it turned out, we are still some way away from that goal. While Grid does allow us to separate visual display from source order, it can come at a cost. Non-visual browsers, and the tab order of the document follow the source and not the visual display. This makes it easy to create a disconnected and difficult to use experience if we essentially jumble up the display of elements, moving them away from how they appear in the document. I still think that an issue we need to solve is how to allow developers to indicate that the visual display should be considered the correct order rather than the document order. The Grid Specification moved on Some of the issues in this early version of the grid spec were apparent in my article. I needed to use a pre-processor, to calculate the columns an element would span. This was partly due to the fact that the early grid specifications did not have a concept of the gap property. In addition the initial spec did not include auto-placement and therefore each item had to be explicitly placed onto the grid. The basics of the final specification were there, however over the years that followed the specification was refined and developed. We got gaps, and auto-placement, and the grid-template-areas property was introduced. By the time Grid shipped in Firefox, Chrome, and Safari many of the sticky things I had encountered when writing this article were resolved. 2015: Grid, Flexbox, Box Alignment: Our New System for Layout Latest web browser versions: Edge 13, Firefox 43, Safari 9, Chrome 47 Grid still hadn’t shipped in more browsers but the specification had moved on. We had support for gaps, with the grid-row-gap, grid-column-gap and grid-gap properties. My own thinking about the specification, and the related specifications had developed. I had started teaching grid not as a standalone module, but alongside Flexbox and Box Alignment. I was trying to demonstrate how these modules worked together to create a layout system for modern web development. Another place my thinking had moved on since my initial Grid article in 2012, was in terms of content reordering and accessibility. In July of 2015 I wrote an article entitled, Modern CSS Layout, Power and Responsibility in which I outlined these concerns. Some things change, and some stay the same. The grid- prefixed gap properties were ultimately moved into the Box Alignment specification in order that they could be defined for Flex layout and any other layout method which in future required gaps. What I did not expect, was that four years on I would still be being asked about Grid versus Flexbox: “A question I keep being asked is whether CSS grid layout and flexbox are competing layout systems, as though it might be possible to back the loser in a CSS layout competition. The reality, however, is that these two methods will sit together as one system for doing layout on the web, each method playing to certain strengths and serving particular layout tasks.” 2016: What next for CSS Grid Layout? Latest web browser versions: Edge 15, Firefox 50, Safari 10, Chrome 55 In 2016, we still didn’t have Grid in browsers, and I was increasingly looking like I was selling CSS vaporware. However, with the spec at Candidate Recommendation, and it looking likely that we would have grid in at least two browsers in the spring, I wrote an article about what might come next for grid. The main subject was the subgrid feature, which had by that point been removed from the Level 1 specification. The CSS Working Group were still trying to decide whether a version of subgrid locked to both dimensions would be acceptable. In this version we would have declared display: subgrid on the grid item, after which its rows and columns would be locked to the tracks of the parent. I am very glad that it was ultimately decided to allow for one-dimensional subgrids. This means that you can use the column tracks of the parent, yet have an implicit grid for the rows. This enables patterns such as the one I described in A design pattern solved by subgrid. At the end of 2019, we don’t yet have wide browser support for subgrid, however Firefox has already shipped the value in Firefox 71. Hopefully other browsers will follow suit. Level 2 of the grid specification ultimately became all about adding support for subgrid, and so we don’t yet have any of the other features I mentioned in that piece. All of those features are detailed in issues in the CSS Working Group Github repo, and aren’t forgotten about. As we come to decide features for Level 3, perhaps some of them will make the cut. It was worth waiting for subgrid, as the one-dimensional version gives us so much more power, and as I take a look back over these 24 ways articles it really underlines how much of a long game contributing to the platform is. I mentioned in the closing paragraph of my 2016 article that you should not feel ignored if your idea or use case is not immediately discussed and added to a spec, and that is still the case. Those of us involved in specifying CSS, and in implementing CSS in browsers care very much about your feedback. We have to balance that with the need for this stuff to be right. 2017: Christmas Gifts for Your Future Self: Testing the Web Platform Latest web browser versions: Edge 16, Firefox 57, Safari 11, Chrome 63 In 2017 I stepped away from directly talking about layout, and instead published an article about testing. Not about testing your own code, but about the Web Platform Tests project, and how contributing to the tests which help to ensure interoperability between browsers could benefit the platform - and you. This article is still relevant today as it was two years ago. I’m often asked by people how they can get involved with CSS, and testing is a great place to start. Specifications need tests in order to progress to become Recommendations, therefore contributing tests can materially help the progress of a spec. You can also help to free up the time of spec editors, to make edits to their specs, by contributing tests they might otherwise need to work on. The Web Platform Tests project has recently got new and improved documentation. If you have some time to spare and would like to help, take a look and see if you can identify some places that are in need of tests. You will learn a lot about the CSS specs you are testing while doing so, and you can feel that you are making a useful and much-needed contribution to the development of the web platform. 2018: Researching a Property in the CSS Specifications Latest web browser versions: Edge 17, Firefox 64, Safari 12, Chrome 71 I almost stayed away from layout in my 2018 piece, however I did feature the Grid Layout property grid-auto-rows in this article. If you want to understand how to dig up all the details of a CSS property, then this article is still useful. One thing that has changed since I began writing for 24 ways, is the amount of great information available to help you learn CSS. Whether you are someone who prefers to read like me, or a person who learns best from video, or by following along with a tutorial, it’s all out there for you. You don’t have to rely on understanding the specifications, though I would encourage everyone to become familiar with doing so, if just to be able to fact check a tutorial which seems to be doing something other than the resulting code. 2019: And that’s a wrap Latest web browser versions: Edge 18, Firefox 71, Safari 12, Chrome 79 This year is the final countdown for 24 ways. With so many other publications creating great content, perhaps there is less of a need for an avalanche of writing in the closing days of each year. The archive will stay as a history of what was important, what we were thinking, and the problems of the day - many of which we have now solved in ways that the authors could never have imagined at the time. I can see through my articles how my thinking evolved over the years, and I’m as excited about what comes next as I was back in 2005, wondering how to make CSS layout easier. About the author Rachel Andrew is a Director of edgeofmyseat.com, a UK web development consultancy and creators of the small content management system, Perch; a W3C Invited Expert to the CSS Working Group; and Editor in Chief of Smashing Magazine. She is the author of a number of books including The New CSS Layout for A Book Apart and a Google Developer Expert for Web Technologies. She curates a popular email newsletter on CSS Layout, and is passing on her layout knowledge over at her CSS Layout Workshop. When not writing about business and technology on her blog at rachelandrew.co.uk or speaking at conferences, you will usually find Rachel running up and down one of the giant hills in Bristol, or attempting to land a small aeroplane while training for her Pilot’s license. More articles by Rachel Full Article Code css
w Five Interesting Ways to Use Array.reduce() (And One Boring Way) By feedproxy.google.com Published On :: Wed, 18 Dec 2019 12:00:00 +0000 Chris Ferdinandi turns the heat down low and lets the sauce reduce while we take a look at how to add spice to our source with a sprinkling of Array.reduce(). Just a little ingenuity with the humblest of functions. Of all the modern array methods, the one I had the hardest time wrapping my head around was Array.reduce(). On the surface, it seems like a simple, boring method that doesn’t do much. But below its humble exterior, Array.reduce() is actually a powerful, flexible addition to your developer toolkit. Today, we’re going to look at some cool things you can do with Array.reduce(). How Array.reduce() works Most of the modern array methods return a new array. The Array.reduce() method is a bit more flexible. It can return anything. Its purpose is to take an array and condense its content into a single value. That value can be a number, a string, or even an object or new array. That’s the part that’s always tripped me up – I didn’t realize just how flexible it is! The syntax The Array.reduce() accepts two arguments: a callback method to run against each item in the array, and a starting value. The callback also accepts two arguments: the accumulator, which is the current combined value, and the current item in the loop. Whatever you return is used as the accumulator for the next item in the loop. On the very first loop, that starting value is used instead. var myNewArray = [].reduce(function (accumulator, current) { return accumulator; }, starting); Let’s look at some examples to make this all tangible. 1. Adding numbers together Let’s say you had an array of numbers that you wanted to add together. Using Array.forEach(), you might do something like this: var total = 0; [1, 2, 3].forEach(function (num) { total += num; }); This is the cliche example for using Array.reduce(). I find the word accumulator confusing, so in this example, I’m calling it sum, because that’s what it is. var total = [1, 2, 3].reduce(function (sum, current) { return sum + current; }, 0); Here, we pass in 0 as our starting value. In the callback, we add the current value to the sum, which has our starting value of 0 on the first loop, then 1 (the starting value of 0 plus the item value of 1), then 3 (the sum value of 1 plus the item value of 2), and so on. Here’s a demo. 2. Combining multiple array methods into Array.map() and Array.filter() into a single step Imagine you had an array of wizards at Hogwarts. var wizards = [ { name: 'Harry Potter', house: 'Gryfindor' }, { name: 'Cedric Diggory', house: 'Hufflepuff' }, { name: 'Tonks', house: 'Hufflepuff' }, { name: 'Ronald Weasley', house: 'Gryfindor' }, { name: 'Hermione Granger', house: 'Gryfindor' } ]; You want to create a new array that contains just the names of wizards who are in Hufflepuff. One way you could do that is by using the Array.filter() method to get back just wizards whose house property is Hufflepuff. Then, you’d use the Array.map() method to create a new array containing just the name property for the remaining wizards. // Get the names of the wizards in Hufflepuff var hufflepuff = wizards.filter(function (wizard) { return wizard.house === 'Hufflepuff'; }).map(function (wizard) { return wizard.name; }); With the Array.reduce() method, we can get the same array in a single pass, improving our performance. You pass in an empty array ([]) as the starting value. On each pass, you check to see if the wizard.house is Hufflepuff. If it is, you push it to the newArr (our accumulator in this example). If not, you do nothing. Either way, you return the newArr to become the accumulator on the next pass. // Get the names of the wizards in Hufflepuff var hufflepuff = wizards.reduce(function (newArr, wizard) { if (wizard.house === 'Hufflepuff') { newArr.push(wizard.name); } return newArr; }, []); Here’s another demo. 3. Creating markup from an array What if, instead of creating an array of names, we wanted to create an unordered list of wizards in Hufflepuff? Instead of passing an empty array into Array.reduce() as our starting value, we’ll pass in an empty string ('') and call it html. If the wizard.house equals Hufflepuff, we’ll concatenate our html string with the wizard.name wrapped in an opening and closing list item (li). Then, we’ll return the html to become the accumulator on the next loop. // Create a list of wizards in Hufflepuff var hufflepuffList = wizards.reduce(function (html, wizard) { if (wizard.house === 'Hufflepuff') { html += '<li>' + wizard.name + '</li>'; } return html; }, ''); Add an opening and closing unordered list element before and after Array.reduce(), and you’re ready to inject your markup string into the DOM. // Create a list of wizards in Hufflepuff var hufflepuffList = '<ul>' + wizards.reduce(function (html, wizard) { if (wizard.house === 'Hufflepuff') { html += '<li>' + wizard.name + '</li>'; } return html; }, '') + '</ul>'; See it in action here. 4. Grouping similar items in an array together The lodash library has a groupBy() method takes a collection of items as an array and groups them together into an object based on some criteria. Let’s say you want an array of numbers. If you wanted to group all of the items in numbers together based on their integer value, you would do this with lodash. var numbers = [6.1, 4.2, 6.3]; // returns {'4': [4.2], '6': [6.1, 6.3]} _.groupBy(numbers, Math.floor); If you had an array of words, and you wanted to group the items in words by their length, you would do this. var words = ['one', 'two', 'three']; // returns {'3': ['one', 'two'], '5': ['three']} _.groupBy(words, 'length'); Creating a groupBy() function with Array.reduce() You can recreate that same functionality using the Array.reduce() method. We’ll create a helper function, groupBy(), that accepts the array and criteria to sort by as arguments. Inside groupBy(), we’ll run Array.reduce() on our array, passing in an empty object ({}) as our starting point, and return the result. var groupBy = function (arr, criteria) { return arr.reduce(function (obj, item) { // Some code will go here... }, {}); }; Inside the Array.reduce() callback function, we’ll check to see if the criteria is a function, or a property of the item. Then we’ll get its value from the current item. If there’s no property in the obj with that value yet, we’ll create it and assign an empty array as its value. Finally, we’ll push the item to that key, and return the object as the accumulator for the next loop. var groupBy = function (arr, criteria) { return arr.reduce(function (obj, item) { // Check if the criteria is a function to run on the item or a property of it var key = typeof criteria === 'function' ? criteria(item) : item[criteria]; // If the key doesn't exist yet, create it if (!obj.hasOwnProperty(key)) { obj[key] = []; } // Push the value to the object obj[key].push(item); // Return the object to the next item in the loop return obj; }, {}); }; Here’s a demo of the completed helper function. Special thanks to Tom Bremer for helping me make some improvements to this one. You can find this helper function and more like it on the Vanilla JS Toolkit. 5. Combining data from two sources into an array Remember our array of wizards? var wizards = [ { name: 'Harry Potter', house: 'Gryfindor' }, { name: 'Cedric Diggory', house: 'Hufflepuff' }, { name: 'Tonks', house: 'Hufflepuff' }, { name: 'Ronald Weasley', house: 'Gryfindor' }, { name: 'Hermione Granger', house: 'Gryfindor' } ]; What if you had another data set, an object of house points each wizard has earned. var points = { HarryPotter: 500, CedricDiggory: 750, RonaldWeasley: 100, HermioneGranger: 1270 }; Imagine you wanted to combine both sets of data into a single array, with the number of points added to each wizard’s data in the wizards array. How would you do it? The Array.reduce() method is perfect for this! var wizardsWithPoints = wizards.reduce(function (arr, wizard) { // Get the key for the points object by removing spaces from the wizard's name var key = wizard.name.replace(' ', ''); // If the wizard has points, add them // Otherwise, set them to 0 if (points[key]) { wizard.points = points[key]; } else { wizard.points = 0; } // Push the wizard object to the new array arr.push(wizard); // Return the array return arr; }, []); Here’s a demo combining data from two sources into an array. 6. Combining data from two sources into an object What if you instead wanted to combine the two data sources into an object, where each wizard’s name was the key, and their house and points were properties? Again, the Array.reduce() method is perfect for this. var wizardsAsAnObject = wizards.reduce(function (obj, wizard) { // Get the key for the points object by removing spaces from the wizard's name var key = wizard.name.replace(' ', ''); // If the wizard has points, add them // Otherwise, set them to 0 if (points[key]) { wizard.points = points[key]; } else { wizard.points = 0; } // Remove the name property delete wizard.name; // Add wizard data to the new object obj[key] = wizard; // Return the array return obj; }, {}); Here’s a demo combining two data sets into an object. Should you use Array.reduce() more? The Array.reduce() method has gone from being something I thought was pointless to my favorite JavaScript method. So, should you use it? And when? The Array.reduce() method has fantastic browser support. It works in all modern browsers, and IE9 and above. It’s been supported in mobile browsers for a long time, too. If you need to go back even further than that, you can add a polyfill to push support back to IE6. The biggest complaint you can make about Array.reduce() is that it’s confusing for people who have never encountered it before. Combining Array.filter() with Array.map() is slower to run and involves extra steps, but it’s easier to read. It’s obvious from the names of the methods what they’re supposed to be doing. That said, there are times where Array.reduce() makes things that would be complicated more simple rather than more complicated. The groupBy() helper function is a good example. Ultimately, this is another tool to add to your toolkit. A tool that, if used right, can give you super powers. About the author Chris Ferdinandi helps people learn vanilla JavaScript. He believes there’s a simpler, more resilient way to make things for the web. Chris is the author of the Vanilla JS Pocket Guide series, creator of the Vanilla JS Academy training program, and host of the Vanilla JS Podcast. His developer tips newsletter is read by thousands of developers each weekday. He’s taught developers at organizations like Chobani and the Boston Globe, and his JavaScript plugins have been used used by Apple and Harvard Business School. Chris Coyier, the founder of CSS-Tricks and CodePen, has described his writing as “infinitely quote-worthy.” Chris loves pirates, puppies, and Pixar movies, and lives near horse farms in rural Massachusetts. He runs Go Make Things with Bailey Puppy, a lab-mix from Tennessee. More articles by Chris Full Article Code javascript
w Four Ways Design Systems Can Promote Accessibility – and What They Can’t Do By feedproxy.google.com Published On :: Mon, 23 Dec 2019 12:00:00 +0000 Amy Hupe prepares a four bird roast of tasty treats so we can learn how the needs of many different types of users can be served through careful implementation of components within a design system. Design systems help us to make our products consistent, and to make sure we’re creating them in the most efficient way possible. They also help us to ensure our products are designed and built to a high quality; that they’re not only consistent in appearance, and efficiently-built, but that they are good. And good design means accessible design. 1 in 5 people in the UK have a long term illness, impairment or disability – and many more have a temporary disability. Designing accessible services is incredibly important from an ethical, reputational and commercial standpoint. For EU government websites and apps, accessibility is also a legal requirement. With that in mind, I’ll explain the four main ways I think we can use design systems to promote accessible design within an organisation, and what design systems can’t do. 1. Bake it in Design systems typically provide guidance and examples to aid the design process, showing what best practice looks like. Many design systems also encompass code that teams can use to take these elements into production. This gives us an opportunity to build good design into the foundations of our products, not just in terms of how they look, but also how they work. For everyone. Let me give an example. The GOV.UK Design System contains a component called the Summary list. It’s used in a few different contexts on GOV.UK, to summarise information. It’s often used at the end of a long or complex form, to let users check their answers before they send them, like this: Users can review the information and, if they’ve entered something incorrectly, they can go back and edit their answer by clicking the “Change” link on the right-hand side. This works well if you can see the change link, because you can see which information it corresponds to. In the top row, for example, I can see that the link is giving me the option to change the name I’ve entered because I can see the name label, and the name I put in is next to it. However, if you’re using a screen reader, this link – and all the others – will just say “change”, and it becomes harder to tell what you’re selecting. So to help with this, the GOV.UK Design System team added some visually-hidden text to the code in the example, to make the link more descriptive. Sighted users won’t see this text, but when a screen reader reads out the link, it’ll say “change name”. This makes the component more accessible, and helps it to satisfy a Web Content Accessibility Guidelines (WCAG 2.1) success criterion for links which says we must “provide link text that identifies the purpose of the link without needing additional context”. By building our components with inclusion in mind, we can make it easier to make products accessible, before anyone’s even had to think about it. And that’s a great starting point. But that doesn’t mean we don’t have to think about it – we definitely do. And a design system can help with that too. 2. Explain it Having worked as the GOV.UK Design System’s content designer for the best part of 3 years, I’m somewhat biased about this, but I think that the most valuable aspect of a design system is its documentation. (Here’s a shameless plug for my patterns Day talk on design system documentation earlier this year, if you want to know more about that.) When it comes to accessibility, written documentation lets us guide good practice in a way that code and examples alone can’t. By carefully documenting implementation rules for each component, we have an opportunity to distribute accessible design principles throughout a design system. This means design system users encounter them not just once, but repeatedly and frequently, in various contexts, which helps to build awareness over time. For instance, WCAG 2.1 warns against using colour as “the only visual means of conveying information, calling an action, prompting a response or distinguishing a visual element”. This is a general principle to follow, but design system documentation lets us explain how this relates to specific components. Take the GOV.UK Design System’s warning buttons. These are used for actions with serious, often destructive consequences that can’t easily be undone – like permanently deleting an account. The example doesn’t tell you this, but the guidance explains that you shouldn’t rely on the red colour of warning buttons to communicate that the button performs a serious action, since not all users will be able to see the colour or understand what it signifies. Instead, it says, “make sure the context and button text makes clear what will happen if the user selects it”. In this way, the colour is used as an enhancement for people who can interpret it, but it’s not necessary in order to understand it. Making the code in our examples and component packages as accessible as possible by default is really important, but written documentation like this lets us be much more explicit about how to design accessible services. 3. Lead by example In our design systems’ documentation, we’re telling people what good design looks like, so it’s really important that we practice what we preach. Design systems are usually for members of staff, rather than members of the public. But if we want to build an inclusive workplace, we need to hold them to the same standards and ensure they’re accessible to everyone who might need to use them – today and in the future. One of the ways we did this in my team, was by making sure the GOV.UK Design System supports users who need to customise the colours they use to browse the web. There are a range of different user needs for changing colours on the web. People who are sensitive to light, for instance, might find a white background too bright. And some users with dyslexia find certain colours easier to read than others. My colleague, Nick Colley, wrote about the work we did to ensure GOV.UK Design System’s components will work when users change colours on GOV.UK. To ensure we weren’t introducing barriers to our colleagues, we also made it possible to customise colours in the GOV.UK Design System website itself. Building this flexibility into our design system helps to support our colleagues who need it, but it also shows others that we’re committed to inclusion and removing barriers. 4. Teach it The examples I’ve drawn on here have mostly focused on design system documentation and tooling, but design systems are much bigger than that. In the fortuitously-timed “There is No Design System”, Jina reminds us that tooling is just one of the ways we systematise design: …it’s a lot of people-focused work: Reviewing. Advising. Organizing. Coordinating. Triaging. Educating. Supporting.” To make a design system successful, we can’t just build a set of components and hope they work. We have to actively help people find it, use it and contribute to it. That means we have to go out and talk about it. We have to support people in learning to use it and help new teams adopt it. These engagement activities and collaborative processes that sit around it can help to promote awareness of the why, not just the what. At GDS, we ran workshops on accessibility in the design system, getting people to browse various web pages using visual impairment simulation glasses to understand how visually impaired users might experience our content. By working closely with our systems’ users and contributors like this, we have an opportunity to bring them along on the journey of making something accessible. We can help them to test out their code and content and understand how they’ll work on different platforms, and how they might need to be adjusted to make sure they’re accessible. We can teach them what accessibility means in practice. These kinds of activities are invaluable in helping to promote accessible design thinking. And these kinds of lessons – when taught well – are disseminated as colleagues share knowledge with their teams, departments and the wider industry. What design systems can’t do Our industry’s excitement about design systems shows no signs of abating, and I’m excited about the opportunities it affords us to make accessible design the default, not an edge case. But I want to finish on a word about their limitations. While a design system can help to promote awareness of the need to be accessible, and how to design products and services that are, a design system can’t make an organisation fundamentally care about accessibility. Even with the help of a thoughtfully created design system, it’s still possible to make really inaccessible products if you’re not actively working to remove barriers. I feel lucky to have worked somewhere that prioritises accessibility. Thanks to the work of some really brilliant people, it’s just part of the fabric at GDS. (For more on that work and those brilliant people, I can’t think of a better place to start than my colleague Ollie Byford’s talk on inclusive forms.) I’m far from being an accessibility expert, but I can write about this because I’ve worked in an organisation where it’s always a central consideration. This shouldn’t be something to feel lucky about. It should be the default, but sadly we’re not there yet. Not even close. Earlier this year, Domino’s pizza was successfully sued by a blind customer after he was unable to order food on their website or mobile app, despite using screen-reading software. And in a recent study carried out by disability equality charity, Scope, 50% of respondents said that they had given up on buying a product because the website, app or in-store machine had accessibility issues. Legally, reputationally and most importantly, morally, we all have a duty to do better. To make sure our products and services are accessible to everyone. We can use design systems to help us on that journey, but they’re just one part of our toolkit. In the end, it’s about committing to the cause – doing the work to make things accessible. Because accessible design is good design. About the author Amy is a content specialist and design systems advocate who’s spent the last 3 years working as a Senior Content Designer at the Government Digital Service. In that time, she’s led the content strategy for the GOV.UK Design System, including a straightforward and inclusive approach to documentation. In January, Amy will continue her work in this space, in her new role as Product Manager for Babylon Health’s design system, DNA. More articles by Amy Full Article Process style-guides
w Cigarette taxes and teen marijuana use [electronic resource] / D. Mark Anderson, Kyutaro Matsuzawa, Joseph J. Sabia By darius.uleth.ca Published On :: Cambridge, Mass. : National Bureau of Economic Research, 2020 Full Article
w Drug courts [electronic resource] : a new approach to treatment and rehabilitation / James E. Lessenger, Glade F. Roper, editors By darius.uleth.ca Published On :: New York : Springer, [2007] Full Article
w The evolving consequences of OxyContin reforumulation on drug overdoses [electronic resource] / David Powell, Rosalie Liccardo Pacula By darius.uleth.ca Published On :: Cambridge, Mass. : National Bureau of Economic Research, 2020 Full Article