{"rowid": 295, "title": "Internet of Stranger Things", "contents": "This year I\u2019ve been running a workshop about using JavaScript and Node.js to work with all different kinds of electronics on the Raspberry Pi. So especially for 24 ways I\u2019m going to show you how I made a very special Raspberry Pi based internet connected project! And nothing says Christmas quite like a set of fairy lights connected to another dimension1.\nWhat you\u2019ll see\nYou can rig up the fairy lights in your home, with the scrawly letters written under each one. The people from the other side (i.e. the internet) will be able to write messages to you from their browser in real time. In fact why not try it now; check this web page. When you click the lights in your browser, my lights (and yours) will turn on and off in real life! (There may be a queue if there are lots of people accessing it, hit the \u201cSend a message\u201d button and wait your turn.)\n\n\n\n\nIt\u2019s all done with JavaScript, using Node.js running on both the Raspberry Pi and on the server. I\u2019m using WebSockets to communicate in real time between the browser, server and Raspberry Pi.\nWhat you\u2019ll need\n\nRaspberry Pi any of the following models: Zero (will need straight male header pins soldered2 and Micro USB OTG adaptor), A+, B+, 2, or 3\nMicro SD card at least 4Gb Class 10 speed3\nMicro USB power supply at least 2A\nUSB Wifi dongle (unless you have a Pi 3 - that has wifi built in). \nAddressable fairy lights\nLogic level shifter (with pins soldered unless you want to do it!)\nBreadboard\nJumper wires (3x male to male and 4x female to male)\n\nOptional but recommended\n\nBase board to hold the Pi and Breadboard (often comes with a breadboard!)\n\nFind links for where to buy all of these items that goes along with this tutorial. The total price should be around $1004.\nSetting up the Raspberry Pi\nYou\u2019ll need to install the SD card for the Raspberry Pi. You\u2019ll find a link to download a disk image on the support document, ready-made with the Raspbian version of Linux, along with Node.js and all the files you need. Download it and write it to the SD card using the fantastic free software Etcher5. \nNext up you have to configure the wifi details on the SD card. If you plug the card into your computer you should see a drive called BOOT. There\u2019s a text file on there called wpa_supplicant.conf. Open it up in your favourite text editor and replace mywifi and mypassword with your wifi details6.\nnetwork={\n ssid=\"mywifi\"\n psk=\"mypassword\"\n}\nSave the file, eject the card from your computer and plug it into the Raspberry Pi. \nIf you have a base board or holder for the Raspberry Pi, attach it now. Then connect the wifi USB dongle7 and power supply, but don\u2019t plug it in yet!\nWiring!\nTime to wire everything up! \nFirst of all, push the Logic Level Converter into the middle of the breadboard:\n\nLogic Level Converter\nThe logic level converter may be labelled differently from the one in the diagram but the pins are usually exactly the same internally. I would just make sure the pins marked HV (High Voltage) are on the bottom and LV (Low Voltage) are on the top. \n\nRaspberry Pi pins only output 3.3v but the lights need 5v. That\u2019s why we need the logic level converter in there to boost up the signal.\nConnect the first two wires between the Raspberry Pi pins and the breadboard:\n\nNote that the pins on the Raspberry Pi are male, so you need a female to male jumper wire to connect between them and the breadboard. The colours don\u2019t have to match but it\u2019s easier to follow (and check) if you use the same ones as in the diagram. \n\nThen the next two:\n\nThis is what you should have so far:\n\nLights\nNow to connect the lights! My ones have a connector with three holes in it that I can push jumper wires into, and hopefully yours will too! So I used the male-to-male jumper wires to connect them to the breadboard.\n\n\n\nMake sure that you connect the right end of the lights, mine has a male connector at the wrong end so it\u2019s impossible to do this, but double check. \nAlso make sure that the holes in the light connector are the same as mine. To do this, follow the wires from the connector to the first light and look at the circuit board inside. You should just about be able to make out the connections labelled + (sometimes 5V, V+ or VCC), GND (or \u2018-\u2019 or G) and DI (sometimes DIN for data in).\n\nYou can just about make out the +, DI and GND on this picture. Note that on the other side of the board there is a DO for data out - that\u2019s what takes the data along to the chip in the next light. Make sure that you\u2019re plugging into the data-in and not the data-out! \nThat\u2019s it! Everything\u2019s plugged in and ready to go! But before you plug power into your Pi, double check all your wires and make sure they\u2019re exactly right! You could damage your Raspberry Pi if it is not wired correctly. So triple check!\n\nThe Moment of Truth!\nPlug in the Raspberry Pi and wait around a minute or two for it to boot up. If all is well, the lights should strobe rainbow colours for one second - that\u2019s your confirmation that it\u2019s connected to my WebSocket server and ready to receive messages from the upside-down! \n\nHowever, if the first light in the string is pulsing red, it means that you\u2019re not connected to the internet. So check the Troubleshooting section of the support document. If it\u2019s pulsing green then you\u2019re connected to the internet but can\u2019t connect to my server. It must have gone down. Sorry! The code will keep trying so leave it running and maybe it\u2019ll come back up. \nRig up the lights!\nFix the lights up on the wall however you want, pins, nails, tape. I\u2019ve used cable clips. Just be careful! I\u2019m using a 50 light string so I\u2019ve programmed it to use the lights at the end for the letters. That way I have just under half the string to extend down to the floor where I can keep the Raspberry Pi. \nCheck the photo here to see how the lights line up, note that there are spare unused lights in-between each row:\n\nNow visit lights.seb.ly and you\u2019ll see this : \n\nIf you\u2019re the only one online you\u2019ll have direct connection to the lights and any letter you click on will light up both in the browser and in real life. If there are other people there, you\u2019ll need to click the button to join the queue and wait your turn. \nHow it works - the geeky details!\nElectronics:\nThe pins on the Raspberry Pi are known as GPIO pins, general-purpose input/output. You can connect a wide variety of electronic components to them, LED lights, buttons, switches, and sensors. You can turn the power to the pins on and off using Node.js (or Python, if you prefer). \nAddressable LEDs or \u201cNeopixels\u201d\nWe\u2019re only using one GPIO pin on the Raspberry Pi (the other connections are 5V, 3.3V and ground) and that single pin is controlling all of the lights in the string. The code turns the pin on and off really fast in strictly timed morse-code-like dots and dashes to transmit binary data. The chips attached to each LED decode the binary and adjust the output to the LED accordingly. That chip then sends the data on to the next light in the string. \nThe chips on each light are the WS2811, part of the WS281x family that come in a multitude of different form factors and are often packaged with tiny LEDs in a single component. They are commonly referred to as Neopixels8 and I used them on my Laser Light Synths project.\nNeopixels with the chip and the LED all in one - it\u2019s the white square shaped component and the darker square inside is the chip. These are only 5mm wide!\nA Laser Light Synth! Covered with around 800 super bright neopixels!\nLogic Level Converter\nThe logic level converter is a really cheap and easy way to change the level from 3.3v to 5v and back again. You must be careful that you do not connect 5v into a GPIO pin or you will most likely damage the Raspberry Pi processor chip. \nPower\nNeopixels can often draw a lot of current so you need to be careful how you power them. I\u2019ve measured the current draw from the string to be less than 800mA so you should be fine wired directly to the 5V output. But if you use more lights or have them all on really bright at once, you\u2019ll need to use a separate 5V power supply. If you want to learn more, check out Adafruit\u2019s Neopixel Uberguide. \nNode.js\nThere are two Node.js apps running here, one on the Raspberry Pi and one on my server. You can see the code on my GitHub at github.com/sebleedelisle/stranger-lights for the Raspberry Pi and github.com/sebleedelisle/stranger-lights-server for the server. And they\u2019re hosted on npm as stranger-lights and stranger-lights-server. \nThe server side code sets up a standard web server to deliver the HTML for the web interface. It also sets up a WebSocket server that allows for real-time communication between the browser and the server. This server code also manages the queue and who is in control of the lights at any given time.\nWebSockets\nI\u2019m using the excellent Socket.io library to manage the WebSocket connection. Both the browser and the Raspberry Pi Node.js app connects to my WebSocket server. \nWhen you click on a letter in the browser, a message is sent to the server, which forwards it to the connected Raspberry Pi clients and also all the web browsers9. \nThe Raspberry Pi code\nThe Node.js app runs automatically on startup, and I made this happen by adding this to the /etc/rc.local file: \nnode /home/pi/strangerthings/client.js > /dev/null &\nAnything in the rc.local file gets executed when the Pi boots up and this line of code runs the Node.js app and routes its output to nowhere (ie /dev/null). The & means that it runs it in the background and doesn\u2019t hold up the boot process. \nWorking with the Raspberry Pi headless\nYou might know that when a computer has no screen or keyboard, you would refer to it as \u201crunning headless\u201d. So just like most web servers, you need to configure it over the network with ssh10. If you\u2019re on a mac you can find your Pi on the network through the name raspberrypi.local11, otherwise you\u2019ll need to find its IP address. There\u2019s more on the guide to Remote Access instructions on the Raspberry Pi website. And if you\u2019re very new to the terminal, I highly recommend this great online Linux command line tutorial.\nImprovements\nThis is quite an early experiment and I\u2019m sure I\u2019ll discover lots of optimisations over the next few weeks, especially if the server gets a proper hammering today! But there are a few things you can do. Obviously I\u2019ve just rigged up my lights with Post-it notes. It\u2019d be a lot nicer to get a paint brush and try to recreate the Winona-in-a-manic-state text style. \nWhere next?\nFinding quality resources about Node.js for electronics on the Pi can be somewhat hit and miss, but this is getting better all the time. Alternatively I am thinking about running some online courses, please let me know if that\u2019s something you\u2019d be interested in, or sign up to my mailing list at st4i.com. \nThere are many many more resources for the Raspberry Pi with Python (gpiozero is a good place to start), so if that language works for you, you\u2019ll be spoilt for choice! \nAlso take a look at Arduino - it\u2019s an incredibly popular platform for electronics and the internet is literally bursting with resources. \nI hope you enjoyed this little foray into the world of JavaScript electronics on the Raspberry Pi! If you get this working at home please let me know! Tweet me at @seb_ly. \n\n\n\n\nNot a particularly original idea, but I don\u2019t think I\u2019ve seen anyone do it quite like this before, ie using WebSockets, and Node.js on a Raspberry Pi. Other examples: Internet of Stranger Things, Strangerlights.com, and loads of examples on Instructables\u00a0\u21a9\ufe0e\n\n\nVideo guide to soldering pins on to a Pi Zero and further soldering advice from Adafruit\u00a0\u21a9\ufe0e\n\n\nSlower cards will work but performance may suffer\u00a0\u21a9\ufe0e\n\n\nOr \u00a35,000 in UK money. Sorry, Brexit joke :)\u00a0\u21a9\ufe0e\n\n\nYou will need a card reader on your computer - most micro SD cards come with an adaptor that fits standard SD slots. \u00a0\u21a9\ufe0e\n\n\nSSID and password should be all that you need but you can see all the config options on this wpa supplicant guide\u00a0\u21a9\ufe0e\n\n\nRaspberry Pi Zero will require the OTG to USB adaptor to attach the wifi dongle\u00a0\u21a9\ufe0e\n\n\nThanks to Adafruit who invented the term neopixels so we don\u2019t have to refer to them as WS281x any more!\u00a0\u21a9\ufe0e\n\n\nSo you can see other people sending messages in the browser\u00a0\u21a9\ufe0e\n\n\nssh is short for Secure Shell and is a way to connect to a remote computer and type in it just like you would in the terminal.\u00a0\u21a9\ufe0e\n\n\nYou can change this default hostname using raspi-config\u00a0\u21a9\ufe0e", "year": "2016", "author": "Seb Lee-Delisle", "author_slug": "sebleedelisle", "published": "2016-12-01T00:00:00+00:00", "url": "https://24ways.org/2016/internet-of-stranger-things/", "topic": "code"} {"rowid": 290, "title": "Creating a Weekly Research Cadence", "contents": "Working on a product team, it\u2019s easy to get hyper-focused on building features and lose sight of your users and their daily challenges. User research can be time-consuming to set up, so it often becomes ad-hoc and irregular, only performed in response to a particular question or concern. But without frequent touch points and opportunities for discovery, your product will stagnate and become less and less relevant. Setting up an efficient cadence of weekly research conversations will re-focus your team on user problems and provide a steady stream of insights for product development.\nAs my team transitioned into a Lean process earlier this year, we needed a way to get more feedback from users in a short amount of time. Our users are internet marketers\u2014always busy and often difficult to reach. Scheduling research took days of emailing back and forth to find mutually agreeable times, and juggling one-off conversations made it difficult to connect with more than one or two people per week. The slow pace of research was allowing additional risk to creep into our product development.\nI wanted to find a way for our team to test ideas and validate assumptions sooner and more often\u2014but without increasing the administrative burden of scheduling. The solution: creating a regular cadence of research and testing that required a minimum of effort to coordinate. \nSetting up a weekly user research cadence accelerated our learning and built momentum behind strategic experiments. By dedicating time every week to talk to a few users, we made ongoing research a painless part of every weekly sprint. But increasing the frequency of our research had other benefits as well. With only five working days between sessions, a weekly cadence forced us to keep our work small and iterative. Committing to testing something every week meant showing work earlier and more often than we might have preferred\u2014pushing us out of your comfort zone into a process of more rapid experimentation.\nBest of all, frequent conversations with users helped us become more customer-focused. After just a few weeks in a consistent research cadence, I noticed user feedback weaving itself through our planning and strategy sessions. Comments like \u201cRemember what Jenna said last week, about not being able to customize her lists?\u201d would pop up as frequent reference points to guide our decisions. As discussions become less about subjective opinions and more about responding to user needs, we saw immediate improvement in the quality of our solutions.\nEstablishing an efficient recruitment process\nThe key to creating a regular cadence of ongoing user research is an efficient recruitment and scheduling process\u2014along with a commitment to prioritize the time needed for research conversations. This is an invaluable tool for product teams (whether or not they follow a Lean process), but could easily be adapted for content strategy teams, agency teams, a UX team of one, or any other project that would benefit from short, frequent conversations with users. \nThe process I use requires a few hours of setup time at the beginning, but pays off in better learning and better releases over the long run. Almost any team could use this as a starting point and adapt it to their own needs.\nPick a dedicated time each week for research\nIn order to make research a priority, we started by choosing a time each week when everyone on the product team was available. Between stand-ups, grooming sessions, and roadmap reviews, it wasn\u2019t easy to do! Nevertheless, it\u2019s important to include as many people as possible in conversations with your users. Getting a second-hand summary of research results doesn\u2019t have the same impact as hearing someone describe their frustrations and concerns first-hand. The more people in the room to hear those concerns, the more likely they are to become priorities for your team.\nI blocked off 2 hours for research conversations every Thursday afternoon. We make this time sacred, and never schedule other meetings or work across those hours. \nDivide your time into several research slots\nAfter my weekly cadence was set, I divided the time into four 20-minute time slots. Twenty minutes is long enough for us to ask several open-ended questions or get feedback on a prototype, without being a burden on our users\u2019 busy schedules. Depending on your work, you may need schedule longer sessions\u2014but beware the urge to create blocks that last an hour or more. A weekly research cadence is designed to facilitate rapid, ongoing feedback and testing; it should force you to talk to users often and to keep your work small and iterative. Projects that require longer, more in-depth testing will probably need a dedicated research project of their own.\nI used the scheduling software Calendly to create interview appointments on a calendar that I can share with users, and customized the confirmation and reminder emails with information about how to access our video conferencing software. (Most of our research is done remotely, but this could be set up with details for in-person meetings as well.) Automating these emails and reminders took a little bit of time to set up, but was worth it for how much faster it made the process overall.\n\n\nInvite users to sign up for a time that\u2019s convenient for them\nWith a calendar set up and follow-up emails automated, it becomes incredibly easy to schedule research conversations. Each week, I send a short email out to a small group of users inviting them to participate, explaining that this is a chance to provide feedback that will improve our product or occasionally promoting the opportunity to get a sneak peek at new features we\u2019re working on. The email includes a link to the Calendly appointments, allowing users who are interested to opt in to a time that fits their schedule.\nSetting up appointments the first go around involved a bit of educated guessing. How many invitations would it take to fill all four of my weekly slots? How far in advance did I need to recruit users? But after a few weeks of trial and error, I found that sending 12-16 invitations usually allows me to fill all four interview slots. Our users often have meetings pop up at short notice, so we get the best results when I send the recruiting email on Tuesday, two days before my research block.\nIt may take a bit of experimentation to fine tune your process, but it\u2019s worth the effort to get it right. (The worst thing that\u2019s happened since I began recruiting this way was receiving emails from users complaining that there were no open slots available!) I can now fill most of an afternoon with back-to-back user research sessions just by sending just one or two emails each week, increasing our research pace while leaving plenty time to focus on discovery and design.\nGetting the most out of your research sessions\nAs you get comfortable with the rhythm of talking to users each week, you\u2019ll find more and more ways to get value out of your conversations. At first, you may prefer to just show work in progress\u2014such as mockups or a simple prototype\u2014and ask open-ended questions to measure user reaction. When you begin new projects, you may want to use this time to research behavior on existing features\u2014either watching participants as they use part of your product or asking them to give an account of a recent experience in your app. You may even want to run more abstracted Lean experiments, if that\u2019s the best way to validate the assumptions your team is working from.\nWhatever you do, plan some time a day or two later to come back together and review what you\u2019ve learned each week. Synthesizing research outcomes as a group will help keep your team in alignment and allow each person to highlight what they took away from each conversation. \nOver time, you may find that the pace of weekly user research becomes more exhausting than energizing, especially if the responsibility for scheduling and planning falls on just one person. Don\u2019t allow yourself to get burned out; a healthy research cadence should also include time to rest and reflect if the pace becomes too rapid to sustain. Take breaks as needed, then pick up the pace again as soon as you\u2019re ready.", "year": "2016", "author": "Wren Lanier", "author_slug": "wrenlanier", "published": "2016-12-02T00:00:00+00:00", "url": "https://24ways.org/2016/creating-a-weekly-research-cadence/", "topic": "ux"} {"rowid": 293, "title": "A Favor for Your Future Self", "contents": "We tend to think about the future when we build things. What might we want to be able to add later? How can we refactor this down the road? Will this be easy to maintain in six months, a year, two years? As best we can, we try to think about the what-ifs, and build our websites, systems, and applications with this lens. \nWe comment our code to explain what we knew at the time and how that impacted how we built something. We add to-dos to the things we want to change. These are all great things! Whether or not we come back to those to-dos, refactor that one thing, or add new features, we put in a bit of effort up front just in case to give us a bit of safety later.\nI want to talk about a situation that Past Alicia and Team couldn\u2019t even foresee or plan for. Recently, the startup I was a part of had to remove large sections of our website. Not just content, but entire pages and functionality. It wasn\u2019t a very pleasant experience, not only for the reason why we had to remove so much of what we had built, but also because it\u2019s the ultimate \u201cI really hope this doesn\u2019t break something else\u201d situation. It was a stressful and tedious effort of triple checking that the things we were removing weren\u2019t dependencies elsewhere. To be honest, we wouldn\u2019t have been able to do this with any amount of success or confidence without our test suite.\nWriting tests for code is one of those things that developers really, really don\u2019t want to do. It\u2019s one of the easiest things to cut in the development process, and there\u2019s often a struggle to have developers start writing tests in the first place. One of the best lessons the web has taught us is that we can\u2019t, in good faith, trust the happy path. We must make sure ourselves, and our users, aren\u2019t in a tough spot later on because we only thought of the best case scenarios.\nJavaScript\nRegardless of your opinion on whether or not everything needs to be built primarily with JavaScript, if you\u2019re choosing to build a JavaScript heavy app, you absolutely should be writing some combination of unit and integration tests.\nUnit tests are for testing extremely isolated and small pieces of code, which we refer to as the units themselves. Great for reused functions and small, scoped areas, this is the closest you examine your code with the testing microscope. For example, if we were to build a calculator, the most minute piece we could test could be the basic operations.\n/*\n * This example uses a test framework called Jasmine\n */\n\ndescribe(\"Calculator Operations\", function () {\n\n it(\"Should add two numbers\", function () {\n\n // Say we have a calculator\n Calculator.init();\n\n // We can run the function that does our addition calculation...\n var result = Calculator.addNumbers(7,3);\n\n // ...and ensure we're getting the right output\n expect(result).toBe(10);\n\n });\n});\nEven though these teeny bits work in isolation, we should ensure that connecting the large pieces work, as well. This is where integration tests excel. These tests ensure that two or more different areas of code, that may not directly know about each other, still behave in expected ways. Let\u2019s build upon our calculator - we may want the operations to be saved in memory after a calculation runs. This isn\u2019t as suited for a unit test because there are a few other moving pieces involved in the process (the calculations, checking if the result was an error, etc.).\n it(\u201cShould remember the last calculation\u201d, function () {\n\n // Run an operation\n Calculator.addNumbers(7,10);\n\n // Expect something else to have happened as a result\n expect(Calculator.updateCurrentValue).toHaveBeenCalled();\n expect(Calculator.currentValue).toBe(17);\n });\nUnit and integration tests provide assurance that your hand-rolled JavaScript should, for the most part, never fail in a grand fashion. Although it still might happen, you could be able to catch problems way sooner than without a test suite, and hopefully never push those failures to your production environment.\nInterfaces\nRegardless of how you\u2019re building something, it most definitely has some kind of interface. Whether you\u2019re using a very barebones structure, or you\u2019re leveraging a whole design system, these things can be tested as well.\nAcceptance testing helps us ensure that users can get from point A to point B within our web things, which can provide assurance that major features are always functioning properly. By simulating user input and data entry, we can go through whole user workflows to test for both success and failure scenarios. These are not necessarily for simulating edge-case scenarios, but rather ensuring that our core offerings are stable.\nFor example, if your site requires signup, you want to make sure the workflow is behaving as expected - allowing valid information to go through signup, while invalid information does not let you progress.\n/*\n * This example uses Jasmine along with an add-on called jasmine-integration\n */\n\ndescribe(\"Acceptance tests\", function () {\n\n // Go to our signup page\n var page = visit(\"/signup\");\n\n // Fill our signup form with invalid information\n page.fill_in(\"input[name='email']\", \"Not An Email\");\n page.fill_in(\"input[name='name']\", \"Alicia\");\n page.click(\"button[type=submit]\");\n\n // Check that we get an expected error message\n it(\"Shouldn't allow signup with invalid information\", function () {\n expect(page.find(\"#signupError\").hasClass(\"hidden\")).toBeFalsy();\n });\n\n // Now, fill our signup form with valid information\n page.fill_in(\"input[name='email']\", \"thisismyemail@gmail.com\");\n page.fill_in(\"input[name='name']\", \"Gerry\");\n page.click(\"button[type=submit]\");\n\n // Check that we get an expected success message and the error message is hidden\n it(\"Should allow signup with valid information\", function () {\n expect(page.find(\"#signupError\").hasClass(\"hidden\")).toBeTruthy();\n expect(page.find(\"#thankYouMessage\").hasClass(\"hidden\")).toBeFalsy();\n });\n});\nIn terms of visual design, we\u2019re now able to take snapshots of what our interfaces look like before and after any code changes to see what has changed. We call this visual regression testing. Rather than being a pass or fail test like our other examples thus far, this is more of an awareness test, intended to inform developers of all the visual differences that have occurred, intentional or not. Developers may accidentally introduce a styling change or fix that has unintended side effects on other areas of a website - visual regression testing helps us catch these sooner rather than later. These do require a bit more consistent grooming than other tests, but can be valuable in major CSS refactors or if your CSS is generally a bit like Jenga.\nTools like PhantomCSS will take screenshots of your pages, and do a visual comparison to check what has changed between two sets of images. The code would look something like this:\n/*\n * This example uses PhantomCSS\n */\n\ncasper.start(\"/home\").then(function(){\n\n // Initial state of form\n phantomcss.screenshot(\"#signUpForm\", \"sign up form\");\n\n // Hit the sign up button (should trigger error)\n casper.click(\"button#signUp\");\n\n // Take a screenshot of the UI component\n phantomcss.screenshot(\"#signUpForm\", \"sign up form error\");\n\n // Fill in form by name attributes & submit\n casper.fill(\"#signUpForm\", {\n name: \"Alicia Sedlock\",\n email: \"alicia@example.com\"\n }, true);\n\n // Take a second screenshot of success state\n phantomcss.screenshot(\"#signUpForm\", \"sign up form success\");\n});\nYou run this code before starting any development, to create your baseline set of screen captures. After you\u2019ve completed a batch of work, you run PhantomCSS again. This will create a second batch of screenshots, which are then put through an image comparison tool to display any differences that occurred. Say you changed your margins on our form elements \u2013 your image diff would look something like this:\n\nThis is a great tool for ensuring not just your site retains its expected styling, but it\u2019s also great for ensuring nothing accidentally changes in the living style guide or modular components you may have developed. It\u2019s hard to keep eagle eyes on every visual aspect of your site or app, so visual regression testing helps to keep these things monitored.\nConclusion\nThe shape and size of what you\u2019re testing for your site or app will vary. You may not need lots of unit or integration tests if you don\u2019t write a lot of JavaScript. You may not need visual regression testing for a one page site. It\u2019s important to assess your codebase to see which tests would provide the most benefit for you and your team.\nWriting tests isn\u2019t a joy for most developers, myself included. But I end up thanking Past Alicia a lot when there are tests, because otherwise I would have introduced a lot of issues into codebases. Shipping code that\u2019s broken breaks trust with our users, and it\u2019s our responsibility as developers to make sure that trust isn\u2019t broken. Testing shouldn\u2019t be considered a \u201cnice to have\u201d - it should be an integral piece of our workflow and our day-to-day job.", "year": "2016", "author": "Alicia Sedlock", "author_slug": "aliciasedlock", "published": "2016-12-03T00:00:00+00:00", "url": "https://24ways.org/2016/a-favor-for-your-future-self/", "topic": "code"} {"rowid": 302, "title": "Flexible Project Management in Inflexible Environments", "contents": "Handling unforeseen circumstances is an inevitable part of any project. It\u2019s also often the most uncomfortable, and there is no amount of skill or planning that will fully eradicate the need to adapt to change. The ability to be flexible, responsive, and unafraid of facing not only problems, but also potentially positive scope changes and new ideas, isn\u2019t an easy one to master. I am by no means saying that I have, but what I have learned is that there is often the temptation to shut out anything that might derail your plan, even sometimes at the cost of the quality you\u2019re committed to.\nThe reality is that as someone leading a project you know there will be challenges, but, in general, it\u2019s a hassle to try keep the landscape open. Problems are bridges we should cross when we come to them, but intentional changes to the plan, and adapting for the sake of improving your first idea, is harder. There are tight schedules, resource is planned miles ahead, and you\u2019re already juggling twenty other things. If you\u2019re passionate about the quality of work you deliver and are working somewhere that considers itself expert within the field of digital, then having an attitude of flexibility is extremely important. It\u2019s important when you\u2019re overcoming a challenge or problem, but it\u2019s also important for allowing ideas to evolve and be refined as much as they can be throughout the course of a project.\nWhere theory falls short\nThe premise of any Agile methodology, Scrum for example, is based around being able to work efficiently, react quickly and deliver relevant chunks of a product in manageable increments. It\u2019s often hailed as king of flexible management and it can work really well, especially for in-house software products developed over a long or even an indefinite period of time. It holds off defining scope too far ahead and lets teams focus on smaller amounts of work, and allows them to regularly reprioritise. Unfortunately though, not all environments lend themselves as easily to a fully Agile setup. Even the ones that do may be restrained from putting it fully into practice for an array of other internal reasons.\nDelivering digital services to clients\u2014within an agency setting or as a freelancer\u2014often demands a more rigid structure. You need clear sign-off points, there\u2019s a lot less flexibility in defining features, or working within budgets and timeframes. To start with, for a project to warrant a fully Agile team working on it, and especially for agencies, you need clients big enough and rich enough to justify the resource. You also need a lot of client trust to propose defining features and scope as you go. Although this is achievable\u2014and there are agencies that operate an agile setup\u2014it takes a long journey to reach that scale in the full sense of the word. Building a reputation that commands unconditional trust and reaching the point where your projects are consistently of a certain size often requires backing by long journey of success and excellence.\nSo there is a lot of room left for understanding how we can best strive to still deliver excellent projects within more constrained structures. We know that rigid waterfall planning, more often than not, falls over as soon as a project gets anything past a basic brochure site. There are many critiques of the system, but one of the main ones tends to be that nobody considers each other\u2019s work properly, which can result in very expensive and inefficient development.\nEqually, for reasons we\u2019ve already touched upon, running fully agile teams often isn\u2019t the right answer. So many companies, individuals, and organisations look for a middle-ground that balances being flexible and adaptive, but also provides enough upfront commitment to agree budgets, get client/stakeholder sign off, and effectively coordinate internal resource across multiple parallel projects.\nAlthough I don\u2019t have a perfect formula\u2014and can very much assert there is no one perfect way of managing a project because every project is different to the next\u2014I\u2019ve identified a few different ways you can approach flexibility that have really helped me in running projects more smoothly within more realistic constraints.\nPlanned Flexibility\nDrawing on some of the traditional methodologies such as PRINCE2, a good starting point for aspiring to be flexible is by planning for it from the start.\nPlanning flexibility comes in a few forms. For one, you can regularly identify and log potential risks as a generally good, on-going habit over the course of the project. This essentially just involves scanning the horizon for potential blips on a regular basis (for example weekly) by consulting with your team and documenting it somewhere. It means you have a checkpoint when you sit down and make sure you\u2019re minimising what will or may catch you by surprise. A good time to do this is in a weekly catch up meeting. It\u2019s not going to fix all your problems, but it will make sure you have a head start on the ones you can see coming.\nOn the subject of team meetings, setting up recurring project events, including a weekly call, a weekly team meeting and (depending on the size of the project) I like to try also do a stand-up as often as possible. Keeping everyone involved and bought in to a project is going to help you infinitely when you need to spot a problem or manage changes to the plan. It will be the difference between your designer spotting an issue and making a mental note to \u2018tell you later\u2019, and them actually coming over to tell you directly and immediately. Despite the overhead of meetings, and looping people into stages that they aren\u2019t directly responsible for, the business benefits are chances for success are drastically increased. Planning in, and being aware of how important your team is, will help you be flexible.\nBuilding contingency (formally know as slack) into your project plan from the word go is another well-known and essential way of planning to be flexible. Your project plan will change a lot over the course of a project, but there are still the days that you estimate a job will take, and the days you should actually plan in. Most sensible management teams understand that budgets need to be agreed with this slack in mind or you will not be able to deliver a quality service. I believe that commercial awareness is one of the most valuable skills a project manager can have, but penny pinching will ruin client and team relationships, destroy buy-in and creativity, and often end you up with a much more expensive, hacky, and resented product.\nIt\u2019s not a justification to let budgets spiral out of control, but a way of thinking about the bigger picture and wider plan of the company itself. It\u2019s unlikely you want high staff turnover because everyone fell out while you were screaming money at them and they didn\u2019t feel like they could do a good job. It\u2019s also unlikely that you will be able to deliver quality products, which will win you a strong reputation and subsequently bigger and better projects. Evaluating risk factors and building in the right amount of slack from the start will give you more wriggle room when you need to adapt and react. On the flip side, also keeping an overview of the wider workload (that you\u2019re not necessarily responsible for), and knowing who to talk if resource is becoming free or needs filling, is another handy way of being able to react quickly and ensuring your management system is respected. You want pockets of backup time planned in, but you also want everyone being as productive as they can most of the time. Never run at 100% capacity: as soon as something does need to change, you\u2019re left with nowhere to move.\nTransparency\nHaving a client or stakeholder that trusts you is a really powerful aid in any regard, but especially so when you need to communicate an issue or new suggestion. Positioning yourself and your team as experts and taking the time to delve into the wider picture\u2014and the goals surrounding your client\u2019s reasons to commission the project in the first place\u2014will make you more valuable to them. Clients and stakeholders will always be different, and sometimes you will get people who are just plain difficult, but more often than not people will listen if you\u2019re willing to talk and explain things.\nAs I\u2019m sure all of us have realised at one point or another, a lot of people think they know what they want, and it\u2019s usually the wrong thing. Managing key stakeholders in your project is arguably your biggest challenge, if they are on the your side and feel like the team is genuinely working to give them something of quality and value, then they will make your job easier. It\u2019s often down to you to educate them, and to help them recognise and understand the work involved and you and your team\u2019s reasoning behind your decisions.\nBeing overly submissive or overly secretive will foster a dynamic in which they feel expected to steer the project. In this situation they may not respect the team\u2019s suggestions or may come up with some unreasonable and counterproductive ideas that are likely to hinder progress and lower morale. Getting the stakeholder on board and making them feel a part of the wider picture will make things easier. Pushing back and challenging ideas or working hard to justify something they don\u2019t quite understand will often work in your favour and protects your team. On quite a basic level it also shows you care and are invested; on another, it shows you feel confident in your expertise within your field and that is ultimately the reason they hired you.\nTaking the time to think about and be aware of this relationship, will make it easier to be flexible and handle new ideas or suggestions that pop up as the project goes along. Change doesn\u2019t need to be \u2018scope creep\u2019 if it\u2019s raised in a practical, value-orientated, and level headed discussion. There is usually a way forward for new ideas, as long as they\u2019re valuable and support the wider goals. Maybe the deadline gets pushed back, maybe you get more budget, maybe the client is happy to forgo something else. As long as there\u2019s value and reason, it shows integrity to the project and respect for its success. You can\u2019t expect for this to go smoothly without having invested in the client relationship, so it\u2019s a large point in paving the way to handling change well.\nReactive Flexibility\nFinally, if you\u2019ve been doing this for a while, you\u2019ll know by now that you can\u2019t anticipate everything. Sometimes you will have to react and change the plan under circumstances that aren\u2019t easy. When an unexpected problem first rears its head\u2014a client\u2019s casual afterthought that\u2019s threatening the scope of the project, an internal resource conflict, a junior member of staff that\u2019s not grasping the ropes quite as quickly as you\u2019d hoped\u2014you have to react quickly.\nIn his book, \u2018Pitch Anything\u2019, Oren Klaff talks about people\u2019s first reactions being processed by their \u2018crocodile brain\u2019 before they\u2019ve had a chance to refine and digest the information more intelligibly. As project managers, product owners, or scrum masters, it\u2019s natural for our immediate reactions to an unexpected problem to cause a pang of stress. But after that initial jolt you need to turn to practical solutions and start racking your brain for different ways forward. It\u2019s here you need to remember to not let your imagination get the better of you, especially if you\u2019ve been putting in the legwork with your team and your client. There is always a way forward and moments like this can be a good opportunity to develop your negotiation and diplomacy skills. Don\u2019t let your immediate reaction be shutting the problem down; instead, take a second to think about it before you decide on the best direction. In a stressful situation, your first idea probably won\u2019t be your best one.\nFrom an internal point of view, it\u2019s very important that whatever went wrong doesn\u2019t turn into a finger pointing exercise and you don\u2019t lose your cool. Getting caught up in a blame game or a witch hunt is never productive. Relationship cultivating can sometimes be the pillar that gets you through a stressful blip. Biggest tip for staying flexible when you\u2019re reacting to a problem\u2014apart form obviously thinking of ways forward\u2014is to communicate. Don\u2019t go quiet until you feel like you have a plan, you\u2019ll often need to put everyone else at ease before you can move things forward. Problem solving is part of the job and will need to happen in even the most flexible of product delivery systems.\nIn conclusion, being flexible is never simple but there are things you can do to make your life easier. Owning a position of expertise, putting together a team that\u2019s involved in each other\u2019s work and cultivating a client/stakeholder relationship that\u2019s as transparent and respectful as possible will get you a long way. In times of crisis, believe in your skills and be open to adapting over getting frustrated.", "year": "2016", "author": "Gillian Sibthorpe", "author_slug": "gilliansibthorpe", "published": "2016-12-04T00:00:00+00:00", "url": "https://24ways.org/2016/flexible-project-management/", "topic": "process"} {"rowid": 303, "title": "We Need to Talk About Technical Debt", "contents": "In my work with clients, a lot of time is spent assessing old, legacy, sprawling systems and identifying good code, bad code, and technical debt.\nOne thing that constantly strikes me is the frequency with which bad code and technical debt are conflated, so let me start by saying this:\nNot all technical debt is bad code, and not all bad code is technical debt.\nSometimes your bad code is just that: bad code. Calling it technical debt often feels like a more forgiving and friendly way of referring to what may have just been a poor implementation or a substandard piece of work.\nIt is an oft-misunderstood phrase, and when mistaken for meaning \u2018anything legacy or old hacky or nasty or bad\u2019, technical debt is swept under the carpet along with all of the other parts of the codebase we\u2019d rather not talk about, and therein lies the problem.\nWe need to talk about technical debt.\nWhat We Talk About When We Talk About Technical Debt\nThe thing that separates technical debt from the rest of the hacky code in our project is the fact that technical debt, by definition, is something that we knowingly and strategically entered into. Debt doesn\u2019t happen by accident: debt happens when we choose to gain something otherwise-unattainable immediately in return for paying it back (with interest) later on.\nAn Example\nYou\u2019re a front-end developer working on a SaaS product, and your sales team is courting a large customer \u2013 a customer so large that you can\u2019t really afford to lose them. The customer tells you that as long as you can allow them to theme your SaaS application according to their branding, they are willing to sign on the dotted line\u2026 the problem being that your CSS architecture was never designed to incorporate theming at all, and there isn\u2019t currently a nice, clean way to incorporate a theme into the codebase.\nYou and the business make the decision that you will hack a theme into the product in two days. It\u2019s going to be messy, it\u2019s going to be ugly, but you can\u2019t afford to lose a huge customer just because your CSS isn\u2019t quite right, right now. This is technical debt.\nYou deliver the theme, the customer signs up, and everyone is happy. Except you (and the business, because you are one and the same) have a decision to make:\n\nDo we go back and build theming into the CSS architecture as a first-class citizen, porting the hacked theme back into a codified and formal framework?\nDo we carry on as we are? Things are working okay, and the customer paid up, so is there any reason to invest time and effort into things after we (and the customer) got what we wanted?\n\nOption 1 is choosing to pay off your debts; Option 2 is ignoring your repayments.\nWith Option 1, you\u2019re acknowledging that you did what you could given the constraints, but, free of constraints, you\u2019d have done something different. Now, you are choosing to implement that something different.\nWith Option 2, however, you are avoiding your responsibility to repay your debt, and you are letting interest accrue. The problem here is that\u2026\n\nyour SaaS product now offers theming to one of your customers;\nanother potential customer might also demand the ability to theme their instance of your product;\nyou can\u2019t refuse them that request, nor can you quickly fulfil it;\nyou hack in another theme, thus adding to the balance of your existing debt;\nand so on (plus interest) for every subsequent theme you need to implement.\n\nHere you have increased entropy whilst making little to no attempt to address what you already knew to be problems.\nYour second, third, fourth, fifth request for theming will be hacked on top of your hack, further accumulating debt whilst offering nothing by way of a repayment. After a long enough period, the code involved will get so unwieldy, so hard to work with, that you are forced to tear it all down and start again, and the most painful part of this is that you\u2019re actually paying off even more than your debt repayments would have been in the first place. Two days of hacking plus, say, five days of subsequent refactoring, would still have been substantially less than the weeks you will now have to spend rewriting your CSS to fix and incorporate the themes properly. You\u2019ve made a loss; your strategic debt ultimately became a loss-making exercise.\nThe important thing to note here is that you didn\u2019t necessarily write bad code. You knew there were two options: the quick way and the correct way. The decision to take the quick route was a definite choice, because you knew there was a better way. Implementing the better way is your repayment.\nGood Debt and Bad Debt\nTechnical debt is acceptable as long as you have intentions to settle; it can be a valuable solution to a business problem, provided the right approach is taken afterwards. That doesn\u2019t, however, mean that all debt is born equal. Just as in real life, there is good debt and there is bad debt.\nGood debt might be\u2026\n\na mortgage;\na student loan, or;\na business loan.\n\nThese are types of debt that will secure you the means of repaying them. These are well considered debts whose very reason for being will allow you to make the money to pay them off\u2014they have real, tangible benefit.\nA business loan to secure some equipment and premises will allow you to start an enterprise whose revenue will allow you to pay that debt back; a student loan will allow you to secure the kind of job that has the ability to pay a student loan back.\nThese kinds of debt involve a considered and well-balanced decision to acquire something in the short term in the knowledge that you will have the means, in the long term, to pay it back.\nConversely, bad debt might be\u2026\n\nborrowing $1,000 from a loan shark so you can go to Vegas, or;\ntaking out a payday loan in order to buy a new television.\n\nBoth of these kinds of debt will leave you paying for things that didn\u2019t provide you a way of earning your own capital. That is to say, the loans taken did not secure anything that would help pay off said loans. These are bad debts that will usually provide a net loss. You really are only gaining the short term in exchange for a long term financial responsibility: i.e., was it worth it?\nA good litmus test for debt is to compare the gains of its immediate benefit with the cost of its long term commitment.\nThe earlier example of theming a site is a good debt, provided we are keeping up our repayments (all debt is bad debt if you don\u2019t). A calculated decision to do something \u2018wrong\u2019 in the short term with the promise of better payoffs later on.\nBad Technical Debt\nThe majority of my work is with front-end development teams\u2014CSS is what I do. To that end, the most succinct example of technical debt for that audience is simply:\n!important\nAll front-end developers know the horrors and dangers associated with using !important, yet we continue to use it. Why?\nIt\u2019s not necessarily because we\u2019re bad developers, but because we see a shortcut. !important is usually implemented as a quick way out of a sticky specificity situation. We could spend the rest of the day refactoring our CSS to fix the issue at its source, or we can spend mere seconds typing the word !important and patch over the symptoms.\nThis is us making an explicit decision to do something less than ideal now in exchange for immediate benefit. After all, refactoring our CSS will take a lot more time, and will still only leave us with the same outcome that the vastly quicker !important solution will, so it seems to make better business sense.\nHowever, this is a bad debt. !important takes seconds to implement but weeks to refactor. The cost of refactoring this back out later will be an order of magnitude higher than it would be to have done things properly the first time. The first !important usually sets a precedent, and subsequent developers are likely to have to use it themselves in order to get around the one that you left.\nSo many CSS projects deteriorate because of this one simple word, and rewrites become more and more imminent. That makes it possibly the most costly 10 bytes a CSS developer could ever write.\nBad Code\nNow we\u2019ve got a good idea of what constitutes technical debt, let\u2019s take a look at what constitutes bad code. Something I hear time and time again in my client work goes a little like this:\n\nWe\u2019ve amassed a lot of technical debt and we\u2019d like to get a strategy in place\nto begin dealing with it.\n\nWhilst I genuinely admire their willingness to identify and desire to fix problems in their code, sometimes they\u2019re not looking at technical debt at\nall\u2014sometimes they\u2019re just looking at bad code, plain and simple.\nWhere technical debt is knowing that there\u2019s a better way, but the quicker way makes more sense right now, bad code is not caring if there\u2019s a better way at all.\nAgain, looking at a CSS-specific world, a lot of bad code is contributed by non-front-end developers with little training, appreciation, or even respect for the front-end landscape. Writing code with reckless abandon should not be described as technical debt, because to do so would imply that\u2026\n\nthe developers knew they were implementing a sub-par solution, but\u2026\nthe developers also knew that a better solution was out there, which\u2026\nimplies that it can be tidied up relatively simply.\n\nDevelopers writing bad code is a larger and more cultural problem that requires a lot more effort to fix. Hopefully\u2014and usually\u2014bad code is in the minority, but it helps to be objective in identifying and solving it. Bad code usually doesn\u2019t happen for a good enough reason, and is therefore much harder to justify.\nTechnical debt often represents ability in judgement, whereas bad code often represents a gap in skills.\nTakeaway\nTake time to familiarise yourself with the true concepts underlying technical debt and why it exists. Understand that technical debt can be good or bad. Admit that sometimes code is just of poor quality.\nUnderstanding these points will allow you to make better calls around what you might need to refactor and when, and what skills gaps you might have in your team.\n\nSometimes it\u2019s okay to cut corners if there is a tangible gain to be had in the immediate term.\nTechnical debt is okay provided it is a sensible debt and you have intentions to pay it off.\nTechnical debt is not necessarily synonymous with bad code, and bad code isn\u2019t necessarily technical debt. Technical debt is code that was implemented given limited knowledge or resource, with the understanding that you would need to repay something in future.\nTechnical debt is not inherently bad\u2014failure to make repayments is. Periodically, it is justifiable\u2014encouraged, even\u2014to enter a debt in order to fulfil a more pressing matter. However, it is imperative that we begin making repayments as soon as we are capable, be that based on newly available time or knowledge.\nBad code is worse than technical debt as it represents a lack of knowledge or quality control within a team. It needs a much more fundamental fix.", "year": "2016", "author": "Harry Roberts", "author_slug": "harryroberts", "published": "2016-12-05T00:00:00+00:00", "url": "https://24ways.org/2016/we-need-to-talk-about-technical-debt/", "topic": "code"} {"rowid": 297, "title": "Public Speaking with a Buddy", "contents": "My book Demystifying Public Speaking focuses on the variety of fears we each have about giving a talk. From presenting to a client, to leading a team standup, to standing on a conference stage, there are lots of things we can do to prepare ourselves for the spotlight and reduce those fears.\nThough it didn\u2019t make it into the final draft, I wanted to highlight how helpful it can be to share that public speaking spotlight with another person, or a few more people. If you have fears about not knowing the answer to a question, fumbling your words, or making a mistake in the spotlight, then buddying up may be for you!\n\nTo some, adding more people to a presentation sounds like a recipe for on-stage disaster. To others, having a friendly face nearby\u2014a partner who can step in if you fumble\u2014is incredibly reassuring. As design director Yesenia Perez-Cruz writes, \u201cWhile public speaking is a deeply personal activity, you don\u2019t have to go it alone. Nothing has helped my speaking career more than turning it into a group effort.\u201d\nCo-presenting can level up a talk in two ways: an additional brain and presentation skill set can improve the content of the talk itself, and you may feel safer with the on-stage safety net of your buddy. \nFor example, when I started giving lengthy workshops about building mobile device labs with my co-worker Destiny Montague, we brought different experience to the table. I was able to talk about the user experience of our lab, and the importance of testing across different screen sizes. Destiny spoke about the hardware aspects of the lab, like power consumption and networking. Our audience benefitted from the spectrum of insight we included in the talk.\nMoreover, Destiny and I kept each other energized and engaging while teaching our audience, having way more fun onstage. Partnering up alleviated the risk (and fear!) of fumbling; where one person makes a mistake, the other person is right there to help. Buddy presentations can be helpful if you fear saying \u201cI don\u2019t know\u201d to a question, as there are other people around you who will be able to help answer it from the stage. By partnering with someone whom I trust and respect, and whose work and knowledge augments my own, it made the experience\u2014and the presentation!\u2014significantly better.\nCo-presenting won\u2019t work if you don\u2019t trust the person you\u2019re onstage with, or if you don\u2019t have good chemistry working together. It might also not work if there\u2019s an imbalance of responsibilities, both in preparing the talk and giving it. Read on for how to make partner talks work to your advantage!\nTrustworthiness\nIf you want to explore co-presenting, make sure that your presentation partner is trustworthy and can carry their weight; it can be stressful if you find yourself trying to meet deadlines and prepare well and your partner isn\u2019t being helpful. We\u2019re all about reducing the fears and stress levels surrounding being in that spotlight onstage; make sure that the person you\u2019re relying on isn\u2019t making the process harder.\nBefore you start working together, sketch out the breakdown of work and timeline you\u2019re each committing to. Have a conversation about your preferred work style so you each have a concrete understanding of the best ways to communicate (in what medium, and how often) and how to check in on each other\u2019s progress without micromanaging or worrying about radio silence. Ask your buddy how they prefer to receive feedback, and give them your own feedback preferences, so neither of you are surprised or offended when someone\u2019s work style or deliverable needs to be tweaked.\nThis should be a partnership in which you both feel supported; it\u2019s healthy to set all these expectations up front, and create a space in which you can each tweak things as the work progresses.\nTalk flow and responsibilities\nThere are a few different ways to organize the structure of your talk with multiple presenters. Start by thinking about the breakdown of the talk content\u2014are there discrete parts you and the other presenters can own or deliver? Or does it feel more appropriate to deliver the entirety of the content together?\nIf you\u2019re finding that you can break down the content into discrete chunks, figure out who should own which pieces, and what ownership means. Will you develop the content together but have only one person present the information? Or will one person research and prepare each content section in addition to delivering it solo onstage?\nRehearse how handoffs will go between sections so it feels natural, rather than stilted. I like breaking a presentation into \u201cchapters\u201d when I\u2019m passionate about particular aspects of a topic and can speak on those, but know that there are other aspects to be shared and there\u2019s someone else who can handle (and enjoy!) talking about them. When Destiny and I rehearsed our \u201cchapter\u201d handoffs, we developed little jingles that we\u2019d both sing together onstage; it indicated to the audience that it was a planned transition in the content, and tied our independent work together into a partnership.\n.embed-container { position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden; max-width: 100%; } .embed-container iframe, .embed-container object, .embed-container embed { position: absolute; top: 0; left: 0; width: 100%; height: 100%; }\n\n\n\nAlternatively, you can give the presentation in a way that\u2019s close to having a rehearsed conversation, rather than independently presenting discrete parts of the talk. In this case, you\u2019ll both be sharing the spotlight at the same time, throughout the duration of the talk. Preparation is key, here, to make sure that you each understand what needs to be communicated, and you have a sense of who will be taking responsibility for communicating those different pieces of information. A poorly-prepared talk like this will look like the co-presenters are talking over each other, or hesitating awkwardly to give the other person more room to speak; the audience will feel how uncomfortable this is, and will probably be distracted from the talk content. Practice the talk the whole way through multiple times so you know what each person is planning on covering and how you want to interact with each other while you\u2019re both holding microphones; also figure out how you\u2019ll be standing in relation to each other. More on that next!\nSharing the stage\nIf you choose to give a talk with a partner, determine ahead of time how you\u2019ll stand (or sit). For example, if you each take \u201cchapters\u201d or major sections of the presentation, ensure that it\u2019s clear who the audience should focus their attention on. You could sit in a chair off to the side (or stand). I recommend placing yourself far enough away that you\u2019re not distracting to the audience; you don\u2019t want them watching you while your partner is speaking. If the audience can still see you, but their focus should be on your buddy, be sure to not look distracted; keep your eyes on your buddy, and don\u2019t just open your laptop and ignore what\u2019s happening! Feel free to smile, laugh, or react how the audience should be reacting as your partner is speaking.\nIf you\u2019re both sharing the spotlight at the same time and having a rehearsed conversation, make sure that your body language engages the audience and you\u2019re not just speaking to each other, ignoring the folks watching. Watch this talk with Guy Podjarny and Assaf Hefetz who have partnered up to talk about security; they have clearly identified roles onstage, and remain engaged with the audience.\n\nConsider whether or not you will share a microphone, or if you will both be mic\u2019d. (Be sure that the event organizer, or the A/V team, has a heads-up well in advance to ensure they have the equipment handy!) Also talk through how you\u2019d like to handle Q&A time during or after the talk, especially if you have clear \u201cchapters\u201d where Q&A might happen naturally during a handoff. The more clarity you and your partner have about who is responsible for which pieces of information sharing, the more you can feel and appear prepared.\nCo-presenting does take a lot of preparation and requires a ton of communication between you and your partner. But the rewards can be awesome: double the brains onstage to help answer questions and communicate information, and a friendly face to help comfort you if you feel nervous.", "year": "2016", "author": "Lara Hogan", "author_slug": "larahogan", "published": "2016-12-06T00:00:00+00:00", "url": "https://24ways.org/2016/public-speaking-with-a-buddy/", "topic": "process"} {"rowid": 299, "title": "What the Heck Is Inclusive Design?", "contents": "Naming things is hard. And I don\u2019t just mean CSS class names and JSON properties. Finding the right term for what we do with the time we spend awake and out of bed turns out to be really hard too.\nI\u2019ve variously gone by \u201cfront-end developer\u201d, \u201cuser experience designer\u201d, and \u201caccessibility engineer\u201d, all clumsy and incomplete terms for labeling what I do as an\u2026 erm\u2026 see, there\u2019s the problem again.\nIt\u2019s tempting to give up entirely on trying to find the right words for things, but this risks summarily dispensing with thousands of years spent trying to qualify the world around us. So here we are again.\nRecently, I\u2019ve been using the term \u201cinclusive design\u201d and calling myself an \u201cinclusive designer\u201d a lot. I\u2019m not sure where I first heard it or who came up with it, but the terminology feels like a good fit for the kind of stuff I care to do when I\u2019m not at a pub or asleep.\nThis article is about what I think \u201cinclusive design\u201d means and why I think you might like it as an idea.\nIsn\u2019t \u2018inclusive design\u2019 just \u2018accessibility\u2019 by another name?\nNo, I don\u2019t think so. But that\u2019s not to say the two concepts aren\u2019t related. Note the \u2018design\u2019 part in \u2018inclusive design\u2019 \u2014 that\u2019s not just there by accident. Inclusive design describes a design activity; a way of designing things.\nThis sets it apart from accessibility \u2014 or at least our expectations of what \u2018accessibility\u2019 entails. Despite every single accessibility expert I know (and I know a lot) recommending that accessibility should be integrated into design process, it is rarely ever done. Instead, it is relegated to an afterthought, limiting its effect.\nThe term \u2018accessibility\u2019 therefore lacks the power to connote design process. It\u2019s not that we haven\u2019t tried to salvage the term, but it\u2019s beginning to look like a lost cause. So maybe let\u2019s use a new term, because new things take new names. People get that.\nThe \u2018access\u2019 part of accessibility is also problematic. Before we get ahead of ourselves, I don\u2019t mean access is a problem \u2014 access is good, and the more accessible something is the better. I mean it\u2019s not enough by itself.\nImagine a website filled with poorly written and lackadaisically organized information, including a bunch of convoluted and confusing functionality. To make this site accessible is to ensure no barriers prevent people from accessing the content. \nBut that doesn\u2019t make the content any better. It just means more people get to suffer it. \nWhoopdidoo.\nAccess is certainly a prerequisite of inclusion, but accessibility compliance doesn\u2019t get you all the way there. It\u2019s possible to check all the boxes but still be left with an unusable interface. And unusable interfaces are necessarily inaccessible ones. Sure, you can take an unusable interface and make it accessibility compliant, but that only placates stakeholders\u2019 lawyers, not users. Users get little value from it.\nSo where have we got to? Access is important, but inclusion is bigger than access. Inclusive design means making something valuable, not just accessible, to as many people as we can.\nSo inclusive design is kind of accessibility + UX?\nCloser, but there are some problems with this definition.\nUX is, you will have already noted, a broad term encompassing activities ranging from conducting research studies to optimizing the perceived affordance of interface elements. But overall, what I take from UX is that it\u2019s the pursuit of making interfaces understandable.\nAs it happens, WCAG 2.0 already contains an \u2018Understandable\u2019 principle covering provisions such as readability, predictability and feedback. So you might say accessibility \u2014 at least as described by WCAG \u2014 already covers UX.\nUnfortunately, the criteria are limited, plus some really important stuff (like readability) is relegated to the AAA level; essentially \u201cbonus points if you get the time (you won\u2019t).\u201d\nSo better to let UX folks take care of this kind of thing. It\u2019s what they do. Except, therein lies a danger. UX professionals don\u2019t tend to be well versed in accessibility, so their \u2018solutions\u2019 don\u2019t tend to work for that many people. My friend Billy Gregory coined the term SUX, or \u201cSome UX\u201d: if it doesn\u2019t work for different users, it\u2019s only doing part of the job it should be. \nSUX won\u2019t do, but it\u2019s not just a disability issue. All sorts of user circumstances go unchecked when you\u2019re shooting straight for what people like, and bypassing what people need: device type, device settings, network quality, location, native language, and available time to name just a few.\nIn short, inclusive design means designing things for people who aren\u2019t you, in your situation. In my experience, mainstream UX isn\u2019t very good at that. By bolting accessibility onto mainstream UX we labor under the misapprehension that most people have a \u2018normal\u2019 experience, a few people are exceptions, and that all of the exceptions pertain to disability directly.\nSo inclusive design isn\u2019t really about disability?\nIt is about disability, but not in the same way as accessibility. Accessibility (as it is typically understood, anyway) aims to make sure things work for people with clinically recognized disabilities. Inclusive design aims to make sure things work for people, not forgetting those with clinically recognized disabilities. A subtle, but not so subtle, difference.\nLet\u2019s go back to discussing readability, because that\u2019s a good example. Now: everyone benefits from readable text; text with concise sentences and widely-understood words. It certainly helps people with cognitive impairments, but it doesn\u2019t hinder folks who have less trouble with comprehension. In fact, they\u2019ll more than likely be thankful for the time saved and the clarity. Readable text covers the whole gamut. It\u2019s \u2014 you\u2019ve got it \u2014 inclusive.\nLegibility is another one. A clear, well-balanced typeface makes the reading experience less uncomfortable and frustrating for all concerned, including those who have various forms of visual dyslexia. Again, everyone\u2019s happy \u2014 so why even contemplate a squiggly, sketchy typeface? Leave well alone.\nContrast too. No one benefits from low contrast; everyone benefits from high contrast. Simple. There\u2019s no more work involved, it just entails better decision making. And that\u2019s what design is really: decision making.\nHow about zoom support? If you let your users pinch zoom on their phones they can compensate for poor eyesight, but they can also increase the touch area of controls, inspect detail in images, and compose better screen shots. Unobtrusively supporting options like zoom makes interfaces much more inclusive at very little cost.\nAnd when it comes to the underlying HTML code, you\u2019re in luck: it has already been designed, from the outset, to be inclusive. HTML is a toolkit for inclusion. Using the right elements for the job doesn\u2019t just mean the few who use screen readers benefit, but keyboard accessibility comes out-of-the-box, you can defer to browser behavior rather than writing additional scripts, the code is easier to read and maintain, and editors can create content that is effortlessly presentable. \nWait\u2026 are you talking about universal design?\nHmmm. Yes, I guess some folks might think of \u201cuniversal design\u201d and \u201cinclusive design\u201d as synonymous. I just really don\u2019t like the term universal in this context. \nThe thing is, it gives the impression that you should be designing for absolutely everyone in the universe. Though few would adopt a literal interpretation of \u201cuniversal\u201d in this context, there are enough developers who would deliberately misconstrue the term and decry universal design as an impossible task. I\u2019ve actually had people push back by saying, \u201cwhat, so I\u2019ve got to make it work for people who are allergic to computers? What about people in comas?\u201d\nFor everyone\u2019s sake, I think the term \u2018inclusive\u2019 is less misleading. Of course you can\u2019t make things that everybody can use \u2014 it\u2019s okay, that\u2019s not the aim. But with everything that\u2019s possible with web technologies, there\u2019s really no need to exclude people in the vast numbers that we usually are. \nAccessibility can never be perfect, but by thinking inclusively from planning, through prototyping to production, you can cast a much wider net. That means more and happier users at very little if any more effort.\nIf you like, inclusive design is the means and accessibility is the end \u2014 it\u2019s just that you get a lot more than just accessibility along the way.\nConclusion\nThat\u2019s inclusive design. Or at least, that\u2019s a definition for a thing I think is a good idea which I identify as inclusive design. I\u2019ll leave you with a few tips.\nInvolve code early\nWeb interfaces are made of code. If you\u2019re not working with code, you\u2019re not working on the interface. That\u2019s not to say there\u2019s anything wrong with sketching or paper prototyping \u2014 in fact, I recommend paper prototyping in my book on inclusive design. Just work with code as soon as you can, and think about code even before that. Maintain a pattern library of coded solutions and omit any solutions that don\u2019t adhere to basic accessibility guidelines.\nRespect conventions\nYour content should be fresh, inventive, radical. Your interface shouldn\u2019t. Adopt accepted conventions in the appearance, placement and coding of interface elements. Users aren\u2019t there to experience interface design; they\u2019re there to use an interface. In other words: stop showing off (unless, of course, the brief is to experiment with new paradigms in interface design, for an audience of interface design researchers).\nDon\u2019t be exact\n\u201cPerfection is the enemy of good\u201d. But the pursuit of perfection isn\u2019t just to be avoided because nothing ever gets finished. Exacting design also makes things inflexible and brittle. If your design depends on elements retaining precise coordinates, they\u2019ll break easily when your users start adjusting font settings or zooming. Choose not to position elements exactly or give them fixed, \u201cmagic number\u201d dimensions. Make less decisions in the interface so your users can make more decisions for it.\nEnforce simplicity\nThe virtue of simplicity is difficult to overestimate. The simpler an interface is, the easier it is to use for all kinds of users. Simpler interfaces require less code to make too, so there\u2019s an obvious performance advantage. There are many design decisions that require user research, but keeping things simple is always the right thing to do. Not simplified or simple-seeming or simplistic, but simple. \nDo a little and do it well, for as many people as you can.", "year": "2016", "author": "Heydon Pickering", "author_slug": "heydonpickering", "published": "2016-12-07T00:00:00+00:00", "url": "https://24ways.org/2016/what-the-heck-is-inclusive-design/", "topic": "process"} {"rowid": 308, "title": "How to Make a Chrome Extension to Delight (or Troll) Your Friends", "contents": "If you\u2019re like me, you grew up drawing mustaches on celebrities. Every photograph was subject to your doodling wrath, and your brilliance was taken to a whole new level with computer programs like Microsoft Paint. The advent of digital cameras meant that no one was safe from your handiwork, especially not your friends. And when you finally got your hands on Photoshop, you spent hours maniacally giggling at your artistic genius. \nBut today is different. You\u2019re a serious adult with important things to do and a reputation to uphold. You keep up with modern web techniques and trends, and have little time for fun other than a random Giphy on Slack\u2026 right? \nNope. \nIf there\u2019s one thing 2016 has taught me, it\u2019s that we\u2014the self-serious, world-changing tech movers and shakers of the universe\u2014haven\u2019t changed one bit from our younger, more delightable selves.\nHow do I know? This year I created a Chrome extension called Tabby Cat and watched hundreds of thousands of people ditch productivity for randomly generated cats. Tabby Cat replaces your new tab page with an SVG cat featuring a silly name like \u201cStinky Dinosaur\u201d or \u201cTiny Potato\u201d. Over time, the cats collect goodies that vary in absurdity from fishbones to lawn flamingos to Raybans. Kids and adults alike use this extension, and analytics show the majority of use happens Monday through Friday from 9-5. The popularity of Tabby Cat has convinced me there\u2019s still plenty of room in our big, grown-up hearts for fun.\n\n\nToday, we\u2019re going to combine the formula behind Tabby Cat with your intrinsic desire to delight (or troll) your friends, and create a web app that generates your friends with random objects and environments of your choosing. You can publish it as a Chrome extension to replace your new tab, or simply host it as a website and point to it with the New Tab Redirect extension. \nHere\u2019s a sneak peek at my final result featuring my partner, my cat, and I in cheerfully weird accessories. Your result will look however you want it to.\n\nAlong the way, we\u2019ll cover how to build a Chrome extension that replaces the new tab page, and explore ways to program randomness into your work to create something truly delightful. \nWhat you\u2019ll need\n\nAdobe Illustrator (or a similar illustration program to export PNG)\nSome images of your friends\nA text editor\n\nNote: This can be as simple or as complex as you want it to be. Most of the application is pre-built so you can focus on kicking back and getting in touch with your creative side. If you want to dive in deeper, you\u2019ll find ways to do it.\nGetting started\n\nDownload a local copy of the boilerplate for today\u2019s tutorial here, and open it in a text editor. Inside, you\u2019ll find a simple web app that you can run in Chrome. \nOpen index.html in Chrome. You should see a grey page that says \u201cNoname\u201d.\nOpen template.pdf in Adobe Illustrator or a similar program that can export PNG. The file contains an artboard measuring 800px x 800px, with a dotted blue outline of a face. This is your template.\n\nNote: We\u2019re using Google Chrome to build and preview this application because the end-result is a Chrome extension. This means that the application isn\u2019t totally cross-browser compatible, but that\u2019s okay.\nStep 1: Gather your friends\nThe first thing to do is choose who your muses are. Since the holidays are upon us, I\u2019d suggest finding inspiration in your family.\nCreate your artwork\nFor each person, find an image where their face is pointed as forward as possible. Place the image onto the Artwork layer of the Illustrator file, and line up their face with the template. Then, rename the artboard something descriptive like face_bob. Here\u2019s my crew:\nAs you can see, my use of the word \u201cfamily\u201d extends to cats. There\u2019s no judgement here.\nNotice that some of my photos don\u2019t completely fill the artboard\u2013that\u2019s fine. The images will be clipped into ovals when they\u2019re rendered in the application.\nNow, export your images by following these steps:\n\nTurn the Template layer off and export the images as PNGs. \nIn the Export dialog, tick the \u201cUse Artboards\u201d checkbox and enter the range with your faces. \nExport at 72ppi to keep things running fast. \nSave your images into the images/ folder in your project.\n\nAdd your images to config.js\nOpen scripts/config.js. This is where you configure your extension. \nAdd key value pairs to the faces object. The key should be the person\u2019s name, and the value should be the filepath to the image.\nfaces: {\n leslie: 'images/face_leslie.png',\n kyle: 'images/face_kyle.png',\n beep: 'images/face_beep.png'\n}\nThe application will choose one of these options at random each time you open a new tab. This pattern is used for everything in the config file. You give the application groups of choices, and it chooses one at random each time it loads. The only thing that\u2019s special about the faces object is that person\u2019s name will also be displayed when their face is chosen.\nNow, when you refresh the project in Chrome, you should see one of your friends along with their name, like this:\n\nCongrats, you\u2019re off and running!\nStep 2: Add adjectives\nNow that you\u2019ve loaded your friends into the application, it\u2019s time to call them names. This step definitely yields the most laughs for the least amount of effort.\nAdd a list of adjectives into the prefixes array in config.js. To get the words flowing, I took inspiration from ways I might describe some of my relatives during a holiday gathering\u2026\nprefixes: [\n 'Loving',\n 'Drunk',\n 'Chatty',\n 'Merry',\n 'Creepy',\n 'Introspective',\n 'Cheerful',\n 'Awkward',\n 'Unrelatable',\n 'Hungry',\n ...\n]\nWhen you refresh Chrome, you should see one of these words prefixed before your friend\u2019s name. Voila!\n\nStep 3: Choose your color palette\nReal talk: I\u2019m bad at choosing color palettes, so I have a trick up my sleeve that I want to share with you. If you\u2019ve been blessed with the gift of color aptitude, skip ahead.\nHow to choose colors\nTo create a color palette, I start by going to a Coolors.co, and I hit the spacebar until I find a palette that I like. We need a wide gamut of hues for our palette, so lock down colors you like and keep hitting the spacebar until you find a nice, full range. You can use as many or as few colors as you like.\nCopy these colors into your swatches in Adobe Illustrator. They\u2019ll be the base for any illustrations you create later.\nNow you need a set of background colors. Here\u2019s my trick to making these consistent with your illustration palette without completely blending in. Use the \u201cAdjust Palette\u201d tool in Coolors to dial up the brightness a few notches, and the saturation down just a tad to remove any neon effect. These will be your background colors.\n\nAdd your background colors to config.js\nCopy your hex codes into the bgColors array in config.js.\nbgColors: [\n '#FFDD77',\n '#FF8E72',\n '#ED5E84',\n '#4CE0B3',\n '#9893DA',\n ...\n]\nNow when you go back to Chrome and refresh the page, you\u2019ll see your new palette!\n\nStep 4: Accessorize\nThis is the fun part. We\u2019re going to illustrate objects, accessories, lizards\u2014whatever you want\u2014and layer them on top of your friends.\nYour objects will be categorized into groups, and one option from each group will be randomly chosen each time you load the page. Think of a group like \u201chats\u201d or \u201cglasses\u201d. This will allow combinations of accessories to show at once, without showing two of the same type on the same person.\nCreate a group of accessories\nTo get started, open up Illustrator and create a new artboard out of the template. Think of a group of objects that you can riff on. I found hats to be a good place to start. If you don\u2019t feel like illustrating, you can use cut-out images instead.\n\nNext, follow the same steps as you did when you exported the faces. Here they are again:\n\nTurn the Template layer off and export the images as PNGs. \nIn the Export dialog, tick the \u201cUse Artboards\u201d checkbox and enter the range with your hats. \nExport at 72ppi to keep things running fast. \nSave your images into the images/ folder in your project.\n\nAdd your accessories to config.js\nIn config.js, add a new key to the customProps object that describes the group of accessories that you just created. Its value should be an array of the filepaths to your images. This is my hats array:\ncustomProps: {\n hats: [ \n 'images/hat_crown.png',\n 'images/hat_santa.png',\n 'images/hat_tophat.png',\n 'images/hat_antlers.png'\n ]\n}\nRefresh Chrome and behold, accessories!\n\nCreate as many more accessories as you want\nRepeat the steps above to create as many groups of accessories as you want. I went on to make glasses and hairstyles, so my final illustrator file looks like this:\n\nThe last step is adding your new groups to the config object. List your groups in the order that you want them to be stacked in the DOM. My final output will be hair, then hats, then glasses:\ncustomProps: {\n hair: [ \n 'images/hair_bowl.png',\n 'images/hair_bob.png'\n ], \n hats: [ \n 'images/hat_crown.png',\n 'images/hat_santa.png',\n 'images/hat_tophat.png',\n 'images/hat_antlers.png'\n ],\n glasses: [\n 'images/glasses_aviators.png',\n 'images/glasses_monacle.png'\n ]\n}\nAnd, there you have it! Randomly generated friends with random accessories. \n\nFeel free to go much crazier than I did. I considered adding a whole group of animals in celebration of the new season of Planet Earth, or even adding Sir David Attenborough himself, or doing a bit of role reversal and featuring the animals with little safari hats! But I digress\u2026\nStep 5: Publish it\nIt\u2019s time to put this in your new tabs! You have two options:\n\nPublish it as a Chrome extension in the Chrome Web Store.\nHost it as a website and point to it with the New Tab Redirect extension.\n\nToday, we\u2019re going to cover Option #1 because I want to show you how to make the simplest Chrome extension possible. However, I recommend Option #2 if you want to keep your project private. Every Chrome extension that you publish is made publicly available, so unless your friends want their faces published to an extension that anyone can use, I\u2019d suggest sticking to Option #2.\nHow to make a simple Chrome extension to replace the new tab page\nAll you need to do to make your project into a Chrome extension is add a manifest.json file to the root of your project with the following contents. There are plenty of other properties that you can add to your manifest file, but these are the only ones that are required for a new tab replacement:\n{\n \"manifest_version\": 2,\n \"name\": \"Your extension name\",\n \"version\": \"1.0\",\n \"chrome_url_overrides\" : {\n \"newtab\": \"index.html\"\n }\n}\nTo test your extension, you\u2019ll need to run it in Developer Mode. Here\u2019s how to do that:\n\nGo to the Extensions page in Chrome by navigating to chrome://extensions/.\nTick the checkbox in the upper-right corner labelled \u201cDeveloper Mode\u201d.\nClick \u201cLoad unpacked extension\u2026\u201d and select this project.\nIf everything is running smoothly, you should see your project when you open a new tab. If there are any errors, they should appear in a yellow box on the Extensions page.\n\nVoila! Like I said, this is a very light example of a Chrome extension, but Google has tons of great documentation on how to take things further. Check it out and see what inspires you.\nShare the love\nNow that you know how to make a new tab extension, go forth and create! But wield your power responsibly. New tabs are opened so often that they\u2019ve become a part of everyday life\u2013just consider how many tabs you opened today. Some people prefer to-do lists in their tabs, and others prefer cats. \nAt the end of the day, let\u2019s make something that makes us happy. Cheers!", "year": "2016", "author": "Leslie Zacharkow", "author_slug": "lesliezacharkow", "published": "2016-12-08T00:00:00+00:00", "url": "https://24ways.org/2016/how-to-make-a-chrome-extension/", "topic": "code"} {"rowid": 307, "title": "Get the Balance Right: Responsive Display Text", "contents": "Last year in 24 ways I urged you to Get Expressive with Your Typography. I made the case for grabbing your readers\u2019 attention by setting text at display sizes, that is to say big. You should consider very large text in the same way you might a hero image: a picture that creates an atmosphere and anchors your layout.\nWhen setting text to be read, it is best practice to choose body and subheading sizes from a pre-defined scale appropriate to the viewport dimensions. We set those sizes using rems, locking the text sizes together so they all scale according to the page default and your reader\u2019s preferences. You can take the same approach with display text by choosing larger sizes from the same scale.\nHowever, display text, as defined by its purpose and relative size, is text to be seen first, and read second. In other words a picture of text. When it comes to pictures, you are likely to scale all scene-setting imagery - cover photos, hero images, and so on - relative to the viewport. Take the same approach with display text: lock the size and shape of the text to the screen or browser window.\nIntroducing viewport units\nWith CSS3 came a new set of units which are locked to the viewport. You can use these viewport units wherever you might otherwise use any other unit of length such as pixels, ems or percentage. There are four viewport units, and in each case a value of 1 is equal to 1% of either the viewport width or height as reported in reference1 pixels:\n\nvw - viewport width,\nvh - viewport height,\nvmin - viewport height or width, whichever is smaller\nvmax - viewport height or width, whichever is larger\n\nIn one fell swoop you can set the size of a display heading to be proportional to the screen or browser width, rather than choosing from a scale in a series of media queries. The following makes the heading font size 13% of the viewport width:\nh1 {\n font-size: 13 vw;\n}\nSo for a selection of widths, the rendered font size would be:\nRendered font size (px)\nViewport width\n13\u202fvw\n320\n42\n768\n100\n1024\n133\n1280\n166\n1920\n250\n\nA problem with using vw in this manner is the difference in text block proportions between portrait and landscape devices. Because the font size is based on the viewport width, the text on a landscape display is far bigger than when rendered on the same device held in a portrait orientation. \nLandscape text is much bigger than portrait text when using vw units.\nThe proportions of the display text relative to the screen are so dissimilar that each orientation has its own different character, losing the inconsistency and considered design you would want when designing to make an impression.\nHowever if the text was the same size in both orientations, the visual effect would be much more consistent. This where vmin comes into its own. Set the font size using vmin and the size is now set as a proportion of the smallest side of the viewport, giving you a far more consistent rendering.\nh1 {\n font-size: 13vmin;\n}\nLandscape text is consistent with portrait text when using vmin units.\nComparing vw and vmin renderings for various common screen dimensions, you can see how using vmin keeps the text size down to a usable magnitude:\nRendered font size (px)\nViewport\n13\u202fvw\n13\u202fvmin\n320 \u00d7 480\n42\n42\n414 \u00d7 736\n54\n54\n768 \u00d7 1024\n100\n100\n1024 \u00d7 768\n133\n100\n1280 \u00d7 720\n166\n94\n1366 \u00d7 768\n178\n100\n1440 \u00d7 900\n187\n117\n1680 \u00d7 1050\n218\n137\n1920 \u00d7 1080\n250\n140\n2560 \u00d7 1440\n333\n187\n\nHybrid font sizing\nUsing vertical media queries to set text in direct proportion to screen dimensions works well when sizing display text. In can be less desirable when sizing supporting text such as sub-headings, which you may not want to scale upwards at the same rate as the display text. For example, we can size a subheading using vmin so that it starts at 16 px on smaller screens and scales up in the same way as the main heading:\nh1 {\n font-size: 13vmin;\n}\nh2 {\n font-size: 5vmin;\n}\nUsing vmin alone for supporting text can scale it too quickly\nThe balance of display text to supporting text on the phone works well, but the subheading text on the tablet, even though it has been increased in line with the main heading, is starting to feel disproportionately large and a little clumsy. This problem becomes magnified on even bigger screens.\nA solution to this is use a hybrid method of sizing text2. We can use the CSS calc() function to calculate a font size simultaneously based on both rems and viewport units. For example:\nh2 {\n font-size: calc(0.5rem + 2.5vmin);\n}\nFor a 320 px wide screen, the font size will be 16 px, calculated as follows:\n(0.5 \u00d7 16) + (320 \u00d7 0.025) = 8 + 8 = 16px\nFor a 768 px wide screen, the font size will be 27 px:\n(0.5 \u00d7 16) + (768 \u00d7 0.025) = 8 + 19 = 27px\nThis results in a more balanced subheading that doesn\u2019t take emphasis away from the main heading:\n\nTo give you an idea of the effect of using a hybrid approach, here\u2019s a side-by-side comparison of hybrid and viewport text sizing:\ntable.ex--scale{width:100%;overflow: hidden;} table.ex--scale td{vertical-align:baseline;text-align:center;padding:0} tr.ex--scale-key{color:#666} tr.ex--scale-key td{font-size:.875rem;padding:0 0.125em} .ex--scale-2 tr.ex--scale-size{color:#ccc} tr.ex--scale-size td{font-size:1em;line-height:.34em;padding-bottom:.5rem} td.ex--scale-step{color:#000} td.ex--scale-hilite{color:red} .ex--scale-3 tr.ex--scale-size td{line-height:.9em}\n\ntop: calc() hybrid method; bottom: vmin only\n16\n20\n27\n32\n35\n40\n44\n16\n24\n38\n48\n54\n64\n72\n320\n480\n768\n960\n1080\n1280\n1440\n\nOver this festive period, try experiment with the proportion of rem and vmin in your hybrid calculation to see what feels best for your particular setting.\n\n\n\n\nA reference pixel is based on the logical resolution of a device which takes into account double density screens such as Retina displays.\u00a0\u21a9\ufe0e\n\n\nFor even more sophisticated uses of hybrid text sizing see the work of Mike Riethmuller.\u00a0\u21a9\ufe0e", "year": "2016", "author": "Richard Rutter", "author_slug": "richardrutter", "published": "2016-12-09T00:00:00+00:00", "url": "https://24ways.org/2016/responsive-display-text/", "topic": "code"} {"rowid": 292, "title": "Watch Your Language!", "contents": "I\u2019m bilingual. My first language is French. I learned English in my early 20s. Learning a new language later in life meant that I was able to observe my thought processes changing over time. It made me realize that some concepts can\u2019t be expressed in some languages, while other languages express these concepts with ease.\nIt also helped me understand the way we label languages. English: business. French: romance. Here\u2019s an example of how words, or the absence thereof, can affect the way we think:\nIn French we love everything. There\u2019s no straightforward way to say we like something, so we just end up loving everything. I love my sisters, I love broccoli, I love programming, I love my partner, I love doing laundry (this is a lie), I love my mom (this is not a lie). I love, I love, I love. It\u2019s no wonder French is considered romantic. When I first learned English I used the word love rather than like because I hadn\u2019t grasped the difference. Needless to say, I\u2019ve scared away plenty of first dates!\nLearning another language made me realize the limitations of my native language and revealed concepts I didn\u2019t know existed. Without the nuances a given language provides, we fail to express what we really think. The absence of words in our vocabulary gets in the way of effectively communicating and considering ideas.\nWhen I lived in Montr\u00e9al, most people in my circle spoke both French and English. I could switch between them when I could more easily express an idea in one language or the other. I liked (or should I say loved?) those conversations. They were meaningful. They were efficient.\n\nI\u2019m quadrilingual. I code in Ruby, HTML/CSS, JavaScript, Python. In the past couple of years I have been lucky enough to write code in these languages at a massive scale. In learning Ruby, much like learning English, I discovered the strengths and limitations of not only the languages I knew but the language I was learning. It taught me to choose the right tool for the job.\nWhen I started working at Shopify, making a change to a view involved copy/pasting HTML and ERB from one view to another. The CSS was roughly structured into modules, but those modules were not responsive to different screen sizes. Our HTML was complete mayhem, and we didn\u2019t consider accessibility. All this made editing views a laborious process.\nGrep. Replace all. Test. Ship it. Repeat.\nThis wasn\u2019t sustainable at Shopify\u2019s scale, so the newly-formed front end team was given two missions:\n\nMake the app responsive (AKA Let\u2019s Make This Thing Responsive ASAP)\nMake the view layer scalable and maintainable (AKA Let\u2019s Build a Pattern Library\u2026 in Ruby)\n\nLet\u2019s make this thing responsive ASAP\nThe year was 2015. The Shopify admin wasn\u2019t mobile friendly. Our browser support was set to IE10. We had the wind in our sails. We wanted to achieve complete responsiveness in the shortest amount of time. Our answer: container queries.\nIt seemed like the obvious decision at the time. We would be able to set rules for each component in isolation and the component would know how to lay itself out on the page regardless of where it was rendered. It would save us a ton of development time since we wouldn\u2019t need to change our markup, it would scale well, and we would achieve complete component autonomy by not having to worry about page layout. By siloing our components, we were going to unlock the ultimate goal of componentization, cutting the tie to external dependencies. We were cool.\nWriting the JavaScript handling container queries was my first contribution to Shopify. It was a satisfying project to work on. We could drop our components in anywhere and they would magically look good. It took us less than a couple weeks to push this to production and make our app mostly responsive.\nBut with time, it became increasingly obvious that this was not as performant as we had hoped. It wasn\u2019t performant at all. Components would jarringly jump around the page before settling in on first paint.\nIt was only when we started using the flex-wrap: wrap CSS property to build new components that we realized we were not using the right language for the job. So we swapped out JavaScript container queries for CSS flex-wrapping. Even though flex wasn\u2019t yet as powerful as we wanted it to be, it was still a good compromise. Our components stayed independent of the window size but took much less time to render. Best of all: they used CSS instead of relying on JavaScript for layout.\nIn other words: we were using the wrong language to express our layout to the browser, when another language could do it much more simply and elegantly.\nLet\u2019s build a pattern library\u2026 in Ruby\nIn order to make our view layer maintainable, we chose to build a comprehensive library of helpers. This library would generate our markup from a single source of truth, allowing us to make changes system-wide, in one place. No. More. Grepping.\nWhen I joined Shopify it was a Rails shop freshly wounded by a JavaScript framework (See: Batman.js). JavaScript was like Voldemort, the language that could not be named. Because of this baggage, the only way for us to build a pattern library that would get buyin from our developers was to use Rails view helpers. And for many reasons using Ruby was the right choice for us. The time spent ramping developers up on the new UI Components would be negligible since the Ruby API felt familiar. The transition would be simple since we didn\u2019t have to introduce any new technology to the stack. The components would be fast since they would be rendered on the server. We had a plan.\nWe put in place a set of Rails tools to make it easy to build components, then wrote a bunch of sweet, sweet components using our shiny new tools. To document our design, content and front end patterns we put together an interactive styleguide to demonstrate how every component works. Our research and development department loved it (and still do)! We continue to roll out new components, and generally the project has been successful, though it has had its drawbacks.\nSince the Shopify admin is mostly made up of a huge number of forms, most of the content is static. For this reason, using server-rendered components didn\u2019t seem like a problem at the time. With new app features increasing the amount of DOM manipulation needed on the client side, our early design decisions mean making requests to the server for each re-paint. This isn\u2019t going to cut it.\nI don\u2019t know the end of this story, because we haven\u2019t written it yet. We\u2019ve been exploring alternatives to our current system to facilitate the rendering of our components on the client, including React, Vue.js, and Web Components, but we haven\u2019t determined the winner yet. Only time (and data gathering) will tell.\nRuby is great but it doesn\u2019t speak the browser\u2019s language efficiently. It was not the right language for the job.\n\nLearning a new spoken language has had an impact on how I write code. It has taught me that you don\u2019t know what you don\u2019t know until you have the language to express it. Understanding the strengths and limitations of any programming language is fundamental to making good design decisions. At the end of the day, you make the best choices with the information you have. But if you still feel like you\u2019re unable to express your thoughts to the fullest with what you know, it might be time to learn a new language.", "year": "2016", "author": "Annie-Claude C\u00f4t\u00e9", "author_slug": "annieclaudecote", "published": "2016-12-10T00:00:00+00:00", "url": "https://24ways.org/2016/watch-your-language/", "topic": "code"} {"rowid": 298, "title": "First Steps in VR", "contents": "The web is all around us. As web folk, it is our responsibility to consider the impact our work can have. Part of this includes thinking about the future; the web changes lives and if we are building the web then we are the ones making decisions that affect people in every corner of the world. I find myself often torn between wanting to make the right decisions, and just wanting to have fun. To fiddle and play. We all know how important it is to sometimes just try ideas, whether they will amount to much or not. \nI think of these two mindsets as production and prototyping, though of course there are lots of overlap and phases in between. I mention this because virtual reality is currently seen as a toy for rich people, and in some ways at the moment it is. But with WebVR we are able to create interesting experiences with a relatively low entry point. I want us to have open minds, play around with things, and then see how we can use the tools we have at our disposal to make things that will help people.\nEvery year we see articles saying it will be the \u201cyear of virtual reality\u201d, that was especially prevalent this year. 2016 has been a year of progress, VR isn\u2019t quite mainstream but with efforts like Playstation VR and Google Cardboard, we are definitely seeing much more of it. This year also saw the consumer editions of the Oculus Rift and HTC Vive. So it does seem to be a good time for an overview of how to get involved with creating virtual reality on the web.\nWebVR is an API for connecting to devices and retrieving continuous data such as the position and orientation. Unlike the Web Audio API and some other APIs, WebVR does not feel like a framework. You use it however you want, taking the data and using it as you wish. To make it easier, there are plenty of resources such as Three.js, A-Frame and ReactVR that help to make the heavy lifting a bit easier.\nGetting Started with A-Frame\nI like taking the opportunity to learn new things whenever I can. So while planning this article I thought that instead of trying to teach WebGL or even Three.js in a way that is approachable for all, I would create my first project using A-Frame and write about that. This is not a tutorial as such, I just want to show how to go about getting involved with VR. The beauty of A-Frame is that it is very similar to web components, you can just write HTML to build worlds that will automatically work on all the different types of devices. It uses WebGL and WebVR but in such a way that it quite drastically reduces the learning curve. That\u2019s not to say you can\u2019t build complex things, you have complete access to write JavaScript and shaders.\nI\u2019m lazy. Whenever I learn a new language or framework I have found that the best way, personally, for me to learn is to have a project and to copy the starting code from someone else. A project lets you have a good idea of what you want to produce and it means you can ignore a lot of the irrelevant documentation, focussing purely on what you need. That reduces the stress of figuring things out. Copying code also makes it easier, because you know your boilerplate code is working. There\u2019s nothing worse than getting stuck before anything actually works the first time. So I tinker. I take code and I modify it, I play around. It\u2019s fun.\nFor this project I wanted to keep things as simple as possible, so I can easily explain it without the classic \u201cdraw a circle then draw an owl\u201d. I wrote a list of requirements, with some stretch goals that you can give a try yourself if you fancy:\n\nMust work on Google Cardboard at a minimum, because of price\nTherefore, it must not rely on having a controller\nAuto-moving around a maze would be a good example\nMove in direction you look\nStretch goal: Scoring, time until you hit a wall or get stuck in maze\nStretch goal: Levels, so the map doesn\u2019t need to be random\nStretch goal: Snow!\n\nI decided to base this project on an example, Platforms, by Don McCurdy who wrote the really useful aframe-extras. Platforms has random 3D blocks that you can jump onto, going up into the sky. So I took his code and reduced it so that the blocks are randomly spread on the ground. \n\n\n\n \n \n 24 ways\n \n \n\n\n\n \n \n\n \n\n \n\n \n\n \n \n\n\n\n\nAs you can see, this is very readable. Especially if you ignore the JavaScript that is used to create the maze. A-Frame (with A-Frame Extras) gives you a lot of power with relatively little to learn. We start with an which is the container for everything that is going to show up on the screen. There are a few which can be compared to
as they are essentially non-semantic containers, able to be used for any purpose. The attributes are used to define functionality, for example the camera attribute sets the entity to function as a camera and kinematic-body makes it collide instead of go through objects. Attributes are also used to set position and sizes, often using JavaScript to dynamically define them.\nStyling\nNow we\u2019ve got the HTML written, we need to style it. To do this we add A-Frame compatible attributes such as color and material. I recommend playing around, you can get some quite impressive effects fairly easily. Originally I wanted a light snowy maze but it ended up being dark and foggy, as I really liked the feeling it gave.\nNote, you will probably need a server running for images to work. You can do this by running python -m \"SimpleHTTPServer\" in the folder where the code is, then go to localhost:8000 in browser.\nTextures\nUnless you are going for a cartoony style, you probably want to find some textures. I found some on textures.com, one image worked well for the walls and the other for the floor.\n\n \n \n\nThe is used to define (as well as preload and cache) all assets, including images, audio and video. As you can see, images in the Asset Management System just use normal img tags. The ids are important here as we can use them later for using the textures. \nTo apply a texture to an object, you create a material. For a simple material where it just shows the image, you set the src to the id selector of the image.\nReplace: \n\nWith:\n\nThis will automatically make the image repeat over the entire floor, in my case filling it with bricks. The walls are pretty much identical, with the slight exception that it is set in JavaScript as they are dynamically defined.\nbox.setAttribute('material', 'src: #texture-wall');\nThat\u2019s it for the textures, for now at least. These will not look completely realistic, as the light will bump off the rectangular wall rather than texture itself. This can be improved by using maps, textures that are used to modify the shape and physical properties of the object. \nLighting\nThe next part of styling is lighting. By using fog and different types of lighting, we are able to add atmospheric details to the game to make it feel that bit more realistic and polished.\nThere are lots of types of light in A-Frame (most coming from Three.js). You can add a light either by using the entity or by attaching a light attribute to any other entity. If there are no lights defined then A-Frame adds some by default so that the scene is always lit.\nTo start with I wanted to light up the scene with a general light, type=\"ambient\", so that the whole game felt slightly dark. I chose to set the light to a reddish colour #92455E. After playing around with intensity I chose 0.4, it added enough light to get the feeling I wanted without it being overly red. I also added a blue skybox (), as it looked a bit odd with a white sky.\n\n\nI felt that the maze looked good with a red tinge but it was a bit flat, everything was the same colour and it was a bit dark. So I added a light within the #player entity, this could have been as an attribute but I set it as a child a-light instead. By using type=\"point\" with a high intensity and low distance, it showed close walls as being lighter. It also added a sort-of object to the player, it isn\u2019t a walking human or anything but by moving light where the player is it feels a bit more physical.\n\n\nBy this point it was starting to look decent, so I wanted to add the fog to really give some personality and depth to the maze. To do this I added the fog attribute to the with type=exponential so it looks thicker the further away it is and a mid intensity, so you feel a bit lost but can still see.\n\nI was very happy with this result. It took a lot of playing around with colours and values, which is fun in itself. I highly recommend you take the code (or write your own) and play around with the numbers.\nMovement\nOne of the reasons I decided to use aframe-extras is that it has a few different camera controls built in. As you saw earlier, I am using the universal-controls which gives WASD (keyboard) controls by default. I wanted to make it automatically move in the direction that you\u2019re looking, but I wasn\u2019t quite sure how without rewriting the controls. So I asked Don McCurdy for advice and he very nicely gave me a small snippet of code to get it working.\nAFRAME.registerComponent('automove-controls', {\n init: function () {\n this.speed = 0.1;\n this.isMoving = true;\n this.velocityDelta = new THREE.Vector3();\n },\n isVelocityActive: function () {\n return this.isMoving;\n },\n getVelocityDelta: function () {\n this.velocityDelta.z = this.isMoving ? -speed : 0;\n return this.velocityDelta.clone();\n }\n});\nReplace:\nuniversal-controls\nWith:\nuniversal-controls=\"movementControls: automove, gamepad, keyboard\"\nThis works by creating a component automove-controls that adds auto-move to the player without overriding movement completely. It doesn\u2019t even touch direction, it just checks if isMoving is true then moves the player by the set speed. Components can be creating for adding all kinds of functionality with relative ease. It makes it very powerful for people of all difficulty levels.\nBuilding a map\nCurrently the maze is created randomly, which is great but means there will often be walls that overlap or the player gets trapped with nowhere to go. So to solve this, I decided to use a map editor (Tiled) so that we can create the mazes ourselves. This is a great start towards one of the stretch goals, levels.\nI made the maze in Tiled by finding a random tileset online (we don\u2019t need to actually show the images), I used one tile for the wall and another for the player. Then I exported as a JavaScript file and modified it in my text editor to get rid of everything I didn\u2019t need. I made it so 0 is the path, 1 is the wall and 2 is the player. I then added the script to the HTML, as a separate file so it\u2019s easy to update in the future. \nvar map =\n{\n \"data\":[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],\n \"height\":10,\n \"width\":10\n}\n\nAs you can see, this gives a simple 10x10 maze with some dead ends. The player starts in the bottom right corner (my choice, could be anywhere). I rewrote the random platforms code (from Don\u2019s example) to instead loop over the map data and place walls where it is 1 and position the player where data is 2. I set the position so that the origin of the map would be 0,1.5,0. The y axis is in this case the height (ground being 0), but if a wall is positioned at 0 by its centre then some of it is underground. So the y needed to be the height divided by 2.\ndocument.querySelector('a-scene').addEventListener('render-target-loaded', function () {\n var WALL_SIZE = 5,\n WALL_HEIGHT = 3;\n var el = document.querySelector('#walls');\n var wall;\n\n for (var x = 0; x < map.height; x++) {\n for (var y = 0; y < map.width; y++) {\n\n var i = y*map.width + x;\n var position = (x-map.width/2)*WALL_SIZE + ' ' + 1.5 + ' ' + (y-map.height/2)*WALL_SIZE;\n if (map.data[i] === 1) {\n // Create wall\n wall = document.createElement('a-box');\n el.appendChild(wall);\n wall.setAttribute('color', '#fff');\n wall.setAttribute('material', 'src: #texture-wall;');\n wall.setAttribute('width', WALL_SIZE);\n wall.setAttribute('height', WALL_HEIGHT);\n wall.setAttribute('depth', WALL_SIZE);\n wall.setAttribute('position', position);\n wall.setAttribute('static-body', ');\n }\n\n if (map.data[i] === 2) {\n // Set player position\n document.querySelector('#player').setAttribute('position', position);\n }\n\n }\n }\n console.info('Walls added.');\n});\n\nWith this added, it makes it nice and easy to change around the map as well as to add new features. Perhaps you want monsters or objects. Just set the number in the map data and add an if statement to the loop. In the future you could add layers, so multiple things can be in the same position. Or perhaps even make the maze go up the y axis too, with ramps or staircases. There\u2019s a lot you can do with relative ease. As you can see, A-Frame really does reduce the learning curve of 3D and VR on the web.\nIt\u2019s Not All Fun And Games\nA lot of examples of virtual reality are games, including this one. So it is understandable to think that VR is for gaming, but actually that\u2019s just a tiny subset. There are all sorts of applications for VR, including story telling, data visualisation and even meditation.\nThere have been a number of cases where it has been shown virtual reality can help as a tool for therapies:\n\nOxford study finds virtual reality can help treat severe paranoia\nVirtual Reality Therapy for Phobias at the Duke Faculty Practice\nBravemind: Virtual Reality Exposure Therapy at the University of Southern California\n\nThese are just a few examples of where virtual reality is being used around the world to help people feel better and get through some very tough times. There have also been examples of it being used for simulating war zones or medical situations, both as a teaching and journalism tool.\nWrapping Up\nTen years ago, on this very site, Cameron Moll wrote an article explaining the mobile web. He explained how mobile phones with data plans were becoming increasingly common, that WAP 2.0 included the XHTML Mobile Profile meaning it would be familiar with web folk. \u201cThe mobile web is rapidly becoming an XHTML environment, and thus you and I can apply our existing \u201cdesktop web\u201d skills to understand how to develop content for it.\u201d\nWe can look at that and laugh a little, we have come a very long way in the last decade. Even people in developing countries with very little money have mobile phones with access to a web that is far more capable than the \u201cdesktop web\u201d Cameron was referring to.\nSo while I am not saying virtual reality is going to change the world or replace our phones, who knows! We can use our skills as web folk to dabble, we don\u2019t need to learn any new languages. If on the 2026 edition of 24 ways, somebody references this article and looks at how far we have come\u2026 well, let\u2019s hope we have used our skills well and made the world just that little bit better. And if VR is a fad? Well it\u2019s fun\u2026 have a go anyway.", "year": "2016", "author": "Shane Hudson", "author_slug": "shanehudson", "published": "2016-12-11T00:00:00+00:00", "url": "https://24ways.org/2016/first-steps-in-vr/", "topic": "code"} {"rowid": 306, "title": "What next for CSS Grid Layout?", "contents": "In 2012 I wrote an article for 24 ways detailing a new CSS Specification that had caught my eye, at the time with an implementation only in Internet Explorer. What I didn\u2019t realise at the time was that CSS Grid Layout was to become a theme on which I would base the next four years of research, experimentation, writing and speaking. \nAs I write this article in December 2016, we are looking forward to CSS Grid Layout being shipped in Chrome and Firefox. What will ship early next year in those browsers is expanded and improved from the early implementation I explored in 2012. Over the last four years the spec has been developed as part of the CSS Working Group process, and has had input from browser engineers, specification writers and web developers. Use cases have been discussed, and features added.\nThe CSS Grid Layout specification is now a Candidate Recommendation. This status means the spec is to all intents and purposes, finished. The discussions now happening are on fine implementation details, and not new feature ideas. It makes sense to draw a line under a specification in order that browser vendors can ship complete, interoperable implementations. That approach is good for all of us, it makes development far easier if we know that a browser supports all of the features of a specification, rather than working out which bits are supported. However it doesn\u2019t mean that works stops here, and that new use cases and features can\u2019t be proposed for future levels of Grid Layout. Therefore, in this article I\u2019m going to take a look at some of the things I think grid layout could do in the future. I would love for these thoughts to prompt you to think about how Grid - or any CSS specification - could better suit the use cases you have.\nSubgrid - the missing feature of Level 1\nThe implementation of CSS Grid Layout in Chrome, Firefox and Webkit is comparable and very feature complete. There is however one standout feature that has not been implemented in any browser as yet - subgrid. Once you set the value of the display property to grid, any direct children of that element become grid items. This is similar to the way that flexbox behaves, set display: flex and all direct children become flex items. The behaviour does not apply to children of those items. You can nest grids, just as you can nest flex containers, but the child grids have no relationship to the parent.\n\nNesting Grids by Rachel Andrew (@rachelandrew) on CodePen.\nThe subgrid behaviour would enable the grid defined on the parent to be used by the children. I feel this would be most useful when working with a multiple column flexible grid - for example a typical 12 column grid. I could define a grid on a wrapper, then position UI elements on that grid - from the major structural elements of my page down through the child elements to a form where I wanted the field to line up with items above.\nThe specification contained an initial description of subgrid, with a value of subgrid for grid-template-columns and grid-template-rows, you can read about this in the August 2015 Working Draft. This version of the specification would have meant you could declare a subgrid in one dimension only, and create a different set of tracks in the other.\nIn an attempt to get some implementation of subgrid, a revised specification was proposed earlier this year. This gives a single subgrid value of the display property. As we now cannot specify a subgrid on rows OR columns this limits us to have a subgrid that works in two dimensions. At this point neither version has been implemented by anyone, and subgrids are marked as \u201cat risk\u201d in the Level 1 Candidate Recommendation. With regard to \u2018at-risk\u2019 this is explained as follows:\n\n\u201c\u2018At-risk\u2019 is a W3C Process term-of-art, and does not necessarily imply that the feature is in danger of being dropped or delayed. It means that the WG believes the feature may have difficulty being interoperably implemented in a timely manner, and marking it as such allows the WG to drop the feature if necessary when transitioning to the Proposed Rec stage, without having to publish a new Candidate Rec without the feature first.\u201d \n\nIf we lose subgrid from Level 1, as it looks likely that we will, this does give us a chance to further discuss and iterate on that feature. My current thoughts are that I\u2019m not completely happy about subgrids being tied to both dimensions and feel that a return to the earlier version, or something like it, would be preferable. \nFurther reading about subgrid\n\nMy post from 2015 detailing why I feel subgrid is important\nMy post based on the revised specification\nEric Meyer\u2019s thoughts on subgrid\nWrite-up of a discussion from Igalia who work on the Blink and Webkit browser implementations\n\nStyling cells, tracks and areas\nHaving defined a grid with CSS Grid Layout you can place child elements into that grid, however what you can\u2019t do is style the grid tracks or cells. Grid doesn\u2019t even go as far as multiple column layout, which has the column-rule properties.\nIn order to set a background colour on a grid cell at the moment you would have to add an empty HTML element or insert some generated content as in the below example. I\u2019m using a 1 pixel grid gap to fake lines between grid cells, and empty div elements, and some generated content to colour those cells.\n\nFaked backgrounds and borders by Rachel Andrew (@rachelandrew) on CodePen.\nI think it would be a nice addition to Grid Layout to be able to directly add backgrounds and borders to cells, tracks and areas. There is an Issue raised in the CSS WG Drafts repository for Decorative Grid Cell pseudo-elements, if you want to add thoughts to that.\nMore control over auto placement\nIf you haven\u2019t explicitly placed the direct children of your grid element they will be laid out according to the grid auto placement rules. You can see in this example how we have created a grid and the items are placing themselves into cells on that grid.\n\nItems auto-place on a defined grid by Rachel Andrew (@rachelandrew) on CodePen.\nThe auto-placement algorithm is very cool. We can position some items, leaving others to auto-place; we can set items to span more than one track; we can use the grid-auto-flow property with a value of dense to backfill gaps in our grid.\n\nWebsafe colors meet CSS Grid (auto-placement demo) by Rachel Andrew (@rachelandrew) on CodePen.\nI think however this could be taken further. In this issue posted to my CSS Grid AMA on GitHub, the question is raised as to whether it would be possible to ask grid to place items on the next available line of a certain name. This would allow you to skip tracks in the grid when using auto-placement, an issue that has also been raised by Emil Bj\u00f6rklund in this post to the www-style list prior to spec discussion moving to Github. I think there are probably similar issues, if you can think of one add a comment here.\nCreating non-rectangular grid areas\nA grid area is a collection of grid cells, defined by setting the start and end lines for columns and rows or by creating the area in the value of the grid-template-areas property as shown below. Those areas however must be rectangular - you can\u2019t create an L-shaped or otherwise non-regular shape.\n\nGrid Areas by Rachel Andrew (@rachelandrew) on CodePen.\n\nPerhaps in the future we could define an L-shape or other non-rectangular area into which content could flow, as in the below currently invalid code where a quote is embedded into an L-shaped content area.\n.wrapper {\n display: grid;\n grid-template-areas:\n \"sidebar header header\"\n \"sidebar content quote\"\n \"sidebar content content\";\n}\nFlowing content through grid cells or areas\nSome uses cases I have seen perhaps are not best solved by grid layout at all, but would involve grid working alongside other CSS specifications. As I detail in this post, there are a class of problems that I believe could be solved with the CSS Regions specification, or a revised version of that spec.\nBeing able to create a grid layout, then flow content through the areas could be very useful. Jen Simmons presented to the CSS Working Group at the Lisbon meeting a suggestion as to how this might work.\nIn a post from earlier this year I looked at a collection of ideas from specifications that include Grid, Regions and Exclusions. These working notes from my own explorations might prompt ideas of your own.\nSolving the keyboard/layout disconnect\nOne issue that grid, and flexbox to a lesser extent, raises is that it is very easy to end up with a layout that is disconnected from the underlying markup. This raises problems for people navigating using the keyboard as when tabbing around the document you find yourself jumping to unexpected places. The problem is explained by L\u00e9onie Watson with reference to flexbox in Flexbox and the keyboard navigation disconnect.\nThe grid layout specification currently warns against creating such a disconnect, however I think it will take careful work by web developers in order to prevent this. It\u2019s also not always as straightforward as it seems. In some cases you want the logical order to follow the source, and others it would make more sense to follow the visual. People are thinking about this issue, as you can read in this mailing list discussion.\nBringing your ideas to the future of Grid Layout\nWhen I\u2019m not getting excited about new CSS features, my day job involves working on a software product - the CMS that is serving this very website, Perch. When we launched Perch there were many use cases that we had never thought of, despite having a good idea of what might be needed in a CMS and thinking through lots of use cases. The additional use cases brought to our attention by our customers and potential customers informed the development of the product from launch. The same will be true for Grid Layout.\nAs a \u201cproduct\u201d grid has been well thought through by many people. Yet however hard we try there will be use cases we just didn\u2019t think of. You may well have one in mind right now. That\u2019s ok, because as with any CSS specification, once Level One of grid is complete, work can begin on Level Two. The feature set of Level Two will be informed by the use cases that emerge as people get to grips with what we have now.\nThis is where you get to contribute to the future of layout on the web. When you hit up against the things you cannot do, don\u2019t just mutter about how the CSS Working Group don\u2019t listen to regular developers and code around the problem. Instead, take a few minutes and write up your use case. Post it to your blog, to Medium, create a CodePen and go to the CSS Working Group GitHub specs repository and post an issue there. Write some pseudo-code, draw a picture, just make sure that the use case is described in enough detail that someone can see what problem you want grid to solve. It may be that - as with any software development - your use case can\u2019t be solved in exactly the way you suggest. However once we have a use case, collected with other use cases, methods of addressing that class of problems can be investigated. \nI opened this article by explaining I\u2019d written about grid layout four years ago, and how we\u2019re only now at a point where we will have Grid Layout available in the majority of browsers. Specification development, and implementation into browsers takes time. This is actually a good thing, as it\u2019s impossible to take back CSS once it is out there and being used by production websites. We want CSS in the wild to be well thought through and that takes time. So don\u2019t feel that because you don\u2019t see your use case added to a spec immediately it has been ignored. Do your future self a favour and write down your frustrations or thoughts, and we can all make sure that the web platform serves the use cases we\u2019re dealing with now and in the future.", "year": "2016", "author": "Rachel Andrew", "author_slug": "rachelandrew", "published": "2016-12-12T00:00:00+00:00", "url": "https://24ways.org/2016/what-next-for-css-grid-layout/", "topic": "code"} {"rowid": 311, "title": "Designing Imaginative Style Guides", "contents": "(Living) style guides and (atomic) patterns libraries are \u201call the rage,\u201d as my dear old Nana would\u2019ve said. If articles and conference talks are to be believed, making and using them has become incredibly popular. I think there are plenty of ways we can improve how style guides look and make them better at communicating design information to creatives without it getting in the way of information that technical people need.\nGuides to libraries of patterns\nMost of my consulting work and a good deal of my creative projects now involve designing style guides. I\u2019ve amassed a huge collection of brand guidelines and identity manuals as well as, more recently, guides to libraries of patterns intended to help designers and developers make digital products and websites.\nTwo pages from one of my Purposeful style guide packs. Designs \u00a9 Stuff & Nonsense.\n\u201cStyle guide\u201d is an umbrella term for several types of design documentation. Sometimes we\u2019re referring to static style or visual identity guides, other times voice and tone. We might mean front-end code guidelines or component/pattern libraries. These all offer something different but more often than not they have something in common. They look ugly enough to have been designed by someone who enjoys configuring a router.\nOK, that was mean, not everyone\u2019s going to think an unimaginative style guide design is a problem. After all, as long as a style guide contains information people need, how it looks shouldn\u2019t matter, should it?\nInspiring not encyclopaedic\nWell here\u2019s the thing. Not everyone needs to take the same information away from a style guide. If you\u2019re looking for markup and styles to code a \u2018media\u2019 component, you\u2019re probably going to be the technical type, whereas if you need to understand the balance of sizes across a typographic hierarchy, you\u2019re more likely to be a creative. What you need from a style guide is different.\nSure, some people1 need rules:\n\n\u201cDo this (responsive pattern)\u201d or \u201cdon\u2019t do that (auto-playing video.)\u201d \n\nThose people probably also want facts:\n\n\u201cUse this (hexadecimal value)\u201d and not that inaccessible colour combination.\u201d\n\nStyle guides need to do more than list facts and rules. They should demonstrate a design, not just document its parts. The best style guides are inspiring not encyclopaedic. I\u2019ll explain by showing how many style guides currently present information about colour. \nColours communicate\nI\u2019m sure you\u2019ll agree that alongside typography, colour\u2019s one of the most important ingredients in a design. Colour communicates personality, creates mood and is vital to an easily understandable interactive vocabulary. So you\u2019d think that an average style guide would describe all this in any number of imaginative ways. Well, you\u2019d be disappointed, because the most inspiring you\u2019ll find looks like a collection of chips from a paint chart.\n\nLonely Planet\u2019s Rizzo does a great job of separating its Design Elements from UI Components, and while its \u2018Click to copy\u2019\u00a0colour values are a thoughtful touch, you\u2019ll struggle to get a feeling for Lonely Planet\u2019s design by looking at their colour chips.\nLonely Planet\u2019s Rizzo style guide.\nLonely Planet approach is a common way to display colour information and it\u2019s one that you\u2019ll also find at Greenpeace, Sky, The Times and on countless more style guides.\n\n\n\n\n\nGreenpeace, Sky and The Times style guides.\nGOV.UK\u2014not a website known for its creative flair\u2014varies this approach by using circles, which I find strange as circles don\u2019t feature anywhere else in its branding or design. On the plus side though, their designers have provided some context by categorising colours by usage such as text, links, backgrounds and more.\nGOV.UK style guide.\nGoogle\u2019s Material Design offers an embarrassment of colours but most helpfully it also advises how to combine its primary and accent colours into usable palettes.\nGoogle\u2019s Material Design.\nWhile the ability to copy colour values from a reference might be all a technical person needs, designers need to understand why particular colours were chosen as well as how to use them. \nInspiration not documentation\nFew style guides offer any explanation and even less by way of inspiring examples. Most are extremely vague when they describe colour:\n\n\u201cUse colour as a presentation element for either decorative purposes or to convey information.\u201d\n\nThe Government of Canada\u2019s Web Experience Toolkit states, rather obviously.\n\n\u201cCertain colors have inherent meaning for a large majority of users, although we recognize that cultural differences are plentiful.\u201d\n\nSalesforce tell us, without actually mentioning any of those plentiful differences. \nI\u2019m also unsure what makes the Draft U.S. Web Design Standards colours a \u201cdistinctly American palette\u201d but it will have to work extremely hard to achieve its goal of communicating \u201cwarmth and trustworthiness\u201d now. \nIn Canada, \u201cbold and vibrant\u201d colours reflect Alberta\u2019s \u201cdiverse landscape.\u201d \nAdding more colours to their palette has made Adobe \u201crich, dynamic, and multi-dimensional\u201d and at Skype, colours are \u201cbold, colourful (obviously) and confident\u201d although their style guide doesn\u2019t actually provide information on how to use them.\nThe University of Oxford, on the other hand, is much more helpful by explaining how and why to use their colours:\n\n\u201cThe (dark) Oxford blue is used primarily in general page furniture such as the backgrounds on the header and footer. This makes for a strong brand presence throughout the site. Because it features so strongly in these areas, it is not recommended to use it in large areas elsewhere. However it is used more sparingly in smaller elements such as in event date icons and search/filtering bars.\u201d\n\nOpenTable style guide.\nThe designers at OpenTable have cleverly considered how to explain the hierarchy of their brand colours by presenting them and their supporting colours in various size chips. It\u2019s also obvious from OpenTable\u2019s design which colours are primary, supporting, accent or neutral without them having to say so.\nArt directing style guides\nFor the style guides I design for my clients, I go beyond simply documenting their colour palette and type styles and describe visually what these mean for them and their brand. I work to find distinctive ways to present colour to better represent the brand and also to inspire designers. \nFor example, on a recent project for SunLife, I described their palette of colours and how to use them across a series of art directed pages that reflect the lively personality of the SunLife brand. Information about HEX and RGB values, Sass variables and when to use their colours for branding, interaction and messaging is all there, but in a format that can appeal to both creative and technical people.\nSunLife style guide. Designs \u00a9 Stuff & Nonsense.\nPurposeful style guides\nIf you want to improve how you present colour information in your style guides, there\u2019s plenty you can do.\nFor a start, you needn\u2019t confine colour information to the palette page in your style guide. Find imaginative ways to display colour across several pages to show it in context with other parts of your design. Here are two CSS gradient filled \u2018cover\u2019 pages from my Purposeful style sheets.\nColour impacts other elements too, including typography, so make sure you include colour information on those pages, and vice-versa.\nPurposeful. Designs \u00a9 Stuff & Nonsense.\nA visual hierarchy can be easier to understand than labelling colours as \u2018primary,\u2019 \u2018supporting,\u2019 or \u2018accent,\u2019 so find creative ways to present that hierarchy. You might use panels of different sizes or arrange boxes on a modular grid to fill a page with colour.\nDon\u2019t limit yourself to rectangular colour chips, use circles or other shapes created using only CSS. If irregular shapes are a part of your brand, fill SVG silhouettes with CSS and then wrap text around them using CSS shapes. \nPurposeful. Designs \u00a9 Stuff & Nonsense.\nSumming up\nIn many ways I\u2019m as frustrated with style guide design as I am with the general state of design on the web. Style guides and pattern libraries needn\u2019t be dull in order to be functional. In fact, they\u2019re the perfect place for you to try out new ideas and technologies. There\u2019s nowhere better to experiment with new properties like CSS Grid than on your style guide.\nThe best style guide designs showcase new approaches and possibilities, and don\u2019t simply document the old ones. Be as creative with your style guide designs as you are with any public-facing part of your website.\n\nPurposeful are HTML and CSS style guides templates designed to help you develop creative style guides and pattern libraries for your business or clients. Save time while impressing your clients by using easily customisable HTML and CSS files that have been designed and coded to the highest standards. Twenty pages covering all common style guide components including colour, typography, buttons, form elements, and tables, plus popular pattern library components. Purposeful style guides will be available to buy online in January.\n\n\n\n\nBoring people\u00a0\u21a9", "year": "2016", "author": "Andy Clarke", "author_slug": "andyclarke", "published": "2016-12-13T00:00:00+00:00", "url": "https://24ways.org/2016/designing-imaginative-style-guides/", "topic": "design"} {"rowid": 291, "title": "Information Literacy Is a Design Problem", "contents": "Information literacy, wrote Dr. Carol Kulthau in her 1987 paper \u201cInformation Skills for an Information Society,\u201d is \u201cthe ability to read and to use information essential for everyday life\u201d\u2014that is, to effectively navigate a world built on \u201ccomplex masses of information generated by computers and mass media.\u201d\nNearly thirty years later, those \u201ccomplex masses of information\u201d have only grown wilder, thornier, and more constant. We call the internet a firehose, yet we\u2019re loathe to turn it off (or even down). The amount of information we consume daily is staggering\u2014and yet our ability to fully understand it all remains frustratingly insufficient. \nThis should hit a very particular chord for those of us working on the web. We may be developers, designers, or strategists\u2014we may not always be responsible for the words themselves\u2014but we all know that communication is much more than just words. From fonts to form fields, every design decision that we make changes the way information is perceived\u2014for better or for worse.\nWhat\u2019s more, the design decisions that we make feed into larger patterns. They don\u2019t just affect the perception of a single piece of information on a single site; they start to shape reader expectations of information anywhere. Users develop cumulative mental models of how websites should be: where to find a search bar, where to look at contact information, how to filter a product list. \nAnd yet: our models fail us. Fundamentally, we\u2019re not good at parsing information, and that\u2019s troubling. Our experience of an \u201cinformation society\u201d may have evolved, but the skills Dr. Kuhlthau spoke of are even more critical now: our lives depend on information literacy.\nPatterns from words\nLet\u2019s start at the beginning: with the words. Our choice of words can drastically alter a message, from its emotional resonance to its context to its literal meaning. Sometimes we can use word choice for good, to reinvigorate old, forgotten, or unfairly besmirched ideas.\nOne time at a wedding bbq we labeled the coleslaw BRASSICA MIXTA so people wouldn\u2019t skip it based on false hatred.\u2014 Eileen Webb (@webmeadow) November 27, 2016\n\nWe can also use clever word choice to build euphemisms, to name sensitive or intimate concepts without conjuring their full details. This trick gifts us with language like \u201cthe beast with two backs\u201d (thanks, Shakespeare!) and \u201csurfing the crimson wave\u201d (thanks, Cher Horowitz!).\nBut when we grapple with more serious concepts\u2014war, death, human rights\u2014this habit of declawing our language gets dangerous. Using more discrete wording serves to nullify the concepts themselves, euphemizing them out of sight and out of mind.\nThe result? Politicians never lie, they just \u201cmisspeak.\u201d Nobody\u2019s racist, but plenty of people are \u201ceconomically anxious.\u201d Nazis have rebranded as \u201calt-right.\u201d \nI\u2019m not an asshole, I\u2019m just alt-nice.\u2014 Andi Zeisler (@andizeisler) November 22, 2016\n\nThe problem with euphemisms like these is that they quickly infect everyday language. We use the words we hear around us. The more often we see \u201calt-right\u201d instead of \u201cNazi,\u201d the more likely we are to use that phrase ourselves\u2014normalizing the term as well as the terrible ideas behind it.\nPatterns from sentences\nThat process of normalization gets a boost from the media, our main vector of information about the world outside ourselves. Headlines control how we interpret the news that follows\u2014even if the story contradicts it in the end. We hear the framing more clearly than the content itself, coloring our interpretation of the news over time.\nEven worse, headlines are often written to encourage clicks, not to convey critical information. When headline-writing is driven by sensationalism, it\u2019s much, much easier to build a pattern of misinformation. Take this CBS News headline: \u201cDonald Trump: \u2018Millions\u2019 voted illegally for Hillary Clinton.\u201d The headline makes no indication that this an objectively false statement; instead, this word choice subtly suggestions that millions did, in fact, illegally vote for Hillary Clinton.\nHeadlines like this are what make lying a worthwhile political strategy. https://t.co/DRjGeYVKmW\u2014 Binyamin Appelbaum (@BCAppelbaum) November 27, 2016\n\nThis is a deeply dangerous choice of words when headlines are the primary way that news is conveyed\u2014especially on social media, where it\u2019s much faster to share than to actually read the article. In fact, according to a study from the Media Insight Project, \u201croughly six in 10 people acknowledge that they have done nothing more than read news headlines in the past week.\u201d \nIf a powerful person asserts X there are 2 responsible ways to cover:1. \u201cX is true\u201d2. \u201cPerson incorrectly thinks X\u201dNever \u201cPerson says X\u201d\u2014 Helen Rosner (@hels) November 27, 2016\n\nEven if we do, in fact, read the whole article, there\u2019s no guarantee that we\u2019re thinking critically about it. A study conducted by Stanford found that \u201c82 percent of students could not distinguish between a sponsored post and an actual news article on the same website. Nearly 70 percent of middle schoolers thought they had no reason to distrust a sponsored finance article written by the CEO of a bank, and many students evaluate the trustworthiness of tweets based on their level of detail and the size of attached photos.\u201d \nFriends: our information literacy is not very good. Luckily, we\u2014workers of the web\u2014are in a position to improve it.\nSentences into design\nConsider the presentation of those all-important headlines in social media cards, as on Facebook. The display is a combination of both the card\u2019s design and the article\u2019s source code, and looks something like this:\n\nA large image, a large headline; perhaps a brief description; and, at the bottom, in pale gray, a source and an author\u2019s name. \nThose choices convey certain values: specifically, they suggest that the headline and the picture are the entire point. The source is so deemphasized that it\u2019s easy to see how fake news gains a foothold: daily exposure to this kind of hierarchy has taught us that sources aren\u2019t important. \nAnd that\u2019s the message from the best-case scenario. Not every article shows every piece of data. Take this headline from the BBC: \u201cWisconsin receives request for vote recount.\u201d \n\nWith no image, no description, and no author, there\u2019s little opportunity to signal trust or provide nuance. There\u2019s also no date\u2014ever\u2014which presents potentially misleading complications, especially in the context of \u201cbreaking news.\u201d \nAnd lest you think dates don\u2019t matter in the light-speed era of social media, take the headline, \u201cMaryland sidesteps electoral college.\u201d Shared into my feed two days after the US presidential election, that\u2019s some serious news with major historical implications. But since there\u2019s no date on this card, there\u2019s no way for readers to know that the \u201cTuesday\u201d it refers to was in 2007. Again, a design choice has made misinformation far too contagious.\n\nMore recently, I posted my personal reaction to the death of Fidel Castro via a series of twenty tweets. Wanting to share my thoughts with friends and family who don\u2019t use Twitter, I then posted the first tweet to Facebook. The card it generated was less than ideal:\n\nThe information hierarchy created by this approach prioritizes the name of the Twitter user (not even the handle), along with the avatar. Not only does that create an awkward \u201cheadline\u201d (at least when you include a full stop in your name), but it also minimizes the content of the tweet itself\u2014which was the whole point. \nThe arbitrary elevation of some pieces of content over others\u2014like huge headlines juxtaposed with minimized sources\u2014teaches readers that these values are inherent to the content itself: that the headline is the news, that the source is irrelevant. We train readers to stop looking for the information we don\u2019t put in front of them. \nThese aren\u2019t life-or-death scenarios; they are just cases where design decisions noticeably dictate the perception of information. Not every design decision makes so obvious an impact, but the impact is there. Every single action adds to the pattern.\nDesign with intention\nWe can\u2019t necessarily teach people to read critically or vet their sources or stop believing conspiracy theories (or start believing facts). Our reach is limited to our roles: we make websites and products for companies and colleges and startups.\nBut we have more reach there than we might realize. Every decision we make influences how information is presented in the world. Every presentation adds to the pattern. No matter how innocuous our organization, how lowly our title, how small our user base\u2014every single one of us contributes, a little bit, to the way information is perceived.\nAre we changing it for the better?\nWhile it\u2019s always been crucial to act ethically in the building of the web, our cultural climate now requires dedicated, individual conscientiousness. It\u2019s not enough to think ourselves neutral, to dismiss our work as meaningless or apolitical. Everything is political. Every action, and every inaction, has an impact.\nAs Chappell Ellison put it much more eloquently than I can:\nEvery single action and decision a designer commits is a political act. The question is, are you a conscious actor?\u2014 Chappell Ellison\ud83e\udd14 (@ChappellTracker) November 28, 2016\n\nAs shapers of information, we have a responsibility: to create clarity, to further understanding, to advance truth. Every single one of us must choose to treat information\u2014and the society it builds\u2014with integrity.", "year": "2016", "author": "Lisa Maria Martin", "author_slug": "lisamariamartin", "published": "2016-12-14T00:00:00+00:00", "url": "https://24ways.org/2016/information-literacy-is-a-design-problem/", "topic": "content"} {"rowid": 309, "title": "HTTP/2 Server Push and Service Workers: The Perfect Partnership", "contents": "Being a web developer today is exciting! The web has come a long way since its early days and there are so many great technologies that enable us to build faster, better experiences for our users. One of these technologies is HTTP/2 which has a killer feature known as HTTP/2 Server Push.\nDuring this year\u2019s Chrome Developer Summit, I watched a really informative talk by Sam Saccone, a Software Engineer on the Google Chrome team. He gave a talk entitled Planning for Performance, and one of the topics that he covered immediately piqued my interest; the idea that HTTP/2 Server Push and Service Workers were the perfect web performance combination.\n\nIf you\u2019ve never heard of HTTP/2 Server Push before, fear not - it\u2019s not as scary as it sounds. HTTP/2 Server Push simply allows the server to send data to the browser without having to wait for the browser to explicitly request it first. In this article, I am going to run through the basics of HTTP/2 Server Push and show you how, when combined with Service Workers, you can deliver the ultimate in web performance to your users.\nWhat is HTTP/2 Server Push?\nWhen a user navigates to a URL, a browser will make an HTTP request for the underlying web page. The browser will then scan the contents of the HTML document for any assets that it may need to retrieve such as CSS, JavaScript or images. Once it finds any assets that it needs, it will then make multiple HTTP requests for each resource that it needs and begin downloading one by one. While this approach works well, the problem is that each HTTP request means more round trips to the server before any data arrives at the browser. These extra round trips take time and can make your web pages load slower. \nBefore we go any further, let\u2019s see what this might look like when your browser makes a request for a web page. If you were to view this in the developer tools of your browser, it might look a little something like this:\n\nAs you can see from the image above, once the HTML file has been downloaded and parsed, the browser then makes HTTP requests for any assets that it needs. \nThis is where HTTP/2 Server Push comes in. The idea behind HTTP/2 Server Push is that when the browser requests a web page from the server, the server already knows about all the assets that are needed for the web page and \u201cpushes\u201d it to browser. This happens when the first HTTP request for the web page takes place and it eliminates an extra round trip, making your site faster. \nUsing the same example above, let\u2019s \u201cpush\u201d the JavaScript and CSS files instead of waiting for the browser to request them. The image below gives you an idea of what this might look like.\n\nWhoa, that looks different - let\u2019s break it down a little. Firstly, you can see that the JavaScript and CSS files appear earlier in the waterfall chart. You might also notice that the loading times for the files are extremely quick. The browser doesn\u2019t need to make an extra HTTP request to the server, instead it receives the critical files it needs all at once. Much better! \nThere are a number of different approaches when it comes to implementing HTTP/2 Server Push. Adoption is growing and many commercial CDNs such as Akamai and Cloudflare already offer support for Server Push. You can even roll your own implementation depending on your environment. I\u2019ve also previously blogged about building a basic HTTP/2 Server Push example using Node.js. In this post, I\u2019m not going to dive into how to implement HTTP/2 Server Push as that is an entire post in itself! However, I do recommend reading this article to find out more about the inner workings.\nHTTP/2 Server Push is awesome, but it isn\u2019t a magic bullet. It is fantastic for improving the load time of a web page when it first loads for a user, but it isn\u2019t that great when they request the same web page again. The reason for this is that HTTP/2 Server Push is not cache \u201caware\u201d. This means that the server isn\u2019t aware about the state of your client. If you\u2019ve visited a web page before, the server isn\u2019t aware of this and will push the resource again anyway, regardless of whether or not you need it. HTTP/2 Server Push effectively tells the browser that it knows better and that the browser should receive the resources whether it needs them or not. In theory browsers can cancel HTTP/2 Server Push requests if they\u2019re already got something in cache but unfortunately no browsers currently support it. The other issue is that the server will have already started to send some of the resource to the browser by the time the cancellation occurs.\nHTTP/2 Server Push & Service Workers\nSo where do Service Workers fit in? Believe it or not, when combined together HTTP/2 Server Push and Service Workers can be the perfect web performance partnership. If you\u2019ve not heard of Service Workers before, they are worker scripts that run in the background of your website. Simply put, they act as middleman between the client and the browser and enable you to intercept any network requests that come and go from the browser. They are packed with useful features such as caching, push notifications, and background sync. Best of all, they are written in JavaScript, making it easy for web developers to understand.\nUsing Service Workers, you can easily cache assets on a user\u2019s device. This means when a browser makes an HTTP request for an asset, the Service Worker is able to intercept the request and first check if the asset already exists in cache on the users device. If it does, then it can simply return and serve them directly from the device instead of ever hitting the server.\nLet\u2019s stop for a second and analyse what that means. Using HTTP/2 Server Push, you are able to push critical assets to the browser before the browser requests them. Then, using Service Workers you are able to cache these resources so that the browser never needs to make a request to the server again. That means a super fast first load and an even faster second load!\nLet\u2019s put this into action. The following HTML code is a basic web page that retrieves a few images and two JavaScript files.\n\n\n\n \n HTTP2 Push Demo\n\n\n

HTTP2 Push

\n \n \n
\n
\n \n \n \n \n \n \n\n\nIn the HTML code above, I am registering a Service Worker file named service-worker.js. In order to start caching assets, I am going to use the Service Worker toolbox . It is a lightweight helper library to help you get started creating your own Service Workers. Using this library, we can actually cache the base web page with the path /push.\nThe Service Worker Toolbox comes with a built-in routing system which is based on the same routing as Express. With just a few lines of code, you can start building powerful caching patterns.\nI\u2019ve add the following code to the service-worker.js file.\n(global => {\n 'use strict';\n\n // Load the sw-toolbox library.\n importScripts('/js/sw-toolbox/sw-toolbox.js');\n\n // The route for any requests\n toolbox.router.get('/push', global.toolbox.fastest);\n\n toolbox.router.get('/images/(.*)', global.toolbox.fastest);\n\n toolbox.router.get('/js/(.*)', global.toolbox.fastest);\n\n // Ensure that our service worker takes control of the page as soon as possible.\n global.addEventListener('install', event => event.waitUntil(global.skipWaiting()));\n global.addEventListener('activate', event => event.waitUntil(global.clients.claim()));\n})(self);\nLet\u2019s break this code down further. Around line 4, I am importing the Service Worker toolbox. Next, I am specifying a route that will listen to any requests that match the URL /push. Because I am also interested in caching the images and JavaScript for that page, I\u2019ve told the toolbox to listen to these routes too.\nThe best thing about the code above is that if any of the assets exist in cache, we will instantly return the cached version instead of waiting for it to download. If the asset doesn\u2019t exist in cache, the code above will add it into cache so that we can retrieve it when it\u2019s needed again.\nYou may also notice the code global.toolbox.fastest - this is important because gives you the compromise of fulfilling from the cache immediately, while firing off an additional HTTP request updating the cache for the next visit.\nBut what does this mean when combined with HTTP/2 Server Push? Well, it means that on the first load of the web page, you are able to \u201cpush\u201d everything to the user at once before the browser has even requested it. The Service Worker activates and starts caching the assets on the users device. The next time a user visits the page, the Service Worker will intercept the request and serve the asset directly from cache. Amazing! \nUsing this technique, the waterfall chart for a repeat visit should look like the image below.\n\nIf you look closely at the image above, you\u2019ll notice that the web page returns almost instantly without ever making an HTTP request over the network. Using the Service Worker library, we cached the base page for the route /push, which allowed us to retrieve this directly from cache.\nWhether used on their own or combined together, the best thing about these two features is that they are the perfect progressive enhancement. If your user\u2019s browser doesn\u2019t support them, they will simply fall back to HTTP/1.1 without Service Workers. Your users may not experience as fast a load time as they would with these two techniques, but it would be no different from their normal experience. HTTP/2 Server Push and Service Workers are really the perfect partners when it comes to web performance.\nSummary\nWhen used correctly, HTTP/2 Server Push and Service Workers can have a positive impact on your site\u2019s load times. Together they mean super fast first load times and even faster repeat views to a web page. Whilst this technique is really effective, it\u2019s worth noting that HTTP/2 push is not a magic bullet. Think about the situations where it might make sense to use it and don\u2019t just simply \u201cpush\u201d everything; it could actually lead to having slower page load times. If you\u2019d like to learn more about the rules of thumb for HTTP/2 Server Push, I recommend reading this article for more information. \nAll of the code in this example is available on my Github repo - if you have any questions, please submit an issue and I\u2019ll get back to you as soon as possible. \nIf you\u2019d like to learn more about this technique and others relating to HTTP/2, I highly recommend watching Sam Saccone\u2019s talk at this years Chrome Developer Summit. \nI\u2019d also like to say a massive thank you to Robin Osborne, Andy Davies and Jeffrey Posnick for helping me review this article before putting it live!", "year": "2016", "author": "Dean Hume", "author_slug": "deanhume", "published": "2016-12-15T00:00:00+00:00", "url": "https://24ways.org/2016/http2-server-push-and-service-workers/", "topic": "code"} {"rowid": 296, "title": "Animation in Design Systems", "contents": "Our modern front-end workflow has matured over time to include design systems and component libraries that help us stay organized, improve workflows, and simplify maintenance. These systems, when executed well, ensure proper documentation of the code available and enable our systems to scale with reduced communication conflicts. \nBut while most of these systems take a critical stance on fonts, colors, and general building blocks, their treatment of animation remains disorganized and ad-hoc. Let\u2019s leverage existing structures and workflows to reduce friction when it comes to animation and create cohesive and performant user experiences. \nUnderstand the importance of animation\nPart of the reason we treat animation like a second-class citizen is that we don\u2019t really consider its power. When users are scanning a website (or any environment or photo), they are attempting to build a spatial map of their surroundings. During this process, nothing quite commands attention like something in motion. \nWe are biologically trained to notice motion: evolutionarily speaking, our survival depends on it. For this reason, animation when done well can guide your users. It can aid and reinforce these maps, and give us a sense that we understand the UX more deeply. We retrieve information and put it back where it came from instead of something popping in and out of place. \n\n\u201cWhere did that menu go? Oh it\u2019s in there.\u201d \n\nFor a deeper dive into how animation can connect disparate states, I wrote about the Importance of Context-Shifting in UX Patterns for CSS-Tricks.\nAn animation flow on mobile.\nAnimation also aids in perceived performance. Viget conducted a study where they measured user engagement with a standard loading GIF versus a custom animation. Customers were willing to wait almost twice as long for the custom loader, even though it wasn\u2019t anything very fancy or crazy. Just by showing their users that they cared about them, they stuck around, and the bounce rates dropped.\n\n14 second generic loading screen.22 second custom loading screen.\nThis also works for form submission. Giving your personal information over to an online process like a static form can be a bit harrowing. It becomes more harrowing without animation used as a signal that something is happening, and that some process is completing. That same animation can also entertain users and make them feel as though the wait isn\u2019t as long. \nEli Fitch gave a talk at CSS Dev Conf called: \u201cPerceived Performance: The Only Kind That Really Matters\u201d, which is one of my favorite talk titles of all time. In it, he discussed how we tend to measure things like timelines and network requests because they are more quantifiable\u2013and therefore easier to measure\u2013but that measuring how a user feels when visiting the site is more important and worth the time and attention. \nIn his talk, he states \u201cHumans over-estimate passive waits by 36%, per Richard Larson of MIT\u201d. This means that if you\u2019re not using animation to speed up how fast the wait time of a form submission loads, users are perceiving it to be much slower than the dev tools timeline is recording.\nReign it in\nUnlike fonts, colors, and so on, we tend to add animation in as a last step, which leads to disorganized implementations that lack overall cohesion. If you asked a designer or developer if they would create a mockup or build a UI without knowing the fonts they were working with, they would dislike the idea. Not knowing the building blocks they\u2019re working with means that the design can fall apart or the development can break with something so fundamental left out at the start. Good animation works the same way.\nThe first step in reigning in your use of animation is to perform an animation audit. Look at all the places you are using animation on your site, or the places you aren\u2019t using animation but probably should. (Hint: perceived performance of a loader on a form submission can dramatically change your bounce rates.) \nNot sure how to perform a good audit? Val Head has a great chapter on it in her book, Designing Interface Animations, which has of buckets of research and great ideas.\nEven some beautiful component libraries that have animation in the docs make this mistake. You don\u2019t need every kind of animation, just like you don\u2019t need every kind of font. This bloats our code. Ask yourself questions like: do you really need a flip 180 degree animation? I can\u2019t even conceive of a place on a typical UI where that would be useful, yet most component libraries that I\u2019ve seen have a mixin that does just this.\nWhich leads to\u2026\nHave an opinion\nMany people are confused about Material Design. They think that Material Design is Motion Design, mostly because they\u2019ve never seen anyone take a stance on animation before and document these opinions well. But every time you use Material Design as your motion design language, people look at your site and think GOOGLE. Now that\u2019s good branding.\nBy using Google\u2019s motion design language and not your own, you\u2019re losing out on a chance to be memorable on your own website.\nWhat does having an opinion on motion look like in practice? It could mean you\u2019ve decided that you never flip things. It could mean that your eases are always going to glide. In that instance, you would put your efforts towards finding an ease that looks \u201cgliding\u201d and pulling out any transform: scaleX(-1) animation you find on your site. Across teams, everyone knows not to spend time mocking up flipping animation (even if they\u2019re working on an entirely different codebase), and to instead work on something that feels like it glides. You save time and don\u2019t have to communicate again and again to make things feel cohesive.\nCreate good developer resources\nSometimes people don\u2019t incorporate animation into a design system because they aren\u2019t sure how, beyond the base hover states. All animation properties can be broken into interchangeable pieces. This allows developers and designers alike to mix and match and iterate quickly, while still staying in the correct language. Here are some recommendations (with code and a demo to follow):\nCreate timing units, similar to h1, h2, h3. In a system I worked on recently, I called these t1, t2, t3. T1 would be reserved for longer pieces, down to t5 which is a bit like h5 in that it\u2019s the default (usually around .25 seconds or thereabouts).\nKeep animation easings for entrance, exit, entrance emphasis and exit emphasis that people can commonly refer to. This, and the animation-fill-mode, are likely to be the only two properties that can be reused for the entrance and exit of the animation.\nUse the animation-name property to define the keyframes for the animation itself. I would recommend starting with 5 or 6 before making a slew of them, and see if you need more. Writing 30 different animations might seem like a nice resource, but just like your color palette having too many can unnecessarily bulk up your codebase, and keep it from feeling cohesive. Think critically about what you need here. \nSee the Pen Modularized Animation for Component Libraries by Sarah Drasner (@sdras) on CodePen.\n\nThe example above is pared-down, but you can see how in a robust system, having pieces that are interchangeable cached across the whole system would save time for iterations and prototyping, not to mention make it easy to make adjustments for different feeling movement on the same animation easily.\nOne low hanging fruit might be a loader that leads to a success dialog. On a big site, you might have that pattern many times, so writing up a component that does only that helps you move faster while also allowing you to really zoom in and focus on that pattern. You avoid throwing something together at the last minute, or using a GIF, which are really heavy and mushy on retina. You can make singular pieces that look really refined and are reusable. \nReact and Vue Implementations are great for reusable components, as you can create a building block with a common animation pattern, and once created, it can be a resource for all. Remember to take advantage of things like props to allow for timing and easing adjustments like we have in the previous example!\nResponsive\nAt the very least we should ensure that interaction also works well on mobile, but if we\u2019d like to create interactions that take advantage of all of the gestures mobile has to offer, we can use libraries like zingtouch or hammer to work with swipe or multiple finger detection. With a bit of work, these can all be created through native detection as well.\nResponsive web pages can specify initial-scale=1.0 in the meta tag so that the device is not waiting the required 300ms on the secondary tap before calling action. Interaction for touch events must either start from a larger touch-target (40px \u00d7 40px or greater) or use @media(pointer:coarse) as support allows.\nBuy-in\nSometimes people don\u2019t create animation resources simply because it gets deprioritized. But design systems were also something we once had to fight for, too. This year at CSS Dev Conf, Rachel Nabors demonstrated how to plot out animation wants vs. needs on a graph (reproduced with her permission) to help prioritize them:\n\n\nThis helps people you\u2019re working with figure out the relative necessity and workload of the addition of these animations and think more critically about it. You\u2019re also more likely to get something through if you\u2019re proving that what you\u2019re making is needed and can be reused. \nGood compromises can be made this way: \u201cwe\u2019re not going to go all out and create an animated \u2018About Us\u2019 page like you wanted, but I suppose we can let our users know their contact email went through with a small progress and success notification.\u201d \nSuccessfully pushing smaller projects through helps build trust with your team, and lets them see what this type of collaboration can look like. This builds up the type of relationship necessary to push through projects that are more involved. It can\u2019t be overstressed that good communication is key.\nGet started!\nWith these tools and good communication, we can make our codebases more efficient, performant, and feel better for our users. We can enhance the user experience on our sites, and create great resources for our teams to allow them to move more quickly while innovating beautifully.", "year": "2016", "author": "Sarah Drasner", "author_slug": "sarahdrasner", "published": "2016-12-16T00:00:00+00:00", "url": "https://24ways.org/2016/animation-in-design-systems/", "topic": "code"} {"rowid": 289, "title": "Front-End Developers Are Information Architects Too", "contents": "The theme of this year\u2019s World IA Day was \u201cInformation Everywhere, Architects Everywhere\u201d. This article isn\u2019t about what you may consider an information architect to be: someone in the user-experience field, who maybe studied library science, and who talks about taxonomies. This is about a realisation I had a couple of years ago when I started to run an increasing amount of usability-testing sessions with people who have disabilities: that the structure, labelling, and connections that can be made in front-end code is information architecture. People\u2019s ability to be successful online is unequivocally connected to the quality of the code that is written.\nPlaces made of information\nIn information architecture we talk about creating places made of information. These places are made of ones and zeros, but we talk about them as physical structures. We talk about going onto a social media platform, posting in blogs, getting locked out of an environment, and building applications. In 2002, Andrew Hinton stated:\n\nPeople live and work in these structures, just as they live and work in their homes, offices, factories and malls. These places are not virtual: they are as real as our own minds.\n25 Theses\n\nWe\u2019re creating structures which people rely on for significant parts of their lives, so it\u2019s critical that we carry out our work responsibly. This means we must use our construction materials correctly. Luckily, our most important material, HTML, has a well-documented specification which tells us how to build robust and accessible places. What is most important, I believe, is to understand the semantics of HTML.\nSemantics\nThe word \u201csemantic\u201d has its origin in Greek words meaning \u201csignificant\u201d, \u201csignify\u201d, and \u201csign\u201d. In the physical world, a structure can have semantic qualities that tell us something about it. For example, the stunning Westminster Abbey inspires awe and signifies much about the intent and purpose of the structure. The building\u2019s size; the quality of the stone work; the massive, detailed stained glass: these are all signs that this is a building meant for something the creators deemed important. Alternatively consider a set of large, clean, well-positioned, well-lit doors on the ground floor of an office block: they don\u2019t need an \u201centrance\u201d sign to communicate their use and to stop people trying to use a nearby fire exit to get into the building. The design of the doors signify their usage. Sometimes a more literal and less awe-inspiring approach to communicating a building\u2019s purpose happens, but the affect is similar: the building is signifying something about its purpose.\nHTML has over 115 elements, many of which have semantics to signify structure and affordance to people, browsers, and assistive technology. The HTML 5.1 specification mentions semantics, stating:\n\nElements, attributes, and attribute values in HTML are defined \u2026 to have certain meanings (semantics). For example, the
    element represents an ordered list, and the lang attribute represents the language of the content.\nHTML 5.1 Semantics, structure, and APIs of HTML documents\n\nHTML\u2019s baked-in semantics means that developers can architect their code to signify structure, create relationships between elements, and label content so people can understand what they\u2019re interacting with. Structuring and labelling information to make it available, usable, and understandable to people is what an information architect does. It\u2019s also what a front-end developer does, whether they realise it or not.\nA brief introduction to information architecture\nWe\u2019re going to start by looking at what an information architect is. There are many definitions, and I\u2019m going to quote Richard Saul Wurman, who is widely regarded as the father of information architecture. In 1976 he said an information architect is:\n\nthe individual who organizes the patterns inherent in data, making the complex clear; a person who creates the structure or map of information which allows others to find their personal paths to knowledge; the emerging 21st century professional occupation addressing the needs of the age focused upon clarity, human understanding, and the science of the organization of information.\nOf Patterns And Structures\n\nTo me, this clearly defines any developer who creates code that a browser, or other user agent (for example, a screen reader), uses to create a structured, navigable place for people.\nJust as there are many definitions of what an information architect is, there are for information architecture itself. I\u2019m going to use the definition from the fourth edition of Information Architecture For The World Wide Web, in which the authors define it as:\nThe structural design of shared information environments.\nThe synthesis of organization, labeling, search, and navigation systems within digital, physical, and cross-channel ecosystems.\nThe art and science of shaping information products and experiences to support usability, findability, and understanding.\nInformation Architecture For The World Wide Web, 4th Edition\nTo me, this describes front-end development. Done properly, there is an art to creating robust, accessible, usable, and findable spaces that delight all our users. For example, at 2015\u2019s State Of The Browser conference, Edd Sowden talked about the accessibility of s. He discovered that by simply not using the semantically-correct
    element to mark up headings, in some situations browsers will decide that a
    is being used for layout and essentially make it invisible to assistive technology. Another example of how coding practices can affect the usability and findability of content is shown by L\u00e9onie Watson in her How ARIA landmark roles help screen reader users video. By using ARIA landmark roles, people who use screen readers are quickly able to identify and jump to common parts of a web page.\nOur definitions of information architects and information architecture mention patterns, rules, organisation, labelling, structure, and relationships. There are numerous different models for how these elements get boiled down to their fundamentals. In his Understanding Context book, Andrew Hinton calls them Labels, Relationships, and Rules; Jorge Arango calls them Links, Nodes, And Order; and Dan Klyn uses Ontology, Taxonomy, and Choreography, which is the one we\u2019re going to use. Dan defines these terms as:\nOntology\nThe definition and articulation of the rules and patterns that govern the meaning of what we intend to communicate.\nWhat we mean when we say what we say.\nTaxonomy\nThe arrangements of the parts. Developing systems and structures for what everything\u2019s called, where everything\u2019s sorted, and the relationships between labels and categories\nChoreography\nRules for interaction among the parts. The structures it creates foster specific types of movement and interaction; anticipating the way users and information want to flow and making affordance for change over time.\n\nWe now have definitions of an information architect, information architecture, and a model of the elements of information architecture. But is writing HTML really creating information or is it just wrangling data and metadata? When does data turn into information? In his book Managing For The Future Peter Drucker states:\n\n\u2026 data is not information. Information is data endowed with relevance and purpose.\nManaging For The Future\n\nIf we use the correct semantic element to mark up content then we\u2019re developing with purpose and creating relevance. For example, if we follow the advice of the HTML 5.1 specification and mark up headings using heading rank instead of the outline algorithm, we\u2019re creating a structure where the depth of one heading is relevant to the previous one. Architected correctly, an

    element should be relevant to its parent, which should be the

    . By following the HTML specification we can create a structured, searchable, labeled document that will hopefully be relevant to what our users need to be successful. If you\u2019ve never used a screen reader, you might be wondering how the headings on a page are searchable. Screen readers give users the ability to interact with headings in a couple of ways:\n\nby creating a list of headings so users can quickly scan the page for information\nby using a keyboard command to cycle through one heading at a time\n\nIf we had a document for Christmas Day TV we might structure it something like this:\n

    Christmas Day TV schedule

    \n

    BBC1

    \n

    Morning

    \n

    Evening

    \n

    BBC2

    \n

    Morning

    \n

    Evening

    \n

    ITV

    \n

    Morning

    \n

    Evening

    \n

    Channel 4

    \n

    Morning

    \n

    Evening

    \nIf I use VoiceOver to generate a list of headings, I get this:\n\nOnce I have that list I can use keyboard commands to filter the list based on the heading level. For example, I can press 2 to hear just the

    s:\n\nIf we hadn\u2019t used headings, of if we\u2019d nested them incorrectly, our users would be frustrated.\nPutting this together\nLet\u2019s put this together with an example of a button that, when pressed, toggles the appearance of a panel of links. There are numerous ways we could create a button on a web page, but the best way is to just use a \n\n
    \n \n
    \nThere\u2019s quite a bit going on here. We\u2019re using the:\n\naria-controls attribute to architect a connection between the