2023-03-08 09:47:33
You ask, "Should I be making a new directory for this feature I'm building?" You expect a return value of: "yes" or "no." You had a 50% chance of guessing the "correct" answer...right?
Four hours, 49 messages, 13 participants (4 whom you've never met?) later, you have not a boolean but instead something rather undefined:
"What makes a feature a feature?"
"Isn't everything in React a component?"
"Where do I put functions that aren't hooks?"
"Why are some of the data objects in snake case and others in kebab case?"
"Why did we invent React when it's just PHP and a side of jQuery?"
Bigger, harder, sometimes just unrelated questions around how we define directories writ large have buried your question. At this point you might give up and leave this unanswered thread to disappear into the Slackwork. (I would blame neither you nor myself for the times I may or may not have have allegedly done this.)
If you've not experienced this situation yourself, it almost always starts off with a harmless question.
Harmless questions are often an unintentional open invitation—a bat signal—for every opinion that's ever existed peripherally related to the question. People generally start off trying to answer the question directly and in earnest. Whatabouts, advocacy for the Devil, edge cases, differences in experiences, flock toward the bright light of existentialism that I (only sort of) exaggerated above.
When you find circled by bats[1] as I often do, enter strawman.
A strawman argument is when someone creates a false premise or variation upon the core argument in order to show how the core argument is false. Make argument A, they'll say argument B, which kinda looks like A, is false. Therefore argument A is false.
While incredibly annoying at the family dinner table and in Congressional session alike, building a strawman to be a unified mental model grounds discussions in reality.
In the case of the directory, your strawman could be an ASCII diagram of a folder structure with real examples from your code base. Whatever your question scope, determine what form your strawman is—a diagram, a list of options, pseudocode. Not even correct, perfect, or even particularly good, the strawman's main job is to just exist. I'd strongly suggest doing it quickly and not allowing for too much editing or analysis as you put down the first draft.
The strawman is built to stand in the field and divert the bats away from the light and toward something tangible, adjustable, and most importantly: held in the same form.
The difference between the strawman your cousin builds at Christmas dinner to prove a conspiracy theory and the one you'll build: Your strawman is there to build up an idea rather than to tear it down.
The question vortex happens because each participant responding to that question likely imagines something different in their head than the next person. Each person frames their questions and critiques through their mental model, which may be very well-defined or amorphous depending on how they think (look up "can you visualise an apple").
By doing this exercise, I have found:
The strawman aligns our mental models (mostly, as best as we can), forces us to reconcile the theoretical concern with tangible application, allows us to ask questions with a form of reference. Sometimes the strawman will be closer to its final form than you might think. Other times, the difficulty of crafting the strawman or the wretchedness of the form may help you to move on from the exercise. Regardless of the outcome, the next time you find yourself in a endless engineering musings vortex, ask your team... What are we going to do? Do you want to build a strawman? ∎
[1] If you are here to question whether a strawman and a scarecrow are the same thing, did you notice I didn't ever use the word scarecrow and just subsumed it into strawmen like it was always one thing? Are you wondering how often this trickery happens? Why did they call it a strawman and not a scarecrow? Are you curious why I didn't degender strawman? Are you making up reasons? Why didn't you listen to Admiral Akbar? Because yeah, this is a trap, you sweet little batcrow.
2021-10-12 18:04:22
At work, I like to observe who:
requests v. demands
is direct v. is indirect
responds v. ignores
The data reveals a lot about how people wield power, especially subconsciously.
Requests are often, “when you get a chance, could you please do X? I would like it by Z date.”
Demands are, “you need to do X by Z date.”
But it gets more complicated:
An indirect demand could look like, “we need to do X ASAP.” “We” in a lot of situations is an unspoken substitute for “you.” ASAP is often an ambiguous urgency. power becomes a critical piece of this.
“We” can hold a collaborative tone when power is equal and trust is shared.
As with many things, “we”—a banal pronoun—can become complicated when you look at power.
Going back to the request v. demand, “we need to…ASAP” can be code for “I want you to do this by a time I haven’t disclosed but will drive urgently toward. When done, I’ll take credit.”
There is often a passive understanding between both parties that “we” means “you” and “ASAP” means “I will move the deadline (up) as it suits me.”
Situations like this are anxiety-ridden, especially for many of us neurodivergent folks.
Now, this is when ignoring comes into play.
As a highly anxious, high producing person, I often ask a lot of upfront questions (trauma is a strong journalist) to avoid the ambiguity that the above situation creates.
Often I notice those questions just… go unanswered. now here you might respond “assume positive intent.”
And I would respond that “I don’t assume any intent, but observe all impact.” It’s always possible someone isn’t intentionally ignoring me; an ADHD person like me knows that especially well.
But the impact remains: not getting clarity leads to massive anxiety and ambiguity.
The ignoring is often a passive and subconscious wielding of power in at least two ways.
Failure to just know are an issue of the helper’s “lack of expertise or initiative” not of the helped’s poor and lacking communication.
The person with less power is far more likely to be blamed for dropping the ball, and here, the former collective “we” becomes “they.”
Does this sound Machiavellian? It is, and also, I think that more often than not, corporatism and capitalism encourage/require us to be Machiavellian without even acknowledging it. In many ways, this is worse because we aren't even aware of or intending to commit a lot of this harm. We are even less able to control our harm here. It's not intentional on our part, but it is intentional design by the system.
The system always favours the ones with the most power and is designed to passively and subversely support that group. The person/people with less power is/are far more likely to be blamed for dropping the ball, and here, the former collective “we” becomes “they.”
On the flip side “annoying” helpers like me will insist on getting answers and keep a paper trail (trauma the journalist!) and we are seen as “difficult, unaccommodating, needs a lot of direction.”
The game is often manipulated to be lose-lose for the less powerful.
Now, when I say I observe this it doesn’t mean I isolate and document each interaction. I understand we live in a pandemic and many of our actions are banal and unpredictable.
I get it. I’m here too. However… what I do mean is that I observe these binaries from the first paragraph as patterns, especially at scale of dozens of interactions. Patterns of power, even if passive and subconscious, often tell me a lot. They show me ways and means to protect myself at work.
This entire power dynamic is one of the most harmful and yet quiet ways that white supremacy culture thrives in the workplace.
It’s a way that many mediocre majoritised people thrive with little effort while exceptional minoritised people barely survive with a lot of effort.
This power dynamic, like white supremacy, goes unnoticed because it is baked into the architecture of the organisation, the politics of the workers, and ultimately, what it takes to survive.
I hope this thread opens up more awareness to it, and conscious actions to resist.
For questions, please reach out on Twitter! I can't promise to answer all your questions, but I'll try my best!
For corrections (typos, factual inaccuracies), please file a GitHub issue.
2021-09-04 01:50:33
If you drive and have had to parallel park, you might have encountered a situation where you could have parked somewhere if that Prius just had pulled up a bit or split the difference better.
If you're even-tempered, you drove around the block and found another spot. If you're easy to temper, you might have cursed under your breath—or maybe, just maybe—you were having a real one and even left a note.
Cursed as a deeply analytical person, whenever I encounter a bad park job, my first question is, "why would they have parked that way?" I try to ask it without as much snark as possible (I have my days, still).
It's very easy for us to assume that that person actively chose to park like an a-hole and decided to ruin a few other people's day for shits and giggles.
Most of the time we'll never know. Equally likely to assume stranger sociopathy, we can write a more likely story, too: They didn't choose to park that way. Relatably: Intent does not erase impact, even in parking. So yeah, they probably didn't actively seek to ruin your life in this minor way, but instead, did it unaware, thinking about the global pandemic, in a rush, or even equally likely, they inherited that spot.
Parallel parking is one of the most brilliant examples of feedback loops. We have some general guidelines (at least here in the U.S., let me tell you about my time in Cairo and how parking works there), but for the most part, you park around other people and other things (fire hydrants, trash cans, driveways, unofficial cones that busybodies leave that mean nothing but I still weirdly abide by). So, in a perfect universe where all our cars are the same lengths and driveways are spaced out equidistantly, we could make more assumptions.
But given the chaos that is humankind, parallel parking is a complete mess. It's highly likely that the conditions you see before you are not the ones the a-hole parker had.
Yet when we're rushing to get our own spot, we're so quick to project pristine conditions for others—hypocritically while we're experiencing the very chaotic impact of parallel parking ourselves!
Inheriting a chaotic system and expecting pristine conditions prior sounds deeply familiar to how many of us navigate inheriting code bases. It is easy to come into a codebase with all of our own context and assumptions as to how it should be in a pristine environment.
Just the other day, I caught myself asking, "why the fork balls would you have done it that convoluted way?" Several hours later, I had refactored an entire flow. And then a day later, when a few things broke, I understood why the previous engineer had done it the convoluted way they did.
Said another way, they parked their car behind a big truck and when I got there, all I saw was a big gap.
I wrongly made an assumption about the conditions and context under which the previous engineer made that decision. It wasn't until I went to park in the same spot that I realised the reasoning.
I stopped to reflect on how I can train myself out of this habit:
Assume no intent and observe all impact. We're often told to assume positive intent because we want to believe in the "good in all people." I have a lot of thoughts on this binary thinking (saved for another day, though you can watch my talk if you're curious). But here, I think we'd be better off to not assume anything. Speculation is fine, as long as we recognise the only way to know for sure is to ask the previous engineer (and that's not always possible).
Leave things better than you found them—when possible. In the parking situation, you can do your best to not worsen the situation for people downstream. Try to neutralise the ill-effects of the unideal park job. The code equivalent is to document. I made sure to document against why I made the decision I did above (redoing, in part, the previous engineer's work. Leaving notes for the future engineer lets them know why I parked like an a-hole, so to speak.
Even more proactively, if you find yourself writing code that is unexpected (which yes, requires a great deal of self-awareness and experience), document it. I am of the school of thought it's better to overdocument than underdocument.
The worst thing that happens with overdocumentation is the (usually arrogant) engineer reads the comments and thinks it's unnecessary (insert cries of "self-documenting code"). The worst thing with underdocumentation is you take down an entire system—I know what I'm picking, but you do you, foo.
Approach with curiosity over critique. It was a really humbling moment for me to realise that I had assumed the previous engineer chose to code like an a-hole, because I generally try to approach with curiousity over critique. But we all have better and worse days. I catch myself regularly telling myself, curiosity, not critique.
When I'm confused by a code decision, I force myself to answer, why would they do it that way? I make a little list. The list is different each time, but one item that is ever present is: There is a lot of ways to do this, and this might have been the best way they knew how.
Like in the parking situation, we rarely have enough information or context to critique effectively. We make a lot of assumptions in critique, but in curiosity, we can ask, we can speculate but ultimately never assume anything. Curiosity is expansive, critique is reductive.
Also, if you feel in a position to critique, it's a gamble. You're allowing yourself to show your ass if you're wrong. Curiosity always allows room for evolving information, missing context, and knowledge you didn't have. After two years in a pandemic, I would hope we'd all see how quickly things can evolve and change on a global scale.
I hope the next time you encounter a shitty park job or a strange function or even a weird situation in your life that makes no sense, you can count to ten, speculate a few reasons why they might have done it that way, and invite curiosity and context into your life.
For questions, please reach out on Twitter! I can't promise to answer all your questions, but I'll try my best!
For corrections (typos, factual inaccuracies), please file a GitHub issue.
2021-03-24 08:34:35
Hyperaware of how annoying it is when you want a recipe and have to read a 20-paragraph story about someone's great gran (and feeling bad you don't care), I have provided a skip link if you don't care about my back story to this post.
My partner and I were watching TV and he said, "Oh, the closed captions are off. Do you want me to turn them on?" It was the moment that I realised:
Whenever I encounter a new course and it's video only without a transript OR closed captioning, I am overwhelmed with sadness. No matter how engaging, funny, well-produced the video is, I will not be able to retain it unless I cannot read along.
If I want to sing along to a song, I have to pull up the lyrics.
If I want to listen to an audio book, I have to coordinate make sure I have the book too, so I can visually read along.
If I want to listen to a podcast, I have to follow along the transcript.
If this sounds cumbersome, it is. I usually choose to go straight to reading at least 95% of the time and skip the other half.
I read fast and I retain what I read. This is my comfort zone and my learning style. But many other people are the opposite. It should be okay that we each learn differently and need different things to succeed.
Unfortunately, so many of our tutorials (and media in general) only comes in one form. When our teachings are only provided in one media, in one language, in one form, it is inherently inaccessible to some subset of our students.
I imagine most of us teach to provide opportunities and access. Creating access requires us to provide more than one way to take in our content. I've broken down each base medium with some of its benefits, tips, and opportunities to make your content more accessible.
alt
text or longdesc
(for longer explanations).Record an audio file of you reading the written content.
I first saw this idea on Lindsey Kopacz' blog, a11y with Lindsey. People can hear pronunciation and personality, learn the language auditorily, and perhaps enjoy it while doing something else (people who don't rely on screen readers don't often think to use them to have things read for them). Come up with a strategy for whether or not you'll read through code snippets and if so, how.
Visualise written content into a more dynamic way.
Many people, some neurodivergent folks especially, benefit from information being distilled into diagrams, comics, or less word-dense formats. Visuals can also benefit people who might not read/understand the language you wrote it in. They can also be an effective lead-in to your long-form from visually-driven avenues like Pinterest or Instagram.
Build in a way for people to translate your posts.
Many people have generously offered to translate my writing into languages cooler than English and I always want to take them up on it. I don't currently have a great mechanism on my site to share them. Don't be like me. Build in a language feature!
(While people can rely on automated translations services, there is something much better about having a human interpret your post into another language. I also love the community building feels. Google Translate is mostly just rude to me.)
Closed captioning allows people to follow along and read your video (if they're not able to listen due to a disability or situational context).
Ideally, closed captioning should be a togglable feature of your video player. However, in platforms where this is not yet possible (i.e., TikTok, Instagram, etc), please use a captioning app to add open captions. (I like MixCaptions for iOS.)
Open captions are burned onto the media and cannot be turned off. While they are not ideal, they are better than no captions.
Transcripts allows people who prefer reading/not able to watch a video to read/skim all the content. Transcripts are also more translatable and searchable and lightweight. If someone can't load your massive video due to a slow connection, they can still benefit.
Videos, tutorials and talks, can be converted into engaging long-form written content beyond just a transcript. Something Ethan Marcotte does that I really admire (well, perhaps second to his impressive meme database) is that he translates his talks into webpages (see The World-Wide Work).
Note that I didn't break out audio into its own separate category. Much of the principles above apply for audio (such as transcripts, preventing audio play, etc).
While repos, pens, and snippets can supplant both written and video content, they sometimes go out into the wild in their own. I provided some ways to help guide people within the snippets.
Through these tips, I hope I've expanded the way you think about your content. You might be thinking, "gosh, this is a lot of work." It is!
How I think about it is: We don't have to do it all at once. Release your tutorial in the first format you feel most comfortable in. Then, build in time to extend it into a second, or third format. Perhaps you can pair/trade with a friend who enjoys a format you hate! The goal should not be to stop, but instead to keep imagining new and inventive ways to make our content as acccessible to as many people as possible, especially those who are usually given the biggest barriers to entry.
2021-03-18 20:56:13
I recognise that my
pre
code needs a lot of work, so the code samples are difficult to read and ugly right now. I plan to update that code. Apologies in the meantime; hopefully the message is still understandable!
Animations help to breathe life into interactive experiences. Animations, especially when overused and abused, can make people very ill. Through this article, I hope to provide you an approach and guidance to discussing how you/your company use animation thoughtfully and responsibly.
I experience benign paroxysmal positional vertigo (BPPV), which is a fancy way of saying, the room can start spinning if I turn my head the wrong way. Another side effect is if a website scrolljacks or has too much animation, I can become dizzy and have to lay down often for the rest of the day. BPPV is one of many vestibular disorders that impact millions of people.
As you can imagine, this can be a problem when you're a frontend engineer and are animating lots of things.
A core accessibility approach of mine is to let the user determine what's best for them and to enable as many user settings as I can. Most operating systems allow us to reduce the motion and have for a very long time.
The setting has been exposed now to most modern browsers using a media feature called prefers-reduced-motion
. prefers-reduced-motion
media query acts as any other media query with two possible options:
no-preference
(the default): the user has not indicated to "Reduce motion" in their OS and will be served all animations and animations designated explicitly as prefers-reduced-motion: no-preference
. [I want to make a critical note here that this is operating on a no-consent model. Ew. The user hasn't necessarily opted into animations. They just haven't checked "Reduce motion." That could be because they like and can tolerate animations, or, it's equally possible the user doesn't know about this setting. So, I want us to make sure we're not assuming that these users necessarily want animations.]reduce
: the user has "Reduce motion" checked in their operating system's Accessibility settings and will be served whatever is in the media query for prefers-reduced-motion: reduce
.What this means is that if we can use prefers-reduced-motion
to customise our animations based on user settings.
We will have two parts to our code:
prefers-reduced-motion
media query.In CSS, it could look something like this:
/*
Part 1: Animation
Here is where we would put our full animation.
*/
.wordArtRotation {
animation: rotation 2s infinite linear;
}
/*
Part 2: Media query
Here is where we would put our partial or no animation.
*/
@media (prefers-reduced-motion: reduce) {
.wordArtRotation {
animation: none;
}
}
When I collaborate with a designer/animator on an animation, I first ask, "Is this animation critical to understanding the content?"
More often than not, the answer is "no." (It might take some finessing of the conversation, so remember to emphasise that being critical isn't the same thing as being important or nice or aesthetic.) When conceived well, animations should be an enhancement to an explanation.
If the animation isn't critical, then my default code is to include animation: none
for all of my animations. In CSS, it could look something like this:
@media (prefers-reduced-motion: reduce) {
.wordArtRotation,
.rainbowWave,
.textFadeIn {
animation: none;
}
}
Another way it could look is to reverse our thought process. Instead of defaulting to adding animations universally, we can instead only add them for people who have designated no-preference
.
The code could look something like this:
/*
Part 1: Animation
Here is where we would put our full animation.
*/
.wordArtRotation {
animation: none;
}
/*
Part 2: Media query
Here is where we would put our partial or no animation.
*/
@media (prefers-reduced-motion: no-preference) {
.wordArtRotation {
animation: rotation 2s infinite linear;
}
}
The difference between the first code block and the second one comes down to browser support. The support for prefers-reduced-motion
is fairly strong, but still has some gaps (see Can I Use: Prefers reduced motion). Defaulting to this latter approach will mean that all users will default to no animation, including users whose browsers won't recognise the media query.
The difference is not just in code, but in mindset shift. I won't tell you which one is right for you/your org, but I think this type of differentiation is important for your design system, for example. I find that sharing the technical approach with the designer gets them thinking about how they intend for their animations to exist in different environments (and getting them to cater their animations to user preferences).
To turn these individual conversations into a systemic one, you could include animation principles with guidance around how your design system would like animations to be not only coded, but conceived. Providing this context in your documentation will help to guide better animator/designer-developer collaboration.
Framer Motion sets a good tone for accessibilty in documentation with their Guide to Accessibility.
Since we've all agreed that our animations aren't critical to perceiving our page (winky face), we can take that one step further and only serve our users CSS if they are cool with prefers-reduced-motion: no-preference
.
Here's what you might include in your HTML file in the <head>
tag:
<link
rel="stylesheet"
href="animations.css"
media="(prefers-reduced-motion: no-preference)"
/>
Code snippet from Web.dev: prefers-reduced-motion
What this requires is we've placed all our animations into one CSS file. If our user has indicated "Reduce motion" (and thus, the media query prefers-reduced-motion: reduce
is true), then the user isn't even served our stylesheet at all. Separating our CSS animations into its own stylesheet can be a very daunting task on a large codebase, so this could require some heavy refactoring. But if CSS animations is a large part of your codebase, it might also mean huge performance savings!
I love this option because it is putting accessibility and performance on the same team—as they should be!
If the animation is critical to understanding, then I ask what other ways we intend to serve up that information, because without alternates, we're excluding anyone who won't be able to see the animation (whether due to physical disability, data/technical restrictions, situational, etc).
Sometimes this conversation between the person who conceived the animation and the person implementing it doesn't happen. That is a damn shame, because I find that's where we needlessly animate things that add exactly zero value to the conversation.
I also ranked these questions in level of spiciness for no other reason than my entertainment to cater your communication to the context of your conversation.
Most of the time, I'm negotiating a way to get information to be served in more ways. Changing the answer from "yes, this animation is critical to understanding" to "no, this animation is not critical but an enhancement." Remember, accessibility means giving the users as many, diversified options as possible, not determining which option works best for them.
Auto-playing anything is cruel to both users who experience vestibular disorders and neurodivergent users for whom autoplay can cause major focus issues.
CSS-tricks covers this well with Reduced motion picture technique: take two.
Now while I am very pro-CSS animations (and think they can handle most standard animations), I recognise that CSS can't handle all types of animations, for example, react-spring
animations. I'm not yet an expert in these areas. Instead of taking weeks to learn this all to regurgigate it back to you right now, I wanted to share some existing articles that already do a great job of distilling down this information.
Vanilla JS: window.matchMedia
demo from web.dev
React: useReduceMotion Hook by infiniteluke
Commentary on prefers-reduced-motion
with authors covered that I did not. (Note there will be some introductory overlap)
A List Apart: Accessibility for vestibular disorders
Provides guidance to designing for vestibular disorders with tactical tips
A11y with Lindsey: Reducing motion to improve accessibility
Code snippets with brief rundown on adding a toggle to your page and using localStorage
to preserve user setting
Josh Comeau: Accessible Animations in React
React Code snippets
For questions, please reach out on Twitter! I can't promise to answer all your questions, but I'll try my best!
For corrections (typos, factual inaccuracies), please file a GitHub issue.