{"rowid": 205, "title": "Why Design Systems Fail", "contents": "Design systems are so hot right now, and for good reason. They promote a modular approach to building a product, and ensure organizational unity and stability via reusable code snippets and utility styles. They make prototyping a breeze, and provide a common language for both designers and developers.\nA design system is a culmination of several individual components, which can include any or all of the following (and more):\n\nStyle guide or visual pattern library\nDesign tooling (e.g. Sketch Library)\nComponent library (where the components live in code)\nCode usage guidelines and documentation\nDesign usage documentation\nVoice and tone guideline\nAnimation language guideline\n\nDesign systems are standalone (internal or external) products, and have proven to be very effective means of design-driven development. However, in order for a design system to succeed, everyone needs to get on board.\nI\u2019d like to go over a few considerations to ensure design system success and what could hinder that success.\nOrganizational Support\nPut simply, any product, including internal products, needs support. Something as cross-functional as a design system, which spans every vertical project team, needs support from the top and bottom levels of your organization. \nWhat I mean by that is that there needs to be top-level support from project managers up through VP\u2019s to see the value of a design system, to provide resources for its implementation, and advocate for its use company-wide. This is especially important in companies where such systems are being put in place on top of existing, crufty codebases, because it may mean there needs to be some time and effort put in the calendar for refactoring work.\nSupport from the bottom-up means that designers and engineers of all levels also need to support this system and feel responsibility for it. A design system is an organization\u2019s product, and everyone should feel confident contributing to it. If your design system supports external clients as well (such as contractors), they too can become valuable teammates.\nA design system needs support and love to be nurtured and to grow. It also needs investment.\nInvestment\nTo have a successful design system, you need to make a continuous effort to invest resources into it. I like to compare this to working out.\nYou can work out intensely for 3 months and see some gains, but once you stop working out, those will slowly fade away. If you continue to work out, even if its less often than the initial investment, you\u2019ll see yourself maintaining your fitness level at a much higher rate than if you stopped completely. \nIf you invest once in a design system (say, 3 months of overhauling it) but neglect to keep it up, you\u2019ll face the same situation. You\u2019ll see immediate impact, but that impact will fade as it gets out of sync with new designs and you\u2019ll end up with strange, floating bits of code that nobody is using. Your engineers will stop using it as the patterns become outdated, and then you\u2019ll find yourself in for another round of large investment (while dreading going through the process since its fallen so far out of shape).\n\nWith design systems, small incremental investments over time lead to big gains overall.\n\nWith this point, I also want to note that because of how they scale, design systems can really make a large impact across the platform, making it extremely important to really invest in things like accessibility and solid architecture from the start. You don\u2019t want to scale a brittle system that\u2019s not easy to use.\nTake care of your design systems, and keep working on them to ensure their effectiveness. One way to ensure this is to have a dedicated team working on this design system, managing tickets and styling updates that trickle out to the rest of your company.\nResponsibility\nWith some kind of team to act as an owner of a design system, whether it be the design team, engineering team, or a new team\nmade of both designers and engineers (the best option), your company is more likely to keep a relevant, up-to-date system that doesn\u2019t break.\nThis team is responsible for a few things:\n\nHelping others get set up on the system (support)\nDesigning and building components (development)\nAdvocating for overall UI consistency and adherence (evangelism)\nCreating a rollout plan and update system (product management)\n\nAs you can see, these are a lot of roles, so it helps to have multiple people on this team, at least part of the time, if you can. One thing I\u2019ve found to be effective in the past is to hold office hours for coworkers to book slots within to help them get set up and to answer any questions about using the system. Having an open Slack channel also helps for this sort of thing, as well as for bringing up bugs/issues/ideas and being an channel for announcements like new releases.\nCommunication\nOnce you have resources and a plan to invest in a design system, its really important that this person or team acts as a bridge between design and engineering. Continuous communication is really important here, and the way you communicate is even more important.\nRemember that nobody wants to be told what to do or prescribed a solution, especially developers, who are used to a lot of autonomy (usually they get to choose their own tools at work). Despite how much control the other engineers have on the process, they need to feel like they have input, and feel heard.\nThis can be challenging, especially since ultimately, some party needs to be making a final decision on direction and execution. Because it\u2019s a hard balance to strike, having open communication channels and being as transparent as possible as early as possible is a good start.\nBuy-in\nFor all of the reasons we\u2019ve just looked over, good communication is really important for getting buy-in from your users (the engineers and designers), as well as from product management.\n\nBuilding and maintaining a design system is surprisingly a lot of people-ops work.\n\nTo get buy-in where you don\u2019t have a previous concensus that this is the right direction to take, you need to make people want to use your design system. A really good way to get someone to want to use a product is to make it the path of least resistance, to show its value.\nGather examples and usage wins, because showing is much more powerful than telling.\nIf you can, have developers use your product in a low-stakes situation where it provides clear benefits. Hackathons are a great place to debut your design system. Having a hackathon internally at DigitalOcean was a perfect opportunity to:\n\nEvangelize for the design system\nSee what people were using the component library for and what they were struggling with (excellent user testing there)\nGet user feedback afterward on how to improve it in future iterations\nLet people experience the benefits of using it themselves\n\nThese kinds of moments, where people explore on their own are where you can really get people on your side and using the design system, because they can get their hands on it and draw their own conclusions (and if they don\u2019t love it \u2014 listen to them on how to improve it so that they do). We don\u2019t always get so lucky as to have this sort of instantaneous user feedback from our direct users.\nArchitecture\nI briefly mentioned the scalable nature of design systems. This is exactly why it\u2019s important to develop a solid architecture early on in the process. Build your design system with growth and scalability in mind. What happens if your company acquires a new product? What happens when it develops a new market segment? How can you make sure there\u2019s room for customization and growth?\nA few things we\u2019ve found helpful include:\nNamespacing\nUse namespacing to ensure that the system doesn\u2019t collide with existing styles if applying it to an existing codebase. This means prefixing every element in the system to indicate that this class is a part of the design system. To ensure that you don\u2019t break parts of the existing build (which may have styled base elements), you can namespace the entire system inside of a parent class. Sass makes this easy with its nested structure. \nThis kind of namespacing wouldn\u2019t be necessary per se on new projects, but it is definitely useful when integrating new and old styles.\nSemantic Versioning\nI\u2019ve used Semantic Versioning on all of the design systems I\u2019ve ever worked on. Semantic versioning uses a system of Major.Minor.Patch for any updates. You can then tag released on Github with versioned updates and ensure that someone\u2019s app won\u2019t break unintentionally when there is an update, if they are anchored to a specific version (which they should be).\nWe also use this semantic versioning as a link with our design system assets at DigitalOcean (i.e. Sketch library) to keep them in sync, with the same version number corresponding to both Sketch and code.\nOur design system is served as a node module, but is also provided as a series of built assets using our CDN for quick prototyping and one-off projects. For these built assets, we run a deploy script that automatically creates folders for each release, as well as a latest folder if someone wanted the always-up-to-date version of the design system. \nSo, semantic versioning for the system I\u2019m currently building is what links our design system node module assets, sketch library assets, and statically built file assets.\nThe reason we have so many ways of consuming our design system is to make adoption easier and to reduce friction.\nFriction\nA while ago, I posed the question of why design systems become outdated and unused, and a major conclusion I drew from the conversation was:\n\n\u201cIf it\u2019s harder for people to use than their current system, people just won\u2019t use it\u201d\n\nYou have to make your design system the path of least resistance, lowering cognitive overhead of development, not adding to it. This is vital. A design system is intended to make development much more efficient, enforce a consistent style across sites, and allow for the developer to not worry as much about small decisions like naming and HTML semantics. These are already sorted out for them, meaning they can focus on building product.\nBut if your design system is complicated and over-engineered, they may find it frustrating to use and go back to what they know, even if its not the best solution. If you\u2019re a Sass expert, and base your system on complex mixins and functions, you better hope your user (the developer) is also a Sass expert, or wants to learn. This is often not the case, however. You need to talk to your audience.\nWith the DigitalOcean design system, we provide a few options:\nOption 1\nUsers can implement the component library into a development environment and use Sass, select just the components they want to include, and extend the system using a hook-based system. This is the most performant and extensible output. Only the components that are called upon are included, and they can be easily extended using mixins.\nBut as noted earlier, not everyone wants to work this way (including Sass a dependency and potentially needing to set up a build system for it and learn a new syntax). There is also the user who just wants to throw a link onto their page and have it look nice, and thats where our versioned built assets come in.\nOption 2\nWith Option 2, users pull in links that are served via a CDN that contain JS, CSS, and our SVG icon library. The code is a bit bigger than the completely customized version, but often this isn\u2019t the aim when people are using Option 2.\nReducing friction for adoption should be a major goal of your design system rollout.\nConclusion\nHaving a design system is really beneficial to any product, especially as it grows. In order to have an effective system, it\u2019s important to primarily always keep your user in mind and garner support from your entire company. Once you have support and acceptance, this system will flourish and grow. Make sure someone is responsible for it, and make sure its built with a solid foundation from the start which will be carefully maintained toward the future. Good luck, and happy holidays!", "year": "2017", "author": "Una Kravets", "author_slug": "unakravets", "published": "2017-12-14T00:00:00+00:00", "url": "https://24ways.org/2017/why-design-systems-fail/", "topic": "process"} {"rowid": 193, "title": "Web Content Accessibility Guidelines\u2014for People Who Haven't Read Them", "contents": "I\u2019ve been a huge fan of the Web Content Accessibility Guidelines 2.0 since the World Wide Web Consortium (W3C) published them, nine years ago. I\u2019ve found them practical and future-proof, and I\u2019ve found that they can save a huge amount of time for designers and developers. You can apply them to anything that you can open in a browser. My favourite part is when I use the guidelines to make a website accessible, and then attend user-testing and see someone with a disability easily using that website.\nToday, the United Nations International Day of Persons with Disabilities, seems like a good time to re-read Laura Kalbag\u2019s explanation of why we should bother with accessibility. That should motivate you to devour this article.\nIf you haven\u2019t read the Web Content Accessibility Guidelines 2.0, you might find them a bit off-putting at first. The editors needed to create a single standard that countries around the world could refer to in legislation, and so some of the language in the guidelines reads like legalese. The editors also needed to future-proof the guidelines, and so some terminology\u2014such as \u201ctime-based media\u201d and \u201cprogrammatically determined\u201d\u2014can sound ambiguous. The guidelines can seem lengthy, too: printing the guidelines, the Understanding WCAG 2.0 document, and the Techniques for WCAG 2.0 document would take 1,200 printed pages.\nThis festive season, let\u2019s rip off that legalese and ambiguous terminology like wrapping paper, and see\u2014in a single article\u2014what gifts the Web Content Accessibility Guidelines 2.0 editors have bestowed upon us.\nCan your users perceive the information on your website?\nThe first guideline has criteria that help you prevent your users from asking \u201cWhat the **** is this thing here supposed to be?\u201d\n1.1.1 Text is the most accessible format for information. Screen readers\u2014such as the \u201cVoiceOver\u201d setting on your iPhone or the \u201cTalkBack\u201d app on your Android phone\u2014understand text better than any other format. The same applies for other assistive technology, such as translation apps and Braille displays. So, if you have anything on your webpage that\u2019s not text, you must add some text that gives your user the same information. You probably know how to do this already; for example:\n\nfor images in webpages, put some alternative text in an alt attribute to tell your user what the image conveys to the user;\nfor photos in tweets, add a description to make the images accessible;\nfor Instagram posts, write a caption that conveys the photo\u2019s information.\n\nThe alternative text should allow the user to get the same information as someone who can see the image. For websites that have too many images for someone to add alternative text to, consider how machine learning and Dynamically Generated Alt Text might\u2014might\u2014be appropriate.\nYou can probably think of a few exceptions where providing text to describe an image might not make sense. Remember I described these guidelines as \u201cpractical\u201d? They cover all those exceptions:\n\nUser interface controls such as buttons and text inputs must have names or labels to tell your user what they do.\nIf your webpage has video or audio (more about these later on!), you must\u2014at least\u2014have text to tell the user what they are.\nMaybe your webpage has a test where your user has to answer a question about an image or some audio, and alternative text would give away the answer. In that case, just describe the test in text so your users know what it is.\nIf your webpage features a work of art, tell your user the experience it evokes.\nIf you have to include a Captcha on your webpage\u2014and please avoid Captchas if at all possible, because some users cannot get past them\u2014you must include text to tell your user what it is, and make sure that it doesn\u2019t rely on only one sense, such as vision.\nIf you\u2019ve included something just as decoration, you must make sure that your user\u2019s assistive technology can ignore it. Again, you probably know how to do this. For example, you could use CSS instead of HTML to include decorative images, or you could add an empty alt attribute to the img element. (Please avoid that recent trend where developers add empty alt attributes to all images in a webpage just to make the HTML validate. You\u2019re better than that.)\n\n(Notice that the guidelines allow you to choose how to conform to them, with whatever technology you choose. To make your website conform to a guideline, you can either choose one of the techniques for WCAG 2.0 for that guideline or come up with your own. Choosing a tried-and-tested technique usually saves time!)\n1.2.1 If your website includes a podcast episode, speech, lecture, or any other recorded audio without video, you must include a transcription or some other text to give your user the same information. In a lot of cases, you might find this easier than you expect: professional transcription services can prove relatively inexpensive and fast, and sometimes a speaker or lecturer can provide the speech or lecture notes that they read out word-for-word. Just make sure that all your users can get the same information and the same results, whether they can hear the audio or not. For example, David Smith and Marco Arment always publish episode transcripts for their Under the Radar podcast. \nSimilarly, if your website includes recorded video without audio\u2014such as an animation or a promotional video\u2014you must either use text to detail what happens in the video or include an audio version. Again, this might work out easier then you perhaps fear: for example, you could check to see whether the animation started life as a list of instructions, or whether the promotional video conveys the same information as the \u201cAbout Us\u201d webpage. You want to make sure that all your users can get the same information and the same results, whether they can see that video or not.\n1.2.2 If your website includes recorded videos with audio, you must add captions to those videos for users who can\u2019t hear the audio. Professional transcription services can provide you with time-stamped text in caption formats that YouTube supports, such as .srt and .sbv. You can upload those to YouTube, so captions appear on your videos there. YouTube can auto-generate captions, but the quality varies from impressively accurate to comically inaccurate. If you have a text version of what the people in the video said\u2014such as the speech that a politician read or the bedtime story that an actor read\u2014you can create a transcript file in .txt format, without timestamps. YouTube then creates captions for your video by synchronising that text to the audio in the video. If you host your own videos, you can ask a professional transcription service to give you .vtt files that you can add to a video element\u2019s track element\u2014or you can handcraft your own. (A quick aside: if your website has more videos than you can caption in a reasonable amount of time, prioritise the most popular videos, the most important videos, and the videos most relevant to people with disabilities. Then make sure your users know how to ask you to caption other videos as they encounter them.)\n1.2.3 If your website has recorded videos that have audio, you must add an \u201caudio description\u201d narration to the video to describe important visual details, or add text to the webpage to detail what happens in the video for users who cannot see the videos. (I like to add audio files from videos to my Huffduffer account so that I can listen to them while commuting.) Maybe your home page has a video where someone says, \u201cI\u2019d like to explain our new TPS reports\u201d while \u201cBill Lumbergh, division Vice President of Initech\u201d appears on the bottom of the screen. In that case, you should add an audio description to the video that announces \u201cBill Lumbergh, division Vice President of Initech\u201d, just before Bill starts speaking. As always, you can make life easier for yourself by considering all of your users, before the event: in this example, you could ask the speaker to begin by saying, \u201cI\u2019m Bill Lumbergh, division Vice President of Initech, and I\u2019d like to explain our new TPS reports\u201d\u2014so you won\u2019t need to spend time adding an audio description afterwards. \n1.2.4 If your website has live videos that have some audio, you should get a stenographer to provide real-time captions that you can include with the video. I\u2019ll be honest: this can prove tricky nowadays. The Web Content Accessibility Guidelines 2.0 predate YouTube Live, Instagram live Stories, Periscope, and other such services. If your organisation creates a lot of live videos, you might not have enough resources to provide real-time captions for each one. In that case, if you know the contents of the audio beforehand, publish the contents during the live video\u2014or failing that, publish a transcription as soon as possible.\n1.2.5 Remember what I said about the recorded videos that have audio? If you can choose to either add an audio description or add text to the webpage to detail what happens in the video, you should go with the audio description.\n1.2.6 If your website has recorded videos that include audio information, you could provide a sign language version of the audio information; some people understand sign language better than written language. (You don\u2019t need to caption a video of a sign language version of audio information.)\n1.2.7 If your website has recorded videos that have audio, and you need to add an audio description, but the audio doesn\u2019t have enough pauses for you to add an \u201caudio description\u201d narration, you could provide a separate version of that video where you have added pauses to fit the audio description into.\n1.2.8 Let\u2019s go back to the recorded videos that have audio once more! You could add text to the webpage to detail what happens in the video, so that people who can neither read captions nor hear dialogue and audio description can use braille displays to understand your video.\n1.2.9 If your website has live audio, you could get a stenographer to provide real-time captions. Again, if you know the contents of the audio beforehand, publish the contents during the live audio or publish a transcription as soon as possible.\n(Congratulations on making it this far! I know that seems like a lot to remember, but keep in mind that we\u2019ve covered a complex area: helping your users to understand multimedia information that they can\u2019t see and/or hear. Grab a mince pie to celebrate, and let\u2019s keep going.)\n1.3.1 You must mark up your website\u2019s content so that your user\u2019s browser, and any assistive technology they use, can understand the hierarchy of the information and how each piece of information relates to the rest. Once again, you probably know how to do this: use the most appropriate HTML element for each piece of information. Mark up headings, lists, buttons, radio buttons, checkboxes, and links with the most appropriate HTML element. If you\u2019re looking for something to do to keep you busy this Christmas, scroll through the list of the elements of HTML. Do you notice any elements that you didn\u2019t know, or that you\u2019ve never used? Do you notice any elements that you could use on your current projects, to mark up the content more accurately? Also, revise HTML table advanced features and accessibility, how to structure an HTML form, and how to use the native form widgets\u2014you might be surprised at how much you can do with just HTML! Once you\u2019ve mastered those, you can make your website much more usable for your all of your users.\n1.3.2 If your webpage includes information that your user has to read in a certain order, you must make sure that their browser and assistive technology can present the information in that order. Don\u2019t rely on CSS or whitespace to create that order visually. Check that the order of the information makes sense when CSS and whitespace aren\u2019t formatting it. Also, try using the Tab key to move the focus through the links and form widgets on your webpage. Does the focus go where you expect it to? Keep this in mind when using order in CSS Grid or Flexbox.\n1.3.3 You must not presume that your users can identify sensory characteristics of things on your webpage. Some users can\u2019t tell what you\u2019ve positioned where on the screen. For example, instead of asking your users to \u201cChoose one of the options on the left\u201d, you could ask them to \u201cChoose one of our new products\u201d and link to that section of the webpage.\n1.4.1 You must not rely on colour as the only way to convey something to your users. Some of your users can\u2019t see, and some of your users can\u2019t distinguish between colours. For example, if your webpage uses green to highlight the products that your shop has in stock, you could add some text to identify those products, or you could group them under a sub-heading.\n1.4.2 If your webpage automatically plays a sound for more than 3 seconds, you must make sure your users can stop the sound or change its volume. Don\u2019t rely on your user turning down the volume on their computer; some users need to hear the screen reader on their computer, and some users just want to keep listening to whatever they were listening before your webpage interrupted them!\n1.4.3 You should make sure that your text contrasts enough with its background, so that your users can read it. Bookmark Lea Verou\u2019s Contrast Ratio calculator now. You can enter the text colour and background colour as named colours, or as RGB, RGBa, HSL, or HSLa values. You should make sure that:\n\nnormal text that set at 24px or larger has a ratio of at least 3:1;\nbold text that set at 18.75px or larger has a ratio of at least 3:1;\nall other text has a ratio of at least 4\u00bd:1.\n\nYou don\u2019t have to do this for disabled form controls, decorative stuff, or logos\u2014but you could!\n1.4.4 You should make sure your users can resize the text on your website up to 200% without using their assistive technology\u2014and still access all your content and functionality. You don\u2019t have to do this for subtitles or images of text.\n1.4.5 You should avoid using images of text and just use text instead. In 1998, Jeffrey Veen\u2019s first Hot Design Tip said, \u201cText is text. Graphics are graphics. Don\u2019t confuse them.\u201d Now that you can apply powerful CSS text-styling properties, use CSS Grid to precisely position text, and choose from thousands of web fonts (Jeffrey co-founded Typekit to help with this), you pretty much never need to use images of text. The guidelines say you can use images of text if you let your users specify the font, size, colour, and background of the text in the image of text\u2014but I\u2019ve never seen that on a real website. Also, this doesn\u2019t apply to logos.\n1.4.6 Let\u2019s go back to colour contrast for a second. You could make your text contrast even more with its background, so that even more of your users can read it. To do that, use Lea Verou\u2019s Contrast Ratio calculator to make sure that:\n\nnormal text that is 24px or larger has a ratio of at least 4\u00bd:1;\nbold text that 18.75px or larger has a ratio of at least 4\u00bd:1;\nall other text has a ratio of at least 7:1.\n\n1.4.7 If your website has recorded speech, you could make sure there are no background sounds, or that your users can turn off any background sounds. If that\u2019s not possible, you could make sure that any background sounds that last longer than a couple of seconds are at least four times quieter than the speech. This doesn\u2019t apply to audio Captchas, audio logos, singing, or rapping. (Yes, these guidelines mention rapping!)\n1.4.8 You could make sure that your users can reformat blocks of text on your website so they can read them better. To do this, make sure that your users can:\n\nspecify the colours of the text and the background, and\nmake the blocks of text less than 80-characters wide, and \nalign text to the left (or right for right-to-left languages), and \nset the line height to 150%, and \nset the vertical distance between paragraphs to 1\u00bd times the line height of the text, and \nresize the text (without using their assistive technology) up to 200% and still not have to scroll horizontally to read it.\n\nBy the way, when you specify a colour for text, always specify a colour for its background too. Don\u2019t rely on default background colours!\n1.4.9 Let\u2019s return to images of text for a second. You could make sure that you use them only for decoration and logos.\nCan users operate the controls and links on your website?\nThe second guideline has criteria that help you prevent your users from asking, \u201cHow the **** does this thing work?\u201d\n2.1.1 You must make sure that you users can carry out all of your website\u2019s activities with just their keyboard, without time limits for pressing keys. (This doesn\u2019t apply to drawing or anything else that requires a pointing device such as a mouse.) Again, if you use the most appropriate HTML element for each piece of information and for each form element, this should prove easy.\n2.1.2 You must make sure that when the user uses the keyboard to focus on some part of your website, they can then move the focus to some other part of your webpage without needing to use a mouse or touch the screen. If your website needs them to do something complex before they can move the focus elsewhere, explain that to your user. These \u201ckeyboard traps\u201d have become rare, but beware of forms that move focus from one text box to another as soon as they receive the correct number of characters.\n2.1.3 Let\u2019s revisit making sure that you users can carry out all of your website\u2019s activities with just their keyboard, without time limits for pressing keys. You could make sure that your user can do absolutely everything on your website with just the keyboard.\n2.2.1 Sometimes people need more time than you might expect to complete a task on your website. If any part of your website imposes a time limit on a task, you must do at least one of these: \n\nlet your users turn off the time limit before they encounter it; or\nlet your users increase the time limit to at least 10 times the default time limit before they encounter it; or\nwarn your users before the time limit expires and give them at least 20 seconds to extend it, and let them extend it at least 10 times.\n\nRemember: these guidelines are practical. They allow you to enforce time limits for real-time events such as auctions and ticket sales, where increasing or extending time limits wouldn\u2019t make sense. Also, the guidelines allow you to enforce a maximum time limit of 20 hours. The editors chose 20 hours because people need to go to sleep at some stage. See? Practical!\n2.2.2 In my experience, this criterion remains the least well-known\u2014even though some users can only use websites that conform to it. If your website presents content alongside other content that can distract users by automatically moving, blinking, scrolling, or updating, you must make sure that your users can:\n\npause, stop, or hide the other content if it\u2019s not essential and lasts more than 5 seconds; and\npause, stop, hide, or control the frequency of the other content if it automatically updates.\n\nIt\u2019s OK if your users miss live information such as stock price updates or football scores; you can\u2019t do anything about that! Also, this doesn\u2019t apply to animations such as progress bars that you put on a website to let all users know that the webpage isn\u2019t frozen.\n(If this one sounds complex, just add a pause button to anything that might distract your users.)\n2.2.3 Let\u2019s go back to time limits on tasks on your website. You could make your website even easier to use by removing all time limits except those on real-time events such as auctions and ticket sales. That would mean your user wouldn\u2019t need to interact with a timer at all.\n2.2.4 You could let your users turn off all interruptions\u2014server updates, promotions, and so on\u2014apart from any emergency information.\n2.2.5 This is possibly my favourite of these criteria! After your website logs your user out, you could make sure that when they log in again, they can continue from where they were without having lost any information. Do that, and you\u2019ll be on everyone\u2019s Nice List this Christmas.\n2.3.1 You must make sure that nothing flashes more than three times a second on your website, unless you can make sure that the flashes remain below the acceptable general flash and red flash thresholds\u2026\n2.3.2 \u2026or you could just make sure that nothing flashes more than three times per second on your website. This is usually an easier goal.\n2.4.1 You must make sure that your users can jump past any blocks of content, such as navigation menus, that are repeated throughout your website. You know the drill here: using HTML\u2019s sectioning elements such as header, nav, main, aside, and footer allows users with assistive technology to go straight to the content they need, and adding \u201cSkip Navigation\u201d links allows everyone to get to your main content faster.\n2.4.2 You must add a proper title to describe each webpage\u2019s topic. Your webpage won\u2019t even validate without a title element, so make it a useful one.\n2.4.3 If your users can focus on links and native form widgets, you must make sure that they can focus on elements in an order that makes sense.\n2.4.4 You must make sure that your users can understand the purpose of a link when they read:\n\nthe text of the link; or\nthe text of the paragraph, list item, table cell, or table header for the cell that contains the link; or\nthe heading above the link.\n\nYou don\u2019t have to do that for games and quizzes.\n2.4.5 You should give your users multiple ways to find any webpage within a set of webpages. Add site-wide search and a site map and you\u2019re done!\nThis doesn\u2019t apply for a webpage that is part of a series of actions (like a shopping cart and checkout flow) or to a webpage that is a result of a series of actions (like a webpage confirming that the user has bought what was in the shopping cart).\n2.4.6 You should help your users to understand your content by providing:\n\nheadings that describe the topics of you content;\nlabels that describe the purpose of the native form widgets on the webpage.\n\n2.4.7 You should make sure that users can see which element they have focussed on. Next time you use your website, try hitting the Tab key repeatedly. Does it visually highlight each item as it moves focus to it? If it doesn\u2019t, search your CSS to see whether you\u2019ve applied outline: 0; to all elements\u2014that\u2019s usually the culprit. Use the :focus pseudo-element to define how elements should appear when they have focus.\n2.4.8 You could help your user to understand where the current webpage is located within your website. Add \u201cbreadcrumb navigation\u201d and/or a site map and you\u2019re done.\n2.4.9 You could make links even easier to understand, by making sure that your users can understand the purpose of a link when they read the text of the link. Again, you don\u2019t have to do that for games and quizzes.\n2.4.10 You could use headings to organise your content by topic. \nCan users understand your content?\nThe third guideline has criteria that help you prevent your users from asking, \u201cWhat the **** does this mean?\u201d\n3.1.1 Let\u2019s start this section with the criterion that possibly takes the least time to implement; you must make sure that the user\u2019s browser can identify the main language that your webpage\u2019s content is written in. For a webpage that has mainly English content, use . \n3.1.2 You must specify when content in another language appears in your webpage, like so: I wish you a Joyeux No\u00ebl.. You don\u2019t have to do this for proper names, technical terms, or words that you can\u2019t identify a language for. You also don\u2019t have to do it for words from a different language that people consider part of the language around those words; for example, Come to our Christmas rendezvous! is OK.\n3.1.3 You could make sure that your users can find out the meaning of any unusual words or phrases, including idioms like \u201cstocking filler\u201d or \u201cBah! Humbug!\u201d and jargon such as \u201cVoiceOver\u201d and \u201cTalkBack\u201d. Provide a glossary or link to a dictionary.\n3.1.4 You could make sure that your users can find out the meaning of any abbreviation. For example, VoiceOver pronounces \u201cXmas\u201d as \u201cSmas\u201d instead of \u201cChristmas\u201d. Using the abbr element and linking to a glossary can help. (Interestingly, VoiceOver pronounces \u201cabbr\u201d as \u201cabbreviation\u201d!)\n3.1.5 Do your users need to be able to read better than a typically educated nine-year-old, to read your content (apart from proper names and titles)? If so, you could provide a version that doesn\u2019t require that level of reading ability, or you could provide images, videos, or audio to explain your content. (You don\u2019t have to add captions or audio description to those videos.)\n3.1.6 You could make sure that your users can access the pronunciation of any word in your content if that word\u2019s meaning depends on its pronunciation. For example, the word \u201cclose\u201d could have one of two meanings, depending on pronunciation, in a phrase such as, \u201cReady for Christmas? Close now!\u201d\n3.2.1 Some users need to focus on elements to access information about them. You must make sure that focusing on an element doesn\u2019t trigger any major changes, such as opening a new window, focusing on another element, or submitting a form.\n3.2.2 Webpages are easier for users when the controls do what they\u2019re supposed to do. Unless you have warned your users about it, you must make sure that changing the value of a control such as a text box, checkbox, or drop-down list doesn\u2019t trigger any major changes, such as opening a new window, focusing on another element, or submitting a form.\n3.2.3 To help your users to find the content they want on each webpage, you should put your navigation elements in the same place on each webpage. (This doesn\u2019t apply when your user has changed their preferences or when they use assistive technology to change how your content appears.) \n3.2.4 When a set of webpages includes things that have the same functionality on different webpages, you should name those things consistently. For example, don\u2019t use the word \u201cSearch\u201d for the search box on one webpage and \u201cFind\u201d for the search box on another webpage within that set of webpages.\n3.2.5 Let\u2019s go back to major changes, such as a new window opening, another element taking focus, or a form being submitted. You could make sure that they only happen when users deliberately make them happen, or when you have warned users about them first. For example, you could give the user a button for updating some content instead of automatically updating that content. Also, if a link will open in a new window, you could add the words \u201copens in new window\u201d to the link text.\n3.3.1 Users make mistakes when filling in forms. Your website must identify each mistake to your user, and must describe the mistake to your users in text so that the user can fix it. One way to identify mistakes reliably to your users is to set the aria-invalid attribute to true in the element that has a mistake. That makes sure that users with assistive technology will be alerted about the mistake. Of course, you can then use the [aria-invalid=\"true\"] attribute selector in your CSS to visually highlight any such mistakes. Also, look into how certain attributes of the input element such as required, type, and list can help prevent and highlight mistakes.\n3.3.2 You must include labels or instructions (and possibly examples) in your website\u2019s forms, to help your users to avoid making mistakes. \n3.3.3 When your user makes a mistake when filling in a form, your webpage should suggest ways to fix that mistake, if possible. This doesn\u2019t apply in scenarios where those suggestions could affect the security of the content.\n3.3.4 Whenever your user submits information that:\n\nhas legal or financial consequences; or\naffects information that they have previously saved in your website; or\nis part of a test\n\n\u2026you should make sure that they can:\n\nundo it; or\ncorrect any mistakes, after your webpage checks their information; or\nreview, confirm, and correct the information before they finally submit it.\n\n3.3.5 You could help prevent your users from making mistakes by providing obvious, specific help, such as examples, animations, spell-checking, or extra instructions.\n3.3.6 Whenever your user submits any information, you could make sure that they can:\n\nundo it; or\ncorrect any mistakes, after your webpage checks their information; or\nreview, confirm, and correct the information before they finally submit it.\n\nHave you made your website robust enough to work on your users\u2019 browsers and assistive technologies?\nThe fourth and final guideline has criteria that help you prevent your users from asking, \u201cWhy the **** doesn\u2019t this work on my device?\u201d\n4.1.1 You must make sure that your website works as well as possible with current and future browsers and assistive technology. Prioritise complying with web standards instead of relying on the capabilities of currently popular devices and browsers. Web developers didn\u2019t expect their users to be unwrapping the Wii U Browser five years ago\u2014who knows what browsers and assistive technologies our users will be unwrapping in five years\u2019 time? Avoid hacks, and use the W3C Markup Validation Service to make sure that your HTML has no errors.\n4.1.2 If you develop your own user interface components, you must make their name, role, state, properties, and values available to your user\u2019s browsers and assistive technologies. That should make them almost as accessible as standard HTML elements such as links, buttons, and checkboxes.\n\u201c\u2026and a partridge in a pear tree!\u201d\n\u2026as that very long Christmas song goes. We\u2019ve covered a lot in this article\u2014because your users have a lot of different levels of ability. Hopefully this has demystified the Web Content Accessibility Guidelines 2.0 for you. Hopefully you spotted a few situations that could arise for users on your website, and you now know how to tackle them. \nTo start applying what we\u2019ve covered, you might like to look at Sarah Horton and Whitney Quesenbery\u2019s personas for Accessible UX. Discuss the personas, get into their heads, and think about which aspects of your website might cause problems for them. See if you can apply what we\u2019ve covered today, to help users like them to do what they need to do on your website.\nHow to know when your website is perfectly accessible for everyone\nLOL! There will never be a time when your website becomes perfectly accessible for everyone. Don\u2019t aim for that. Instead, aim for regularly testing and making your website more accessible.\nWeb Content Accessibility Guidelines (WCAG) 2.1\nThe W3C hope to release the Web Content Accessibility Guidelines (WCAG) 2.1 as a \u201crecommendation\u201d (that\u2019s what the W3C call something that we should start using) by the middle of next year. Ten years may seem like a long time to move from version 2.0 to version 2.1, but consider the scale of the task: the editors have to update the guidelines to cover all the new ways that people interact with new technologies, while keeping the guidelines backwards-compatible. Keep an eye out for 2.1!\nYou\u2019ll go down in history\nOne last point: I\u2019ve met a surprising number of web designers and developers who do great work to make their websites more accessible without ever telling their users about it. Some of your potential customers have possibly tried and failed to use your website in the past. They probably won\u2019t try again unless you let them know that things have improved. A quick Twitter search for your website\u2019s name alongside phrases like \u201cassistive technology\u201d, \u201cdoesn\u2019t work\u201d, or \u201c#fail\u201d can let you find frustrated users\u2014so you can tell them about how you\u2019re making your website more accessible. Start making your websites work better for everyone\u2014and please, let everyone know.", "year": "2017", "author": "Alan Dalton", "author_slug": "alandalton", "published": "2017-12-03T00:00:00+00:00", "url": "https://24ways.org/2017/wcag-for-people-who-havent-read-them/", "topic": "code"} {"rowid": 207, "title": "Want to Break Out of Comparison Syndrome? Do a Media Detox", "contents": "\u201cComparison is the thief of joy.\u201d\n\u2014Theodore Roosevelt\n\nI grew up in an environment of perpetual creativity and inventiveness. My father Dennis built and flew experimental aircraft as a hobby. During my entire childhood, there was an airplane fuselage in the garage instead of a car. My mother Deloria was a self-taught master artisan who could quickly acquire any skills that it took to work with fabric and weaving. She could sew any garment she desired, and was able to weave intricate wall hangings just by looking at a black and white photos in magazines. My older sister Diane blossomed into a consummate fine artist who drew portraits with uncanny likeness, painted murals, and studied art and architecture. In addition, she loved good food and had a genius for cooking and baking, which converged in her creating remarkable art pieces out of cake that were incredibly delicious to boot. Yes. This was the household in which I grew up.\nWhile there were countless positives to being surrounded by people who were compelled to create, there was also a downside to it. I incessantly compared myself to my parents and older sister and always found myself lacking.\nIt wasn\u2019t a fair comparison, but tell that to a sensitive kid who wanted to fit in to her family by being creative as well. From my early years throughout my teens, I convinced myself that I would never understand how to build an airplane or at least be as proficient with tools as my father, the aeronautical engineer. Even though my sister was six years older than I was, I lamented that I would never be as good a visual artist as she was. And I marveled at my mother\u2019s seemingly magical ability to make and tailor clothes and was certain that I would never attain her level of mastery.\nThis habit of comparing myself to others grew over the years, continuing to subtly and effectively undermine my sense of self. I had almost reached an uneasy truce with my comparison habit when social media happened.\nAs an early adopter of Twitter, I loved staying connected to people I met at tech conferences. However, as I began to realize my aspirations of being an author and a speaker, Twitter became a dreaded hall of mirrors where I only saw distorted reflections of my lack of achievement in other people\u2019s success. Every person announcing a publishing deal caused me to drown under waves of envy over the imagined size of her or his book advance as I struggled to pay my mortgage. Every announcement I read of someone speaking at a conference led to thoughts of, \u201cI wish I were speaking at that conference \u2013 I must not be good enough to be invited.\u201d Twitter was fertile ground for my Inner Critic to run rampant.\nOne day in 2011, my comparisons to people who I didn\u2019t even know rose to a fever pitch. I saw a series of tweets that sparked a wave of self-loathing so profound that I spent the day sobbing and despondent, as I chastised myself for being a failure. I had fallen into the deep pit of Comparison Syndrome, and to return to anything close to being productive took a day or two of painstakingly clawing my way out.\nComparison Syndrome Takes Deficiency Anxiety to Eleven\nDo any of these scenarios ring true?\n\nYou frequently feel like a failure when viewing the success of others.\nYou feel dispirited and paralyzed in moving forward with your own work because it will never measure up to what others have done.\nYou discount your ideas because you fear that they aren\u2019t as good as those of your colleagues or industry peers.\n\nAre you making yourself miserable by thinking thoughts like these?\n\n\u201cI\u2019m surrounded by people who are so good at what they do, how can I possibly measure up?\u201d\n\u201cCompared to my partner, my musical ability is childish \u2013 and music is no longer fun.\u201d\n\u201cWhy haven\u2019t I accomplished more by now? My peers are so much more successful than I am.\u201d\n\nUnenviable Envy\nMany people use the terms envy and jealousy interchangeably, but they are two distinct emotions. Jealousy is the fear of losing someone to a perceived rival: a threat to an important relationship and the parts of the self that are served by that relationship. Jealousy is always about the relationship between three people. Envy is wanting what another has because of a perceived shortcoming on your part. Envy is always based on a social comparison to another.1\nEnvy is a reaction to the feeling of lacking something. Envy always reflects something we feel about ourselves, about how we are somehow deficient in qualities, possessions, or success.2 It\u2019s based on a scarcity mentality: the idea that there is only so much to go around, and another person got something that should rightfully be yours.3\nA syndrome is a condition characterized by a set of associated symptoms. I call it Comparison Syndrome because a perceived deficiency of some sort \u2013 in talent, accomplishments, success, skills, etc. \u2013 is what initially sparks it. While at the beginning you may merely feel inadequate, the onset of the syndrome will bring additional symptoms. Lack of self-trust and feelings of low self-worth will fuel increased thoughts of not-enoughness and blindness to your unique brilliance. If left unchecked, Deficiency Anxieties can escalate to full-blown Comparison Syndrome: a form of the Inner Critic in which we experience despair from envy and define ourselves as failures in light of another\u2019s success.\nThe irony is that when we focus so much on what we lack, we can\u2019t see what we have in abundance that the other person doesn\u2019t have. And in doing so, we block what is our birthright: our creative expression. Envy shackles our creativity, keeps us trapped in place, and prevents forward movement. The Inner Critic in the form of Comparison Syndrome caused by envy blocks us from utilizing our gifts, seeing our path clearly, and reveling in our creative power.\nIn order to keep a grip on reality and not fall into the abyss of Comparison Syndrome, we\u2019ll quell the compulsion to compare before it happens: we will free the mental bandwidth to turn our focus inward so we can start to see ourselves clearly. \nBreak the Compulsion to Compare\n\n\u201cWhy compare yourself with others? No one in the entire world can do a better job of being you than you.\u201d\n\u2014 Krystal Volney, poet and author\n\nAt some point in time, many of us succumb to moments of feeling that we are lacking and comparing ourselves unfavorably to others. As social animals, much of our self-definition comes from comparison with others. This is how our personalities develop. We learn this behavior as children, and we grow up being compared to siblings, peers, and kids in the media. Because of this, the belief that somehow, someway, we aren\u2019t good enough becomes deeply ingrained. The problem is that whenever we deem ourselves to be \u201cless than,\u201d our self-esteem suffers. This creates a negative feedback loop where negative thoughts produce strong emotions that result in self-defeating behaviors that beget more negative thoughts.\nCouple this cycle with the messages we get from society that only \u201cgifted\u201d people are creative, and it\u2019s no wonder that many of us will fall down the rabbit hole of Comparison Syndrome like I did on that fated day while reading tweets. Comparing ourselves to others is worse than a zero-sum game, it\u2019s a negative-sum game. No one wins, our self-esteem deteriorates, and our creative spark dies out.\nWith effort, we can break the compulsion to compare and stop the decline into Comparison Syndrome by turning the focus of comparison inward to ourselves and appreciating who we\u2019ve become. But first, we need to remove some of the instances that trigger our comparisons in the first place.\nArrest: Stop the Triggers\n\n\u201cRight discipline consists, not in external compulsion, but in the habits of mind which lead spontaneously to desirable rather than undesirable activities.\u201d\n\u2014 Bertrand Russell, philosopher\n\nAfter my Twitter post meltdown, I knew had to make a change. While bolstering my sense of self was clearly a priority, I also knew that my ingrained comparison habit was too strong to resist and that I needed to instill discipline. I decided then and there to establish boundaries with social media.\nFirst, to maintain my sanity, I took this on as my mantra:\n\u201cI will not compare myself to strangers on the Internet or acquaintances on Facebook.\u201d\nIf you find yourself sliding down the slippery slope of social media comparison, you can do the same: repeat this mantra to yourself to help put on the brakes.\nSecond, in order to reduce my triggers, I stopped reading the tweets of the people I followed. However, I continued to be active on Twitter through sharing information, responding to mentions, crowdsourcing, and direct messaging people. It worked! The only time I\u2019d start to slip into darkness were the rare instances when I would break my rules and look at my Twitstream.\nBut we can do even more than calm ourselves with helpful mantras. Just like my example of modifying my use of Twitter, and more recently, of separating myself from Facebook, you can get some distance from the media that activates your comparison reflex and start creating the space for other habits that are more supportive to your being to take its place.\nCreative Dose: Trigger-free and Happy\nPurpose: To stop comparison triggers in their tracks\nMindfulness is a wonderful tool, but sometimes you have to get hardcore and do as much as you can to eliminate distractions so that you can first hear your own thoughts in order to know which ones you need to focus on.\nHere are four steps to becoming trigger-free and happier.\nStep 1: Make a List\nPay attention when you get the most triggered and hooked.\nIs it on Twitter, Facebook, Instagram, or Snapchat?\nIs it YouTube, TV shows, or magazines?\nMake list of your top triggers.\nMy primary trigger is:______________________________________\nMy second trigger is:______________________________________\nMy third trigger is:______________________________________\nNow that you have your list, you need to get an idea just how often you\u2019re getting triggered.\nStep 2: Monitor\nIt\u2019s easy to think that we should track our activity on the computer, but these days, it\u2019s no longer our computer use that is the culprit: most of us access social media and news from our phones. Fortunately, there are apps that will track the usage for both.\nSeeing just how much you consume media from either or both will show you how much of an accomplice the use of devices is to your comparison syndrome, and how much you need to modify your behavior accordingly.\nFor tracking both computer use and tablet use, this app works great:\n\nRescueTime.com tracks app usage and sends a productivity report at the end of the week via email.\n\nFor your phone, there are many for either platform.4 Although I recommend fully researching what is available and will work for you best, here are a few recommendations:\n\nFor both platforms: Offtime, Breakfree, Checky\nFor Android only: Flipd, AppDetox, QualityTime, Stay On Task\nFor iOS only: Moment\n\nInstall your app of choice, and see what you find. How much time are you spending on sites or apps that compel you to compare?\nStep 3: Just Say No\nNow that you know what your triggers are and how much you\u2019re exposing yourself to them, it\u2019s time to say No.\nPut yourself on a partial social media and/or media detox for a specified period of time; consider even going for a full media detox.5 I recommend starting with one month.\nTo help you to fully commit, I recommend writing this down and posting it where you can see it.\nI, ___________________, commit to avoiding my comparison triggers \nof ___________________, ___________________, and ___________________ \nfor the period of ___________________, \nstarting on ___________________ and ending on ___________________ .\nTo help you out, I\u2019ve created a social media detox commitment sheet for you.\nStep 4: Block\nWhen I decided to reduce my use of Twitter and Facebook to break my comparison habit, initially I tried to rely solely on self-discipline, which was only moderately successful. Then I realized that I could use the power of technology to help. Don\u2019t think you have to rely upon sheer willpower to block, or at least limit, your exposure to known triggers. If your primary access to the items that cause you to compare yourself to others is via computers and other digitalia, use these devices to help maintain your mental equilibrium.\nHere are some apps and browser extensions that you can use during your media detox to help keep yourself sane and stay away from sites that could throw you into a comparison tailspin.\nThese apps are installed onto your computer:\n\nRescueTime.com works on both computer and mobile devices, and does a lot more than just prevent you from going to sites that will ruin your concentration, it will also track your apps usage and give you a productivity report at the end of the week.\nFocus and SelfControl (Mac-only)\n\nTo go right to the source and prevent you from visiting sites through your browser, there are browser extensions.\nNot only can you put in the list of the URLs that are your points of weakness, but you can also usually set the times of the day you need the self-control the most.\n\nGoogle Chrome: StayFocusd, Strict Workflow, and Website Blocker\nFirefox: Idderall and Leechblock\nSafari: WasteNoTime and MindfulBrowsing\nEdge (or Explorer): Unfortunately, there are currently no website blocking extensions for these browsers.\n\nI currently use a browser extension to block me from using Facebook between 9:00am \u2013 6:00pm. It\u2019s been a boon for my sanity: I compare tons less. A bonus is that it\u2019s been terrific for my productivity as well. \nWhich tool will you use for your media detox time? Explore them all and then settle upon the one(s) that will work the best for you. Install it and put it to work.\nDespite the tool, you will still need to exercise discipline. Resist the urge to browse Instagram or Facebook while waiting for your morning train. You can do it!\nStep 5: Relax\nInstead of panicking from FOMO (Fear of Missing Out), take comfort from this thought: what you don\u2019t know won\u2019t affect you. Start embracing JOMO (Joy of Missing Out), and the process of rebuilding and maintaining your sanity.\nWhat will you do instead of consuming the media that compels you to\ncompare? Here are some ideas:\n\nRead a book \nGo for a walk \nHave dinner with a friend \nGo watch a movie \nLearn how to play the harmonica \nTake an improv class\n\nReally, you could do anything. And depending on how much of your time and attention you\u2019ve devoted to media, you could be recapturing a lot of lost moments, minutes, hours, and days.\nStep 6: Reconnect\nUse your recovered time and attention to focus on your life and reconnect with your true value-driven goals, higher aspirations, and activities that you\u2019ve always wanted to do.\n\nThis article is an excerpt from the book Banish Your Inner Critic by Denise Jacobs, and has been reprinted with permission. If you\u2019d like to read more, you can find the book on Amazon.\n\n\n\n\nShane Parrish, \u201cMental Model: Bias from Envy and Jealousy,\u201d Farnam Street, accessed February 9, 2017.\u00a0\u21a9\n\n\nParrish, \u201cMental Model: Bias from Envy and Jealousy.\u201d\u00a0\u21a9\n\n\nHenrik Edberg, \u201cHow to Overcome Envy: 5 Effective Tips,\u201d Practical Happiness Advice That Works | The Positivity Blog, accessed February 9, 2017.\u00a0\u21a9\n\n\nJeremy Golden, \u201c6 Apps to Stop Your Smartphone Addiction,\u201d Inc.com, accessed February 10, 2017.\u00a0\u21a9\n\n\nEmily Nickerson, \u201cHow to Silence the Voice of Doubt,\u201d The Muse, accessed February 8, 2017.\u00a0\u21a9", "year": "2017", "author": "Denise Jacobs", "author_slug": "denisejacobs", "published": "2017-12-19T00:00:00+00:00", "url": "https://24ways.org/2017/do-a-media-detox/", "topic": "process"} {"rowid": 215, "title": "Teach the CLI to Talk Back", "contents": "The CLI is a daunting tool. It\u2019s quick, powerful, but it\u2019s also incredibly easy to screw things up in \u2013 either with a mistyped command, or a correctly typed command used at the wrong moment. This puts a lot of people off using it, but it doesn\u2019t have to be this way.\nIf you\u2019ve ever interacted with Slack\u2019s Slackbot to set a reminder or ask a question, you\u2019re basically using a command line interface, but it feels more like having a conversation. (My favourite Slack app is Lunch Train which helps with the thankless task of herding colleagues to a particular lunch venue on time.)\nSame goes with voice-operated assistants like Alexa, Siri and Google Home. There are even games, like Lifeline, where you interact with a stranded astronaut via pseudo SMS, and KOMRAD where you chat with a Soviet AI.\nI\u2019m not aiming to build an AI here \u2013 my aspirations are a little more down to earth. What I\u2019d like is to make the CLI a friendlier, more forgiving, and more intuitive tool for new or reluctant users. I want to teach it to talk back.\nInteractive command lines in the wild\nIf you\u2019ve used dev tools in the command line, you\u2019ve probably already used an interactive prompt \u2013 something that asks you questions and responds based on your answers. Here are some examples:\nYeoman\nIf you have Yeoman globally installed, running yo will start a command prompt.\n\nThe prompt asks you what you\u2019d like to do, and gives you options with how to proceed. Seasoned users will run specific commands for these options rather than go through this prompt, but it\u2019s a nice way to start someone off with using the tool.\nnpm\nIf you\u2019re a Node.js developer, you\u2019re probably familiar with typing npm init to initialise a project. This brings up prompts that will populate a package.json manifest file for that project.\n\nThe alternative would be to expect the user to craft their own package.json, which is more error-prone since it\u2019s in JSON format, so something as trivial as an extraneous comma can throw an error.\nSnyk\nSnyk is a dev tool that checks for known vulnerabilities in your dependencies. Running snyk wizard in the CLI brings up a list of all the known vulnerabilities, and gives you options on how to deal with it \u2013 such as patching the issue, applying a fix by upgrading the problematic dependency, or ignoring the issue (you are then prompted for a reason).\n\nThese decisions get mapped to the manifest and a .snyk file, and committed into the repo so that the settings are the same for everyone who uses that project.\nI work at Snyk, and running the wizard is what made me think about building my own personal assistant in the command line to help me with some boring, repetitive tasks.\nWriting your own\nSomething I do a lot is add bookmarks to styleguides.io \u2013 I pull down the entire repo, copy and paste a template YAML file, and edit to contents. Sometimes I get it wrong and break the site. So I\u2019ve been putting together a tool to help me add bookmarks.\nIt\u2019s called bookmarkbot \u2013 it\u2019s a personal assistant squirrel called Mark who will collect and bury your bookmarks for safekeeping.*\n\n*Fortunately, this metaphor also gives me a charming excuse for any situation where bookmarks sometimes get lost \u2013 it\u2019s not my poorly-written code, honest, it\u2019s just being realistic because sometimes squirrels forget where they buried things!\nWhen you run bookmarkbot, it will ask you for some information, and save that information as a Markdown file in YAML format.\nFor this demo, I\u2019m going to use a Node.js package called inquirer, which is a well supported tool for creating command line prompts. I like it because it has a bunch of different question types; from input, which asks for some text back, confirm which expects a yes/no response, or a list which gives you a set of options to choose from. You can even nest questions, Choose Your Own Adventure style.\nPrerequisites\n\nNode.js\nnpm\nRubyGems (Only if you want to go as far as serving a static site for your bookmarks, and you want to use Jekyll for it)\n\nDisclaimer\nBear in mind that this is a really simplified walkthrough. It doesn\u2019t have any error states, and it doesn\u2019t handle the situation where we save a file with the same name. But it gets you in a good place to start building out your tool.\nLet\u2019s go!\nCreate a new folder wherever you keep your projects, and give it an awesome name (I\u2019ve called mine bookmarks and put it in the Sites directory because I\u2019m unimaginative). Now cd to that directory. \ncd Sites/bookmarks\nLet\u2019s use that example I gave earlier, the trusty npm init.\nnpm init\nPop in the information you\u2019d like to provide, or hit ENTER to skip through and save the defaults. Your directory should now have a package.json file in it. Now let\u2019s install some of the dependencies we\u2019ll need.\nnpm install --save inquirer\nnpm install --save slugify\nNext, add the following snippet to your package.json to tell it to run this file when you run npm start.\n\"scripts\": {\n \u2026\n \"start\": \"node index.js\"\n}\nThat index.js file doesn\u2019t exist yet, so let\u2019s create it in the root of our folder, and add the following:\n// Packages we need\nvar fs = require('fs'); // Creates our file (part of Node.js so doesn't need installing)\nvar inquirer = require('inquirer'); // The engine for our questions prompt\nvar slugify = require('slugify'); // Will turn a string into a usable filename\n\n// The questions\nvar questions = [\n {\n type: 'input',\n name: 'name',\n message: 'What is your name?',\n },\n];\n\n// The questions prompt\nfunction askQuestions() {\n\n // Ask questions\n inquirer.prompt(questions).then(answers => {\n\n // Things we'll need to generate the output\n var name = answers.name;\n\n // Finished asking questions, show the output\n console.log('Hello ' + name + '!');\n\n });\n\n}\n\n// Kick off the questions prompt\naskQuestions();\nThis is just some barebones where we\u2019re including the inquirer package we installed earlier. I\u2019ve stored the questions in a variable, and the askQuestions function will prompt the user for their name, and then print \u201cHello \u201d in the console.\nEnough setup, let\u2019s see some magic. Save the file, go back to the command line and run npm start.\n\nExtending what we\u2019ve learnt\nAt the moment, we\u2019re just saving a name to a file, which isn\u2019t really achieving our goal of saving bookmarks. We don\u2019t want our tool to forget our information every time we talk to it \u2013 we need to save it somewhere. So I\u2019m going to add a little function to write the output to a file.\nSaving to a file\nCreate a folder in your project\u2019s directory called _bookmarks. This is where the bookmarks will be saved.\nI\u2019ve replaced my questions array, and instead of asking for a name, I\u2019ve extended out the questions, asking to be provided with a link and title (as a regular input type), a list of tags (using inquirer\u2019s checkbox type), and finally a description, again, using the input type.\nSo this is how my code looks now:\n// Packages we need\nvar fs = require('fs'); // Creates our file\nvar inquirer = require('inquirer'); // The engine for our questions prompt\nvar slugify = require('slugify'); // Will turn a string into a usable filename\n\n// The questions\nvar questions = [\n {\n type: 'input',\n name: 'link',\n message: 'What is the url?',\n },\n {\n type: 'input',\n name: 'title',\n message: 'What is the title?',\n },\n {\n type: 'checkbox',\n name: 'tags',\n message: 'Would you like me to add any tags?',\n choices: [\n { name: 'frontend' },\n { name: 'backend' },\n { name: 'security' },\n { name: 'design' },\n { name: 'process' },\n { name: 'business' },\n ],\n },\n {\n type: 'input',\n name: 'description',\n message: 'How about a description?',\n },\n];\n\n// The questions prompt\nfunction askQuestions() {\n\n // Say hello\n console.log('\ud83d\udc3f Oh, hello! Found something you want me to bookmark?\\n');\n\n // Ask questions\n inquirer.prompt(questions).then((answers) => {\n\n // Things we'll need to generate the output\n var title = answers.title;\n var link = answers.link;\n var tags = answers.tags + '';\n var description = answers.description;\n var output = '---\\n' +\n 'title: \"' + title + '\"\\n' +\n 'link: \"' + link + '\"\\n' +\n 'tags: [' + tags + ']\\n' +\n '---\\n' + description + '\\n';\n\n // Finished asking questions, show the output\n console.log('\\n\ud83d\udc3f All done! Here is what I\\'ve written down:\\n');\n console.log(output);\n\n // Things we'll need to generate the filename\n var slug = slugify(title);\n var filename = '_bookmarks/' + slug + '.md';\n\n // Write the file\n fs.writeFile(filename, output, function () {\n console.log('\\n\ud83d\udc3f Great! I have saved your bookmark to ' + filename);\n });\n\n });\n\n}\n\n// Kick off the questions prompt\naskQuestions();\nThe output is formatted into YAML metadata as a Markdown file, which will allow us to turn it into a static HTML file using a build tool later. Run npm start again and have a look at the file it outputs.\n\nGetting confirmation\nBefore the user makes critical changes, it\u2019s good to verify those changes first. We\u2019re going to add a confirmation step to our tool, before writing the file. More seasoned CLI users may favour speed over a \u201chey, can you wait a sec and just check this is all ok\u201d step, but I always think it\u2019s worth adding one so you can occasionally save someone\u2019s butt.\nSo, underneath our questions array, let\u2019s add a confirmation array.\n// Packages we need\n\u2026\n// The questions\n\u2026\n\n// Confirmation questions\nvar confirm = [\n {\n type: 'confirm',\n name: 'confirm',\n message: 'Does this look good?',\n },\n];\n\n// The questions prompt\n\u2026\n\nAs we\u2019re adding the confirm step before the file gets written, we\u2019ll need to add the following inside the askQuestions function:\n// The questions prompt\nfunction askQuestions() {\n // Say hello\n \u2026\n // Ask questions\n inquirer.prompt(questions).then((answers) => {\n \u2026\n // Things we'll need to generate the output\n \u2026\n // Finished asking questions, show the output\n \u2026\n\n // Confirm output is correct\n inquirer.prompt(confirm).then(answers => {\n\n // Things we'll need to generate the filename\n var slug = slugify(title);\n var filename = '_bookmarks/' + slug + '.md';\n\n if (answers.confirm) {\n // Save output into file\n fs.writeFile(filename, output, function () {\n console.log('\\n\ud83d\udc3f Great! I have saved your bookmark to ' +\n filename);\n });\n } else {\n // Ask the questions again\n console.log('\\n\ud83d\udc3f Oops, let\\'s try again!\\n');\n askQuestions();\n }\n\n });\n\n });\n}\n\n// Kick off the questions prompt\naskQuestions();\nNow run npm start and give it a go!\n\nTyping y will write the file, and n will take you back to the start. Ideally, I\u2019d store the answers already given as defaults so the user doesn\u2019t have to start from scratch, but I want to keep this demo simple.\nServing the files\nNow that your bookmarking tool is successfully saving formatted Markdown files to a folder, the next step is to serve those files in a way that lets you share them online. The easiest way to do this is to use a static-site generator to convert your YAML files into HTML, and pop them all on one page. Now, you\u2019ve got a few options here and I don\u2019t want to force you down any particular path, as there are plenty out there \u2013 it\u2019s just a case of using the one you\u2019re most comfortable with.\nI personally favour Jekyll because of its tight integration with GitHub Pages \u2013 I don\u2019t want to mess around with hosting and deployment, so it\u2019s really handy to have my bookmarks publish themselves on my site as soon as I commit and push them using Git.\nI\u2019ll give you a very brief run-through of how I\u2019m doing this with bookmarkbot, but I recommend you read my Get Started With GitHub Pages (Plus Bonus Jekyll) guide if you\u2019re unfamiliar with them, because I\u2019ll be glossing over some bits that are already covered in there.\nSetting up a build tool\nIf you haven\u2019t already, install Jekyll and Bundler globally through RubyGems. Jekyll is our static-site generator, and Bundler is what we use to install Ruby dependencies.\ngem install jekyll bundler\nIn my project folder, I\u2019m going to run the following which will install the Jekyll files we\u2019ll need to build our listing page. I\u2019m using --force, otherwise it will complain that the directory isn\u2019t empty.\njekyll new . --force\nIf you check your project folder, you\u2019ll see a bunch of new files. Now run the following to start the server:\nbundle exec jekyll serve\nThis will build a new directory called _site. This is where your static HTML files have been generated. Don\u2019t touch anything in this folder because it will get overwritten the next time you build.\nNow that serve is running, go to http://127.0.0.1:4000/ and you\u2019ll see the default Jekyll page and know that things are set up right. Now, instead, we want to see our list of bookmarks that are saved in the _bookmarks directory (make sure you\u2019ve got a few saved). So let\u2019s get that set up next.\nOpen up the _config.yml file that Jekyll added earlier. In here, we\u2019re going to tell it about our bookmarks. Replace everything in your _config.yml file with the following:\ntitle: My Bookmarks\ndescription: These are some of my favourite articles about the web.\nmarkdown: kramdown\nbaseurl: /bookmarks # This needs to be the same name as whatever you call your repo on GitHub.\ncollections:\n - bookmarks\nThis will make Jekyll aware of our _bookmarks folder so that we can call it later. Next, create a new directory and file at _layouts/home.html and paste in the following.\n\n\n\n \n {{site.title}}\n \n\n\n\n\n

{{site.title}}

\n

{{site.description}}

\n\n \n\n\n\n\nRestart Jekyll for your config changes to kick in, and go to the url it provides you (probably http://127.0.0.1:4000/bookmarks, unless you gave something different as your baseurl).\n\nIt\u2019s a decent start \u2013 there\u2019s a lot more we can do in this area but now we\u2019ve got a nice list of all our bookmarks, let\u2019s get it online!\nIf you want to use GitHub Pages to host your files, your first step is to push your project to GitHub. Go to your repository and click \u201csettings\u201d. Scroll down to the section labelled \u201cGitHub Pages\u201d, and from here you can enable it. Select your master branch, and it will provide you with a url to view your published pages.\n\nWhat next?\nNow that you\u2019ve got a framework in place for publishing bookmarks, you can really go to town on your listing page and make it your own. First thing you\u2019ll probably want to do is add some CSS, then when you\u2019ve added a bunch of bookmarks, you\u2019ll probably want to have some filtering in place for the tags, perhaps extend the types of questions that you ask to include an image (if you\u2019re feeling extra-fancy, you could just ask for a url and pull in metadata from the site itself). Maybe you\u2019ve got an idea that doesn\u2019t involve bookmarks at all.\nYou could use what you\u2019ve learnt to build a place where you can share quotes, a list of your favourite restaurants, or even Christmas gift ideas.\nHere\u2019s one I made earlier\n\nMy demo, bookmarkbot, is on GitHub, and I\u2019ve reused a lot of the code from styleguides.io. Feel free to grab bits of code from there, and do share what you end up making!", "year": "2017", "author": "Anna Debenham", "author_slug": "annadebenham", "published": "2017-12-11T00:00:00+00:00", "url": "https://24ways.org/2017/teach-the-cli-to-talk-back/", "topic": "code"} {"rowid": 216, "title": "Styling Components - Typed CSS With Stylable", "contents": "There\u2019s been a lot of debate recently about how best to style components for web apps so that styles don\u2019t accidentally \u2018leak\u2019 out of the component they\u2019re meant for, or clash with other styles on the page.\nElaborate CSS conventions have sprung up, such as OOCSS, SMACSS, BEM, ITCSS, and ECSS. These work well, but they are methodologies, and require everyone in the team to know them and follow them, which can be a difficult undertaking across large or distributed teams.\nOthers just give up on CSS and put all their styles in JavaScript. Now, I\u2019m not bashing JS, especially so close to its 22nd birthday, but CSS-in-JS has problems of its own. Browsers have 20 years experience in optimising their CSS engines, so JavaScript won\u2019t be as fast as using real CSS, and in any case, this requires waiting for JS to download, parse, execute then render the styles.\nThere\u2019s another problem with CSS-in-JS, too. Since Responsive Web Design hit the streets, most designers no longer make comps in Photoshop or its equivalents; instead, they write CSS. Why hire an expensive design professional and require them to learn a new way of doing their job? \nA recent thread on Twitter asked \u201cWhat\u2019s your biggest gripe with CSS-in-JS?\u201d, and the replies were illuminating: \u201cAlways having to remember to camelCase properties then spending 10min pulling hair out when you do forget\u201d, \u201cthe cryptic domain-specific languages that each of the frameworks do just ever so slightly differently\u201d, \u201cWhen I test look and feel in browser, then I copy paste from inspector, only to have to re-write it as a JSON object\u201d, \u201cLack of linting, autocomplete, and css plug-ins for colors/ incrementing/ etc\u201d. \nIf you\u2019re a developer, and you\u2019re still unconvinced, I challenge you to let designers change the font in your IDE to Zapf Chancery and choose a new colour scheme, simply because they like it better. Does that sound like fun? Will that boost your productivity? Thought not.\nSome chums at Wix Engineering and I wanted to see if we could square this circle. Wix-hosted sites have always used CSS-in-JS (the concept isn\u2019t new; it was in Netscape 4!) but that was causing performance problems. Could we somehow devise a method of extending CSS (like SASS and LESS do) that gives us styles that are guaranteed not to leak or clash, that is compatible with code editors\u2019 autocompletion, and which could be pre-processed at build time to valid, cross-browser, static CSS?\nAfter a few months and a few proofs of concept later (drumroll), yes \u2013 we could! We call it Stylable.\nIntroducing Stylable\nStylable is a CSS pre-processor, like SASS or LESS. It uses CSS syntax so all your development tools will work. At build time, the Stylable CSS extensions are transpiled to flat, valid, cross-browser vanilla CSS for maximum performance. There\u2019s quite a bit to it, and this is a short article, so let\u2019s look at the basic concepts.\nComponents all the way down\nStylable is designed for component-based systems. Imagine you have a Gallery component. Within that, there is a Navigation component (for example, containing a \u2018next\u2019, \u2018previous\u2019, \u2018show all thumbnails\u2019, and \u2018show all albums\u2019 controls), and within that there are NavButton components. Each component is discrete, used elsewhere in the system in different contexts, perhaps maintained by different team members or even different organisations \u2014 you can use Stylable to add a typed interface to non-Stylable component libraries, as well as using it to build an app from scratch.\nFirstly, Stylable will automatically namespace styles so they only apply inside that component, by rewriting them at build time with a unique (but human-readable) prefix. So, for example,\n
might be re-written as
. \nSo far, so BEM-like (albeit without the headache of remembering a convention). But what else can it do?\nCustom pseudo-elements\nAn important feature of Stylable is the ability to reach into a component and style it from the outside, without having to know about its internal structure. Let\u2019s see the guts of a simple JSX button component in the file button.jsx:\nrender () {\n return (\n \n );\n}\n(Note:className is the JSX way of setting a class on an element; this example uses React, but Stylable itself is framework-agnostic.)\nI style it using a Stylable stylesheet (the .st.css suffix tells the preprocessor to process this file):\n/* button.st.css */\n\n/* note that the root class is automatically placed on the root HTML \nelement by Stylable React integration */\n.root {\n background: #b0e0e6;\n}\n\n.icon {\n display: block; \n height: 2em;\n background-image: url('./assets/btnIcon.svg');\n}\n\n.label {\n font-size: 1.2em;\n color: rgba(81, 12, 68, 1.0);\n}\nNote that Stylable allows all the CSS that you know and love to be included. As Drew Powers wrote in his review:\n\nwith Stylable, you get CSS, and every part of CSS. This seems like a \u201cduh\u201d observation, but this is significant if you\u2019ve ever battled with a CSS-in-JS framework over a lost or \u201chacky\u201d implementation of a basic CSS feature.\n\nI can import my Button component into another component - this time, panel.jsx:\n/* panel.jsx */\nimport * as React from 'react';\nimport {properties, stylable} from 'wix-react-tools';\nimport {Button} from '../button';\nimport style from './panel.st.css';\n\nexport const Panel = stylable(style)(() => (\n
\n
\n));\nIn panel.st.css: \n/* panel.st.css */\n:import {\n -st-from: './button.st.css';\n -st-default: Button;\n}\n\n/* cancelBtn is of type Button */\n.cancelBtn {\n -st-extends: Button;\n background: cornflowerblue;\n}\n\n/* targets the label of