This code only worked in Internet Explorer and in some versions of Safari, but that was plenty of people to befriend. However, MySpace was prepared for this: they also filtered the word javascript from
.
Samy discovered that by inserting a line break into his code, MySpace would not filter out the word javascript. The browser would continue to run the code just fine! Samy had now broken past MySpace’s first line of defence and was able to start running code on his profile page. Now he started looking at what he could do with that code.
alert(document.body.innerHTML)
Samy wondered if he could inspect the page’s source to find the details of other MySpace users to befriend. To do this, you would normally use document.body.innerHTML, but MySpace had filtered this too.
alert(eval('document.body.inne' + 'rHTML'))
This isn’t a problem if you build up JavaScript code inside a string and execute it using the eval() function. This trick also worked with XMLHttpRequest.onReadyStateChange, which allowed Samy to send friend requests to the MySpace API and install the JavaScript code on his new friends’ pages.
One final obstacle stood in his way. The same origin policy is a security mechanism that prevents scripts hosted on one domain interacting with sites hosted on another domain.
if (location.hostname == 'profile.myspace.com') {
document.location = 'http://www.myspace.com'
+ location.pathname + location.search
}
Samy discovered that only the http://www.myspace.com domain would accept his API requests, and requests from http://profile.myspace.com were being blocked by the browser’s same-origin policy. By redirecting the browser to http://www.myspace.com, he discovered that he could load profile pages and successfully make requests to MySpace’s API. Samy installed this code on his profile page, and he waited.
Over the course of the next day, over a million people unwittingly installed Samy’s code into their MySpace profile pages and invited their friends. The load of friend requests on MySpace was so large that the site buckled and shut down. It took them two hours to remove Samy’s code and patch the security holes he exploited. Samy was raided by the United States secret service and sentenced to do 90 days of community service.
This is the power of installing a little bit of JavaScript on someone else’s website. It is called cross site scripting, and its effects can be devastating. It is suspected that cross-site scripting was to blame for the 2018 British Airways breach that leaked the credit card details of 380,000 people.
So how can you help protect yourself from cross-site scripting?
Always sanitise user input when it comes in, using a library such as sanitize-html. Open source tools like this benefit from hundreds of hours of work from dozens of experienced contributors. Don’t be tempted to roll your own protection. MySpace was prepared, but they were not prepared enough. It makes no sense to turn this kind of help down.
You can also use an auto-escaping templating language to make sure nobody else’s HTML can get into your pages. Both Angular and React will do this for you, and they are extremely convenient to use.
You should also implement a content security policy to restrict the domains that content like scripts and stylesheets can be loaded from. Loading content from sites not under your control is a significant security risk, and you should use a CSP to lock this down to only the sources you trust. CSP can also block the use of the eval() function.
For content not under your control, consider setting up sub-resource integrity protection. This allows you to add hashes to stylesheets and scripts you include on your website. Hashes are like fingerprints for digital files; if the content changes, so does the fingerprint. Adding hashes will allow your browser to keep your site safe if the content changes without you knowing.
npm audit: Protecting yourself from code you don’t own
JavaScript and npm run the modern web. Together, they make it easy to take advantage of the world’s largest public registry of open source software. How do you protect yourself from code written by someone you’ve never met? Enter npm audit.
npm audit reviews the security of your website’s dependency tree. You can start using it by upgrading to the latest version of npm:
npm install npm -g
npm audit
When you run npm audit, npm submits a description of your dependencies to the Registry, which returns a report of known vulnerabilities for the packages you have installed.
If your website has a known cross-site scripting vulnerability, npm audit will tell you about it. What’s more, if the vulnerability has been patched, running npm audit fix will automatically install the patched package for you!
Securing your site like it’s 2019
The truth is that since the early days of the web, the stakes of a security breach have become much, much higher. The web is so much more than fandom and mailing DVDs - online banking is now mainstream, social media and dating websites store intimate information about our personal lives, and we are even inviting the internet into our homes.
However, we have powerful new allies helping us stay safe. There are more resources than ever before to teach us how to write secure code. Tools like Angular and React are designed with security features baked-in from the start. We have a new generation of security tools like npm audit to watch over our dependencies.
As we roll over into 2019, let’s take the opportunity to reflect on the security of the code we write and be grateful for the everything we’ve learned in the last twenty years.",2018,Katie Fenn,katiefenn,2018-12-01T00:00:00+00:00,https://24ways.org/2018/securing-your-site-like-its-1999/,code
117,The First Tool You Reach For,"Microsoft recently announced that Internet Explorer 8 will be released in the first half of 2009. Compared to the standards support of other major browsers, IE8 will not be especially great, but it will finally catch up with the state of the art in one specific area: support for CSS tables. This milestone has the potential to trigger an important change in the way you approach web design.
To show you just how big a difference CSS tables can make, think about how you might code a fluid, three-column layout from scratch. Just to make your life more difficult, give it one fixed-width column, with a background colour that differs from the rest of the page. Ready? Go!
Okay, since you’re the sort of discerning web designer who reads 24ways, I’m going to assume you at least considered doing this without using HTML tables for the layout. If you’re especially hardcore, I imagine you began thinking of CSS floats, negative margins, and faux columns. If you did, colour me impressed!
Now admit it: you probably also gave an inward sigh about the time it would take to figure out the math on the negative margin overlaps, check for dropped floats in Internet Explorer and generally wrestle each of the major browsers into giving you what you want. If after all that you simply gave up and used HTML tables, I can’t say I blame you.
There are plenty of professional web designers out there who still choose to use HTML tables as their main layout tool. Sure, they may know that users with screen readers get confused by inappropriate use of tables, but they have a job to do, and they want tools that will make that job easy, not difficult.
Now let me show you how to do it with CSS tables. First, we have a div element for each of our columns, and we wrap them all in another two divs:
Don’t sweat the “div clutter” in this code. Unlike tables, divs have no semantic meaning, and can therefore be used liberally (within reason) to provide hooks for the styles you want to apply to your page.
Using CSS, we can set the outer div to display as a table with collapsed borders (i.e. adjacent cells share a border) and a fixed layout (i.e. cell widths unaffected by their contents):
.container {
display: table;
border-collapse: collapse;
table-layout: fixed;
}
With another two rules, we set the middle div to display as a table row, and each of the inner divs to display as table cells:
.container > div {
display: table-row;
}
.container > div > div {
display: table-cell;
}
Finally, we can set the widths of the cells (and of the table itself) directly:
.container {
width: 100%;
}
#menu {
width: 200px;
}
#content {
width: auto;
}
#sidebar {
width: 25%;
}
And, just like that, we have a rock solid three-column layout, ready to be styled to your own taste, like in this example:
This example will render perfectly in reasonably up-to-date versions of Firefox, Safari and Opera, as well as the current beta release of Internet Explorer 8.
CSS tables aren’t only useful for multi-column page layout; they can come in handy in most any situation that calls for elements to be displayed side-by-side on the page. Consider this simple login form layout:
The incantation required to achieve this layout using CSS floats may be old hat to you by now, but try to teach it to a beginner, and watch his eyes widen in horror at the hoops you have to jump through (not to mention the assumptions you have to build into your design about the length of the form labels).
Here’s how to do it with CSS tables:
This time, we’re using a mixture of divs and spans as semantically transparent styling hooks. Let’s look at the CSS code.
First, we set up the outer div to display as a table, the inner divs to display as table rows, and the labels and spans as table cells (with right-aligned text):
form > div {
display: table;
}
form > div > div {
display: table-row;
}
form label,
form span {
display: table-cell;
text-align: right;
}
We want the first column of the table to be wide enough to accommodate our labels, but no wider. With CSS float techniques, we had to guess at what that width was likely to be, and adjust it whenever we changed our form labels. With CSS tables, we can simply set the width of the first column to something very small (1em), and then use the white-space property to force the column to the required width:
form label {
white-space: nowrap;
width: 1em;
}
To polish off the layout, we’ll make our text and password fields occupy the full width of the table cells that contain them:
input[type=text],
input[type=password] {
width: 100%;
}
The rest is margins, padding and borders to get the desired look. Check out the finished example.
As the first tool you reach for when approaching any layout task, CSS tables make a lot more sense to your average designer than the cryptic incantations called for by CSS floats. When IE8 is released and all major browsers support CSS tables, we can begin to gradually deploy CSS table-based layouts on sites that are more and more mainstream.
In our new book, Everything You Know About CSS Is Wrong!, Rachel Andrew and I explore in much greater detail how CSS tables work as a page layout tool in the real world. CSS tables have their quirks just like floats do, but they don’t tend to affect common layout tasks, and the workarounds tend to be less fiddly too. Check it out, and get ready for the next big step forward in web design with CSS.",2008,Kevin Yank,kevinyank,2008-12-13T00:00:00+00:00,https://24ways.org/2008/the-first-tool-you-reach-for/,code
106,Checking Out: Progress Meters,"It’s the holiday season, so you know what that means: online shopping! When I started developing Web sites back in the 90s, many of my first clients were small local shops wanting to sell their goods online, so I developed many a checkout system. And because of slow dial-up speeds back then, informing the user about where they were in the checkout process was pretty important.
Even though we’re (mostly) beyond the dial-up days, informing users about where they are in a flow is still important. In usability tests at the companies I’ve worked at, I’ve seen time and time again how not adequately informing the user about their state can cause real frustration. This is especially true for two sets of users: mobile users and users of assistive devices, in particular, screen readers.
The progress meter is a very common design solution used to indicate to the user’s state within a flow. On the design side, much effort may go in to crafting a solution that is as visually informative as possible. On the development side, however, solutions range widely. I’ve checked out the checkouts at a number of sites and here’s what I’ve found when it comes to progress meters: they’re sometimes inaccessible and often confusing or unhelpful — all because of the way in which they’re coded. For those who use assistive devices or text-only browsers, there must be a better way to code the progress meter — and there is.
(Note: All code samples are from live sites but have been tweaked to hide the culprits’ identities.)
How not to make progress
A number of sites assemble their progress meters using non- or semi-semantic markup and images with no alternate text. On text-only browsers (like my mobile phone) and to screen readers, this looks and reads like chunks of content with no context given.
Shipping information
Payment information
Place your order
In the above example, the third state, “Place your order”, is the current state. But a screen reader may not know that, and my cell phone only displays ""Shipping informationPayment informationPlace your order"". Not good.
Is this progress?
Other sites present the entire progress meter as a graphic, like the following:
Now, I have no problem with using a graphic to render a very stylish progress meter (my sample above is probably not the most stylish example, of course, but you understand my point). What becomes important in this case is the use of appropriate alternate text to describe the image. Disappointingly, sites today have a wide range of solutions, including using no alternate text. Check out these code samples which call progress meter images.
I think we can all agree that the above is bad, unless you really don’t care whether or not users know where they are in a flow.
The alt text in the example above just copies all of the text found in the graphic, but it doesn’t represent the status at all. So for every page in the checkout, the user sees or hears the same text. Sure, by the second or third page in the flow, the user has figured out what’s going on, but she or he had to think about it. I don’t think that’s good.
The above probably has the best alternate text out of these examples, because the user at least understands that they’re in the Checkout process, on the Place your order page. But going through the flow with alt text like this, the user doesn’t know how many steps are in the flow.
Semantic progress
Of course, there are some sites that use an ordered list when marking up the progress meter. Hooray! Unfortunately, no text-only browser or screen reader would be able to describe the user’s current state given this markup.
shipping information
payment information
place your order
Without CSS enabled, the above is rendered as follows:
Progress at last
We all know that semantic markup makes for the best foundation, so we’ll start with the markup found above. In order to make the state information accessible, let’s add some additional text in paragraph and span elements.
There are three steps in this checkout process.
Enter your shipping information
Enter your payment information
Review details and place your order
Add on some simple CSS to hide the paragraph and spans, and arrange the list items on a single line with a background image to represent the large number, and this is what you’ll get:
There are three steps in this checkout process.
Enter your shipping information
Enter your payment information
Review details and place your order
To display and describe a state as active, add the class “current” to one of the list items. Then change the hidden content such that it better describes the state to the user.
There are three steps in this checkout process.
You are currently entering your shipping information
In the next step, you will enter your payment information
In the last step, you will review the details and place your order
The end result is an attractive progress meter that gives much greater semantic and contextual information.
There are three steps in this checkout process.
You are currently entering your shipping information
In the next step, you will enter your payment information
In the last step, you will review the details and place your order
For example, the above example renders in a text-only browser as follows:
There are three steps in this checkout process.
You are currently entering your shipping information
In the next step, you will enter your payment information
In the last step, you will review the details and place your order
And the screen reader I use for testing announces the following:
There are three steps in this checkout process. List of three items. You are currently entering your shipping information. In the next step, you will enter your payment information. In the last step, you will review the details and place your order. List end.
Here’s a sample code page that summarises this approach.
Happy frustration-free online shopping with this improved progress meter!",2008,Kimberly Blessing,kimberlyblessing,2008-12-12T00:00:00+00:00,https://24ways.org/2008/checking-out-progress-meters/,ux
319,Avoiding CSS Hacks for Internet Explorer,"Back in October, IEBlog issued a call to action, asking developers to clean up their CSS hacks for IE7 testing. Needless to say, a lot of hubbub ensued… both on IEBlog and elsewhere. My contribution to all of the noise was to suggest that developers review their code and use good CSS hacks. But what makes a good hack?
Tantek Çelik, the Godfather of CSS hacks, gave us the answer by explaining how CSS hacks should be designed. In short, they should (1) be valid, (2) target only old/frozen/abandoned user-agents/browsers, and (3) be ugly. Tantek also went on to explain that using a feature of CSS is not a hack.
Now, I’m not a frequent user of CSS hacks, but Tantek’s post made sense to me. In particular, I felt it gave developers direction on how we should be coding to accommodate that sometimes troublesome browser, Internet Explorer. But what I’ve found, through my work with other developers, is that there is still much confusion over the use of CSS hacks and IE. Using examples from the code I’ve seen recently, allow me to demonstrate how to clean up some IE-specific CSS hacks.
The two hacks that I’ve found most often in the code I’ve seen and worked with are the star html bug and the underscore hack. We know these are both IE-specific by checking Kevin Smith’s CSS Filters chart. Let’s look at each of these hacks and see how we can replace them with the same CSS feature-based solution.
The star html bug
This hack violates Tantek’s second rule as it targets current (and future) UAs. I’ve seen this both as a stand alone rule, as well as an override to some other rule in a style sheet. Here are some code samples:
* html div#header {margin-top:-3px;}
.promo h3 {min-height:21px;}
* html .promo h3 {height:21px;}
The underscore hack
This hack violates Tantek’s first two rules: it’s invalid (according to the W3C CSS Validator) and it targets current UAs. Here’s an example:
ol {padding:0; _padding-left:5px;}
Using child selectors
We can use the child selector to replace both the star html bug and underscore hack. Here’s how:
Write rules with selectors that would be successfully applied to all browsers. This may mean starting with no declarations in your rule!
div#header {}
.promo h3 {}
ol {padding:0;}
To these rules, add the IE-specific declarations.
div#header {margin-top:-3px;}
.promo h3 {height:21px;}
ol {padding:0 0 0 5px;}
After each rule, add a second rule. The selector of the second rule must use a child selector. In this new rule, correct any IE-specific declarations previously made.
div#header {margin-top:-3px;}
body > div#header {margin-top:0;}
.promo h3 {height:21px;}
.promo > h3 {height:auto; min-height:21px;}
ol {padding:0 0 0 5px;}
html > body ol {padding:0;}
Voilà – no more hacks! There are a few caveats to this that I won’t go into… but assuming you’re operating in strict mode and barring any really complicated stuff you’re doing in your code, your CSS will still render perfectly across browsers. And while this may make your CSS slightly heftier in size, it should future-proof it for IE7 (or so I hope). Happy holidays!",2005,Kimberly Blessing,kimberlyblessing,2005-12-17T00:00:00+00:00,https://24ways.org/2005/avoiding-css-hacks-for-internet-explorer/,code
56,Helping VIPs Care About Performance,"Making a site feel super fast is the easy part of performance work. Getting people around you to care about site speed is a much bigger challenge. How do we keep the site fast beyond the initial performance work? Keeping very important people like your upper management or clients invested in performance work is critical to keeping a site fast and empowering other designers and developers to contribute.
The work to get others to care is so meaty that I dedicated a whole chapter to the topic in my book Designing for Performance. When I speak at conferences, the majority of questions during Q&A are on this topic. When I speak to developers and designers who care about performance, getting other people at one’s organization or agency to care becomes the most pressing question.
My primary response to folks who raise this issue is the question: “What metric(s) do your VIPs care about?” This is often met with blank stares and raised eyebrows. But it’s also our biggest clue to what we need to do to help empower others to care about performance and work on it. Every organization and executive is different. This means that three major things vary: the primary metrics VIPs care about; the language they use about measuring success; and how change is enacted. By clueing in to these nuances within your organization, you can get a huge leg up on crafting a successful pitch about performance work.
Let’s start with the metric that we should measure. Sure, (most) everybody cares about money - but is that really the metric that your VIPs are looking at each day to measure the success or efficacy of your site? More likely, dollars are the end game, but the metrics or key performance indicators (KPIs) people focus on might be:
rate of new accounts created/signups
cost of acquiring or retaining a customer
visitor return rate
visitor bounce rate
favoriting or another interaction rate
These are just a few examples, but they illustrate how wide-ranging the options are that people care about. I find that developers and designers haven’t necessarily investigated this when trying to get others to care about performance. We often reach for the obvious – money! – but if we don’t use the same kind of language our VIPs are using, we might not get too far. You need to know this before you can make the case for performance work.
To find out these metrics or KPIs, start reading through the emails your VIPs are sending within your company. What does it say on company wikis? Are there major dashboards internally that people are looking at where you could find some good metrics? Listen intently in team meetings or thoroughly read annual reports to see what these metrics could be.
The second key here is to pick up on language you can effectively copy and paste as you make the case for performance work. You need to be able to reflect back the metrics that people already find important in a way they’ll be able to hear. Once you know your key metrics, it’s time to figure out how to communicate with your VIPs about performance using language that will resonate with them.
Let’s start with visit traffic as an example metric that a very important person cares about. Start to dig up research that other people and companies have done that correlates performance and your KPI. For example, cite studies:
“When the home page of Google Maps was reduced from 100KB to 70–80KB, traffic went up 10% in the first week, and an additional 25% in the following three weeks.” (source).
Read through websites like WPOStats, which collects the spectrum of studies on the impact of performance optimization on user experience and business metrics. Tweet and see if others have done similar research that correlates performance and your site’s main KPI.
Once you have collected some research that touches on the same kind of language your VIPs use about the success of your site, it’s time to present it. You can start with something simple, like a qualitative description of the work you’re actively doing to improve the site that translates to improved metrics that your VIPs care about. It can be helpful to append a performance budget to any proposal so you can compare the budget to your site’s reality and how it might positively impact those KPIs folks care about.
Words and graphs are often only half the battle when it comes to getting others to care about performance. Often, videos appeal to folks’ emotions in a way that is missed when glancing through charts and graphs. On A List Apart I recently detailed how to create videos of how fast your site loads. Let’s say that your VIPs care about how your site loads on mobile devices; it’s time to show them how your site loads on mobile networks.
Open video
You can use these videos to make a number of different statements to your VIPs, depending on what they care about:
Look at how slow our site loads versus our competitor!
Look at how slow our site loads for users in another country!
Look at how slow our site loads on mobile networks!
Again, you really need to know which metrics your VIPs care about and tune into the language they’re using. If they don’t care about the overall user experience of your site on mobile devices, then showing them how slow your site loads on 3G isn’t going to work. This will be your sales pitch; you need to practice and iterate on the language and highlights that will land best with your audience.
To make your sales pitch as solid as possible, gut-check your ideas on how to present it with other co-workers to get their feedback. Read up on how to construct effective arguments and deliver them; do some research and see what others have done at your company when pitching to VIPs. Are slides effective? Memos or emails? Hallway conversations? Sometimes the best way to change people’s minds is by mentioning it in informal chats over coffee. Emulate the other leaders in your organization who are successful at this work.
Every organization and very important person is different. Learn what metrics folks truly care about, study the language that they use, and apply what you’ve learned in a way that’ll land with those individuals. It may take time to craft your pitch for performance work over time, but it’s important work to do. If you’re able to figure out how to mirror back the language and metrics VIPs care about, and connect the dots to performance for them, you will have a huge leg up on keeping your site fast in the long run.",2015,Lara Hogan,larahogan,2015-12-08T00:00:00+00:00,https://24ways.org/2015/helping-vips-care-about-performance/,business
297,Public Speaking with a Buddy,"My book Demystifying Public Speaking focuses on the variety of fears we each have about giving a talk. From presenting to a client, to leading a team standup, to standing on a conference stage, there are lots of things we can do to prepare ourselves for the spotlight and reduce those fears.
Though it didn’t make it into the final draft, I wanted to highlight how helpful it can be to share that public speaking spotlight with another person, or a few more people. If you have fears about not knowing the answer to a question, fumbling your words, or making a mistake in the spotlight, then buddying up may be for you!
To some, adding more people to a presentation sounds like a recipe for on-stage disaster. To others, having a friendly face nearby—a partner who can step in if you fumble—is incredibly reassuring. As design director Yesenia Perez-Cruz writes, “While public speaking is a deeply personal activity, you don’t have to go it alone. Nothing has helped my speaking career more than turning it into a group effort.”
Co-presenting can level up a talk in two ways: an additional brain and presentation skill set can improve the content of the talk itself, and you may feel safer with the on-stage safety net of your buddy.
For example, when I started giving lengthy workshops about building mobile device labs with my co-worker Destiny Montague, we brought different experience to the table. I was able to talk about the user experience of our lab, and the importance of testing across different screen sizes. Destiny spoke about the hardware aspects of the lab, like power consumption and networking. Our audience benefitted from the spectrum of insight we included in the talk.
Moreover, Destiny and I kept each other energized and engaging while teaching our audience, having way more fun onstage. Partnering up alleviated the risk (and fear!) of fumbling; where one person makes a mistake, the other person is right there to help. Buddy presentations can be helpful if you fear saying “I don’t know” to a question, as there are other people around you who will be able to help answer it from the stage. By partnering with someone whom I trust and respect, and whose work and knowledge augments my own, it made the experience—and the presentation!—significantly better.
Co-presenting won’t work if you don’t trust the person you’re onstage with, or if you don’t have good chemistry working together. It might also not work if there’s an imbalance of responsibilities, both in preparing the talk and giving it. Read on for how to make partner talks work to your advantage!
Trustworthiness
If you want to explore co-presenting, make sure that your presentation partner is trustworthy and can carry their weight; it can be stressful if you find yourself trying to meet deadlines and prepare well and your partner isn’t being helpful. We’re all about reducing the fears and stress levels surrounding being in that spotlight onstage; make sure that the person you’re relying on isn’t making the process harder.
Before you start working together, sketch out the breakdown of work and timeline you’re each committing to. Have a conversation about your preferred work style so you each have a concrete understanding of the best ways to communicate (in what medium, and how often) and how to check in on each other’s progress without micromanaging or worrying about radio silence. Ask your buddy how they prefer to receive feedback, and give them your own feedback preferences, so neither of you are surprised or offended when someone’s work style or deliverable needs to be tweaked.
This should be a partnership in which you both feel supported; it’s healthy to set all these expectations up front, and create a space in which you can each tweak things as the work progresses.
Talk flow and responsibilities
There are a few different ways to organize the structure of your talk with multiple presenters. Start by thinking about the breakdown of the talk content—are there discrete parts you and the other presenters can own or deliver? Or does it feel more appropriate to deliver the entirety of the content together?
If you’re finding that you can break down the content into discrete chunks, figure out who should own which pieces, and what ownership means. Will you develop the content together but have only one person present the information? Or will one person research and prepare each content section in addition to delivering it solo onstage?
Rehearse how handoffs will go between sections so it feels natural, rather than stilted. I like breaking a presentation into “chapters” when I’m passionate about particular aspects of a topic and can speak on those, but know that there are other aspects to be shared and there’s someone else who can handle (and enjoy!) talking about them. When Destiny and I rehearsed our “chapter” handoffs, we developed little jingles that we’d both sing together onstage; it indicated to the audience that it was a planned transition in the content, and tied our independent work together into a partnership.
.embed-container { position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden; max-width: 100%; } .embed-container iframe, .embed-container object, .embed-container embed { position: absolute; top: 0; left: 0; width: 100%; height: 100%; }
Alternatively, you can give the presentation in a way that’s close to having a rehearsed conversation, rather than independently presenting discrete parts of the talk. In this case, you’ll both be sharing the spotlight at the same time, throughout the duration of the talk. Preparation is key, here, to make sure that you each understand what needs to be communicated, and you have a sense of who will be taking responsibility for communicating those different pieces of information. A poorly-prepared talk like this will look like the co-presenters are talking over each other, or hesitating awkwardly to give the other person more room to speak; the audience will feel how uncomfortable this is, and will probably be distracted from the talk content. Practice the talk the whole way through multiple times so you know what each person is planning on covering and how you want to interact with each other while you’re both holding microphones; also figure out how you’ll be standing in relation to each other. More on that next!
Sharing the stage
If you choose to give a talk with a partner, determine ahead of time how you’ll stand (or sit). For example, if you each take “chapters” or major sections of the presentation, ensure that it’s clear who the audience should focus their attention on. You could sit in a chair off to the side (or stand). I recommend placing yourself far enough away that you’re not distracting to the audience; you don’t want them watching you while your partner is speaking. If the audience can still see you, but their focus should be on your buddy, be sure to not look distracted; keep your eyes on your buddy, and don’t just open your laptop and ignore what’s happening! Feel free to smile, laugh, or react how the audience should be reacting as your partner is speaking.
If you’re both sharing the spotlight at the same time and having a rehearsed conversation, make sure that your body language engages the audience and you’re not just speaking to each other, ignoring the folks watching. Watch this talk with Guy Podjarny and Assaf Hefetz who have partnered up to talk about security; they have clearly identified roles onstage, and remain engaged with the audience.
Consider whether or not you will share a microphone, or if you will both be mic’d. (Be sure that the event organizer, or the A/V team, has a heads-up well in advance to ensure they have the equipment handy!) Also talk through how you’d like to handle Q&A time during or after the talk, especially if you have clear “chapters” where Q&A might happen naturally during a handoff. The more clarity you and your partner have about who is responsible for which pieces of information sharing, the more you can feel and appear prepared.
Co-presenting does take a lot of preparation and requires a ton of communication between you and your partner. But the rewards can be awesome: double the brains onstage to help answer questions and communicate information, and a friendly face to help comfort you if you feel nervous.",2016,Lara Hogan,larahogan,2016-12-06T00:00:00+00:00,https://24ways.org/2016/public-speaking-with-a-buddy/,process
1,Why Bother with Accessibility?,"Web accessibility (known in other fields as inclusive design or universal design) is the degree to which a website is available to as many people as possible. Accessibility is most often used to describe how people with disabilities can access the web.
How we approach accessibility
In the web community, there’s a surprisingly inconsistent approach to accessibility. There are some who are endlessly dedicated to accessible web design, and there are some who believe it so intrinsic to the web that it shouldn’t be considered a separate topic. Still, of those who are familiar with accessibility, there’s an overwhelming number of designers, developers, clients and bosses who just aren’t that bothered.
Over the last few months I’ve spoken to a lot of people about accessibility, and I’ve heard the same reasons to ignore it over and over again. Let’s take a look at the most common excuses.
Excuse 1: “People with disabilities don’t really use the web”
Accessibility will make your site available to more people — the inclusion case
In the same way that the accessibility of a building isn’t just about access for wheelchair users, web accessibility isn’t just about blind users and screen readers. We can affect positively the lives of many people by making their access to the web easier.
There are four main types of disability that affect use of the web:
Visual
Blindness, low vision and colour-blindness
Auditory
Profoundly deaf and hard of hearing
Motor
The inability to use a mouse, slow response time, limited fine motor control
Cognitive
Learning difficulties, distractibility, the inability to focus on large amounts of information
None of these disabilities are completely black and white
Examining deafness, it’s clear from the medical scale that there are many grey areas between full hearing and total deafness:
mild
moderate
moderately severe
severe
profound
totally deaf
For eyesight, and brain conditions that affect what users see, there is a huge range of conditions and challenges:
astigmatism
colour blindness
akinetopsia (motion blindness)
scotopic visual sensitivity (visual stress related to light)
visual agnosia (impaired recognition or identification of objects)
While we might have medical and government-recognised definitions that tell us what makes a disability, day-to-day life is not so straightforward. People experience varying degrees of different conditions, and often one or more conditions at a time, creating a false divide when you view disability in terms of us and them.
Impairments aren’t always permanent
As we age, we’re more likely to experience different levels of visual, auditory, motor and cognitive impairments. We might have an accident or illness that affects us temporarily. We might struggle more earlier or later in the day. There are so many little physiological factors that affect the way people interact with the web that we can’t afford to make any assumptions based on our own limited experiences.
Impairments might be somewhere between the user and the website
There are also impairments that aren’t directly related to the user. Environmental factors have a huge effect on the way people interact with the web. These could be:
Low bandwidth, or intermittent internet connection
Bright light, rain, or other weather-based conditions
Noisy environments, or a location where the user doesn’t want to disturb their neighbours with sound
Browsing with mobile devices, games consoles and other non-desktop devices
Browsing with legacy browsers or operating systems
Such environmental factors show that it’s not just those with physical impairments who benefit from more accessible websites. We started designing responsive websites so we could be more future-friendly, and with a shared goal of better optimised experiences, accessibility should be at the core of responsive web design.
Excuse 2: “We don’t want to affect the experience for the majority of our users”
Accessibility will improve your site for all your users — the usability case
On a basic level, the different disability groups, as shown in the inclusion case, equate to simple usability goals:
Visual – make it easy to read
Auditory – make it easy to hear
Motor – make it easy to interact
Cognitive – make it easy to understand and focus
Taking care to ensure good usability in these areas will also have an impact on accessibility. Unless your site is catering specifically to a particular disability, where extreme optimisation is most beneficial, taking care to design with accessibility in mind will rarely negatively affect the experience of your wider audience.
Excuse 3: “We don’t have the budget for accessibility”
Accessibility will make you money — the business case
By reducing your audience through ignoring accessibility, you’re potentially excluding the income from those users. Designing with accessibility in mind from the beginning of a project makes it easier to make small inexpensive optimisations as part of the design and development process, rather than bolting on costly updates to increase your potential audience later on.
The following are excerpts from a white paper about companies that increased the accessibility of their websites to comply with government regulation.
Improvements in accessibility doubled Legal and General’s life insurance sales online.
Improvements in accessibility increased Tesco’s grocery home delivery sales by £13 million in 2005… To their surprise they found that many normal visitors preferred the ease of navigation and improved simplicity of the [parallel] accessible site and switched to use it. Tesco have replaced their ‘normal’ site with their accessible version and expect a further increase in revenues.
Improvements in accessibility increased Virgin.net sales by 68%.
Statistics all from WSI white paper: Improve your website’s usability and accessibility to increase sales (PDF).
Excuse 4: “Accessible websites are ugly”
Accessibility won’t stop your site from being beautiful — the beauty case
Many people use ugly accessible websites as proof that all accessible websites are ugly. This just isn’t the case. I’ve compiled some examples of beautiful and accessible websites with screenshots of how they look through the Color Oracle simulator and how they perform when run through Webaim’s Wave accessibility checker tool.
While automated tools are no substitute for real users, they can help you learn more about good practices, and give you guidance on where your site needs improvements to make it more accessible.
Amazon.co.uk
It may not be a decorated beauty, but Amazon is often first in functional design. It’s a huge website with a lot of interactive content, but it generates just five errors on the Wave test, and is easy to read under a Color Oracle filter.
Screenshot of Amazon website
Screenshot of Amazon’s Wave results – five errors
Screenshot of Amazon through a Color Oracle filter
24 ways
When Tim Van Damme redesigned 24 ways back in 2007, it was a striking and unusual design that showed what could be achieved with CSS and some imagination. Despite the complexity of the design, it gets an outstanding zero errors on the Wave test, and is still readable under a Color Oracle filter.
Screenshot of pre-2013 24 ways website design
Screenshot of 24 ways Wave results – zero errors
Screenshot of 24ways through a Color Oracle filter
Opera’s Shiny Demos
Demos and prototypes are notorious for ignoring accessibility, but Opera’s Shiny Demos site shows how exploring new technologies doesn’t have to exclude anyone. It only gets one error on the Wave test, and looks fine under a Color Oracle filter.
Screenshot of Opera’s Shiny Demos website
Screenshot of Opera’s Shiny Demos Wave results – 1 error
Screenshot of Opera’s Shiny Demos through a Color Oracle filter
SoundCloud
When a site is more app-like, relying on more interaction from the user, accessibility can be more challenging. However, SoundCloud only gets one error on the Wave test, and the colour contrast holds up well under a Color Oracle filter.
Screenshot of SoundCloud website
Screenshot of SoundCloud’s Wave results – one error
Screenshot of SoundCloud through a Color Oracle filter
Education and balance
As with most web design, doing accessibility well is about combining your knowledge of accessibility with your project’s context to create a balance that serves your users’ needs. Your types of content and interactions will dictate one set of constraints. Your users’ needs and goals will dictate another. In broad terms, web design as a practice is finding the equilibrium between these constraints.
And then there’s just caring. The web as a platform is open, affordable and available to many. Accessibility is our way to ensure that nobody gets shut out.",2013,Laura Kalbag,laurakalbag,2013-12-10T00:00:00+00:00,https://24ways.org/2013/why-bother-with-accessibility/,design
93,Design Systems,"The most important part of responsive web design is that, no matter what the viewport width, the content is accessible in an optimum display. The best responsive designs are those that allow you to go from one optimised display to another, but with the feeling that these experiences are part of a greater product whole.
Responsive design: where we’ve been going wrong
Responsive web design was a shock to my web designer system. Those of us who had already been designing sites for mobile probably had the biggest leap to make. We might have been detecting user agents in order to deliver a mobile-specific site, or using the slightly more familiar Bushido technique to deliver sites optimised for device type and viewport size, but either way our focus was on devices. A site was optimised for either a mobile phone or a desktop.
Responsive web design brought us back to pre-table layout fluid sites that expanded or contracted to fit the viewport. This was a big difference to get our heads around when we were so used to designing for fixed-width layouts. Suddenly, an element could be any width or, at least, we needed to consider its maximum and minimum widths. Pixel perfection, while pretty, became wholly unrealistic, and a whole load of designers who prided themselves in detailed and precise designs got a bit scared.
Hanging on to our previous processes and typical deliverables led us to continue to optimise our sites for particular devices and provide pixel-perfect mockups for those device widths.
With all this we were concentrating on devices, not content, deliverables and not process, and making assumptions about users and their devices based on nothing but the width of the viewport.
I don’t think this is a crime, I think it was inevitable.
We can be up to date with our principles and ideals, but it’s never as easy in practice. That’s why it’s more important than ever to share our successful techniques and processes. Let’s drag each other into modern web design.
Design systems: the principles
What are design systems?
A visual design system is built out of the core components of typography, layout, shape or form, and colour. When considering the design of a whole product, a design system should also include patterns in user flow, content strategy, copy, and tone of voice. These concepts, design decisions or rules, created around the core components are used consistently across your product to create a cohesive feel, whether it’s from one element to another, page to page, or viewport width to viewport width.
Responsive design is one of the most important considerations in the components of a design system. For each component, you must decide what will unite the design across the viewports to maintain that consistent feel, and what parts of the design will differentiate in order to provide a flexible and optimal experience for different viewport sizes.
Components you might keep the same across viewports
typeface
base unit
colour
shape/form
Components you might differentiate across viewports
grids
layout
font size
measure (line length)
leading (line height)
Content: it must always be the same
The focus of a design system is the optimum display of content. As Mark Boulton put it, designing “content out, not canvas in.” Chris Armstrong puts the emphasis on not designing for viewports but for content – “we need to build on what we do know: content.” In order to do this, we must share the same content across all devices and focus on how best to display and represent content through design system components.
The practical: core visual components
Typography first
When you work with a lot of text content, typography is the easiest way to set the visual tone of the design across all viewport widths. It’s likely that you’ll choose one or two typefaces to use across the whole system, but you might change the most legible font size, balanced with the most comfortable measure, as the viewport width changes.
Where typography meets layout
The unit on which you choose to base the grid and layout design, font sizes and leading could be based on the typeface, an optimal reading size, or something more arbitrary. Sometimes I’ll choose a unit based on multiples of ten because it makes the maths in the CSS easier. Tim Brown suggests trying a modular scale. Chris Armstrong suggests basing it on your ideal measure, or the width of a fixed item of content such as an ad unit.
Grids and layouts
Sensible grid design can be a flexible yet solid foundation for your design system layout component. But you must be wary in responsive design that a grid might not work across all widths: even four columns could make for very cramped content and one-word measures on smaller screens.
Maybe the grid columns are something you differentiate across widths, but you can keep the concept of the grid consistent. If the content has blocks in groups of three, you might decide on a three-column grid which folds down to one column for narrow viewports. If the grid focuses on the idea of symmetry and has a four-column grid on larger viewports, it might fold down to two columns for narrower viewports. These consistencies may seem subtle, not at all obvious to many except the designer, but it’s all these little constants and patterns across the whole of the design system that makes design decisions easier to make (as they adhere to the guiding concepts of your system), and give the product a uniform feel no matter what the device.
Shape or form
The shape or form components are concepts you already use in fixed-width web design for a strong, consistent look and feel.
Since CSS border-radius became widely supported by browsers, a lot of designs feature circle themes. These are very distinctive and can be used across viewport widths giving them the same united feel, even if they’re not used in the same way. This could also apply to border styles, consistent shadows and any number of decorative details and textures. These are the elements that make up the shape or form of a design system.
Colour
Colour is the most basic way to reinforce a brand and unite experiences across viewports. The same hex colour used system-wide is instantly recognisable, no matter what the viewport width.
The process
While using a design system isn’t necessarily attached to any particular process, it does lend itself to some process ideals.
Detaching design considerations from viewport widths
A design system allows you to focus separately on the components that make up the system, disconnecting the look and feel from the layout. This helps prevent us getting stuck in the rut of the Apple breakpoints (brilliantly coined by Simon Foster) of mobile, tablet and desktop. It also forces us to design for variation in viewport experiences side by side, not one after the other.
Design in the browser
I can’t start off designing in the browser – it just doesn’t seem to bring out my creative side (and I’m incredibly envious of you if you can; I just have to start on paper) – but static mock-ups aren’t the only alternative. Style guides and style tiles are perfect for expressing the concepts of your design system. Pattern libraries could also work well.
Mock-ups and breakpoints
At some point, whether it’s to test your system ideas, or because a client needs help visualising how your system might work, you may end up producing some static mock-ups. It’s not the end of the world, but you must ensure that these consider all the viewports, not just those of the iDevices, or even the devices currently on the market. You need to decide the breakpoints where the states of your design change. The blocks within your content will always have optimum points for their display (based on their hierarchy, density, width, or type of interaction) and so your breakpoints should be based around these points.
These are probably the ideal points at which to produce static mockups; treat them as snapshots. They’re not necessarily mock-ups, so much as a way of capturing how your design system would be interpreted when frozen at that particular viewport width.
The future
Creating design systems will give us the flexibility we need for working with the unknown devices of the future. It may be a change in process, but it shouldn’t be too much of a difference in thinking. The pioneers in responsive design have a hard job. Some of these problems may have already been solved in other technologies or industries, but it’s up to the pioneers to find those connections and help us formulate solutions and standards that will make responsive design the best it can possibly be. We need to keep experimenting and communicating, particularly in the area of design, as good user experiences are the true sign of whether our products are a success.",2012,Laura Kalbag,laurakalbag,2012-12-12T00:00:00+00:00,https://24ways.org/2012/design-systems/,design
213,Accessibility Through Semantic HTML,"Working on Better, a tracker blocker, I spend an awful lot of my time with my nose in other people’s page sources. I’m mostly there looking for harmful tracking scripts, but often notice the HTML on some of the world’s most popular sites is in a sad state of neglect.
What does neglected HTML look like? Here’s an example of the markup I found on a news site just yesterday. There’s a bit of text, a few links, and a few images. But mostly it’s div elements.
divs and spans, why do we use them so much?
While I find tracking scripts completely inexcusable, I do understand why people write HTML like the above. As developers, we like to use divs and spans as they’re generic elements. They come with no associated default browser styles or behaviour except that div displays as a block, and span displays inline. If we make our page up out of divs and spans, we know we’ll have absolute control over styles and behaviour cross-browser, and we won’t need a CSS reset.
Absolute control may seem like an advantage, but there’s a greater benefit to less generic, more semantic elements. Browsers render semantic elements with their own distinct styles and behaviours. For example, button looks and behaves differently from a. And ul is different from ol. These defaults are shortcuts to a more usable and accessible web. They provide consistent and well-tested components for common interactions.
Semantic elements aid usability
A good example of how browser defaults can benefit the usability of an element is in the
option menu. In Safari on the desktop, the browser renders as a popover-style menu. On a touchscreen, Safari overlays the same menu over the lower half of the screen as a “picker view.”
Option menu in Safari on macOS.
Option menu picker in Safari on iOS.
The iOS picker is a much better experience than struggling to pick from a complicated interface inside the page. The menu is shown more clearly than in the confined space on the page, which makes the options easier to read. The required swipe and tap gestures are consistent with the rest of the operating system, making the expected interaction easier to understand. The whole menu is scaled up, meaning the gestures don’t need such fine motor control. Good usability is good accessibility.
When we choose to use a div or span over a more semantic HTML element, we’re also doing hard work the browser could be doing for us. We don’t need to tie ourselves in knots making a custom div into a keyboard navigable option menu. Using select passes the bulk of the responsibility over to the browser.
Letting the browser do most of the work is also more future-friendly. More devices, with different expected interactions, will be released in the future. When that happens, the devices’ browsers can adapt our sites according to those interactions. Then we can spend our time doing something more fun than rewriting cross-browser JavaScript for each new device.
HTML’s impact on accessibility
Assistive technology also uses semantic HTML to understand how best to convey each element to its user.
For screen readers
Semantic HTML gives context to screen readers. Screen readers are a type of assistive technology that reads the content of the screen to the person using it. All sites have a linear page source. Sighted visitors can use visual cues on the page to navigate to their desired content in a non-linear fashion. As screen readers output audio (and sometimes braille), those visual cues aren’t usable in the same way.
Screen readers provide alternative means of navigation, enabling people to jump between different types of content, such as links, forms, headings, lists, and paragraphs. If all our content is marked up using divs and spans, we’re not giving screen readers a chance to index the valuable content.
For keyboard navigation
Keyboard-only navigation is also aided by semantic HTML. Forms, option menus, navigation, video, and audio are particularly hard for people relying on a keyboard to access. For instance, option menus and navigation can be very fiddly if you need to use a mouse to hover a menu open and move to select the desired item at the same time.
Again, we can leave much of the interaction to the browser through semantic HTML. Semantic form elements can convey if a check box has been checked, or which label is associated with which input field. These default behaviours can make the difference between a person being able to use a form or leaving the site out of frustration.
Did I convince you yet? I hope so. Let’s finish with some easy guidelines to follow.
1. Use the most semantic HTML element for the job
When you reach for a div, first check if there’s a better element to do the job. What is the role of that element? How should a person be interacting with the element?
Are you using class names like nav, header, or main? There are HTML5 elements for those sections! Using specific elements can also make writing CSS simpler, and ensure a consistent design with minimal effort.
2. Separate structure and style
Don’t choose HTML elements based on how they’re styled in your CSS. Nowadays, common practice is to use class names rather than elements for CSS selectors. You’re unlikely to wrap all your page content in an element because you want all the text to be big and bold. Still, it can be easy to choose an HTML element because it will be the easiest to style. Focusing on content without style will help us choose the most semantic HTML element without that temptation. For example, you could add a class of .btn to a div to make it look like a button. But we all know that only a button will really behave like a button.
3. Use progressive enhancement for enhanced functionality
Airbnb and Groupon recently proved we’re not past the laziness of “this site only works in X browser.” Baffling disregard for the open web aside, making complex interactive experiences work cross-browser and cross-device is not easy. We can use progressive enhancement to layer fancy or unsupported features on top of a baseline “it works” experience.
We should build the baseline experience on a foundation of accessible, semantic HTML. Then, if you really want to add a specific feature for a proprietary browser, you can layer that on top, without breaking the underlying experience.
4. Test your work
Validators are always valuable for checking the browser will be able to correctly interpret your markup. Document outline checkers can be valuable for testing your structure, but be aware that the HTML5 document outline is not actually implemented in browsers.
Once you’ve got something resembling a web page, test the experience! Ensure that semantic HTML element you chose looks and behaves in a predictable manner consistent with its use across the web. Test cross-browser, test cross-device, and test with assistive technology. Testing with assistive technology is not as expensive as it used to be, you can even use your smartphone for testing on iOS and Android. Your visitors will thank you!
Further reading
Accessibility For Everyone by Laura Kalbag
HTML5 Doctor
HTML5 Accessibility
An overview of HTML5 Semantics
HTML reference on MDN
Heydon Pickering’s Inclusive Design Checklist
The Paciello Group’s Inclusive Design Principles",2017,Laura Kalbag,laurakalbag,2017-12-15T00:00:00+00:00,https://24ways.org/2017/accessibility-through-semantic-html/,code
283,"CSS3 Patterns, Explained","Many of you have probably seen my CSS3 patterns gallery. It became very popular throughout the year and it showed many web developers how powerful CSS3 gradients really are. But how many really understand how these patterns are created? The biggest benefit of CSS-generated backgrounds is that they can be modified directly within the style sheet. This benefit is void if we are just copying and pasting CSS code we don’t understand. We may as well use a data URI instead.
Important note
In all the examples that follow, I’ll be using gradients without a vendor prefix, for readability and brevity. However, you should keep in mind that in reality you need to use all the vendor prefixes (-moz-, -ms-, -o-, -webkit-) as no browser currently implements them without a prefix. Alternatively, you could use -prefix-free and have the current vendor prefix prepended at runtime, only when needed.
The syntax described here is the one that browsers currently implement. The specification has since changed, but no browser implements the changes yet. If you are interested in what is coming, I suggest you take a look at the dev version of the spec.
If you are not yet familiar with CSS gradients, you can read these excellent tutorials by John Allsopp and return here later, as in the rest of the article I assume you already know the CSS gradient basics:
CSS3 Linear Gradients
CSS3 Radial Gradients
The main idea
I’m sure most of you can imagine the background this code generates:
background: linear-gradient(left, white 20%, #8b0 80%);
It’s a simple gradient from one color to another that looks like this:
See this example live
As you probably know, in this case the first 20% of the container’s width is solid white and the last 20% is solid green. The other 60% is a smooth gradient between these colors. Let’s try moving these color stops closer to each other:
background: linear-gradient(left, white 30%, #8b0 70%);
See this example live
background: linear-gradient(left, white 40%, #8b0 60%);
See this example live
background: linear-gradient(left, white 50%, #8b0 50%);
See this example live
Notice how the gradient keeps shrinking and the solid color areas expanding, until there is no gradient any more in the last example. We can even adjust the position of these two color stops to control where each color abruptly changes into another:
background: linear-gradient(left, white 30%, #8b0 30%);
See this example live
background: linear-gradient(left, white 90%, #8b0 90%);
See this example live
What you need to take away from these examples is that when two color stops are at the same position, there is no gradient, only solid colors. Even without going any further, this trick is useful for a number of different use cases like faux columns or the effect I wanted to achieve in my homepage or the -prefix-free page where the background is only shown on one side and hidden on the other:
Combining with background-size
We can do wonders, however, if we combine this with the CSS3 background-size property:
background: linear-gradient(left, white 50%, #8b0 50%);
background-size: 100px 100px;
See this example live
And there it is. We just created the simplest of patterns: (vertical) stripes. We can remove the first parameter (left) or replace it with top and we’ll get horizontal stripes. However, let’s face it: Horizontal and vertical stripes are kinda boring. Most stripey backgrounds we see on the web are diagonal. So, let’s try doing that.
Our first attempt would be to change the angle of the gradient to something like 45deg. However, this results in an ugly pattern like this:
See this example live
Before reading on, think for a second: why didn’t this produce the desired result? Can you figure it out?
The reason is that the gradient angle rotates the gradient inside each tile, not the tiled background as a whole. However, didn’t we have the same problem the first time we tried to create diagonal stripes with an image? And then we learned that every stripe has to be included twice, like so:
So, let’s try to create that effect with CSS gradients. It’s essentially what we tried before, but with more color stops:
background: linear-gradient(45deg, white 25%,
#8b0 25%, #8b0 50%,
white 50%, white 75%,
#8b0 75%);
background-size:100px 100px;
See this example live
And there we have our stripes! An easy way to remember the order of the percentages and colors it is that you always have two of the same in succession, except the first and last color.
Note: Firefox for Mac also needs an additional 100% color stop at the end of any pattern with more than two stops, like so: ..., white 75%, #8b0 75%, #8b0). The bug was reported in February 2011 and you can vote for it and track its progress at Bugzilla.
Unfortunately, this is essentially a hack and we will realize that if we try to change the gradient angle to 60deg:
See this example live
Not that maintainable after all, eh? Luckily, CSS3 offers us another way of declaring such backgrounds, which not only helps this case but also results in much more concise code:
background: repeating-linear-gradient(60deg, white, white 35px, #8b0 35px, #8b0 70px);
See this example live
In this case, however, the size has to be declared in the color stop positions and not through background-size, since the gradient is supposed to cover the entire container. You might notice that the declared size is different from the one specified the previous way. This is because the size of the stripes is measured differently: in the first example we specify the dimensions of the tile itself; in the second, the width of the stripes (35px), which is measured diagonally.
Multiple backgrounds
Using only one gradient you can create stripes and that’s about it. There are a few more patterns you can create with just one gradient (linear or radial) but they are more or less boring and ugly. Almost every pattern in my gallery contains a number of different backgrounds. For example, let’s create a polka dot pattern:
background: radial-gradient(circle, white 10%, transparent 10%),
radial-gradient(circle, white 10%, black 10%) 50px 50px;
background-size:100px 100px;
See this example live
Notice that the two gradients are almost the same image, but positioned differently to create the polka dot effect. The only difference between them is that the first (topmost) gradient has transparent instead of black. If it didn’t have transparent regions, it would effectively be the same as having a single gradient, as the topmost gradient would obscure everything beneath it.
There is an issue with this background. Can you spot it?
This background will be fine for browsers that support CSS gradients but, for browsers that don’t, it will be transparent as the whole declaration is ignored. We have two ways to provide a fallback, each for different use cases. We have to either declare another background before the gradient, like so:
background: black;
background: radial-gradient(circle, white 10%, transparent 10%),
radial-gradient(circle, white 10%, black 10%) 50px 50px;
background-size:100px 100px;
or declare each background property separately:
background-color: black;
background-image: radial-gradient(circle, white 10%, transparent 10%),
radial-gradient(circle, white 10%, transparent 10%);
background-size:100px 100px;
background-position: 0 0, 50px 50px;
The vigilant among you will have noticed another change we made to our code in the last example: we altered the second gradient to have transparent regions as well. This way background-color serves a dual purpose: it sets both the fallback color and the background color of the polka dot pattern, so that we can change it with just one edit. Always strive to make code that can be modified with the least number of edits. You might think that it will never be changed in that way but, almost always, given enough time, you’ll be proved wrong.
We can apply the exact same technique with linear gradients, in order to create checkerboard patterns out of right triangles:
background-color: white;
background-image: linear-gradient(45deg, black 25%, transparent 25%, transparent 75%, black 75%),
linear-gradient(45deg, black 25%, transparent 25%, transparent 75%, black 75%);
background-size:100px 100px;
background-position: 0 0, 50px 50px;
See this example live
Using the right units
Don’t use pixels for the sizes without any thought. In some cases, ems make much more sense. For example, when you want to make a lined paper background, you want the lines to actually follow the text. If you use pixels, you have to change the size every time you change font-size. If you set the background-size in ems, it will naturally follow the text and you will only have to update it if you change line-height.
Is it possible?
The shapes that can be achieved with only one gradient are:
stripes
right triangles
circles and ellipses
semicircles and other shapes formed from slicing ellipses horizontally or vertically
You can combine several of them to create squares and rectangles (two right triangles put together), rhombi and other parallelograms (four right triangles), curves formed from parts of ellipses, and other shapes.
Just because you can doesn’t mean you should
Technically, anything can be crafted with these techniques. However, not every pattern is suitable for it. The main advantages of this technique are:
no extra HTTP requests
short code
human-readable code (unlike data URIs) that can be changed without even leaving the CSS file.
Complex patterns that require a large number of gradients are probably better left to SVG or bitmap images, since they negate almost every advantage of this technique:
they are not shorter
they are not really comprehensible – changing them requires much more effort than using an image editor
They still save an HTTP request, but so does a data URI.
I have included some very complex patterns in my gallery, because even though I think they shouldn’t be used in production (except under very exceptional conditions), understanding how they work and coding them helps somebody understand the technology in much more depth.
Another rule of thumb is that if your pattern needs shapes to obscure parts of other shapes, like in the star pattern or the yin yang pattern, then you probably shouldn’t use it. In these patterns, changing the background color requires you to also change the color of these shapes, making edits very tedious.
If a certain pattern is not practicable with a reasonable amount of CSS, that doesn’t mean you should resort to bitmap images. SVG is a very good alternative and is supported by all modern browsers.
Browser support
CSS gradients are supported by Firefox 3.6+, Chrome 10+, Safari 5.1+ and Opera 11.60+ (linear gradients since Opera 11.10). Support is also coming in Internet Explorer when IE10 is released. You can get gradients in older WebKit versions (including most mobile browsers) by using the proprietary -webkit-gradient(), if you really need them.
Epilogue
I hope you find these techniques useful for your own designs. If you come up with a pattern that’s very different from the ones already included, especially if it demonstrates a cool new technique, feel free to send a pull request to the github repo of the patterns gallery. Also, I’m always fascinated to see my techniques put in practice, so if you made something cool and used CSS patterns, I’d love to know about it!
Happy holidays!",2011,Lea Verou,leaverou,2011-12-16T00:00:00+00:00,https://24ways.org/2011/css3-patterns-explained/,code
92,Redesigning the Media Query,"Responsive web design is showing us that designing content is more important than designing containers. But if you’ve given RWD a serious try, you know that shifting your focus from the container is surprisingly hard to do. There are many factors and
instincts working against you, and one culprit is a perpetrator you’d least suspect.
The media query is the ringmaster of responsive design. It lets us establish the rules of the game and gives us what we need most: control. However, like some kind of evil double agent, the media query is actually working against you.
Its very nature diverts your attention away from content and forces you to focus on the container.
The very act of choosing a media query value means choosing a screen size.
Look at the history of the media query—it’s always been about the container. Values like screen, print, handheld and tv don’t have anything to do with content. The modern media query lets us choose screen dimensions, which is great because it makes RWD possible. But it’s still the act of choosing something that is completely unpredictable.
Content should dictate our breakpoints, not the container. In order to get our focus back to the only thing that matters, we need a reengineered media query—one that frees us from thinking about screen dimensions. A media query that works for your content, not the window. Fortunately, Sass 3.2 is ready and willing to take on this challenge.
Thinking in Columns
Fluid grids never clicked for me. I feel so disoriented and confused by their squishiness. Responsive design demands their use though, right?
I was ready to surrender until I found a grid that turned my world upright again. The Frameless Grid by Joni Korpi demonstrates that column and gutter sizes can stay fixed. As the screen size changes, you simply add or remove columns to accommodate. This made sense to me and armed with this concept I was able to give Sass the first component it needs to rewrite the media query: fixed column and gutter size variables.
$grid-column: 60px;
$grid-gutter: 20px;
We’re going to want some resolution independence too, so let’s create a function that converts those nasty pixel values into ems.
@function em($px, $base: $base-font-size) {
@return ($px / $base) * 1em;
}
We now have the components needed to figure out the width of multiple columns in ems. Let’s put them together in a function that will take any number of columns and return the fixed width value of their size.
@function fixed($col) {
@return $col * em($grid-column + $grid-gutter)
}
With the math in place we can now write a mixin that takes a column count as a parameter, then generates the perfect media query necessary to fit that number of columns on the screen. We can also build in some left and right margin for our layout by adding an additional gutter value (remembering that we already have one gutter built into our fixed function).
@mixin breakpoint($min) {
@media (min-width: fixed($min) + em($grid-gutter)) {
@content
}
}
And, just like that, we’ve rewritten the media query. Instead of picking a minimum screen size for our layout, we can simply determine the number of columns needed. Let’s add a wrapper class so that we can center our content on the screen.
@mixin breakpoint($min) {
@media (min-width: fixed($min) + em($grid-gutter)) {
.wrapper {
width: fixed($min) - em($grid-gutter);
margin-left: auto; margin-right: auto;
}
@content
}
}
Designing content with a column count gives us nice, easy, whole numbers to work with. Sizing content, sidebars or widgets is now as simple as specifying a single-digit number.
@include breakpoint(8) {
.main { width: fixed(5); }
.sidebar { width: fixed(3); }
}
Those four lines of Sass just created a responsive layout for us. When the screen is big enough to fit eight columns, it will trigger a fixed width layout. And give widths to our main content and sidebar. The following is the outputted CSS…
@media (min-width: 41.25em) {
.wrapper {
width: 38.75em;
margin-left: auto; margin-right: auto;
}
.main { width: 25em; }
.sidebar { width: 15em; }
}
Demo
I’ve created a Codepen demo that demonstrates what we’ve covered so far. I’ve added to the demo some grid classes based on Griddle by Nicolas Gallagher to create a floatless layout. I’ve also added a CSS gradient overlay to help you visualize columns. Try changing the column variable sizes or the breakpoint includes to see how the layout reacts to different screen sizes.
Responsive Images
Responsive images are a serious problem, but I’m excited to see the community talk so passionately about a solution. Now, there are some excellent stopgaps while we wait for something official, but these solutions require you to mirror your breakpoints in JavaScript or HTML. This poses a serious problem for my Sass-generated media queries, because I have no idea what the real values of my breakpoints are anymore. For responsive images to work, JavaScript needs to recognize which media query is active so that proper images can be loaded for that layout.
What I need is a way to label my breakpoints. Fortunately, people much smarter than I have figured this out. Jeremy Keith devised a labeling method by using CSS-generated content as the storage method for breakpoint labels. We can use this technique in our breakpoint mixin by passing a label as another argument.
@include breakpoint(8, 'desktop') { /* styles */ }
Sass can take that label and use it when writing the corresponding media query. We just need to slightly modify our breakpoint mixin.
@mixin breakpoint($min, $label) {
@media (min-width: fixed($min) + em($grid-gutter)) {
// label our mq with CSS generated content
body::before { content: $label; display: none; }
.wrapper {
width: fixed($min) - em($grid-gutter);
margin-left: auto; margin-right: auto;
}
@content
}
}
This allows us to label our breakpoints with a user-friendly string. Now that our media queries are defined and labeled, we just need JavaScript to step in and read which label is active.
// get css generated label for active media query
var label = getComputedStyle(document.body, '::before')['content'];
JavaScript now knows which layout is active by reading the label in the current media query—we just need to match that label to an image. I prefer to store references to different image sizes as data attributes on my image tag.
These data attributes have names that match the labels set in my CSS. So while there is some duplication going on, setting a keyword like ‘tablet’ in two places is much easier than hardcoding media query values. With matching labels in CSS and HTML our script can marry the two and load the right sized image for our layout.
// get css generated label for active media query
var label = getComputedStyle(document.body, '::before')['content'];
// select image
var $image = $('.responsive-image');
// create source from data attribute
$image.attr('src', $image.data(label));
Demo
With some slight additions to our previous Codepen demo you can see this responsive image technique in action. While the above JavaScript will work it is not nearly robust enough for production so the demo uses a jQuery plugin that can accomodate multiple images, reloading on screen resize and fallbacks if something doesn’t match up.
Creating a Framework
This media query mixin and responsive image JavaScript are the center piece of a front end framework I use to develop websites. It’s a fluid, mobile first foundation that uses the breakpoint mixin to structure fixed width layouts for tablet and desktop. Significant effort was focused on making this framework completely cross-browser. For example, one of the problems with using media queries is that essential desktop structure code ends up being hidden from legacy Internet Explorer. Respond.js is an excellent polyfill, but if you’re comfortable serving a single desktop layout to older IE, we don’t need JavaScript. We simply need to capture layout code outside of a media query and sandbox it under an IE only class name.
// set IE fallback layout to 8 columns
$ie-support = 8;
// inside of our breakpoint mixin (but outside the media query)
@if ($ie-support and $min <= $ie-support) {
.lt-ie9 { @content; }
}
Perspective Regained
Thinking in columns means you are thinking about content layout. How big of a screen do you need for 12 columns? Who cares? Having Sass write media queries means you can use intuitive numbers for content layout. A fixed grid means more layout control and less edge cases to test than a fluid grid. Using CSS labels for activating responsive images means you don’t have to duplicate breakpoints across separations of concern.
It’s a harmonious blend of approaches that gives us something we need—responsive design that feels intuitive. And design that, from the very outset, focuses on what matters most. Just like our kindergarten teachers taught us: It’s what’s inside that counts.",2012,Les James,lesjames,2012-12-13T00:00:00+00:00,https://24ways.org/2012/redesigning-the-media-query/,code
39,Meet for Learning,"“I’ve never worked in a place like this,” said one of my direct reports during our daily stand-up meeting.
And with that statement, my mind raced to the most important thing about lawyering that I’ve learned from decades of watching lawyers lawyer on TV: don’t ask a question you don’t know the answer to.
But I couldn’t stop myself. I wanted to learn more. The thought developed in my mind. The words formed in my mouth. And the vocalization occurred: “A place like this?”
“I’ve never worked where people are so honest and transparent about things.”
Designing a learning-centered culture
Before we started Center Centre, Jared Spool and I discussed both the larger goals and the smaller details of this new UX design school. We talked about things like user experience, curriculum, and structure.
We discussed the pattern we saw in our research. Hiring managers told us time and again that great designers have excellent technical and interpersonal skills. But, more importantly, the best designers are lifelong learners—they are willing and able to learn how to do new things. Learning this led us to ask a critical question: how would we intentionally design a learning-centered experience?
To craft the experience we were aiming for, we knew we had to create a learning-centered culture for our students and our employees. We knew that our staff would need to model the behaviors our students needed to learn. We knew the best way to shape the culture was to work with our direct reports—our directs—to develop the behaviors we wanted them to exemplify.
To craft the experience we were aiming for, we knew we had to create a learning-centered culture for our students and our employees. We knew that our staff would need to model the behaviors our students needed to learn.
Building a learning team
Our learning-centered culture starts with our staff. We believe in transparency. Transparency builds trust. Effective organizations have effective teams who trust each other as individuals.
One huge way we build that trust and provide opportunities for transparency is in our meetings. (I know, I know—meetings! Yuck!) But seriously, running and participating in effective meetings is a great opportunity to build a learning-centered culture.
Meetings—when done well—allow individuals time to come together, to share, and to listen. These behaviors, executed on a consistent and regular basis, build honest and trusting relationships.
An effective meeting is one that achieves the desired outcomes of that meeting. While different meetings aim for different results, at Center Centre all meetings have a secondary goal: meet for learning.
A framework for learning-centered meetings
We’ve developed a framework for our meetings. We use it for all our meetings, which means attendees know what to expect. It also saves us from reinventing the wheel in each meeting.
These basic steps help our meetings focus on the valuable face-to-face interaction we’re having, and help us truly begin to learn from one another.
An agenda for a staff meeting.
Use effective meeting basics
Prepare for the meeting before the meeting.
If you’re running the meeting, prepare a typed agenda and share it before the meeting. Agendas have start times for each item.
Start the meeting on time. Don’t wait for stragglers.
Define ground rules. Get input from attendees. Recurring meetings don’t have to do this every time.
Keep to the meeting agenda. Put off-topic questions and ideas in a parking lot, a visual document that everyone can see, so you can address the questions and ideas later.
Finish on time. And if you’ve reached the meeting’s goals, finish early.
Parking lots where ideas on sticky notes can be posted for later consideration.
Focus to learn
Have tech-free meetings: no laptops, no phones, no things with notifications.
Bring a notebook and a pen.
Take notes by hand. You’re not taking minutes, you’re writing to learn.
Come with a learning mindset
Ask: what are our goals for this meeting? (Hopefully answered by the meeting agenda.)
Ask: what can I learn overall?
Ask: what can I learn from each of my colleagues?
Ask: what can I share that will help the team learn overall?
Ask: what can I share that will help each of my colleagues learn?
Investing in regularly scheduled learning-centered meetings
At Center Centre, we have two types of recurring all-staff meetings: daily stand-ups and weekly staff meetings. (We are a small organization, so it makes sense to meet as an entire group.)
Yes, that means we spend thirty minutes each day in stand-up, for a total of two and a half hours of stand-up meeting time each week. And, yes, we also have a weekly ninety-minute sit-down staff meeting on top of that. This investment in time is an investment in learning.
We use these meetings to build our transparency, and, therefore, our trust. The regularity of these meetings helps us maintain ongoing, open sharing about our responsibilities, our successes, and our learning.
For instance, we answer five questions in our stand-up:
What did I get done since the last stand-up (I reported at)?
What is my goal to accomplish before the next stand-up?
What’s preventing me from getting these things done, if anything?
What’s the highest risk or most unknown thing right now about what I’m trying to get done?
What is the most important thing I learned since the last time we met and how will what I learned change the way I approach things in the future?
Each person writes out their answers to these questions before the meeting. Each person brings their answers printed on paper to the meeting. And each person brings a pen to jot down notes.
Notes compiled for a stand-up meeting.
During the stand-up, each person shares their answers to the five questions. To sustain a learning-centered culture, the fifth question is the most important question to answer. It allows individual reflection focused on learning. Sometimes this isn’t an easy question to answer. It makes us stretch. It makes us think.
By sharing our individual answers to the fifth question, we open ourselves up to the group. When we honestly share what we’ve learned, we openly admit that we didn’t know something. Sharing like this would be scary (and even risky) if we didn’t have a learning-centered culture.
We often share the actual process of how we learned something. By listening, each of us is invited to learn more about the topic at hand, consider what more there is to learn about that topic, and even gain insights into other methods of learning—which can be applied to other topics.
Sharing the answers to the fifth question also allows opportunities for further conversations. We often take what someone has individually learned and find ways to apply it for our entire team in support of our organization. We are, after all, learning together.
Building individual learners
We strive to grow together as a team at Center Centre, but we don’t lose sight of the importance of the individuals who form our team. As individuals, we bring our goals, dreams, abilities, and prior knowledge to the team.
To build learning teams, we must build individual learners. A team made up of lifelong learners, who share their learning and learn from each other, is a team that will continually produce better results.
As a manager, I need to meet each direct where they are with their current abilities and knowledge. Then, I can help them take their skills and knowledge base to the next levels. This process requires each individual direct to engage in professional development.
We believe effective managers help their directs engage in behaviors that support growth and development. Effective managers encourage and support learning.
Our weekly one-on-ones
One way we encourage learning is through weekly one-on-ones. Each of my directs meets with me, individually, for thirty minutes each week. The meeting is their meeting. It is not my meeting.
My direct sets the agenda. They talk about what they want to talk about. They can talk about work. They can talk about things outside of work. They can talk about their health, their kids, and even their cat. Whatever is important to them is important to me. I listen. I take notes.
Although the direct sets the specific agenda, the meeting has three main parts. Approximately ten minutes for them (the direct), ten minutes for me (the manager), and ten minutes for us to talk about their future within—and beyond—our organization.
Coaching for future performance
The final third of our one-on-one is when I coach my directs. Coaching looks to the direct’s future performance. It focuses on developing the direct’s skills.
Coaching isn’t hard. It doesn’t take much time. For me, it usually takes less than five minutes a week during a one-on-one.
The first time I coach one of my directs, I ask them to brainstorm about the skills they want to improve. They usually already have an idea about this. It’s often something they’ve wanted to work on for some time, but didn’t think they had the time or the knowhow to improve.
If a direct doesn’t know what they want to improve, we discuss their job responsibilities—specifically the aspects of the job that concern them.
Coaching provides an opportunity for me to ask, “In your job, what are the required skills that you feel like you don’t have (or know well enough, or perform effectively, or use with ease)?”
Sometimes I have to remind a direct that it’s okay not to know how to do something (even if it’s a required part of their job). After all, our organization is a learning organization. In a learning organization, no one knows everything but everyone is willing to learn anything.
After we review the job responsibilities together, I ask my direct what skill they’d like to work to improve. Whatever they choose, we focus on that skill for coaching—I’ve found my directs work better when they’re internally motivated.
Sometimes the first time I talk with a direct about coaching, they get a bit anxious. If this happens, I share a personal story about my professional learning journey. I say something like:
I didn’t know how to make a school before we started to make Center Centre.
I didn’t know how to manage an entire team of people—day in and day out—until I started managing a team of people every day.
When I realized that I was the boss—and that the success of the school would hinge, at least in part, on my skills as a manager—I was a bit terrified. I was missing an important skill set that I needed to know (and I needed to know well).
When I first understood this, I felt bad—like I should have already known how to be a great manager. But then I realized, I’d never faced this situation. I’d never needed to know how to use this skill set in this way.
I worked through my anxiety about feeling inadequate. I decided I’d better learn how to be an effective manager because the school needed me to be one. You needed me to be one.
Every day, I work to improve my management skills. You’ve probably noticed that some days I’m better at it than others. I try not to beat myself up about this, although it’s hard—I’d like to be perfect at it. But I’m not.
I know that if I make a conscious, daily effort to learn how to be a better manager, I’ll continue to improve. So that’s what I do.
Every day I learn. I learn by doing. I learn how to be better than I was the day before. That’s what I ask of you.
Once we determine the skill the direct wants to learn, we figure out how they can go about learning it. I ask: “How could you learn this skill?”
We brainstorm for two or three minutes about this. We write down every idea that comes to mind, and we write it so both of us can easily see the options (both whiteboards and sticky notes on the wall work well for this exercise).
Read a book. Research online. Watch a virtual seminar. Listen to a podcast. Talk to a mentor. Reach out to an expert. Attend a conference. Shadow someone else while they do the skill. Join a professional organization.
The goal is to get the direct on a path of self-development. I’m coaching their development, but I’m not the main way my direct will learn this new skill.
I ask my direct which path seems like the best place to start. I let them choose whatever option they want (as long as it works with our budget). They are more likely to follow through if they are in control of this process.
Next, we work to break down the selected path into tasks. We only plan one week’s worth of tasks. The tasks are small, and the deadlines are short. My direct reports when each task is completed.
At our next one-on-one, I ask my direct about their experience learning this new skill.
Rinse. Repeat.
That’s it. I spend five minutes a week talking with each direct about their individual learning. They develop their professional skills, and together we’re creating a learning-centered culture.
Asking questions I don’t know the answer to
When my direct said, “I’ve never worked where people are so honest and transparent about things,” it led me to believe that all this is working. We are building a learning-centered culture.
This week I was reminded that creating a learning-centered culture starts not just with the staff, but with me. When I challenge myself to learn and then share what I’m currently learning, my directs want to learn more about what I’m learning about.
For example, I decided I needed to improve my writing skills. A few weeks ago, I realized that I was sorely out of practice and I felt like I had lost my voice. So I started to write. I put words on paper. I felt overwhelmed. I felt like I didn’t know how to write anymore (at least not well or effectively).
I bought some books on writing (mostly Peter Elbow’s books like Writing with Power, Writing Without Teachers, and Vernacular Eloquence), and I read them. I read them all. Reading these books was part of my personal coaching. I used the same steps to coach myself as I use with my directs when I coach them.
In stand-ups, I started sharing what I accomplished (like I completed one of the books) and what I learned by doing—specific things, like engaging in freewriting and an open-ended writing process.
This week, I went to lunch with one of my directs. She said, “You’ve been talking about freewriting a lot. You’re really excited about it. Freewriting seems like it’s helping your writing process. Would you tell me more about it?”
So I shared the details with her. I shared the reasons why I think freewriting is helping. I’m not focused on perfection. Instead, each day I’m focused on spending ten, uninterrupted minutes writing down whatever comes to my mind. It’s opening my writing mind. It’s allowing my words to flow more freely. And it’s helping me feel less self-conscious about my writing.
She said, “Leslie, when you say you’re self-conscious about your writing, I laugh. Not because it’s funny. But because when I read what you write, I think, ‘What is there to improve?’ I think you’re a great writer. It’s interesting to know that you think you can be a better writer. I like learning about your learning process. I think I could do freewriting. I’m going to give it a try.”
There’s something magical about all of this. I’m not even sure I can eloquently put it into words. I just know that our working environment is something very different. I’ve never experienced anything quite like it. Somehow, by sharing that I don’t know everything and that I’m always working to learn more, I invite my directs to be really open about what they don’t know. And they see it’s possible always to learn and grow.
I’m glad I ignore all the lawyering I’ve learned from watching TV. I’m glad I ask the questions I don’t know the answers to. And I’m glad my directs do the same. When we meet for learning, we accelerate and amplify the learning process—building individual learners and learning teams. Embracing the unknown and working toward understanding is what makes our culture a learning-centered culture.
Photos by Summer Kohlhorst.",2014,Leslie Jensen-Inman,lesliejenseninman,2014-12-20T00:00:00+00:00,https://24ways.org/2014/meet-for-learning/,process
224,Go Forth and Make Awesomeness,"We’ve all dreamed of being a superhero: maybe that’s why we’ve ended up on the web—a place where we can do good deeds and celebrate them on a daily basis.
Wear your dreams
At age four, I wore my Wonder Woman Underoos around my house, my grandparents’ house, our neighbor’s house, and even around the yard. I wanted to be a superhero when I grew up. I was crushed to learn that there is no school for superheroes—no place to earn a degree in how to save the world from looming evil. Instead, I—like everyone else—was destined to go to ordinary school to focus on ABCs and 123s. Even still, I want to save the world.
Intend your goodness
Random acts of kindness make a difference. Books, films, and advertising campaigns tout random acts of kindness and the positive influence they can have on the world. But why do acts of kindness have to be so random? Why can’t we intend to be kind? A true superhero wakes each morning intending to perform selfless acts for the community. Why can’t we do the same thing?
As a child, my mother taught me to plan to do at least three good deeds each day. And even now, years later, I put on my invisible cape looking for ways to do good.
Here are some examples:
slowing down to allow another driver in before me from the highway on-ramp
bringing a co-worker their favorite kind of coffee or tea
sharing my umbrella on a rainy day
holding a door open for someone with full hands
listening intently when someone shares a story
complimenting someone on a job well done
thanking someone for a job well done
leaving a constructive, or even supportive comment on someone’s blog
As you can see, these acts are simple. Doing good and being kind is partially about being aware—aware of the words we speak and the actions we take. Like superheroes, we create our own code of conduct to live by. Hopefully, we choose to put the community before ourselves (within reason) and to do our best not to damage it as we move through our lives.
Take a bite out of the Apple
With some thought, we can weave this type of thinking and action into our business choices. We can take the simple acts of kindness concept and amplify it a bit. With this amplification, we can be a new kind of superhero.
In 1997, during a presentation, Steve Jobs stated Apple’s core value in a simple, yet powerful, sentence:
We believe that people with passion can change the world for the better.
Apple fan or not, those are powerful words.
Define your core
Every organization must define its core values. Core values help us to frame, recognize, and understand the principles our organization embodies and practices. It doesn’t matter if you’re starting a new organization or you want to define values within an existing organization. Even if you’re a freelancer, defining core values will help guide your decisions and actions.
If you can, work as a team to define core values. Gather the people who are your support system—your business partners, your colleagues, and maybe even a trusted client—this is now your core value creation team. Have a brainstorming session with your team. Let ideas flow. Give equal weight to the things people say. You may not hear everything you thought you might hear—that’s OK. You want the session to be free-flowing and honest. Ask yourself and your team questions like:
What do you think my/our/your core values are?
What do you think my/our/your priorities are?
What do you think my/our/your core values should be?
What do you think my/our/your priorities should be?
How do you think I/we should treat customers, clients, and each other?
How do we want others to treat us?
What are my/our/your success stories?
What has defined these experiences as successful?
From this brainstorming session, you will craft your superhero code of conduct. You will decide what you will and will not do. You will determine how you will and will not act. You’re setting the standards that you will live and work by—so don’t take this exercise lightly. Take your time. Use the exercise as a way to open a discussion about values. Find out what you and your team believe in. Set these values and keep them in place. Write them down and share these with your team and with the world. By sharing your core values, you hold yourself more accountable to them. You also send a strong message to the rest of the world about what type of organization you are and what you believe in. Other organizations and people may decide to align or not to align themselves with you because of your core values. This is good. Chances are, you’ll be happier and more profitable if you work with other organizations and people who share similar core values.
Photo: Laura Winn
During your brainstorming session, list keywords. Don’t edit. Allow things to take their course. Some examples of keywords might be:
Ability · Achievement · Adventure · Ambition · Altruism · Awareness · Balance · Caring · Charity · Citizenship · Collaboration · Commitment · Community · Compassion · Consideration · Cooperation · Courage · Courtesy · Creativity · Democracy · Dignity · Diplomacy · Discipline · Diversity · Education · Efficiency · Energy · Equality · Excellence · Excitement · Fairness · Family · Freedom · Fun · Goodness · Gratefulness · Growth · Happiness · Harmony · Helping · Honor · Hope · Humility · Humor · Imagination · Individuality · Innovation · Integrity · Intelligence · Joy · Justice · Kindness · Knowledge · Leadership · Learning · Loyalty · Meaning · Mindfulness · Moderation · Modesty · Nurture · Openness · Organization · Passion · Patience · Peace · Planning · Principles · Productivity · Purpose · Quality · Reliability · Respectfulness · Responsibility · Security · Sensitivity · Service · Sharing · Simplicity · Stability · Tolerance · Transparency · Trust · Truthfulness · Understanding · Unity · Variety · Vision · Wisdom
After you have a list of keywords, create your core values statement using the themes from your brainstorming session. There are no rules: while above, Steve Jobs summed up Apple’s core values in one sentence, Zappos has ten core values:
Deliver WOW Through Service
Embrace and Drive Change
Create Fun and A Little Weirdness
Be Adventurous, Creative, and Open-Minded
Pursue Growth and Learning
Build Open and Honest Relationships With Communication
Build a Positive Team and Family Spirit
Do More With Less
Be Passionate and Determined
Be Humble
To see how Zappos’ employees embrace these core values, watch the video they created and posted on their website.
Dog food is yummy
Although I find merit in every keyword listed, I’ve distilled my core values to their simplest form:
Make awesomeness. Do good.
How do you make awesomeness and do good? You need ambition, balance, collaboration, commitment, fun, and you need every keyword listed to support these actions. Again, there are no rules: your core values can be one sentence or a bulleted list. What matters is being true to yourself and creating core values that others can understand. Before I start any project I ask myself: is there a way to make awesomeness and to do good? If the answer is “yes,” I embrace the endeavor because it aligns with my core values. If the answer is “no,” I move on to a project that supports my core values.
Unleash your powers
Although every organization will craft different core values, I imagine that you want to be a superhero and that you will define “doing good” (or something similar) as one of your core values. Whether you work by yourself or with a team, you can use the web as a tool to help do good. It can be as simple as giving a free hug, or something a little more complex to help others and help your organization meet the bottom line. Some interesting initiatives that use the web to do good are:
Yahoo!: How Good Grows
Desigual: Happy Hunters
Edge Shave Gel: Anti-irritation campaign
Knowing your underlying desire to return to your Underoos-and-cape-sporting childhood and knowing that you don’t always have the opportunity to develop an entire initiative to “do good,” remember that as writers, designers, and developers, we can perform superhero acts on a daily basis by making content, design, and development accessible to the greatest number of people. By considering other people’s needs, we are intentionally performing acts of kindness—we’re doing good. There are many ways to write, design, and develop websites—many of which will be discussed in other 24ways.org articles. As we make content, design, and development decisions—as we develop campaigns and initiatives—we need to keep our core values in mind. It’s easy to make a positive difference in the world. Just be the superhero you’ve always wanted to be. Go forth and make awesomeness.
If you would like to do good today, support The United Nations Children’s Fund, an organization that works for children’s rights, their survival, development and protection, by purchasing this year’s 24 ways Annual 2010 created by Five Simple Steps. All proceeds go to UNICEF.",2010,Leslie Jensen-Inman,lesliejenseninman,2010-12-04T00:00:00+00:00,https://24ways.org/2010/go-forth-and-make-awesomeness/,business
308,How to Make a Chrome Extension to Delight (or Troll) Your Friends,"If you’re like me, you grew up drawing mustaches on celebrities. Every photograph was subject to your doodling wrath, and your brilliance was taken to a whole new level with computer programs like Microsoft Paint. The advent of digital cameras meant that no one was safe from your handiwork, especially not your friends. And when you finally got your hands on Photoshop, you spent hours maniacally giggling at your artistic genius.
But today is different. You’re a serious adult with important things to do and a reputation to uphold. You keep up with modern web techniques and trends, and have little time for fun other than a random Giphy on Slack… right?
Nope.
If there’s one thing 2016 has taught me, it’s that we—the self-serious, world-changing tech movers and shakers of the universe—haven’t changed one bit from our younger, more delightable selves.
How do I know? This year I created a Chrome extension called Tabby Cat and watched hundreds of thousands of people ditch productivity for randomly generated cats. Tabby Cat replaces your new tab page with an SVG cat featuring a silly name like “Stinky Dinosaur” or “Tiny Potato”. Over time, the cats collect goodies that vary in absurdity from fishbones to lawn flamingos to Raybans. Kids and adults alike use this extension, and analytics show the majority of use happens Monday through Friday from 9-5. The popularity of Tabby Cat has convinced me there’s still plenty of room in our big, grown-up hearts for fun.
Today, we’re going to combine the formula behind Tabby Cat with your intrinsic desire to delight (or troll) your friends, and create a web app that generates your friends with random objects and environments of your choosing. You can publish it as a Chrome extension to replace your new tab, or simply host it as a website and point to it with the New Tab Redirect extension.
Here’s a sneak peek at my final result featuring my partner, my cat, and I in cheerfully weird accessories. Your result will look however you want it to.
Along the way, we’ll cover how to build a Chrome extension that replaces the new tab page, and explore ways to program randomness into your work to create something truly delightful.
What you’ll need
Adobe Illustrator (or a similar illustration program to export PNG)
Some images of your friends
A text editor
Note: This can be as simple or as complex as you want it to be. Most of the application is pre-built so you can focus on kicking back and getting in touch with your creative side. If you want to dive in deeper, you’ll find ways to do it.
Getting started
Download a local copy of the boilerplate for today’s tutorial here, and open it in a text editor. Inside, you’ll find a simple web app that you can run in Chrome.
Open index.html in Chrome. You should see a grey page that says “Noname”.
Open template.pdf in Adobe Illustrator or a similar program that can export PNG. The file contains an artboard measuring 800px x 800px, with a dotted blue outline of a face. This is your template.
Note: We’re using Google Chrome to build and preview this application because the end-result is a Chrome extension. This means that the application isn’t totally cross-browser compatible, but that’s okay.
Step 1: Gather your friends
The first thing to do is choose who your muses are. Since the holidays are upon us, I’d suggest finding inspiration in your family.
Create your artwork
For each person, find an image where their face is pointed as forward as possible. Place the image onto the Artwork layer of the Illustrator file, and line up their face with the template. Then, rename the artboard something descriptive like face_bob. Here’s my crew:
As you can see, my use of the word “family” extends to cats. There’s no judgement here.
Notice that some of my photos don’t completely fill the artboard–that’s fine. The images will be clipped into ovals when they’re rendered in the application.
Now, export your images by following these steps:
Turn the Template layer off and export the images as PNGs.
In the Export dialog, tick the “Use Artboards” checkbox and enter the range with your faces.
Export at 72ppi to keep things running fast.
Save your images into the images/ folder in your project.
Add your images to config.js
Open scripts/config.js. This is where you configure your extension.
Add key value pairs to the faces object. The key should be the person’s name, and the value should be the filepath to the image.
faces: {
leslie: 'images/face_leslie.png',
kyle: 'images/face_kyle.png',
beep: 'images/face_beep.png'
}
The application will choose one of these options at random each time you open a new tab. This pattern is used for everything in the config file. You give the application groups of choices, and it chooses one at random each time it loads. The only thing that’s special about the faces object is that person’s name will also be displayed when their face is chosen.
Now, when you refresh the project in Chrome, you should see one of your friends along with their name, like this:
Congrats, you’re off and running!
Step 2: Add adjectives
Now that you’ve loaded your friends into the application, it’s time to call them names. This step definitely yields the most laughs for the least amount of effort.
Add a list of adjectives into the prefixes array in config.js. To get the words flowing, I took inspiration from ways I might describe some of my relatives during a holiday gathering…
prefixes: [
'Loving',
'Drunk',
'Chatty',
'Merry',
'Creepy',
'Introspective',
'Cheerful',
'Awkward',
'Unrelatable',
'Hungry',
...
]
When you refresh Chrome, you should see one of these words prefixed before your friend’s name. Voila!
Step 3: Choose your color palette
Real talk: I’m bad at choosing color palettes, so I have a trick up my sleeve that I want to share with you. If you’ve been blessed with the gift of color aptitude, skip ahead.
How to choose colors
To create a color palette, I start by going to a Coolors.co, and I hit the spacebar until I find a palette that I like. We need a wide gamut of hues for our palette, so lock down colors you like and keep hitting the spacebar until you find a nice, full range. You can use as many or as few colors as you like.
Copy these colors into your swatches in Adobe Illustrator. They’ll be the base for any illustrations you create later.
Now you need a set of background colors. Here’s my trick to making these consistent with your illustration palette without completely blending in. Use the “Adjust Palette” tool in Coolors to dial up the brightness a few notches, and the saturation down just a tad to remove any neon effect. These will be your background colors.
Add your background colors to config.js
Copy your hex codes into the bgColors array in config.js.
bgColors: [
'#FFDD77',
'#FF8E72',
'#ED5E84',
'#4CE0B3',
'#9893DA',
...
]
Now when you go back to Chrome and refresh the page, you’ll see your new palette!
Step 4: Accessorize
This is the fun part. We’re going to illustrate objects, accessories, lizards—whatever you want—and layer them on top of your friends.
Your objects will be categorized into groups, and one option from each group will be randomly chosen each time you load the page. Think of a group like “hats” or “glasses”. This will allow combinations of accessories to show at once, without showing two of the same type on the same person.
Create a group of accessories
To get started, open up Illustrator and create a new artboard out of the template. Think of a group of objects that you can riff on. I found hats to be a good place to start. If you don’t feel like illustrating, you can use cut-out images instead.
Next, follow the same steps as you did when you exported the faces. Here they are again:
Turn the Template layer off and export the images as PNGs.
In the Export dialog, tick the “Use Artboards” checkbox and enter the range with your hats.
Export at 72ppi to keep things running fast.
Save your images into the images/ folder in your project.
Add your accessories to config.js
In config.js, add a new key to the customProps object that describes the group of accessories that you just created. Its value should be an array of the filepaths to your images. This is my hats array:
customProps: {
hats: [
'images/hat_crown.png',
'images/hat_santa.png',
'images/hat_tophat.png',
'images/hat_antlers.png'
]
}
Refresh Chrome and behold, accessories!
Create as many more accessories as you want
Repeat the steps above to create as many groups of accessories as you want. I went on to make glasses and hairstyles, so my final illustrator file looks like this:
The last step is adding your new groups to the config object. List your groups in the order that you want them to be stacked in the DOM. My final output will be hair, then hats, then glasses:
customProps: {
hair: [
'images/hair_bowl.png',
'images/hair_bob.png'
],
hats: [
'images/hat_crown.png',
'images/hat_santa.png',
'images/hat_tophat.png',
'images/hat_antlers.png'
],
glasses: [
'images/glasses_aviators.png',
'images/glasses_monacle.png'
]
}
And, there you have it! Randomly generated friends with random accessories.
Feel free to go much crazier than I did. I considered adding a whole group of animals in celebration of the new season of Planet Earth, or even adding Sir David Attenborough himself, or doing a bit of role reversal and featuring the animals with little safari hats! But I digress…
Step 5: Publish it
It’s time to put this in your new tabs! You have two options:
Publish it as a Chrome extension in the Chrome Web Store.
Host it as a website and point to it with the New Tab Redirect extension.
Today, we’re going to cover Option #1 because I want to show you how to make the simplest Chrome extension possible. However, I recommend Option #2 if you want to keep your project private. Every Chrome extension that you publish is made publicly available, so unless your friends want their faces published to an extension that anyone can use, I’d suggest sticking to Option #2.
How to make a simple Chrome extension to replace the new tab page
All you need to do to make your project into a Chrome extension is add a manifest.json file to the root of your project with the following contents. There are plenty of other properties that you can add to your manifest file, but these are the only ones that are required for a new tab replacement:
{
""manifest_version"": 2,
""name"": ""Your extension name"",
""version"": ""1.0"",
""chrome_url_overrides"" : {
""newtab"": ""index.html""
}
}
To test your extension, you’ll need to run it in Developer Mode. Here’s how to do that:
Go to the Extensions page in Chrome by navigating to chrome://extensions/.
Tick the checkbox in the upper-right corner labelled “Developer Mode”.
Click “Load unpacked extension…” and select this project.
If everything is running smoothly, you should see your project when you open a new tab. If there are any errors, they should appear in a yellow box on the Extensions page.
Voila! Like I said, this is a very light example of a Chrome extension, but Google has tons of great documentation on how to take things further. Check it out and see what inspires you.
Share the love
Now that you know how to make a new tab extension, go forth and create! But wield your power responsibly. New tabs are opened so often that they’ve become a part of everyday life–just consider how many tabs you opened today. Some people prefer to-do lists in their tabs, and others prefer cats.
At the end of the day, let’s make something that makes us happy. Cheers!",2016,Leslie Zacharkow,lesliezacharkow,2016-12-08T00:00:00+00:00,https://24ways.org/2016/how-to-make-a-chrome-extension/,code
24,Kill It With Fire! What To Do With Those Dreaded FAQs,"In the mid-1640s, a man named Matthew Hopkins attempted to rid England of the devil’s influence, primarily by demanding payment for the service of tying women to chairs and tossing them into lakes.
Unsurprisingly, his methods garnered criticism. Hopkins defended himself in The Discovery of Witches in 1647, subtitled “Certaine Queries answered, which have been and are likely to be objected against MATTHEW HOPKINS, in his way of finding out Witches.”
Each “querie” was written in the voice of an imagined detractor, and answered in the voice of an imagined defender (always referring to himself as “the discoverer,” or “him”):
Quer. 14.
All that the witch-finder doth is to fleece the country of their money, and therefore rides and goes to townes to have imployment, and promiseth them faire promises, and it may be doth nothing for it, and possesseth many men that they have so many wizzards and so many witches in their towne, and so hartens them on to entertaine him.
Ans.
You doe him a great deale of wrong in every of these particulars.
Hopkins’ self-defense was an early modern English FAQ.
Digital beginnings
Question and answer formatting certainly isn’t new, and stretches back much further than witch-hunt days. But its most modern, most notorious, most reviled incarnation is the internet’s frequently asked questions page.
FAQs began showing up on pre-internet mailing lists as a way for list members to answer and pre-empt newcomers’ repetitive questions:
The presumption was that new users would download archived past messages through ftp. In practice, this rarely happened and the users tended to post questions to the mailing list instead of searching its archives. Repeating the “right” answers becomes tedious…
When all the users of a system can hear all the other users, FAQs make a lot of sense: the conversation needs to be managed and manageable. FAQs were a stopgap for the technological limitations of the time.
But the internet moved past mailing lists. Online information can be stored, searched, filtered, and muted; we choose and control our conversations. New users no longer rely on the established community to answer their questions for them.
And yet, FAQs are still around. They’re a content anti-pattern, replicated from site to site to solve a problem we no longer have.
What we hate when we hate FAQs
As someone who creates and structures online content – always with the goal of making that content as useful as possible to people – FAQs drive me absolutely batty. Almost universally, FAQs represent the opposite of useful. A brief list of their sins:
Double trouble
Duplicated content is practically a given with FAQs. They’re written as though they’ll be accessed in a vacuum – but search results, navigation patterns, and curiosity ensure that users will seek answers throughout the site. Is our goal to split their focus? To make them uncertain of where to look? To divert them to an isolated microcosm of the website? Duplicated content means user confusion (to say nothing of the duplicated workload for maintaining content).
Leaving the job unfinished
Many FAQs fail before they’re even out of the gate, presenting a list of questions that’s incomplete (too short and careless to be helpful) or irrelevant (avoiding users’ real concerns in favor of soundbites). Alternately, if the right questions are there, the answers may be convoluted, jargon-heavy, or otherwise difficult to understand.
Long lists of not-my-question
Getting a single answer often means sifting through a haystack of questions. For each potential question, the user must read, comprehend, assess, move on, rinse, repeat. That’s a lot of legwork for little reward – and a lot of opportunity for mistakes. Users may miss their question, or they may fail to recognize a differently worded version of their question, or they may not notice when their sought-after answer appears somewhere they didn’t expect.
The ventriloquist act
FAQs shift the point of view. While websites speak on behalf of the organization (“our products,” “our services,” “you can call us for assistance,” etc.), FAQs speak as the user – “I can’t find my password” or “How do I sign up?” Both voices are written from the first-person perspective, but speak for different entities, which is disorienting: it breaks the tone and messaging across the website. It’s also presumptuous: why do you get to speak for the user?
These all underscore FAQs’ fatal flaw: they are content without context, delivered without regard for the larger experience of the website. You can hear the absurdity in the name itself: if users are asking the same questions so frequently, then there is an obvious gulf between their needs and the site content. (And if not, then we have a labeling problem.)
Instead of sending users to a jumble of maybe-it’s-here-maybe-it’s-not questions, the answers to FAQs should be found naturally throughout a website. They are not separated, not isolated, not other. They are the content.
To present it otherwise is to create a runaround, and users know it. Jay Martel’s parody, “F.A.Q.s about F.A.Q.s” captures the silliness and frustration of such a system:
Q: Why are you so rude?
A: For that answer, you would have to consult an F.A.Q.s about F.A.Q.s about F.A.Q.s. But your time might be better served by simply abandoning your search for a magic answer and taking responsibility for your own profound ignorance.
FAQs aren’t magic answers. They don’t resolve a content dilemma or even help users. Yet they keep cropping up, defiant, weedy, impossible to eradicate.
Where are they all coming from?
Blame it on this: writing is hard. When generating content, most of us do whatever it takes to get some words on the screen. And the format of question and answer makes it easy: a reactionary first stab at content development.
After all, the point of website content is to answer users’ questions. So this – to give everyone credit – is a really good move. Content creators who think in terms of questions and answers are actually thinking of their users, particularly first-time users, trying to anticipate their needs and write towards them.
It’s a good start. But it’s scaffolding: writing that helps you get to the writing you’re supposed to be doing. It supports you while you write your way to the heart of your content. And once you get there, you have to look back and take the scaffolding down.
Leaving content in the Q&A format that helped you develop it is missing the point. You’re not there to build scaffolding. You have to see your content in its naked purpose and determine the best method for communicating that purpose – and it usually won’t be what got you there.
The goal (to borrow a lesson from content management systems) is to separate the content from its presentation, to let the meaning of the content inform its display.
This is, of course, a nice theory.
An occasionally necessary evil
I have a lot of clients who adore FAQs. They’ve developed their content over a long period of time. They’ve listened to the questions their users are asking. And they’ve answered them all on a page that I simply cannot get them to part with.
Which means I’ve had to consider that there may be occasions where an FAQ page is appropriate.
As an example: one of my clients is a financial office in a large institution. Because this office manages several third-party systems that serve a range of niche audiences, they had developed FAQs that addressed hyper-specific instances of dysfunction within systems for different users – à la “I’m a financial director and my employee submitted an expense report in such-and-such system and it returned such-and-such error. What do I do?”
Yes, this content could be removed from the question format and rewritten. But I’m not sure it would be an improvement. It won’t necessarily resolve concerns about length and searchability, and the different audiences may complicate the delivery. And since the work of rewriting it didn’t fit into the client workflow (small team, no writers, pressed for time), I didn’t recommend the change.
I’ve had to make peace with not being to torch all the FAQs on the internet. Some content, like troubleshooting information or complex procedures, may be better in that format. It may be the smartest way for a particular client to handle that particular information.
Of course, this has to be determined on a case-by-case basis, taking into account the amount of content, the subject matter, the skill levels of the content creators, the publishing workflow, and the search habits of the users.
If you determine that an FAQ page is the only way to go, ask yourself:
Is there a better label or more specific term for the page (support, troubleshooting, product concerns, etc.)?
Is there way to structure the page, categorize the questions, or otherwise make it easier for users to navigate quickly to the answer they need?
Is a question and answer format absolutely the best way to communicate this information?
Form follows function
Just as a question and answer format isn’t necessarily required to deliver the content, neither is it an inappropriate method in and of itself. Content professionals have developed a knee-jerk reaction: It’s an FAQ page! Quick, burn it! Buuuuurn it!
But there’s no inherent evil in questions and answers. Framing content in an interrogatory construct is no more a deal with the devil than subheads and paragraphs, or narrative arcs, or bullet points.
Yes, FAQs are riddled with communication snafus. They deserve, more often than not, to be tied to a chair and thrown into a lake. But that wouldn’t fix our content problems. FAQs are a shiny and obvious target for our frustration, but they’re not unique in their flaws. In any format, in any display, in any kind of page, weak content can rear its ugly, poorly written head.
It’s not the Q&A that’s to blame, it’s bad content. Content without context will always fail users. That’s the real witch in our midst.",2013,Lisa Maria Martin,lisamariamartin,2013-12-08T00:00:00+00:00,https://24ways.org/2013/what-to-do-with-faqs/,content