in the markup.\nIn this article, I\u2019m going to take a look at the common features of our new layout systems, along with a couple of examples which serve to highlight the differences between them.\nTo see the grid layout examples you will need to enable grid in your browser. The easiest thing to do is to enable the experimental web platform features flag in Chrome. Details of current browser support can be found here. \nRelationship\nItems only become flex or grid items if they are a direct child of the element that has display:flex, display:grid or display:inline-grid applied. Those direct children then understand themselves in the context of the complete layout. This makes many things possible. It\u2019s the lack of relationship between elements that makes our existing layout methods difficult to use. If we float two columns, left and right, we have no way to tell the shorter column to extend to the height of the taller one. We have expended a lot of effort trying to figure out the best way to make full-height columns work, using techniques that were never really designed for page layout.\nAt a very simple level, the relationship between elements means that we can easily achieve full-height columns. In flexbox:\nSee the Pen Flexbox equal height columns by rachelandrew (@rachelandrew) on CodePen.\n\nAnd in grid layout (requires a CSS grid-supporting browser):\nSee the Pen Grid equal height columns by rachelandrew (@rachelandrew) on CodePen.\n\nAlignment\nFull-height columns rely on our flex and grid items understanding themselves as part of an overall layout. They also draw on a third new specification: the box alignment module. If vertical centring is a gift you\u2019d like to have under your tree this Christmas, then this is the box you\u2019ll want to unwrap first.\nThe box alignment module takes the alignment and space distribution properties from flexbox and applies them to other layout methods. That includes grid layout, but also other layout methods. Once implemented in browsers, this specification will give us true vertical centring of all the things.\nOur examples above achieved full-height columns because the default value of align-items is stretch. The value ensured our columns stretched to the height of the tallest. If we want to use our new vertical centring abilities on all items, we would set align-items:center on the container. To align one flex or grid item, apply the align-self property.\nThe examples below demonstrate these alignment properties in both grid layout and flexbox. The portrait image of Widget the cat is aligned with the default stretch. The other three images are aligned using different values of align-self.\nTake a look at an example in flexbox:\nSee the Pen Flexbox alignment by rachelandrew (@rachelandrew) on CodePen.\n\nAnd also in grid layout (requires a CSS grid-supporting browser):\nSee the Pen Grid alignment by rachelandrew (@rachelandrew) on CodePen.\n\nThe alignment properties used with CSS grid layout.\nFluid grids\nA cornerstone of responsive design is the concept of fluid grids.\n\n\u201c[\u2026]every aspect of the grid\u2014and the elements laid upon it\u2014can be expressed as a proportion relative to its container.\u201d\n\u2014Ethan Marcotte, \u201cFluid Grids\u201d\n\nThe method outlined by Marcotte is to divide the target width by the context, then use that value as a percentage value for the width property on our element.\nh1 {\n margin-left: 14.575%; /*\u00a0144px / 988px = 0.14575\u00a0*/\n width: 70.85%; /*\u00a0700px / 988px = 0.7085\u00a0*/\n}\nIn more recent years, we\u2019ve been able to use calc() to simplify this (at least, for those of us able to drop support for Internet Explorer 8). However, flexbox and grid layout make fluid grids simple.\nThe most basic of flexbox demos shows this fluidity in action. The justify-content property \u2013 another property defined in the box alignment module \u2013 can be used to create an equal amount of space between or around items. As the available width increases, more space is assigned in proportion.\nIn this demo, the list items are flex items due to display:flex being added to the ul. I have given them a maximum width of 250 pixels. Any remaining space is distributed equally between the items as the justify-content property has a value of space-between.\nSee the Pen Flexbox: justify-content by rachelandrew (@rachelandrew) on CodePen.\n\nFor true fluid grid-like behaviour, your new flexible friends are flex-grow and flex-shrink. These properties give us the ability to assign space in proportion.\nThe flexbox flex property is a shorthand for:\n\nflex-grow\nflex-shrink\nflex-basis\n\nThe flex-basis property sets the default width for an item. If flex-grow is set to 0, then the item will not grow larger than the flex-basis value; if flex-shrink is 0, the item will not shrink smaller than the flex-basis value.\n\nflex: 1 1 200px: a flexible box that can grow and shrink from a 200px basis.\nflex: 0 0 200px: a box that will be 200px and cannot grow or shrink.\nflex: 1 0 200px: a box that can grow bigger than 200px, but not shrink smaller.\n\nIn this example, I have a set of boxes that can all grow and shrink equally from a 100 pixel basis.\nSee the Pen Flexbox: flex-grow by rachelandrew (@rachelandrew) on CodePen.\n\nWhat I would like to happen is for the first element, containing a portrait image, to take up less width than the landscape images, thus keeping it more in proportion. I can do this by changing the flex-grow value. By giving all the items a value of 1, they all gain an equal amount of the available space after the 100 pixel basis has been worked out.\nIf I give them all a value of 3 and the first box a value of 1, the other boxes will be assigned three parts of the available space while box 1 is assigned only one part. You can see what happens in this demo:\nSee the Pen Flexbox: flex-grow by rachelandrew (@rachelandrew) on CodePen.\n\nOnce you understand flex-grow, you should easily be able to grasp how the new fraction unit (fr, defined in the CSS grid layout specification) works. Like flex-grow, this unit allows us to assign available space in proportion. In this case, we assign the space when defining our track sizes.\nIn this demo (which requires a CSS grid-supporting browser), I create a four-column grid using the fraction unit to define my track sizes. The first track is 1fr in width, and the others 2fr.\ngrid-template-columns: 1fr 2fr 2fr 2fr;\nSee the Pen Grid fraction units by rachelandrew (@rachelandrew) on CodePen.\n\nThe four-track grid.\nSeparation of concerns\nMy younger self petitioned my peers to stop using tables for layout and to move to CSS. One of the rallying cries of that movement was the concept of separating our source and content from how they were displayed. It was something of a failed promise given the tools we had available: the display leaked into the markup with the need for redundant elements to cope with browser bugs, or visual techniques that just could not be achieved without supporting markup.\nBrowsers have improved, but even now we can find ourselves compromising the ideal document structure so we can get the layout we want at various breakpoints. In some ways, the situation has returned to tables-for-layout days. Many of the current grid frameworks rely on describing our layout directly in the markup. We add divs for rows, and classes to describe the number of desired columns. We nest these constructions of divs inside one another.\nHere is a snippet from the Bootstrap grid examples \u2013 two columns with two nested columns:\n
\n
\n .col-md-8\n
\n
\n .col-md-6\n
\n
\n .col-md-6\n
\n
\n
\n
\n .col-md-4\n
\n
\nNot a million miles away from something I might have written in 1999.\n
\n \n \n .col-md-8\n \n \n \n .col-md-6\n \n \n .col-md-6\n \n \n
\n \n \n .col-md-4\n \n \n
\nGrid and flexbox layouts do not need to be described in markup. The layout description happens entirely in the CSS, meaning that elements can be moved around from within the presentation layer.\nFlexbox gives us the ability to reverse the flow of elements, but also to set the order of elements with the order property. This is demonstrated here, where Widget the cat is in position 1 in the source, but I have used the order property to display him after the things that are currently unimpressive to him.\nSee the Pen Flexbox: order by rachelandrew (@rachelandrew) on CodePen.\n\nGrid layout takes this a step further. Where flexbox lets us set the order of items in a single dimension, grid layout gives us the ability to position things in two dimensions: both rows and columns. Defined in the CSS, this positioning can be changed at any breakpoint without needing additional markup. Compare the source order with the display order in this example (requires a CSS grid-supporting browser):\nSee the Pen Grid positioning in two dimensions by rachelandrew (@rachelandrew) on CodePen.\n\nLaying out our items in two dimensions using grid layout.\nAs these demos show, a straightforward way to decide if you should use grid layout or flexbox is whether you want to position items in one dimension or two. If two, you want grid layout.\nA note on accessibility and reordering\nThe issues arising from this powerful ability to change the way items are ordered visually from how they appear in the source have been the subject of much discussion. The current flexbox editor\u2019s draft states\n\n\u201cAuthors must use order only for visual, not logical, reordering of content. Style sheets that use order to perform logical reordering are non-conforming.\u201d\n\u2014CSS Flexible Box Layout Module Level 1, Editor\u2019s Draft (3 December 2015)\n\nThis is to ensure that non-visual user agents (a screen reader, for example) can rely on the document source order as being correct. Take care when reordering that you do so from the basis of a sound document that makes sense in terms of source order. Avoid using visual order to convey meaning.\nAutomatic content placement with rules\nHaving control over the order of items, or placing items on a predefined grid, is nice. However, we can often do that already with one method or another and we have frameworks and tools to help us. Tools such as Susy mean we can even get away from stuffing our markup full of grid classes. However, our new layout methods give us some interesting new possibilities.\nSomething that is useful to be able to do when dealing with content coming out of a CMS or being pulled from some other source, is to define a bunch of rules and then say, \u201cDisplay this content, using these rules.\u201d\nAs an example of this, I will leave you with a Christmas poem displayed in a document alongside Widget the cat and some of the decorations that are bringing him no Christmas cheer whatsoever.\nThe poem is displayed first in the source as a set of paragraphs. I\u2019ve added a class identifying each of the four paragraphs but they are displayed in the source as one text. Below that are all my images, some landscape and some portrait; I\u2019ve added a class of landscape to the landscape ones.\nThe mobile-first grid is a single column and I use line-based placement to explicitly position my poem paragraphs. The grid layout auto-placement rules then take over and place the images into the empty cells left in the grid.\nAt wider screen widths, I declare a four-track grid, and position my poem around the grid, keeping it in a readable order.\nI also add rules to my landscape class, stating that these items should span two tracks. Once again the grid layout auto-placement rules position the rest of my images without my needing to position them. You will see that grid layout takes items out of source order to fill gaps in the grid. It does this because I have set the property grid-auto-flow to dense. The default is sparse meaning that grid will not attempt this backfilling behaviour.\nTake a look and play around with the full demo (requires a CSS grid layout-supporting browser):\nSee the Pen Grid auto-flow with rules by rachelandrew (@rachelandrew) on CodePen.\n\nThe final automatic placement example.\nMy wish for 2016\nI really hope that in 2016, we will see CSS grid layout finally emerge from behind browser flags, so that we can start to use these features in production \u2014 that we can start to move away from using the wrong tools for the job.\nHowever, I also hope that we\u2019ll see developers fully embracing these tools as the new system that they are. I want to see people exploring the possibilities they give us, rather than trying to get them to behave like the grid systems of 2015. As you discover these new modules, treat them as the new paradigm that they are, get creative with them. And, as you find the edges of possibility with them, take that feedback to the CSS Working Group. Help improve the layout systems that will shape the look of the future web.\nSome further reading\n\nI maintain a site of grid layout examples and resources at Grid by Example.\nThe three CSS specifications I\u2019ve discussed can be found as editor\u2019s drafts: CSS grid, flexbox, box alignment.\nI wrote about the last three years of my interest in CSS grid layout, which gives something of a history of the specification.\nMore examples of box alignment and grid layout.\nMy presentation at Fronteers earlier this year, in which I explain more about these concepts.", "year": "2015", "author": "Rachel Andrew", "author_slug": "rachelandrew", "published": "2015-12-15T00:00:00+00:00", "url": "https://24ways.org/2015/grid-flexbox-box-alignment-our-new-system-for-layout/", "topic": "code"}
{"rowid": 63, "title": "Be Fluid with Your Design Skills: Build Your Own Sites", "contents": "Just five years ago in 2010, when we were all busy trying to surprise and delight, learning CSS3 and trying to get whole websites onto one page, we had a poster on our studio wall. It was entitled \u2018Designers Vs Developers\u2019, an infographic that showed us the differences between the men(!) who created websites. \nDesigners wore skinny jeans and used Macs and developers wore cargo pants and brought their own keyboards to work. We began to learn that designers and developers were not only doing completely different jobs but were completely different people in every way. This opinion was backed up by hundreds of memes, millions of tweets and pages of articles which used words like void and battle and versus.\nThankfully, things move quickly in this industry; the wide world of web design has moved on in the last five years. There are new devices, technologies, tools \u2013 and even a few women. Designers have been helped along by great apps, software, open source projects, conferences, and a community of people who, to my unending pride, love to share their knowledge and their work.\nSo the world has moved on, and if Miley Cyrus, Ruby Rose and Eliot Sumner are identifying as gender fluid (an identity which refers to a gender which varies over time or is a combination of identities), then I would like to come out as discipline fluid! \nOK, I will probably never identify as a developer, but I will identify as fluid! How can we be anything else in an industry that moves so quickly? That\u2019s how we should think of our skills, our interests and even our job titles. After all, Steve Jobs told us that \u201cDesign is not just what it looks like and feels like. Design is how it works.\u201d Sorry skinny-jean-wearing designers \u2013 this means we\u2019re all designing something together. And it\u2019s not just about knowing the right words to use: you have to know how it feels. How it feels when you make something work, when you fix that bug, when you make it work on IE.\nLike anything in life, things run smoothly when you make the effort to share experiences, empathise and deeply understand the needs of others. How can designers do that if they\u2019ve never built their own site? I\u2019m not talking the big stuff, I\u2019m talking about your portfolio site, your mate\u2019s business website, a website for that great idea you\u2019ve had. I\u2019m talking about doing it yourself to get an unique insight into how it feels.\nWe all know that designers and developers alike love an
, so here it is.\nTen reasons designers should be fluid with their skills and build their own sites\n1. It\u2019s never been easier\nNow here\u2019s where the definition of \u2018build\u2019 is going to get a bit loose and people are going to get angry, but when I say it\u2019s never been easier I mean because of the existence of apps and software like WordPress, Squarespace, Tumblr, et al. It\u2019s easy to make something and get it out there into the world, and these are all gateway drugs to hard coding!\n2. You\u2019ll understand how it feels\nHow it feels to be so proud that something actually works that you momentarily don\u2019t notice if the kerning is off or the padding is inconsistent. How it feels to see your site appear when you\u2019ve redirected a URL. How it feels when you just can\u2019t work out where that one extra space is in a line of PHP that has killed your whole site.\n3. It makes you a designer\nNot a better designer, it makes you a designer when you are designing how things look and how they work. \n4. You learn about movement\nPhotoshop and Sketch just don\u2019t cut it yet. Until you see your site in a browser or your app on a phone, it\u2019s hard to imagine how it moves. Building your own sites shows you that it\u2019s not just about how the content looks on the screen, but how it moves, interacts and feels.\n5. You make techie friends\nAll the tutorials and forums in the world can\u2019t beat your network of techie friends. Since I started working in web design I have worked with, sat next to, and co-created with some of the greatest developers. Developers who\u2019ve shared their knowledge, encouraged me to build things, patiently explained HTML, CSS, servers, divs, web fonts, iOS development. There has been no void, no versus, very few battles; just people who share an interest and love of making things. \n6. You will own domain names\nWhen something is paid for, online and searchable then it\u2019s real and you\u2019ve got to put the work in. Buying domains has taught me how to stop procrastinating, but also about DNS, FTP, email, and how servers work.\n7. People will ask you to do things\u2028\nLearning about code and development opens a whole new world of design. When you put your own personal websites and projects out there people ask you to do more things. OK, so sometimes those things are \u201cMake me a website for free\u201d, but more often it\u2019s cool things like \u201cCome and speak at my conference\u201d, \u201cWrite an article for my magazine\u201d and \u201cCollaborate with me.\u201d\n8. The young people are coming!\nThey love typography, they love print, they love layout, but they\u2019ve known how to put a website together since they started their first blog aged five and they show me clever apps they\u2019ve knocked together over the weekend! They\u2019re new, they\u2019re fluid, and they\u2019re better than us!\n9. Your portfolio is your portfolio\nOK, it\u2019s an obvious one, but as designers our work is our CV, our legacy! We need to show our skill, our attention to detail and our creativity in the way we showcase our work. Building your portfolio is the best way to start building your own websites. (And please be that designer who\u2019s bothered to work out how to change the Squarespace favicon!) \n10. It keeps you fluid!\nBuilding your own websites is tough. You\u2019ll never be happy with it, you\u2019ll constantly be updating it to keep up with technology and fashion, and by the time you\u2019ve finished it you\u2019ll want to start all over again. Perfect for forcing you to stay up-to-date with what\u2019s going on in the industry.\n ", "year": "2015", "author": "Ros Horner", "author_slug": "roshorner", "published": "2015-12-12T00:00:00+00:00", "url": "https://24ways.org/2015/be-fluid-with-your-design-skills-build-your-own-sites/", "topic": "code"}
{"rowid": 71, "title": "Upping Your Web Security Game", "contents": "When I started working in web security fifteen years ago, web development looked very different. The few non-static web applications were built using a waterfall process and shipped quarterly at best, making it possible to add security audits before every release; applications were deployed exclusively on in-house servers, allowing Info Sec to inspect their configuration and setup; and the few third-party components used came from a small set of well-known and trusted providers. And yet, even with these favourable conditions, security teams were quickly overwhelmed and called for developers to build security in.\nIf the web security game was hard to win before, it\u2019s doomed to fail now. In today\u2019s web development, every other page is an application, accepting inputs and private data from users; software is built continuously, designed to eliminate manual gates, including security gates; infrastructure is code, with servers spawned with little effort and even less security scrutiny; and most of the code in a typical application is third-party code, pulled in through open source repositories with rarely a glance at who provided them.\nSecurity teams, when they exist at all, cannot solve this problem. They are vastly outnumbered by developers, and cannot keep up with the application\u2019s pace of change. For us to have a shot at making the web secure, we must bring security into the core. We need to give it no less attention than that we give browser compatibility, mobile design or web page load times. More broadly, we should see security as an aspect of quality, expecting both ourselves and our peers to address it, and taking pride when we do it well.\nWhere To Start?\nEmbracing security isn\u2019t something you do overnight.\nA good place to start is by reviewing things you\u2019re already doing \u2013 and trying to make them more secure. Here are three concrete steps you can take to get going.\nHTTPS\nThreats begin when your system interacts with the outside world, which often means HTTP. As is, HTTP is painfully insecure, allowing attackers to easily steal and manipulate data going to or from the server. HTTPS adds a layer of crypto that ensures the parties know who they\u2019re talking to, and that the information exchanged can be neither modified nor sniffed.\nHTTPS is relevant to any site. If your non-HTTPS site holds opinions, reading it may get your users in trouble with employers or governments. If your users believe what you say, attackers can modify your non-HTTPS to take advantage of and abuse that trust. If you want to use new browser technologies like HTTP2 and service workers, your site will need to be HTTPS. And if you want to be discovered on the web, using HTTPS can help your Google ranking. For more details on why I think you should make the switch to HTTPS, check out this post, these slides and this video.\nUsing HTTPS is becoming easier and cheaper. Here are a few free tools that can help:\n\nGet free and easy HTTPS delivery from Cloudflare (be sure to use \u201cFull SSL\u201d!)\nGet a free and automation-friendly certificate from Let\u2019s Encrypt (now in open beta).\nTest how well your HTTPS is set up using SSLTest.\n\nOther vendors and platforms are rapidly simplifying and reducing the cost of their HTTPS offering, as demand and importance grows.\nTwo-Factor Authentication\nThe most sensitive data is usually stored behind a login, and the authentication process is the primary gate in front of this data. Making this process secure has many aspects, including using HTTPS when accepting credentials, having a strong password policy, never storing the password, and more.\nAll of these are important, but the best single step to boost your authentication security is to introduce two-factor authentication (2FA). Adding 2FA usually means prompting users for an additional one-time code when logging in, which they get via SMS or a mobile app (e.g. Google Authenticator). This code is short-lived and is extremely hard for a remote attacker to guess, thus vastly reducing the risk a leaked or easily guessed password presents.\nThe typical algorithm for 2FA is based on an IETF standard called the time-based one-time password (TOTP) algorithm, and it isn\u2019t that hard to implement. Joel Franusic wrote a great post on implementing 2FA; modules like speakeasy make it even easier; and you can swap SMS with Google Authenticator or your own app if you prefer. If you don\u2019t want to build 2FA support yourself, you can purchase two/multi-factor authentication services from vendors such as DuoSecurity, Auth0, Clef, Hypr and others.\nIf implementing 2FA still feels like too much work, you can also choose to offload your entire authentication process to an OAuth-based federated login. Many companies offer this today, including Facebook, Google, Twitter, GitHub and others. These bigger players tend to do authentication well and support 2FA, but you should consider what data you\u2019re sharing with them in the process.\nTracking Known Vulnerabilities\nMost of the code in a modern application was actually written by third parties, and pulled into your app as frameworks, modules and libraries. While using these components makes us much more productive, along with their functionality we also adopt their security flaws. To make things worse, some of these flaws are well-known vulnerabilities, making it easy for hackers to take advantage of them in an attack.\nThis is a real problem and happens on pretty much every platform. Do you develop in Java? In 2014, over 6% of Java modules downloaded from Maven had a known severe security issue, the typical Java applications containing 24 flaws. Are you coding in Node.js? Roughly 14% of npm packages carry a known vulnerability, and over 60% of dev shops find vulnerabilities in their code. 30% of Docker Hub containers include a high priority known security hole, and 60% of the top 100,000 websites use client-side libraries with known security gaps.\nTo find known security issues, take stock of your dependencies and match them against language-specific lists such as Snyk\u2019s vulnerability DB for Node.js, rubysec for Ruby, victims-db for Python and OWASP\u2019s Dependency Check for Java. Once found, you can fix most issues by upgrading the component in question, though that may be tricky for indirect dependencies. \nThis process is still way too painful, which means most teams don\u2019t do it. The Snyk team and I are hoping to change that by making it as easy as possible to find, fix and monitor known vulnerabilities in your dependencies. Snyk\u2019s wizard will help you find and fix these issues through guided upgrades and patches, and adding Snyk\u2019s test to your continuous integration and deployment (CI/CD) will help you stay secure as your code evolves.\nNote that newly disclosed vulnerabilities usually impact old code \u2013 the one you\u2019re running in production. This means you have to stay alert when new vulnerabilities are disclosed, so you can fix them before attackers can exploit them. You can do so by subscribing to vulnerability lists like US-CERT, OSVDB and NVD. Snyk\u2019s monitor will proactively let you know about new disclosures relevant to your code, but only for Node.js for now \u2013 you can register to get updated when we expand.\nSecuring Yourself\nIn addition to making your application secure, you should make the contributors to that application secure \u2013 including you. Earlier this year we\u2019ve seen attackers target mobile app developers with a malicious Xcode. The real target, however, wasn\u2019t these developers, but rather the users of the apps they create. That you create. Securing your own work environment is a key part of keeping your apps secure, and your users from being compromised.\nThere\u2019s no single step that will make you fully secure, but here are a few steps that can make a big impact:\n\nUse 2FA on all the services related to the application, notably source control (e.g. GitHub), cloud platform (e.g. AWS), CI/CD, CDN, DNS provider and domain registrar. If an attacker compromises any one of those, they could modify or replace your entire application. I\u2019d recommend using 2FA on all your personal services too.\nUse a password manager (e.g. 1Password, LastPass) to ensure you have a separate and complex password for each service. Some of these services will get hacked, and passwords will leak. When that happens, don\u2019t let the attackers access your other systems too.\nSecure your workstation. Be careful what you download, lock your screen when you walk away, change default passwords on services you install, run antivirus software, etc. Malware on your machine can translate to malware in your applications.\nBe very wary of phishing. Smart attackers use \u2018spear phishing\u2019 techniques to gain access to specific systems, and can trick even security savvy users. There are even phishing scams targeting users with 2FA. Be alert to phishy emails.\nDon\u2019t install things through curl
| sudo bash, especially if the URL is on GitHub, meaning someone else controls it. Don\u2019t do it on your machines, and definitely don\u2019t do it in your CI/CD systems. Seriously.\n\nStaying secure should be important to you personally, but it\u2019s doubly important when you have privileged access to an application. Such access makes you a way to reach many more users, and therefore a more compelling target for bad actors.\nA Culture of Security\nUsing HTTPS, enabling two-factor authentication and fixing known vulnerabilities are significant steps in building security at your core. As you implement them, remember that these are just a few steps in a longer journey.\nThe end goal is to embrace security as an aspect of quality, and accept we all share the responsibility of keeping ourselves \u2013 and our users \u2013 safe.", "year": "2015", "author": "Guy Podjarny", "author_slug": "guypodjarny", "published": "2015-12-11T00:00:00+00:00", "url": "https://24ways.org/2015/upping-your-web-security-game/", "topic": "code"}
{"rowid": 54, "title": "Putting My Patterns through Their Paces", "contents": "Over the last few years, the conversation around responsive design has shifted subtly, focusing not on designing pages, but on patterns: understanding the small, reusable elements that comprise a larger design system. And given that many of those patterns are themselves responsive, learning to manage these small layout systems has become a big part of my work.\nThe thing is, the more pattern-driven work I do, the more I realize my design process has changed in a number of subtle, important ways. I suppose you might even say that pattern-driven design has, in a few ways, redesigned me.\nMeet the Teaser\nHere\u2019s a recent example. A few months ago, some friends and I redesigned The Toast. (It was a really, really fun project, and we learned a lot.) Each page of the site is, as you might guess, stitched together from a host of tiny, reusable patterns. Some of them, like the search form and footer, are fairly unique, and used once per page; others are used more liberally, and built for reuse. The most prevalent example of these more generic patterns is the teaser, which is classed as, uh, .teaser. (Look, I never said I was especially clever.)\nIn its simplest form, a teaser contains a headline, which links to an article:\n\nFairly straightforward, sure. But it\u2019s just the foundation: from there, teasers can have a byline, a description, a thumbnail, and a comment count. In other words, we have a basic building block (.teaser) that contains a few discrete content types \u2013 some required, some not. In fact, very few of those pieces need to be present; to qualify as a teaser, all we really need is a link and a headline. But by adding more elements, we can build slight variations of our teaser, and make it much, much more versatile.\n\n Nearly every element visible on this page is built out of our generic \u201cteaser\u201d pattern.\n \nBut the teaser variation I\u2019d like to call out is the one that appears on The Toast\u2019s homepage, on search results or on section fronts. In the main content area, each teaser in the list features larger images, as well as an interesting visual treatment: the byline and comment count were the most prominent elements within each teaser, appearing above the headline.\n\n The approved visual design of our teaser, as it appears on lists on the homepage and the section fronts.\n \nAnd this is, as it happens, the teaser variation that gave me pause. Back in the old days \u2013 you know, like six months ago \u2013 I probably would\u2019ve marked this module up to match the design. In other words, I would\u2019ve looked at the module\u2019s visual hierarchy (metadata up top, headline and content below) and written the following HTML:\n\n
By Author Name
\n \n
\n
Lorem ipsum dolor sit amet, consectetur\u2026
\n
\nBut then I caught myself, and realized this wasn\u2019t the best approach.\nMoving Beyond Layout\nSince I\u2019ve started working responsively, there\u2019s a question I work into every step of my design process. Whether I\u2019m working in Sketch, CSSing a thing, or researching a project, I try to constantly ask myself:\n\nWhat if someone doesn\u2019t browse the web like I do?\n\n\u2026Okay, that doesn\u2019t seem especially fancy. (And maybe you came here for fancy.) But as straightforward as that question might seem, it\u2019s been invaluable to so many aspects of my practice. If I\u2019m working on a widescreen layout, that question helps me remember the constraints of the small screen; if I\u2019m working on an interface that has some enhancements for touch, it helps me consider other input modes as I work. It\u2019s also helpful as a reminder that many might not see the screen the same way I do, and that accessibility (in all its forms) should be a throughline for our work on the web.\nAnd that last point, thankfully, was what caught me here. While having the byline and comment count at the top was a lovely visual treatment, it made for a terrible content hierarchy. For example, it\u2019d be a little weird if the page was being read aloud in a speaking browser: the name of the author and the number of comments would be read aloud before the title of the article with which they\u2019re associated.\nThat\u2019s why I find it\u2019s helpful to begin designing a pattern\u2019s hierarchy before its layout: to move past the visual presentation in front of me, and focus on the underlying content I\u2019m trying to support. In other words, if someone\u2019s encountering my design without the CSS I\u2019ve written, what should their experience be?\nSo I took a step back, and came up with a different approach:\n\n
\n
\n
\n Lorem ipsum dolor sit amet, consectetur\u2026\n \n
\n
\nMuch, much better. This felt like a better match for the content I was designing: the headline \u2013 easily most important element \u2013 was at the top, followed by the author\u2019s name and an excerpt. And while the comment count is visually the most prominent element in the teaser, I decided it was hierarchically the least critical: that\u2019s why it\u2019s at the very end of the excerpt, the last element within our teaser. And with some light styling, we\u2019ve got a respectable-looking hierarchy in place:\n\nYeah, you\u2019re right \u2013 it\u2019s not our final design. But from this basic-looking foundation, we can layer on a bit more complexity. First, we\u2019ll bolster the markup with an extra element around our title and byline:\n\nWith that in place, we can use flexbox to tweak our layout, like so:\n.teaser-hed {\n display: flex;\n flex-direction: column-reverse;\n}\nflex-direction: column-reverse acts a bit like a change in gravity within our teaser-hed element, vertically swapping its two children.\n\nGetting closer! But as great as flexbox is, it doesn\u2019t do anything for elements outside our container, like our little comment count, which is, as you\u2019ve probably noticed, still stranded at the very bottom of our teaser.\nFlexbox is, as you might already know, wonderful! And while it enjoys incredibly broad support, there are enough implementations of old versions of Flexbox (in addition to plenty of bugs) that I tend to use a feature test to check if the browser\u2019s using a sufficiently modern version of flexbox. Here\u2019s the one we used:\nvar doc = document.body || document.documentElement;\nvar style = doc.style;\n\nif ( style.webkitFlexWrap == '' ||\n style.msFlexWrap == '' ||\n style.flexWrap == '' ) {\n doc.className += \" supports-flex\";\n}\nEagle-eyed readers will note we could have used @supports feature queries to ask browsers if they support certain CSS properties, removing the JavaScript dependency. But since we wanted to serve the layout to IE we opted to write a little question in JavaScript, asking the browser if it supports flex-wrap, a property used elsewhere in the design. If the browser passes the test, then a class of supports-flex gets applied to our html element. And with that class in place, we can safely quarantine our flexbox-enabled layout from less-capable browsers, and finish our teaser\u2019s design:\n.supports-flex .teaser-hed {\n display: flex;\n flex-direction: column-reverse;\n}\n.supports-flex .teaser .comment-count {\n position: absolute;\n right: 0;\n top: 1.1em;\n}\nIf the supports-flex class is present, we can apply our flexbox layout to the title area, sure \u2013 but we can also safely use absolute positioning to pull our comment count out of its default position, and anchor it to the top right of our teaser. In other words, the browsers that don\u2019t meet our threshold for our advanced styles are left with an attractive design that matches our HTML\u2019s content hierarchy; but the ones that pass our test receive the finished, final design.\n\nAnd with that, our teaser\u2019s complete.\nDiving Into Device-Agnostic Design\nThis is, admittedly, a pretty modest application of flexbox. (For some truly next-level work, I\u2019d recommend Heydon Pickering\u2019s \u201cFlexbox Grid Finesse\u201d, or anything Zoe Mickley Gillenwater publishes.) And for such a simple module, you might feel like this is, well, quite a bit of work. And you\u2019d be right! In fact, it\u2019s not one layout, but two: a lightly styled content hierarchy served to everyone, with the finished design served conditionally to the browsers that can successfully implement it. But I\u2019ve found that thinking about my design as existing in broad experience tiers \u2013 in layers \u2013 is one of the best ways of designing for the modern web. And what\u2019s more, it works not just for simple modules like our teaser, but for more complex or interactive patterns as well.\nOpen video\n \n Even a simple search form can be conditionally enhanced, given a little layered thinking.\n \nThis more layered approach to interface design isn\u2019t a new one, mind you: it\u2019s been championed by everyone from Filament Group to the BBC. And with all the challenges we keep uncovering, a more device-agnostic approach is one of the best ways I\u2019ve found to practice responsive design. As Trent Walton once wrote,\n\nLike cars designed to perform in extreme heat or on icy roads, websites should be built to face the reality of the web\u2019s inherent variability.\n\nWe have a weird job, working on the web. We\u2019re designing for the latest mobile devices, sure, but we\u2019re increasingly aware that our definition of \u201csmartphone\u201d is much too narrow. Browsers have started appearing on our wrists and in our cars\u2019 dashboards, but much of the world\u2019s mobile data flows over sub-3G networks. After all, the web\u2019s evolution has never been charted along a straight line: it\u2019s simultaneously getting slower and faster, with devices new and old coming online every day. With all the challenges in front of us, including many we don\u2019t yet know about, a more device-agnostic, more layered design process can better prepare our patterns \u2013 and ourselves \u2013 for the future.\n(It won\u2019t help you get enough to eat at holiday parties, though.)", "year": "2015", "author": "Ethan Marcotte", "author_slug": "ethanmarcotte", "published": "2015-12-10T00:00:00+00:00", "url": "https://24ways.org/2015/putting-my-patterns-through-their-paces/", "topic": "code"}
{"rowid": 52, "title": "Git Rebasing: An Elfin Workshop Workflow", "contents": "This year Santa\u2019s helpers have been tasked with making a garland. It\u2019s a pretty simple task: string beads onto yarn in a specific order. When the garland reaches a specific length, add it to the main workshop garland. Each elf has a specific sequence they\u2019re supposed to chain, which is given to them via a work order. (This is starting to sound like one of those horrible calculus problems. I promise it isn\u2019t. It\u2019s worse; it\u2019s about Git.)\nFor the most part, the system works really well. The elves are able to quickly build up a shared chain because each elf specialises on their own bit of garland, and then links the garland together. Because of this they\u2019re able to work independently, but towards the common goal of making a beautiful garland.\nAt first the elves are really careful with each bead they put onto the garland. They check with one another before merging their work, and review each new link carefully. As time crunches on, the elves pour a little more cheer into the eggnog cooler, and the quality of work starts to degrade. Tensions rise as mistakes are made and unkind words are said. The elves quickly realise they\u2019re going to need a system to change the beads out when mistakes are made in the chain.\nThe first common mistake is not looking to see what the latest chain is that\u2019s been added to the main garland. The garland is huge, and it sits on a roll in one of the corners of the workshop. It\u2019s a big workshop, so it is incredibly impractical to walk all the way to the roll to check what the last link is on the chain. The elves, being magical, have set up a monitoring system that allows them to keep a local copy of the main garland at their workstation. It\u2019s an imperfect system though, so the elves have to request a manual refresh to see the latest copy. They can request a new copy by running the command\ngit pull --rebase=preserve\n(They found that if they ran git pull on its own, they ended up with weird loops of extra beads off the main garland, so they\u2019ve opted to use this method.) This keeps the shared garland up to date, which makes things a lot easier. A visualisation of the rebase process is available.\nThe next thing the elves noticed is that if they worked on the main workshop garland, they were always running into problems when they tried to share their work back with the rest of the workshop. It was fine if they were working late at night by themselves, but in the middle of the day, it was horrible. (I\u2019ve been asked not to talk about that time the fight broke out.) Instead of trying to share everything on their local copy of the main garland, the elves have realised it\u2019s a lot easier to work on a new string and then knot this onto the main garland when their pattern repeat is finished. They generate a new string by issuing the following commands:\ngit checkout master\ngit checkout -b 1234_pattern-name\n1234 represents the work order number and pattern-name describes the pattern they\u2019re adding. Each bead is then added to the new link (git add bead.txt) and locked into place (git commit). Each elf repeats this process until the sequence of beads described in the work order has been added to their mini garland.\nTo combine their work with the main garland, the elves need to make a few decisions. If they\u2019re making a single strand, they issue the following commands:\ngit checkout master\ngit merge --ff-only 1234_pattern-name\nTo share their work they publish the new version of the main garland to the workshop spool with the command git push origin master.\nSometimes this fails. Sharing work fails because the workshop spool has gotten new links added since the elf last updated their copy of the main workshop spool. This makes the elves both happy and sad. It makes them happy because it means the other elves have been working too, but it makes them sad because they now need to do a bit of extra work to close their work order. \nTo update the local copy of the workshop spool, the elf first unlinks the chain they just linked by running the command:\ngit reset --merge ORIG_HEAD\nThis works because the garland magic notices when the elves are doing a particularly dangerous thing and places a temporary, invisible bookmark to the last safe bead in the chain before the dangerous thing happened. The garland no longer has the elf\u2019s work, and can be updated safely. The elf runs the command git pull --rebase=preserve and the changes all the other elves have made are applied locally.\nWith these new beads in place, the elf now has to restring their own chain so that it starts at the right place. To do this, the elf turns back to their own chain (git checkout 1234_pattern-name) and runs the command git rebase master. Assuming their bead pattern is completely unique, the process will run and the elf\u2019s beads will be restrung on the tip of the main workshop garland.\nSometimes the magic fails and the elf has to deal with merge conflicts. These are kind of annoying, so the elf uses a special inspector tool to figure things out. The elf opens the inspector by running the command git mergetool to work through places where their beads have been added at the same points as another elf\u2019s beads. Once all the conflicts are resolved, the elf saves their work, and quits the inspector. They might need to do this a few times if there are a lot of new beads, so the elf has learned to follow this update process regularly instead of just waiting until they\u2019re ready to close out their work order.\nOnce their link is up to date, the elf can now reapply their chain as before, publish their work to the main workshop garland, and close their work order:\ngit checkout master\ngit merge --ff-only 1234_pattern-name\ngit push origin master\nGenerally this process works well for the elves. Sometimes, though, when they\u2019re tired or bored or a little drunk on festive cheer, they realise there\u2019s a mistake in their chain of beads. Fortunately they can fix the beads without anyone else knowing. These tools can be applied to the whole workshop chain as well, but it causes problems because the magic assumes that elves are only ever adding to the main chain, not removing or reordering beads on the fly. Depending on where the mistake is, the elf has a few different options.\nLet\u2019s pretend the elf has a sequence of five beads she\u2019s been working on. The work order says the pattern should be red-blue-red-blue-red.\n\nIf the sequence of beads is wrong (for example, blue-blue-red-red-red), the elf can remove the beads from the chain, but keep the beads in her workstation using the command git reset --soft HEAD~5.\n\nIf she\u2019s been using the wrong colours and the wrong pattern (for example, green-green-yellow-yellow-green), she can remove the beads from her chain and discard them from her workstation using the command git reset --hard HEAD~5.\n\nIf one of the beads is missing (for example, red-blue-blue-red), she can restring the beads using the first method, or she can use a bit of magic to add the missing bead into the sequence.\n\nUsing a tool that\u2019s a bit like orthoscopic surgery, she first selects a sequence of beads which contains the problem. A visualisation of this process is available.\nStart the garland surgery process with the command:\ngit rebase --interactive HEAD~4\nA new screen comes up with the following information (the oldest bead is on top):\npick c2e4877 Red bead\npick 9b5555e Blue bead\npick 7afd66b Blue bead\npick e1f2537 Red bead\nThe elf adjusts the list, changing \u201cpick\u201d to \u201cedit\u201d next to the first blue bead:\npick c2e4877 Red bead\nedit 9b5555e Blue bead\npick 7afd66b Blue bead\npick e1f2537 Red bead\nShe then saves her work and quits the editor. The garland magic has placed her back in time at the moment just after she added the first blue bead.\n\nShe needs to manually fix up her garland to add the new red bead. If the beads were files, she might run commands like vim beads.txt and edit the file to make the necessary changes.\nOnce she\u2019s finished her changes, she needs to add her new bead to the garland (git add --all) and lock it into place (git commit). This time she assigns the commit message \u201cRed bead \u2013 added\u201d so she can easily find it.\n\nThe garland magic has replaced the bead, but she still needs to verify the remaining beads on the garland. This is a mostly automatic process which is started by running the command git rebase --continue.\nThe new red bead has been assigned a position formerly held by the blue bead, and so the elf must deal with a merge conflict. She opens up a new program to help resolve the conflict by running git mergetool.\n\nShe knows she wants both of these beads in place, so the elf edits the file to include both the red and blue beads.\n\nWith the conflict resolved, the elf saves her changes and quits the mergetool.\nBack at the command line, the elf checks the status of her work using the command git status.\nrebase in progress; onto 4a9cb9d\nYou are currently rebasing branch '2_RBRBR' on '4a9cb9d'.\n (all conflicts fixed: run \"git rebase --continue\")\n\nChanges to be committed:\n (use \"git reset HEAD ...\" to unstage)\n\n modified: beads.txt\n\nUntracked files:\n (use \"git add ...\" to include in what will be committed)\n\n beads.txt.orig\nShe removes the file added by the mergetool with the command rm beads.txt.orig and commits the edits she just made to the bead file using the commands:\ngit add beads.txt\ngit commit --message \"Blue bead -- resolved conflict\"\n\nWith the conflict resolved, the elf is able to continue with the rebasing process using the command git rebase --continue. There is one final conflict the elf needs to resolve. Once again, she opens up the visualisation tool and takes a look at the two conflicting files.\n\nShe incorporates the changes from the left and right column to ensure her bead sequence is correct.\n\nOnce the merge conflict is resolved, the elf saves the file and quits the mergetool. Once again, she cleans out the backup file added by the mergetool (rm beads.txt.orig) and commits her changes to the garland:\ngit add beads.txt\ngit commit --message \"Red bead -- resolved conflict\"\nand then runs the final verification steps in the rebase process (git rebase --continue).\n\nThe verification process runs through to the end, and the elf checks her work using the command git log --oneline.\n9269914 Red bead -- resolved conflict\n4916353 Blue bead -- resolved conflict\naef0d5c Red bead -- added\n9b5555e Blue bead\nc2e4877 Red bead\nShe knows she needs to read the sequence from bottom to top (the oldest bead is on the bottom). Reviewing the list she sees that the sequence is now correct.\nSometimes, late at night, the elf makes new copies of the workshop garland so she can play around with the bead sequencer just to see what happens. It\u2019s made her more confident at restringing beads when she\u2019s found real mistakes. And she doesn\u2019t mind helping her fellow elves when they run into trouble with their beads. The sugar cookies they leave her as thanks don\u2019t hurt either. If you would also like to play with the bead sequencer, you can get a copy of the branches the elf worked.\n\nOur lessons from the workshop:\n\nBy using rebase to update your branches, you avoid merge commits and keep a clean commit history.\nIf you make a mistake on one of your local branches, you can use reset to take commits off your branch. If you want to save the work, but uncommit it, add the parameter --soft. If you want to completely discard the work, use the parameter, --hard.\nIf you have merged working branch changes to the local copy of your master branch and it is preventing you from pushing your work to a remote repository, remove these changes using the command reset with the parameter --merge ORIG_HEAD before updating your local copy of the remote master branch.\nIf you want to make a change to work that was committed a little while ago, you can use the command rebase with the parameter --interactive. You will need to include how many commits back in time you want to review.", "year": "2015", "author": "Emma Jane Westby", "author_slug": "emmajanewestby", "published": "2015-12-07T00:00:00+00:00", "url": "https://24ways.org/2015/git-rebasing/", "topic": "code"}
{"rowid": 70, "title": "Bringing Your Code to the Streets", "contents": "\u2014 or How to Be a Street VJ\nOur amazing world of web code is escaping out of the browser at an alarming rate and appearing in every aspect of the environment around us. Over the past few years we\u2019ve already seen JavaScript used server-side, hardware coded with JavaScript, a rise of native style and desktop apps created with HTML, CSS and JavaScript, and even virtual reality (VR) is getting its fair share of front-end goodness.\nYou can go ahead and play with JavaScript-powered hardware such as the Tessel or the Espruino to name a couple. Just check out the Tessel project page to see JavaScript in the world of coffee roasting or sleep tracking your pet. With the rise of the internet of things, JavaScript can be seen collecting information on flooding among other things. And if that\u2019s not enough \u2018outside the browser\u2019 implementations, Node.js servers can even be found in aircraft!\nI previously mentioned VR and with three.js\u2019s extra StereoEffect.js module it\u2019s relatively simple to get browser 3D goodness to be Google Cardboard-ready, and thus set the stage for all things JavaScript and VR. It\u2019s been pretty popular in the art world too, with interactive works such as Seb Lee-Delisle\u2019s Lunar Trails installation, featuring the old arcade game Lunar Lander, which you can now play in your browser while others watch (it is the web after all). The Science Museum in London held Chrome Web Lab, an interactive exhibition featuring five experiments, showcasing the magic of the web. And it\u2019s not even the connectivity of the web that\u2019s being showcased; we can even take things offline and use web code for amazing things, such as fighting Ebola.\nOne thing is for sure, JavaScript is awesome. Hell, if you believe those telly programs (as we all do), JavaScript can even take down the stock market, purely through the witchcraft of canvas! Go JavaScript!\nNow it\u2019s our turn\nSo I wanted to create a little project influenced by this theme, and as it\u2019s Christmas, take it to the streets for a little bit of party fun! Something that could take code anywhere. Here\u2019s how I made a portable visual projection pack, a piece of video mixing software and created some web-coded street art.\nStep one: The equipment\nYou will need:\n\nOne laptop: with HDMI output and a modern browser installed, such as Google Chrome.\nOne battery-powered mini projector: I\u2019ve used a Texas Instruments DLP; for its 120 lumens it was the best cost-to-lumens ratio I could find.\nOne MIDI controller (optional): mine is an ICON iDJ as it suits mixing visuals. However, there is more affordable hardware on the market such as an Akai LPD8 or a Korg nanoPAD2. As you\u2019ll see in the article, this is optional as it can be emulated within the software.\nA case to carry it all around in.\n\n\nStep two: The software\nThe projected visuals, I imagined, could be anything you can create within a browser, whether that be simple HTML and CSS, images, videos, SVG or canvas. The only requirement I have is that they move or change with sound and that I can mix any one visual into another.\nYou may remember a couple of years ago I created a demo on this very site, allowing audio-triggered visuals from the ambient sounds your device mic was picking up. That was a great starting point \u2013 I used that exact method to pick up the audio and thus the first requirement was complete. If you want to see some more examples of visuals I\u2019ve put together for this, there\u2019s a showcase on CodePen.\nThe second requirement took a little more thought. I needed two screens, which could at any point show any of the visuals I had coded, but could be mixed from one into the other and back again. So let\u2019s start with two divs, both absolutely positioned so they\u2019re on top of each other, but at the start the second screen\u2019s opacity is set to zero.\nNow all we need is a slider, which when moved from one side to the other slowly sets the second screen\u2019s opacity to 1, thereby fading it in.\nSee the Pen Mixing Screens (Software Version) by Rumyra (@Rumyra) on CodePen.\nMixing Screens (CodePen)\n\nAs you saw above, I have a MIDI controller and although the software method works great, I\u2019d quite like to make use of this nifty piece of kit. That\u2019s easily done with the Web MIDI API. All I need to do is call it, and when I move one of the sliders on the controller (I\u2019ve allocated the big cross fader in the middle for this), pick up on the change of value and use that to control the opacity instead.\nvar midi, data;\n// start talking to MIDI controller\nif (navigator.requestMIDIAccess) {\n navigator.requestMIDIAccess({\n sysex: false\n }).then(onMIDISuccess, onMIDIFailure);\n} else {\n alert(\u201cNo MIDI support in your browser.\u201d);\n}\n\n// on success\nfunction onMIDISuccess(midiData) {\n // this is all our MIDI data\n midi = midiData;\n\n var allInputs = midi.allInputs.values();\n // loop over all available inputs and listen for any MIDI input\n for (var input = allInputs.next(); input && !input.done; input = allInputs.next()) {\n // when a MIDI value is received call the onMIDIMessage function\n input.value.onmidimessage = onMIDIMessage;\n }\n}\n\nfunction onMIDIMessage(message) {\n // data comes in the form [command/channel, note, velocity]\n data = message.data;\n\n // Opacity change for screen. The cross fader values are [176, 8, {0-127}]\n if ( (data[0] === 176) && (data[1] === 8) ) {\n // this value will change as the fader is moved\n var opacity = data[2]/127;\n screenTwo.style.opacity = opacity;\n }\n}\n\nThe final code was slightly more complicated than this, as I decided to switch the two screens based on the frequencies of the sound that was playing, and use the cross fader to depict the frequency threshold value. This meant they flickered in and out of each other, rather than just faded. There\u2019s a very rough-and-ready first version of the software on GitHub.\nPhew, Great! Now we need to get all this to the streets!\nStep three: Portable kit\nDid you notice how I mentioned a case to carry it all around in? I wanted the case to be morphable, so I could use the equipment from it too, a sort of bag-to-usherette-tray-type affair. Well, I had an unused laptop bag\u2026\n\nI strengthened it with some MDF, so when I opened the bag it would hold like a tray where the laptop and MIDI controller would sit. The projector was Velcroed to the external pocket of the bag, so when it was a tray it would project from underneath. I added two durable straps, one for my shoulders and one round my waist, both attached to the bag itself. There was a lot of cutting and trimming. As it was a laptop bag it was pretty thick to start and sewing was tricky. However, I only broke one sewing machine needle; I\u2019ve been known to break more working with leather, so I figured I was doing well. By the way, you can actually buy usherette trays, but I just couldn\u2019t resist hacking my own :)\nStep four: Take to the streets\nFirst, make sure everything is charged \u2013 everything \u2013 a lot! The laptop has to power both the MIDI controller and the projector, and although I have a mobile phone battery booster pack, that\u2019ll only charge the projector should it run out. I estimated I could get a good hour of visual artistry before I needed to worry, though.\nI had a couple of ideas about time of day and location. Here in the UK at this time of year, it gets dark around half past four, so I could easily head out in a city around 5pm and it would be dark enough for the projections to be seen pretty well. I chose Bristol, around the waterfront, as there were some interesting locations to try it out in. The best was Millennium Square: busy but not crowded and plenty of surfaces to try projecting on to.\nMy first time out with the portable audio/visual pack (PAVP as it will now be named) was brilliant. I played music and projected visuals, like a one-woman band of A/V!\n\n\nYou might be thinking what the point of this was, besides, of course, it being a bit of fun. Well, this project got me to look at canvas and SVG more closely. The Web MIDI API was really interesting; MIDI as a data format has some great practical uses. I think without our side projects we may not have all these wonderful uses for our everyday code. Not only do they remind us coding can, and should, be fun, they also help us learn and grow as makers.\nMy favourite part? When I was projecting into a water feature in Millennium Square. For those who are familiar, you\u2019ll know it\u2019s like a wall of water so it produced a superb effect. I drew quite a crowd and a kid came to stand next to me and all I could hear him say with enthusiasm was, \u2018Oh wow! That\u2019s so cool!\u2019\nYes\u2026 yes, kid, it was cool. Making things with code is cool.\nMassive thanks to the lovely Drew McLellan for his incredibly well-directed photography, and also Simon Johnson who took a great hand in perfecting the kit while it was attached.", "year": "2015", "author": "Ruth John", "author_slug": "ruthjohn", "published": "2015-12-06T00:00:00+00:00", "url": "https://24ways.org/2015/bringing-your-code-to-the-streets/", "topic": "code"}
{"rowid": 49, "title": "Universal React", "contents": "One of the libraries to receive a huge amount of focus in 2015 has been ReactJS, a library created by Facebook for building user interfaces and web applications.\nMore generally we\u2019ve seen an even greater rise in the number of applications built primarily on the client side with most of the logic implemented in JavaScript. One of the main issues with building an app in this way is that you immediately forgo any customers who might browse with JavaScript turned off, and you can also miss out on any robots that might visit your site to crawl it (such as Google\u2019s search bots). Additionally, we gain a performance improvement by being able to render from the server rather than having to wait for all the JavaScript to be loaded and executed.\nThe good news is that this problem has been recognised and it is possible to build a fully featured client-side application that can be rendered on the server. The way in which these apps work is as follows:\n\nThe user visits www.yoursite.com and the server executes your JavaScript to generate the HTML it needs to render the page.\nIn the background, the client-side JavaScript is executed and takes over the duty of rendering the page.\nThe next time a user clicks, rather than being sent to the server, the client-side app is in control.\nIf the user doesn\u2019t have JavaScript enabled, each click on a link goes to the server and they get the server-rendered content again.\n\nThis means you can still provide a very quick and snappy experience for JavaScript users without having to abandon your non-JS users. We achieve this by writing JavaScript that can be executed on the server or on the client (you might have heard this referred to as isomorphic) and using a JavaScript framework that\u2019s clever enough handle server- or client-side execution. Currently, ReactJS is leading the way here, although Ember and Angular are both working on solutions to this problem.\nIt\u2019s worth noting that this tutorial assumes some familiarity with React in general, its syntax and concepts. If you\u2019d like a refresher, the ReactJS docs are a good place to start.\n\u00a0Getting started\nWe\u2019re going to create a tiny ReactJS application that will work on the server and the client. First we\u2019ll need to create a new project and install some dependencies. In a new, blank directory, run:\nnpm init -y\nnpm install --save ejs express react react-router react-dom\nThat will create a new project and install our dependencies:\n\nejs is a templating engine that we\u2019ll use to render our HTML on the server.\nexpress is a small web framework we\u2019ll run our server on.\nreact-router is a popular routing solution for React so our app can fully support and respect URLs.\nreact-dom is a small React library used for rendering React components.\n\nWe\u2019re also going to write all our code in ECMAScript 6, and therefore need to install BabelJS and configure that too.\nnpm install --save-dev babel-cli babel-preset-es2015 babel-preset-react\nThen, create a .babelrc file that contains the following:\n{\n \"presets\": [\"es2015\", \"react\"]\n}\nWhat we\u2019ve done here is install Babel\u2019s command line interface (CLI) tool and configured it to transform our code from ECMAScript 6 (or ES2015) to ECMAScript 5, which is more widely supported. We\u2019ll need the React transforms when we start writing JSX when working with React.\nCreating a server\nFor now, our ExpressJS server is pretty straightforward. All we\u2019ll do is render a view that says \u2018Hello World\u2019. Here\u2019s our server code:\nimport express from 'express';\nimport http from 'http';\n\nconst app = express();\n\napp.use(express.static('public'));\n\napp.set('view engine', 'ejs');\n\napp.get('*', (req, res) => {\n res.render('index');\n});\n\nconst server = http.createServer(app);\n\nserver.listen(3003);\nserver.on('listening', () => {\n console.log('Listening on 3003');\n});\nHere we\u2019re using ES6 modules, which I wrote about on 24 ways last year, if you\u2019d like a reminder. We tell the app to render the index view on any GET request (that\u2019s what app.get('*') means, the wildcard matches any route).\nWe now need to create the index view file, which Express expects to be defined in views/index.ejs:\n\n\n \n My App \n \n\n \n Hello World\n \n\nFinally, we\u2019re ready to run the server. Because we installed babel-cli earlier we have access to the babel-node executable, which will transform all your code before running it through node. Run this command:\n./node_modules/.bin/babel-node server.js\nAnd you should now be able to visit http://localhost:3003 and see \u2018Hello World\u2019 right there:\n\nBuilding the React app\nNow we\u2019ll build the React application entirely on the server, before adding the client-side JavaScript right at the end. Our app will have two routes, / and /about which will both show a small amount of content. This will demonstrate how to use React Router on the server side to make sure our React app plays nicely with URLs.\nFirstly, let\u2019s update views/index.ejs. Our server will figure out what HTML it needs to render, and pass that into the view. We can pass a value into our view when we render it, and then use EJS syntax to tell it to output that data. Update the template file so the body looks like so:\n\n <%- markup %>\n\nNext, we\u2019ll define the routes we want our app to have using React Router. For now we\u2019ll just define the index route, and not worry about the /about route quite yet. We could define our routes in JSX, but I think for server-side rendering it\u2019s clearer to define them as an object. Here\u2019s what we\u2019re starting with:\nconst routes = {\n path: '',\n component: AppComponent,\n childRoutes: [\n {\n path: '/',\n component: IndexComponent\n }\n ]\n}\nThese are just placed at the top of server.js, after the import statements. Later we\u2019ll move these into a separate file, but for now they are fine where they are.\nNotice how I define first that the AppComponent should be used at the '' path, which effectively means it matches every single route and becomes a container for all our other components. Then I give it a child route of /, which will match the IndexComponent. Before we hook these routes up with our server, let\u2019s quickly define components/app.js and components/index.js. app.js looks like so:\nimport React from 'react';\n\nexport default class AppComponent extends React.Component {\n render() {\n return (\n \n
Welcome to my App \n { this.props.children }\n \n );\n }\n}\nWhen a React Router route has child components, they are given to us in the props under the children key, so we need to include them in the code we want to render for this component. The index.js component is pretty bland:\nimport React from 'react';\n\nexport default class IndexComponent extends React.Component {\n render() {\n return (\n \n
This is the index page
\n
\n );\n }\n}\nServer-side routing with React Router\nHead back into server.js, and firstly we\u2019ll need to add some new imports:\nimport React from 'react';\nimport { renderToString } from 'react-dom/server';\nimport { match, RoutingContext } from 'react-router';\n\nimport AppComponent from './components/app';\nimport IndexComponent from './components/index';\nThe ReactDOM package provides react-dom/server which includes a renderToString method that takes a React component and produces the HTML string output of the component. It\u2019s this method that we\u2019ll use to render the HTML from the server, generated by React. From the React Router package we use match, a function used to find a matching route for a URL; and RoutingContext, a React component provided by React Router that we\u2019ll need to render. This wraps up our components and provides some functionality that ties React Router together with our app. Generally you don\u2019t need to concern yourself about how this component works, so don\u2019t worry too much.\nNow for the good bit: we can update our app.get('*') route with the code that matches the URL against the React routes:\napp.get('*', (req, res) => {\n // routes is our object of React routes defined above\n match({ routes, location: req.url }, (err, redirectLocation, props) => {\n if (err) {\n // something went badly wrong, so 500 with a message\n res.status(500).send(err.message);\n } else if (redirectLocation) {\n // we matched a ReactRouter redirect, so redirect from the server\n res.redirect(302, redirectLocation.pathname + redirectLocation.search);\n } else if (props) {\n // if we got props, that means we found a valid component to render\n // for the given route\n const markup = renderToString( );\n\n // render `index.ejs`, but pass in the markup we want it to display\n res.render('index', { markup })\n\n } else {\n // no route match, so 404. In a real app you might render a custom\n // 404 view here\n res.sendStatus(404);\n }\n });\n});\nWe call match, giving it the routes object we defined earlier and req.url, which contains the URL of the request. It calls a callback function we give it, with err, redirectLocation and props as the arguments. The first two conditionals in the callback function just deal with an error occuring or a redirect (React Router has built in redirect support). The most interesting bit is the third conditional, else if (props). If we got given props and we\u2019ve made it this far it means we found a matching component to render and we can use this code to render it:\n...\n} else if (props) {\n // if we got props, that means we found a valid component to render\n // for the given route\n const markup = renderToString( );\n\n // render `index.ejs`, but pass in the markup we want it to display\n res.render('index', { markup })\n} else {\n ...\n}\nThe renderToString method from ReactDOM takes that RoutingContext component we mentioned earlier and renders it with the properties required. Again, you need not concern yourself with what this specific component does or what the props are. Most of this is data that React Router provides for us on top of our components.\nNote the {...props}, which is a neat bit of JSX syntax that spreads out our object into key value properties. To see this better, note the two pieces of JSX code below, both of which are equivalent:\n \n\n// OR:\n\nconst props = { a: \"foo\", b: \"bar\" };\n \nRunning the server again\nI know that felt like a lot of work, but the good news is that once you\u2019ve set this up you are free to focus on building your React components, safe in the knowledge that your server-side rendering is working. To check, restart the server and head to http://localhost:3003 once more. You should see it all working!\n\nRefactoring and one more route\nBefore we move on to getting this code running on the client, let\u2019s add one more route and do some tidying up. First, move our routes object out into routes.js:\nimport AppComponent from './components/app';\nimport IndexComponent from './components/index';\n\nconst routes = {\n path: '',\n component: AppComponent,\n childRoutes: [\n {\n path: '/',\n component: IndexComponent\n }\n ]\n}\n\nexport { routes };\nAnd then update server.js. You can remove the two component imports and replace them with:\nimport { routes } from './routes';\nFinally, let\u2019s add one more route for ./about and links between them. Create components/about.js:\nimport React from 'react';\n\nexport default class AboutComponent extends React.Component {\n render() {\n return (\n \n
A little bit about me.
\n
\n );\n }\n}\nAnd then you can add it to routes.js too:\nimport AppComponent from './components/app';\nimport IndexComponent from './components/index';\nimport AboutComponent from './components/about';\n\nconst routes = {\n path: '',\n component: AppComponent,\n childRoutes: [\n {\n path: '/',\n component: IndexComponent\n },\n {\n path: '/about',\n component: AboutComponent\n }\n ]\n}\n\nexport { routes };\nIf you now restart the server and head to http://localhost:3003/about` you\u2019ll see the about page!\n\nFor the finishing touch we\u2019ll use the React Router link component to add some links between the pages. Edit components/app.js to look like so:\nimport React from 'react';\nimport { Link } from 'react-router';\n\nexport default class AppComponent extends React.Component {\n render() {\n return (\n \n
Welcome to my App \n
\n { this.props.children }\n
\n );\n }\n}\nYou can now click between the pages to navigate. However, everytime we do so the requests hit the server. Now we\u2019re going to make our final change, such that after the app has been rendered on the server once, it gets rendered and managed in the client, providing that snappy client-side app experience.\nClient-side rendering\nFirst, we\u2019re going to make a small change to views/index.ejs. React doesn\u2019t like rendering directly into the body and will give a warning when you do so. To prevent this we\u2019ll wrap our app in a div:\n\n <%- markup %>
\n \n\nI\u2019ve also added in a script tag to build.js, which is the file we\u2019ll generate containing all our client-side code.\nNext, create client-render.js. This is going to be the only bit of JavaScript that\u2019s exclusive to the client side. In it we need to pull in our routes and render them to the DOM.\nimport React from 'react';\nimport ReactDOM from 'react-dom';\nimport { Router } from 'react-router';\n\nimport { routes } from './routes';\n\nimport createBrowserHistory from 'history/lib/createBrowserHistory';\n\nReactDOM.render(\n ,\n document.getElementById('app')\n)\nThe first thing you might notice is the mention of createBrowserHistory. React Router is built on top of the history module, a module that listens to the browser\u2019s address bar and parses the new location. It has many modes of operation: it can keep track using a hashbang, such as http://localhost/#!/about (this is the default), or you can tell it to use the HTML5 history API by calling createBrowserHistory, which is what we\u2019ve done. This will keep the URLs nice and neat and make sure the client and the server are using the same URL structure. You can read more about React Router and histories in the React Router documentation.\nFinally we use ReactDOM.render and give it the Router component, telling it about all our routes, and also tell ReactDOM where to render, the #app element.\nGenerating build.js\nWe\u2019re actually almost there! The final thing we need to do is generate our client side bundle. For this we\u2019re going to use webpack, a module bundler that can take our application, follow all the imports and generate one large bundle from them. We\u2019ll install it and babel-loader, a webpack plugin for transforming code through Babel.\nnpm install --save-dev webpack babel-loader\nTo run webpack we just need to create a configuration file, called webpack.config.js. Create the file in the root of our application and add the following code:\nvar path = require('path');\nmodule.exports = {\n entry: path.join(process.cwd(), 'client-render.js'),\n output: {\n path: './public/',\n filename: 'build.js'\n },\n module: {\n loaders: [\n {\n test: /.js$/,\n loader: 'babel'\n }\n ]\n }\n}\nNote first that this file can\u2019t be written in ES6 as it doesn\u2019t get transformed. The first thing we do is tell webpack the main entry point for our application, which is client-render.js. We use process.cwd() because webpack expects an exact location \u2013 if we just gave it the string \u2018client-render.js\u2019, webpack wouldn\u2019t be able to find it.\nNext, we tell webpack where to output our file, and here I\u2019m telling it to place the file in public/build.js. Finally we tell webpack that every time it hits a file that ends in .js, it should use the babel-loader plugin to transform the code first.\nNow we\u2019re ready to generate the bundle!\n./node_modules/.bin/webpack\nThis will take a fair few seconds to run (on my machine it\u2019s about seven or eight), but once it has it will have created public/build.js, a client-side bundle of our application. If you restart your server once more you\u2019ll see that we can now navigate around our application without hitting the server, because React on the client takes over. Perfect!\nThe first bundle that webpack generates is pretty slow, but if you run webpack -w it will go into watch mode, where it watches files for changes and regenerates the bundle. The key thing is that it only regenerates the small pieces of the bundle it needs, so while the first bundle is very slow, the rest are lightning fast. I recommend leaving webpack constantly running in watch mode when you\u2019re developing.\nConclusions\nFirst, if you\u2019d like to look through this code yourself you can find it all on GitHub. Feel free to raise an issue there or tweet me if you have any problems or would like to ask further questions.\nNext, I want to stress that you shouldn\u2019t use this as an excuse to build all your apps in this way. Some of you might be wondering whether a static site like the one we built today is worth its complexity, and you\u2019d be right. I used it as it\u2019s an easy example to work with but in the future you should carefully consider your reasons for wanting to build a universal React application and make sure it\u2019s a suitable infrastructure for you.\nWith that, all that\u2019s left for me to do is wish you a very merry Christmas and best of luck with your React applications!", "year": "2015", "author": "Jack Franklin", "author_slug": "jackfranklin", "published": "2015-12-05T00:00:00+00:00", "url": "https://24ways.org/2015/universal-react/", "topic": "code"}
{"rowid": 36, "title": "Naming Things", "contents": "There are only two hard things in computer science: cache invalidation and naming things.\nPhil Karlton\n\n\nBeing a professional web developer means taking responsibility for the code you write and ensuring it is comprehensible to others. Having a documented code style is one means of achieving this, although the size and type of project you\u2019re working on will dictate the conventions used and how rigorously they are enforced.\n\nWorking in-house may mean working with multiple developers, perhaps in distributed teams, who are all committing changes \u2013 possibly to a significant codebase \u2013 at the same time. Left unchecked, this codebase can become unwieldy. Coding conventions ensure everyone can contribute, and help build a product that works as a coherent whole.\n\nEven on smaller projects, perhaps working within an agency or by yourself, at some point the resulting product will need to be handed over to a third party. It\u2019s sensible, therefore, to ensure that your code can be understood by those who\u2019ll eventually take ownership of it.\n\nPut simply, code is read more often than it is written or changed. A consistent and predictable naming scheme can make code easier for other developers to understand, improve and maintain, presumably leaving them free to worry about cache invalidation.\n\nLet\u2019s talk about semantics\n\nNames not only allow us to identify objects, but they can also help us describe the objects being identified.\n\nSemantics (the meaning or interpretation of words) is the cornerstone of standards-based web development. Using appropriate HTML elements allows us to create documents and applications that have implicit structural meaning. Thanks to HTML5, the vocabulary we can choose from has grown even larger.\n\nHTML elements provide one level of meaning: a widely accepted description of a document\u2019s underlying structure. It\u2019s only with the mutual agreement of browser vendors and developers that indicates a paragraph.\n\nYet (with the exception of widely accepted microdata and microformat schemas) only HTML elements convey any meaning that can be parsed consistently by user agents. While using semantic values for class names is a noble endeavour, they provide no additional information to the visitor of a website; take them away and a document will have exactly the same semantic value.\n\nI didn\u2019t always think this was the case, but the real world has a habit of changing your opinion. Much of my thinking around semantics has been informed by the writing of my peers. In \u201cAbout HTML semantics and front-end architecture\u201d, Nicholas Gallagher wrote:\n\n\n\tThe important thing for class name semantics in non-trivial applications is that they be driven by pragmatism and best serve their primary purpose \u2013 providing meaningful, flexible, and reusable presentational/behavioural hooks for developers to use.\n\n\nThese thoughts are echoed by Harry Roberts in his CSS Guidelines:\n\n\n\tThe debate surrounding semantics has raged for years, but it is important that we adopt a more pragmatic, sensible approach to naming things in order to work more efficiently and effectively. Instead of focussing on \u2018semantics\u2019, look more closely at sensibility and longevity \u2013 choose names based on ease of maintenance, not for their perceived meaning.\n\n\nNaming methodologies\n\nFront-end development has undergone a revolution in recent years. As the projects we\u2019ve worked on have grown larger and more important, our development practices have matured. The pros and cons of object-orientated approaches to CSS can be endlessly debated, yet their introduction has highlighted the usefulness of having documented naming schemes.\n\nJonathan Snook\u2019s SMACSS (Scalable and Modular Architecture for CSS) collects style rules into five categories: base, layout, module, state and theme. This grouping makes it clear what each rule does, and is aided by a naming convention:\n\n\n\tBy separating rules into the five categories, naming convention is beneficial for immediately understanding which category a particular style belongs to and its role within the overall scope of the page. On large projects, it is more likely to have styles broken up across multiple files. In these cases, naming convention also makes it easier to find which file a style belongs to.\n\n\tI like to use a prefix to differentiate between layout, state and module rules. For layout, I use l- but layout- would work just as well. Using prefixes like grid- also provide enough clarity to separate layout styles from other styles. For state rules, I like is- as in is-hidden or is-collapsed. This helps describe things in a very readable way.\n\n\nSMACSS is more a set of suggestions than a rigid framework, so its ideas can be incorporated into your own practice. Nicholas Gallagher\u2019s SUIT CSS project is far more strict in its naming conventions:\n\n\n\tSUIT CSS relies on structured class names and meaningful hyphens (i.e., not using hyphens merely to separate words). This helps to work around the current limits of applying CSS to the DOM (i.e., the lack of style encapsulation), and to better communicate the relationships between classes.\n\n\nOver the last year, I\u2019ve favoured a BEM-inspired approach to CSS. BEM stands for block, element, modifier, which describes the three types of rule that contribute to the style of a single component. This means that, given the following markup:\n\n
\n Rudolph \n Dasher \n Dancer \n Prancer \n Vixen \n Comet \n Cupid \n Dunder \n Blixem \n \n\nI know that:\n\n\n\t.sleigh is a containing block or component.\n\t.sleigh__reindeer is used only as a descendent element of .sleigh.\n\t.sleigh__reindeer\u2013\u2013famous is used only as a modifier of .sleigh__reindeer.\n\n\nWith this naming scheme in place, I know which styles relate to a particular component, and which are shared. Beyond reducing specificity-related head-scratching, this approach has given me a framework within which I can consistently label items, and has sped up my workflow considerably.\n\nEach of these methodologies shows that any robust CSS naming convention will have clear rules around case (lowercase, camelCase, PascalCase) and the use of special (allowed) characters like hyphens and underscores.\n\nWhat makes for a good name?\n\nRegardless of higher-level conventions, there\u2019s no getting away from the fact that, at some point, we\u2019re still going to have to name things. Recognising that classes should be named with other developers in mind, what makes for a good name?\n\nUnderstandable\n\nThe most important aspect is for a name to be understandable. Words used in your project may come from a variety of sources: some may be widely understood, and others only be recognised by people working within a particular environment.\n\n\n\tCulture\nMost words you\u2019ll choose will have common currency outside the world of web development, although they may have a particular interpretation among developers (think menu, list, input). However, words may have a narrower cultural significance; for example, in Germany and other German-speaking countries, impressum is the term used for legally mandated statements of ownership.\n\tIndustry\nIndustries often use specific terms to describe common business practices and concepts. Publishing has a number of these (headline, standfirst, masthead, colophon\u2026) all have well understood meanings \u2013 and not all of them are relevant to online usage.\n\tOrganisation\nCompanies may have internal names (or nicknames) for their products and services. The Guardian is rife with such names: bisons (and buffalos), pixies (and super-pixies), bentos (and mini-bentos)\u2026 all of which mean something very different outside the organisation. Although such names can be useful inside smaller teams, in larger organisations they can become a barrier to entry, a sort of secret code used among employees who have been around long enough to know what they mean.\n\tProduct\nYour team will undoubtedly have created names for specific features or interface components used in your product. For example, at Clearleft we coined the term gravigation for a navigation bar that was pinned to the bottom of the viewport. Elements of a visual design language may have names, too. Transport for London\u2019s bar and circle logo is known internally as the roundel, while Nike\u2019s logo is called the swoosh. Branding agencies often christen colours within a brand palette, too, either to evoke aspects of the identity or to indicate intended usage.\n\n\nOnce you recognise the origin of the words you use, you\u2019ll be better able to judge their appropriateness. Using Latin words for class names may satisfy a need to use semantic-sounding terms but, unless you work in a company whose employees have a basic grasp of Latin, a degree of translation will be required. Military ranks might be a clever way of declaring sizes without implying actual values, but I\u2019d venture most people outside the armed forces don\u2019t know how they\u2019re ordered.\n\nObvious\n\nQuite often, the first name that comes into your head will be the best option. Names that obliquely reference the function of a class (e.g. receptacle instead of container, kevlar instead of no-bullets) only serve to add an additional layer of abstraction. Don\u2019t overthink it!\n\nOne way of knowing if the names you use are well understood is to look at what similar concepts are called in existing vocabularies. schema.org, Dublin Core and the BBC\u2019s ontologies are all useful sources for object names.\n\nFunctional\n\nWhile we\u2019ve learned to avoid using presentational classes, there remains a tension between naming things based on their content, and naming them for their intended presentation or behaviour (which may change at different breakpoints). Rather than think about a component\u2019s appearance or behaviour, instead look to its function, its purpose. To clarify, ask what a component\u2019s function is, and not how the component functions.\n\nFor example, the Guardian\u2019s internal content system uses the following names for different types of image placement: supporting, showcase and thumbnail, with inline being the default. These options make no promise of the resulting position on a webpage (or smartphone app, or television screen\u2026), but do suggest intended use, and therefore imply the likely presentation.\n\nConsistent\n\nBeing consistent in your approach to names will allow for easier naming of successive components, and extending the vocabulary when necessary. For example, a predictably named hierarchy might use names like primary and secondary. Should another level need to be added, tertiary is clearly be preferred over third.\n\nAppropriate\n\nYour project will feature a mix of style rules. Some will perform utility functions (clearing floats, removing bullets from a list, reseting margins), while others will perform specific functions used only once or twice in a project. Names should reflect this. For commonly used classes, be generic; for unique components be more specific.\n\nIt\u2019s also worth remembering that you can use multiple classes on an element, so combining both generic and specific can give you a powerful modular design system:\n\n\n\tGeneric: list\n\tSpecific: naughty-children\n\tCombined: naughty-children list\n\n\nIf following the BEM methodology, you might use the following classes:\n\n\n\tGeneric: list\n\tSpecific: list\u2013\u2013nice-children\n\tCombined: list list\u2013\u2013nice-children\n\n\nExtensible\n\nGood naming schemes can be extended. One way of achieving this is to use namespaces, which are basically a way of grouping related names under a higher-level term.\n\nMicroformats are a good example of a well-designed naming scheme, with many of its vocabularies taking property names from existing and related specifications (e.g. hCard is a 1:1 representation of vCard). Microformats 2 goes one step further by grouping properties under several namespaces:\n\n\n\th-* for root class names (e.g. h-card)\n\tp-* for simple (text) properties (e.g. p-name)\n\tu-* for URL properties (e.g. u-photo)\n\tdt-* for date/time properties (e.g. dt-bday)\n\te-* for embedded markup properties (e.g. e-note)\n\n\nThe inclusion of namespaces is a massive improvement over the earlier specification, but the downside is that microformats now occupy five separate namespaces. This might be problematic if you are using u-* for your utility classes. While nothing will break, your naming system won\u2019t be as robust, so plan accordingly.\n\n(Note: Microformats perform a very specific function, separate from any presentational concerns. It\u2019s therefore considered best practice to not use microformat classes as styling hooks, but instead use additional classes that relate to the function of the component and adhere to your own naming conventions.)\n\nShort\n\nNames should be as long as required, but no longer. When looking for words to describe a particular function, I try to look for single words where possible. Avoid abbreviations unless they are understood within the contexts described above. rrp is fine if labelling a recommended retail price in an online shop, but not very helpful if used to mean ragged-right paragraph, for example.\n\nFun!\n\nFinally, names can be an opportunity to have some fun! Names can give character to a project, be it by providing an outlet for in-jokes or adding little easter eggs for those inclined to look.\n\nThe copyright statement on Apple\u2019s website has long been named sosumi, a word that has a nice little history inside Apple. Until recently, the hamburger menu icon on the Guardian website was labelled honest-burger, after the developer\u2019s favourite burger restaurant.\n\nA few thoughts on preprocessors\n\nCSS preprocessors have solved a lot of problems, but they have an unfortunate downside: they require you to name yet more things! Whereas we needed to worry only about style rules, now we need names for variables, mixins, functions\u2026 oh my!\n\nA second article could be written about naming these, so for now I\u2019ll offer just a few thoughts. The first is to note that preprocessors make it easier to change things, as they allow for DRYer code. So while the names of variables are important (and the advice in this article still very much applies), you can afford to relax a little.\n\nLooking to name colour variables? If possible, find out if colours have been assigned names in a brand palette. If not, use obvious names (based on appearance or function, depending on your preference) and adapt as the palette grows. If it becomes difficult to name colours that are too similar, I\u2019d venture that the problem lies with the design rather than the naming scheme.\n\nThe same is true for responsive breakpoints. Preprocessors allow you to move awkward naming conventions out of the markup and into the CSS. Although terms like mobile, tablet and desktop are not desirable given the need to think about device-agnostic design, if these terms are widely understood within a product team and among stakeholders, using them will ensure everyone is using the same language (they can always be changed later).\n\nIt still feels like we\u2019re at the very beginning of understanding how preprocessors fit into a development workflow, if at all! I suspect over the next few years, best practices will emerge for all of these considerations. In the meantime, use your brain!\n\n\n\nEven with sensible rules and conventions in place, naming things can remain difficult, but hopefully I\u2019ve made this exercise a little less painful. Christmas is a time of giving, so to the developer reading your code in a year\u2019s time, why not make your gift one of clearer class names.", "year": "2014", "author": "Paul Lloyd", "author_slug": "paulrobertlloyd", "published": "2014-12-21T00:00:00+00:00", "url": "https://24ways.org/2014/naming-things/", "topic": "code"}
{"rowid": 42, "title": "An Overview of SVG Sprite Creation Techniques", "contents": "SVG can be used as an icon system to replace icon fonts. The reasons why SVG makes for a superior icon system are numerous, but we won\u2019t be going over them in this article. If you don\u2019t use SVG icons and are interested in knowing why you may want to use them, I recommend you check out \u201cInline SVG vs Icon Fonts\u201d by Chris Coyier \u2013 it covers the most important aspects of both systems and compares them with each other to help you make a better decision about which system to choose.\n\nOnce you\u2019ve made the decision to use SVG instead of icon fonts, you\u2019ll need to think of the best way to optimise the delivery of your icons, and ways to make the creation and use of icons faster.\n\nJust like bitmaps, we can create image sprites with SVG \u2013 they don\u2019t look or work exactly alike, but the basic concept is pretty much the same.\n\nThere are several ways to create SVG sprites, and this article will give you an overview of three of them. While we\u2019re at it, we\u2019re going to take a look at some of the available tools used to automate sprite creation and fallback for us.\n\nPrerequisites\n\nThe content of this article assumes you are familiar with SVG. If you\u2019ve never worked with SVG before, you may want to look at some of the introductory tutorials covering SVG syntax, structure and embedding techniques. I recommend the following:\n\n\n\tSVG basics: Using SVG.\n\tStructure: Structuring, Grouping, and Referencing in SVG \u2014 The , , and Elements. We\u2019ll mention and quite a bit in this article.\n\tEmbedding techniques: Styling and Animating SVGs with CSS. The article covers several topics, but the section linked focuses on embedding techniques.\n\tA compendium of SVG resources compiled by Chris Coyier \u2014 contains resources to almost every aspect of SVG you might be interested in.\n\n\nAnd if you\u2019re completely new to the concept of spriting, Chris Coyier\u2019s CSS Sprites explains all about them.\n\nAnother important SVG feature is the viewBox attribute. For some of the techniques, knowing your way around this attribute is not required, but it\u2019s definitely more useful if you understand \u2013 even if just vaguely \u2013 how it works. The last technique mentioned in the article requires that you do know the attribute\u2019s syntax and how to use it. To learn all about viewBox, you can refer to my blog post about SVG coordinate systems.\n\nWith the prerequisites in place, let\u2019s move on to spriting SVGs!\n\nBefore you sprite\u2026\n\nIn order to create an SVG sprite with your icons, you\u2019ll of course need to have these icons ready for use.\n\nSome spriting tools require that you place your icons in a folder to which a certain spriting process is to be applied. As such, for all of the upcoming sections we\u2019ll work on the assumption that our SVG icons are placed in a folder named SVG.\n\nEach icon is an individual .svg file.\n\nYou\u2019ll need to make sure each icon is well-prepared and optimised for use \u2013 make sure you\u2019ve cleaned up the code by running it through one of the optimisation tools or processes available (or doing it manually if it\u2019s not tedious).\n\nAfter prepping the icon files and placing them in a folder, we\u2019re ready to create our SVG sprite.\n\nHTML inline SVG sprites\n\nSince SVG is XML code, it can be embedded inline in an HTML document as a code island using the element. Chris Coyier wrote about this technique first on CSS-Tricks.\n\nThe embedded SVG will serve as a container for our icons and is going to be the actual sprite we\u2019re going to use. So we\u2019ll start by including the SVG in our document.\n\n\n\n\n\n \n \n\n\n\n\nNext, we\u2019re going to place the icons inside the . Each icon will be wrapped in a element we can then reference and use elsewhere in the page using the SVG element. The element has many benefits, and we\u2019re using it because it allows us to define a symbol (which is a convenient markup for an icon) without rendering that symbol on the screen. The elements defined inside will only be rendered when they are referenced \u2013 or called \u2013 by the element.\n\nMoreover, can have its own viewBox attribute, which makes it possible to control the positioning of its content inside its container at any time.\n\nBefore we move on, I\u2019d like to shed some light on the style=\"display:none;\" part of the snippet above. Without setting the display of the SVG to none, and even though its contents are not rendered on the page, the SVG will still take up space in the page, resulting in a big empty area. In order to avoid that, we\u2019re hiding the SVG entirely with CSS.\n\nNow, suppose we have a Twitter icon in the icons folder. twitter.svg might look something like this:\n\n\n\n\n\n \n \n\nWe don\u2019t need the root svg element, so we\u2019ll strip the code and only keep the parts that make up the Twitter icon\u2019s shape, which in this example is just the element.Let\u2019s drop that into the sprite container like so:\n\n\n \n\n \n \n \n \n\n \n \n\nRepeat for the other icons.\n\nThe value of the element\u2019s viewBox attribute depends on the size of the SVG. You don\u2019t need to know how the viewBox works to use it in this case. Its value is made up of four parts: the first two will almost always be \u201c0 0\u201d; the second two will be equal to the size of the icon. For example, our Twitter icon is 32px by 32px (see twitter.svg above), so the viewBox value is \u201c0 0 32 32\u201d.\n\nThat said, it is certainly useful to understand how the viewBox works \u2013 it can help you troubleshoot SVG sometimes and gives you better control over it, allowing you to scale, position and even crop SVGs manually without having to resort to an editor. My blog post explains all about the viewBox attribute and its related attributes.\n\nOnce you have your SVG sprite ready, you can display the icons anywhere on the page by referencing them using the SVG element:\n\n