123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044 |
- <!doctype html><!-- This is a valid HTML5 document. -->
- <!-- Screen readers, SEO, extensions and so on. -->
- <html lang="fr">
- <!-- Has to be within the first 1024 bytes, hence before the `title` element
- See: https://www.w3.org/TR/2012/CR-html5-20121217/document-metadata.html#charset -->
- <meta charset="utf-8">
- <!-- Why no `X-UA-Compatible` meta: https://stackoverflow.com/a/6771584 -->
- <!-- The viewport meta is quite crowded and we are responsible for that.
- See: https://codepen.io/tigt/post/meta-viewport-for-2015 -->
- <meta name="viewport" content="width=device-width,initial-scale=1">
- <!-- Required to make a valid HTML5 document. -->
- <title>No, We Won’t Have a Video Call for That! (archive) — David Larlet</title>
- <meta name="description" content="Publication mise en cache pour en conserver une trace.">
- <!-- That good ol' feed, subscribe :). -->
- <link rel="alternate" type="application/atom+xml" title="Feed" href="/david/log/">
- <!-- Generated from https://realfavicongenerator.net/ such a mess. -->
- <link rel="apple-touch-icon" sizes="180x180" href="/static/david/icons2/apple-touch-icon.png">
- <link rel="icon" type="image/png" sizes="32x32" href="/static/david/icons2/favicon-32x32.png">
- <link rel="icon" type="image/png" sizes="16x16" href="/static/david/icons2/favicon-16x16.png">
- <link rel="manifest" href="/static/david/icons2/site.webmanifest">
- <link rel="mask-icon" href="/static/david/icons2/safari-pinned-tab.svg" color="#07486c">
- <link rel="shortcut icon" href="/static/david/icons2/favicon.ico">
- <meta name="msapplication-TileColor" content="#f7f7f7">
- <meta name="msapplication-config" content="/static/david/icons2/browserconfig.xml">
- <meta name="theme-color" content="#f7f7f7" media="(prefers-color-scheme: light)">
- <meta name="theme-color" content="#272727" media="(prefers-color-scheme: dark)">
- <!-- Documented, feel free to shoot an email. -->
- <link rel="stylesheet" href="/static/david/css/style_2021-01-20.css">
- <!-- See https://www.zachleat.com/web/comprehensive-webfonts/ for the trade-off. -->
- <link rel="preload" href="/static/david/css/fonts/triplicate_t4_poly_regular.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: light), (prefers-color-scheme: no-preference)" crossorigin>
- <link rel="preload" href="/static/david/css/fonts/triplicate_t4_poly_bold.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: light), (prefers-color-scheme: no-preference)" crossorigin>
- <link rel="preload" href="/static/david/css/fonts/triplicate_t4_poly_italic.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: light), (prefers-color-scheme: no-preference)" crossorigin>
- <link rel="preload" href="/static/david/css/fonts/triplicate_t3_regular.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: dark)" crossorigin>
- <link rel="preload" href="/static/david/css/fonts/triplicate_t3_bold.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: dark)" crossorigin>
- <link rel="preload" href="/static/david/css/fonts/triplicate_t3_italic.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: dark)" crossorigin>
- <script>
- function toggleTheme(themeName) {
- document.documentElement.classList.toggle(
- 'forced-dark',
- themeName === 'dark'
- )
- document.documentElement.classList.toggle(
- 'forced-light',
- themeName === 'light'
- )
- }
- const selectedTheme = localStorage.getItem('theme')
- if (selectedTheme !== 'undefined') {
- toggleTheme(selectedTheme)
- }
- </script>
-
- <meta name="robots" content="noindex, nofollow">
- <meta content="origin-when-cross-origin" name="referrer">
- <!-- Canonical URL for SEO purposes -->
- <link rel="canonical" href="https://xahteiwi.eu/resources/presentations/no-we-wont-have-a-video-call-for-that/">
-
- <body class="remarkdown h1-underline h2-underline h3-underline em-underscore hr-center ul-star pre-tick" data-instant-intensity="viewport-all">
-
-
- <article>
- <header>
- <h1>No, We Won’t Have a Video Call for That!</h1>
- </header>
- <nav>
- <p class="center">
- <a href="/david/" title="Aller à l’accueil"><svg class="icon icon-home">
- <use xlink:href="/static/david/icons2/symbol-defs-2021-12.svg#icon-home"></use>
- </svg> Accueil</a> •
- <a href="https://xahteiwi.eu/resources/presentations/no-we-wont-have-a-video-call-for-that/" title="Lien vers le contenu original">Source originale</a>
- </p>
- </nav>
- <hr>
- <p>FrOSCon 2020 was an online event due to the COVID-19 pandemic, and
- gave me the opportunity to present an extended and heavily updated
- version of my <a href="https://xahteiwi.eu/resources/presentations/devopsdays-tel-aviv-2019/">DevOpsDays 2019</a> talk.</p>
- <hr>
- <p>I normally make my talks available as a video, and a slide deck with
- full speaker notes. In this case though, I consider it fitting to
- write the whole thing out, so that you <em>don’t</em> need to watch a full
- length video in 45 minutes, but can read the whole thing in 15.</p>
- <p>You’ll still find links to the recording and deck downpage, as usual.</p>
- <hr>
- <p>No, we won’t have a video call for that!</p>
- <p>Communications for distributed teams</p>
- <p>FrOSCon 2020</p>
-
- <p>This presentation is a talk presented at <a href="https://www.froscon.de/">FrOSCon 2020
- Cloud Edition</a>. It is <a href="https://creativecommons.org/licenses/by-sa/4.0/">CC-BY-SA
- 4.0</a> licensed, see
- <a href="/LICENSE">the license</a> for details.</p>
- <p>Hello and welcome, dear FrOScon people — this is my talk on
- communications in distributed teams. My name is Florian, this is the
- second time I‘m speaking at FrOScon, and you probably want to know
- what the hell qualifies me to talk about this specific issue. So:</p>
- <h3>Why am I talking here?</h3>
- <p>So, why am I talking about <strong>that</strong>?</p>
- <p>Or rather more precisely, why am <strong>I</strong> talking about that?</p>
- <p>I turned 40 last year, have been in IT for about 20 years now (19
- full-time), and out of that I have worked</p>
- <ul>
- <li>
- <p>in 4 successive companies, all of which worked out of offices,
- for 11 years, </p>
- </li>
- <li>
- <p>in a completely distributed company, that I founded, for 6 years,</p>
- </li>
- <li>
- <p>and now, for about three years, I have been running a distributed
- team that is a business unit of a company that has existed for 15
- years and throughout that time, has only ever worked from a single
- office.</p>
- </li>
- </ul>
- <p>So I think I might have seen and become aware of some of the rather
- interesting challenges that come with this.</p>
- <h3>What changed since last time?</h3>
- <p>I originally wrote and presented this talk for the first time in
- December 2019. At the time, you probably had forgotten about SARS, had
- no idea what SARS-CoV2 or COVID-19 were, and many of you were probably
- working from offices.</p>
- <p>And then something like three months later, everything changed and
- suddenly, this talk became much more relevant to a much greater
- audience.</p>
- <p>And something else happened: a lot of people suddenly started talking
- about working from home and distributed teams, and a lot of those
- people who were talking very loudly, had themselves only been working
- with or managing distributed teams since March. And a fair amount of
- what you could about the subject then, and can still read now, is
- complete and utter bullshit.</p>
- <p>So there’s one point I actually <em>didn’t</em> make in the initial version
- of this talk, because I thought it was self-evident. But I have come
- to the conclusion that to a lot of people it is not, so to rectify
- this omission from last December — and with apologies for that
- omission to the wonderful DevOpsDays Tel Aviv crowd, who were my first
- audience for this talk, let me make this one thing very clear from the
- outset:</p>
- <blockquote>
- <p>Effective distributed collaboration is <strong>not</strong> pretending to be in
- an office while staring into a webcam all day.</p>
- </blockquote>
- <p>You will never be able to capitalize on work as a distributed team
- unless you kick some office habits. The key to distributed teams being
- effective is <strong>not</strong> that they happen to not be in the same place, as
- you’ll see from the remainder of this talk. So to expect success from
- the approach that you take the habits of an office, simply remove the
- element of locality, replace every face to face meeting with a video
- call and carry on, is ludicrous.</p>
- <p>The good news is that if you do it right, you’ll end up with a far
- better team than a local one would ever be, <em>and</em> everyone has a
- chance at far better work-life balance, <em>and</em> you don’t waste awful
- amounts of time and energy and fossil fuels on your commute.</p>
- <h3>What’s in this talk?</h3>
- <p>So you’ll find a few general themes throughout this talk:</p>
- <ul>
- <li>
- <p>What modes we have <em>available</em> for communications in teams;</p>
- </li>
- <li>
- <p>Why distributed teams always collaborate <em>asynchronously,</em> and what
- communication modes lend themselves to that particularly well;</p>
- </li>
- <li>
- <p>Why <em>written communication</em> is so important in distributed teams;</p>
- </li>
- <li>
- <p>And why <em>meetings</em> (like video calls) are a mode of communication
- that effective distributed teams hardly ever need to use — except
- for very specific reasons.</p>
- </li>
- </ul>
- <p>But I do want to state one thing upfront:</p>
- <blockquote>
- <p>This is <em>not science.</em></p>
- </blockquote>
- <p>Nothing of what I am talking about is steeped in any scientific
- rigour. I present anecdotes, not evidence. I might be mistaking
- correlation for causation, or the other way round. It’s solely based
- on my personal experience, and the experience of others I have talked
- to, watched, or read. Everything I say here is subject to debate and
- rebuttal, or you can simply have a different opinion.</p>
- <p>But it’s definitely <strong>not</strong> science.</p>
- <p>Now with all of that said, let me attempt to give a definition of a
- distributed team, according to my understanding:</p>
- <p>A distributed team is a <strong>professional</strong> group whose members do not
- rely on proximity in order to <strong>routinely</strong> collaborate
- productively.</p>
- <p>Now this is clearly not an ideal definition, not least because it
- defines something by a negative, and an outside factor to boot: it
- defines a distributed team by what it <em>does not need</em> to exist to
- function. But it’s the best definition I’ve been able to come up with.</p>
- <p>Now there’s a couple of key words in here:</p>
- <ul>
- <li>
- <p><strong>Professional.</strong> I’m talking about teams that work towards a
- professional goal. This doesn’t necessarily mean that they all work
- in the same company. They could, for example, all work in different
- companies collaborating on a joint project, which is what frequently
- happens in open source software projects. But they’re not pursuing
- their hobby, they’re doing their jobs.</p>
- </li>
- <li>
- <p><strong>Routinely.</strong> I’m talking about teams that <em>habitually</em> work in a
- distributed fashion, not the work that goes on in an office-based
- team when one person is having a work-from-home day.</p>
- </li>
- </ul>
- <p>It is important to understand that that lack of proximity is not only
- spatial, it is temporal as well, because:</p>
- <blockquote>
- <p>Working in a distributed team means <strong>working asynchronously.</strong></p>
- </blockquote>
- <p>If your team is distributed, this is equivalent to saying that it
- works in an asynchronous fashion, that is to say, that people will
- work on things in parallel, and a capable distributed team will have
- just as few synchronization points as absolutely necessary.</p>
- <p>The reason for this is not just working in different timezones, but
- also the fact that everyone will have their own daily routine, and/or
- have their individual times when they are most productive. Which you
- <em>will not attempt to synchronize.</em> (Doing so would mean setting the
- entire team up for failure.)</p>
- <p>Now, this doesn’t come for free, nor does it fall in our lap:</p>
- <blockquote>
- <p>Being productive in a distributed team is a skill
- that most people must <strong>learn;</strong> it is not innate to us.</p>
- </blockquote>
- <p>People are not born with the ability to work in a distributed
- team. Humans function best in groups that collaborate in close
- proximity to one another; it is only very recently that technology has
- started to enable us to override that to an extent — giving us other
- benefits like the ability to work from home, or the ability to hire
- people residing anywhere, provided they have internet connectivity.</p>
- <p>So we now <em>can</em> work in teams despite being continental distances away
- from each other but we do have to acquire the skills to do that. And
- if we fail to do so, that has a rather grave disadvantage, which is
- that...</p>
- <blockquote>
- <p><strong>Nothing</strong> has as dire an impact on productivity as <strong>poor
- communications.</strong></p>
- </blockquote>
- <p>This is a truism that applies to both distributed and non-distributed
- teams. Having bad communications will wreck any project, blow any
- budget, fail any objective. Now note that the reverse is <em>not true:</em>
- having <em>good</em> communications does not guarantee success. But having
- bad communications does guarantee failure.</p>
- <p>And here is one thing to start with:</p>
- <blockquote>
- <p>A capable distributed team <strong>habitually externalises</strong> information.</p>
- </blockquote>
- <p>Information is generally far less useful when it is only stored in one
- person’s head, as opposed to being accessible in a shared system that
- everyone trusts and can use. If you take important information out of
- your own head and store it in a medium that allows others to easily
- find and contextualise it, that’s a win for everyone.</p>
- <p>And since we’re all technology people, we typically have multiple
- facilities to externalise, share, and then access information at our
- disposal. So let’s see how those compare.</p>
- <h2>Modes of communication in distributed teams</h2>
- <p>A distributed team will habitually use multiple modes of
- communication, relying mostly on those that make sharing, finding, and
- contextualising information easy, and avoiding those that make it
- difficult.</p>
- <p>In many teams, distributed or not, using chat as a default mode of
- communication is becoming the norm. Now with an important exception,
- which I’ll get to near the end of the talk, this is <strong>not</strong> a symptom
- of having a particularly dynamic or efficient team; it’s the opposite.</p>
- <blockquote>
- <p>Excessively using chat isn’t being efficient.
- It’s being lazy.</p>
- </blockquote>
- <p>It’s a symptom of the worst kind of laziness <em>(not malice!)</em>: in an
- attempt to communicate quickly and easily, for yourself, you are really
- making things harder for everyone, including yourself.</p>
- <table class="table-hover table table-striped">
- <thead>
- <tr>
- <th></th>
- <th align="center">Share</th>
- <th align="center">Find</th>
- <th>Contextualise</th>
- </tr>
- </thead>
- <tbody>
- <tr>
- <td>Chat</td>
- <td align="center">🙂</td>
- <td align="center">😐</td>
- <td>🙁</td>
- </tr>
- </tbody>
- </table>
- <p>This is because, while <em>sharing</em> information in a chat is extremely
- easy, it is also a “fire and forget” mode of communications. Chat
- makes it difficult to find information after the fact. If you’ve ever
- attempted to scour a busy Slack or IRC archive for a discussion on a
- specific topic that you only remember to have happened a “few months
- ago”, you’ll agree with me here.</p>
- <p>It’s even <em>more</em> difficult to read a Slack discussion in context, that
- is to say in relation to <em>other</em> discussions on the same topic, days
- or weeks earlier or later.</p>
- <p>Let’s compare that to other communication modes:</p>
- <table class="table-hover table table-striped">
- <thead>
- <tr>
- <th></th>
- <th align="center">Share</th>
- <th align="center">Find</th>
- <th>Contextualise</th>
- </tr>
- </thead>
- <tbody>
- <tr>
- <td>Chat</td>
- <td align="center">🙂</td>
- <td align="center">😐</td>
- <td>🙁</td>
- </tr>
- <tr>
- <td>Email</td>
- <td align="center">😐</td>
- <td align="center">😐</td>
- <td>😐</td>
- </tr>
- </tbody>
- </table>
- <ul>
- <li>Email makes it easy to share information with a person or a group
- from the get-go, but quite difficult to loop people into an ongoing
- discussion after the fact. Finding information later is just as hard
- as with chat, and it’s marginally better at contextualizing
- information than chat (because you get proper threading).</li>
- </ul>
- <table class="table-hover table table-striped">
- <thead>
- <tr>
- <th></th>
- <th align="center">Share</th>
- <th align="center">Find</th>
- <th>Contextualise</th>
- </tr>
- </thead>
- <tbody>
- <tr>
- <td>Chat</td>
- <td align="center">🙂</td>
- <td align="center">😐</td>
- <td>🙁</td>
- </tr>
- <tr>
- <td>Email</td>
- <td align="center">😐</td>
- <td align="center">😐</td>
- <td>😐</td>
- </tr>
- <tr>
- <td>Wiki</td>
- <td align="center">🙂</td>
- <td align="center">🙂</td>
- <td>🙂</td>
- </tr>
- <tr>
- <td>Issue tracker</td>
- <td align="center">🙂</td>
- <td align="center">🙂</td>
- <td>🙂</td>
- </tr>
- </tbody>
- </table>
- <ul>
- <li>A wiki and an issue tracker (provided you don’t lock them down with
- silly view permissions), in contrast, both make it <em>very</em> easy to
- share, find, <strong>and</strong> contextualise information.<br>
- Note that “wiki”, in this context, is shorthand for any facility
- that allows you to collaboratively edit long-form documents
- online. That can be an actual wiki like a MediaWiki, but also
- something like Confluence, or even shared Google Docs.<br>
- Likewise, “issue tracker” can mean RT, OTRS, Jira, Taiga, Bugzilla,
- whatever works for you.</li>
- </ul>
- <table class="table-hover table table-striped">
- <thead>
- <tr>
- <th></th>
- <th align="center">Share</th>
- <th align="center">Find</th>
- <th>Contextualise</th>
- </tr>
- </thead>
- <tbody>
- <tr>
- <td>Chat</td>
- <td align="center">🙂</td>
- <td align="center">😐</td>
- <td>🙁</td>
- </tr>
- <tr>
- <td>Email</td>
- <td align="center">😐</td>
- <td align="center">😐</td>
- <td>😐</td>
- </tr>
- <tr>
- <td>Wiki</td>
- <td align="center">🙂</td>
- <td align="center">🙂</td>
- <td>🙂</td>
- </tr>
- <tr>
- <td>Issue tracker</td>
- <td align="center">🙂</td>
- <td align="center">🙂</td>
- <td>🙂</td>
- </tr>
- <tr>
- <td>Video call</td>
- <td align="center">😐</td>
- <td align="center">🙁</td>
- <td>🙁</td>
- </tr>
- </tbody>
- </table>
- <ul>
- <li>Video calls are even worse than chat or email, because sharing
- information works but doesn’t scale — you can’t reasonably have more
- than 5-or-so people in a video call, and sharing the recording of a
- full video call is just pointless.</li>
- </ul>
- <p>So really, make your wiki and your issue tracker your default mode of
- communications, and use the others sparingly. (This isn’t meant to be
- a euphemism for “don’t use them”, as we’ll get to in a moment.)</p>
- <h2>Text chat</h2>
- <p>So. Let’s talk about text chat. These days, that frequently means
- <a href="https://slack.com/">Slack</a>, but what I am talking about also and
- equally applies to
- <a href="https://en.wikipedia.org/wiki/Internet_Relay_Chat">IRC</a>,
- <a href="https://mattermost.com/">Mattermost</a>, <a href="https://riot.im/">Riot</a>, and
- anything similar.</p>
- <p>Is text chat universally useful? No. Is it universally bad? Not that,
- either. There is a very specific type of situation in which text chat
- is a good thing:</p>
- <blockquote>
- <p>Use <strong>chat</strong> for collaboration that requires <strong>immediate,
- interactive mutual feedback.</strong></p>
- </blockquote>
- <p>Using interactive chat is a good idea for the kind of communication
- that requires immediate, interactive mutual feedback from two or more
- participants. If that is not the case, chat is not a good idea.</p>
- <p>This means that the only thing that chat is good for is communication
- that is required to be <em>synchronous,</em> and remember, in a distributed
- team <em>asychronicity</em> is the norm. So using interactive chat for
- communications needs to be an <em>exceptional</em> event for a distributed
- team; if it is instead a regular occurrence you’ll make everyone on
- the team miserable.</p>
- <p>For any interaction that does <em>not</em> require feedback that is <em>both</em>
- immediate and interactive, email, a wiki, or an issue tracker are <em>far
- superior</em> modes of communication.</p>
- <blockquote>
- <p>The only reason to use <strong>DMs</strong> for collaboration<br>
- is a need for immediate, interactive mutual feedback<br>
- <strong>and confidentiality.</strong></p>
- </blockquote>
- <p>Using chat direct messages (DMs) as the <em>default</em> means of
- communication is utterly braindead. In order for a chat DM to be
- useful, there is precisely one clearly delineated confluence of events
- that must occur:</p>
- <ul>
- <li>You need immediate feedback from the other person,</li>
- <li>you need mutual back-and-forth with the other person,</li>
- <li>you don’t want others to follow the conversation.</li>
- </ul>
- <p>I can’t emphasize enough that this combination is perfectly valid —
- but it is <em>exceedingly rare.</em> If you want just a private exchange of
- ideas with someone, encrypted email will do. If you want to work on
- something together with one person before you share it with others,
- restricted view permissions on a wiki page or an issue tracker ticket
- will work just fine.</p>
- <p>If you don’t need confidentiality but you do need interactive and
- immediate feedback, chances are that you’re working on something
- urgent, and it is far more likely you’ll eventually need to poll other
- opinions, than that you won’t. So just use a shared channel from the
- get-go, that way it’s easier for others to follow the conversation if
- needed — and they might be able to point out an incorrect assumption
- that one of you has, before you end up chasing a red herring.</p>
- <blockquote>
- <p>A chat ping is a shoulder tap.</p>
- </blockquote>
- <p>“Pinging” someone in a chat (that is, mentioning their username, which
- usually triggers a visual or auditory notification), is exactly like
- walking up to a person, interrupting what they are doing, tapping them
- on the shoulder, and asking them a question.</p>
- <p><strong>No matter whether it is your intention or not,</strong> they will feel
- compelled to answer, relatively promptly (the only exception is when
- you’ve done this so often that you have conditioned your colleagues
- to ignore you — congratulations).</p>
- <p>This means that you’ve broken their train of thought, yanked them out
- of a potentially complex task, forced them to redo what they did
- pre-interruption, or actually have them commit a mistake.</p>
- <p>So pinging someone in a chat is something you should only do if you
- are aware of exactly this risk, <em>and</em> you are convinced that whatever
- you’re pinging about is more important. Otherwise, to be very blunt,
- you’ll be seen as the asshole.</p>
- <blockquote>
- <p>Want people to hate you? Send naked pings.</p>
- </blockquote>
- <p>A “naked ping” is the action of sending someone a message consisting
- only of their username and a marker like “ping”, “hi”, “hey” or
- similar.</p>
- <div class="highlight"><pre><span></span><code><span class="mi">14</span><span class="o">:</span><span class="mi">00</span><span class="o">:</span><span class="mi">02</span><span class="n">Z</span> <span class="n">johndoe</span><span class="o">:</span> <span class="n">florian</span><span class="o">:</span> <span class="n">ping</span>
- <span class="o">[...]</span>
- <span class="mi">15</span><span class="o">:</span><span class="mi">56</span><span class="o">:</span><span class="mi">17</span><span class="n">Z</span> <span class="n">florian</span><span class="o">:</span> <span class="n">johndoe</span><span class="o">:</span> <span class="n">I</span> <span class="n">hate</span> <span class="n">you</span>
- </code></pre></div>
- <p>Don’t. Just don’t.</p>
- <p>Any person who is versed in the use of chat communications will, when
- subjected to this behavior, be inclined to flay you alive. Infinitely
- more so if it’s a DM. <strong>Do not do this.</strong></p>
- <p>Instead, always provide context. Always always always. Don’t say “can
- I ask you a question, instead, <em>ask the question.</em> If something isn’t
- urgent, say something like “no urgency.”</p>
- <div class="highlight"><pre><span></span><code><span class="mi">14</span><span class="o">:</span><span class="mi">00</span><span class="o">:</span><span class="mi">02</span><span class="n">Z</span> <span class="n">johndoe</span><span class="o">:</span> <span class="n">florian</span><span class="o">:</span> <span class="n">can</span> <span class="n">I</span> <span class="kd">get</span> <span class="n">your</span> <span class="n">eyes</span> <span class="n">on</span> <span class="n">PR</span> <span class="err">#</span><span class="mi">1422</span><span class="o">?</span>
- <span class="o">[...]</span>
- <span class="mi">15</span><span class="o">:</span><span class="mi">56</span><span class="o">:</span><span class="mi">17</span><span class="n">Z</span> <span class="n">florian</span><span class="o">:</span> <span class="n">johndoe</span><span class="o">:</span> <span class="n">done</span><span class="o">!</span>
- <span class="o">(</span><span class="n">was</span> <span class="n">afk</span> <span class="k">for</span> <span class="n">a</span> <span class="n">bit</span> <span class="err">–</span> <span class="n">sick</span> <span class="n">kiddo</span><span class="o">)</span>
- <span class="mi">15</span><span class="o">:</span><span class="mi">56</span><span class="o">:</span><span class="mi">58</span><span class="n">Z</span> <span class="n">johndoe</span><span class="o">:</span> <span class="n">florian</span><span class="o">:</span> <span class="n">np</span><span class="o">,</span> <span class="n">ty</span>
- </code></pre></div>
- <p>It should be self-evident why this is better than naked pings, but if
- to you it is not, then please read <a href="https://blogs.gnome.org/markmc/2014/02/20/naked-pings/">Naked
- Pings</a>,
- courtesy of Adam Jackson and Mark McLoughlin.</p>
- <h2>Video calls</h2>
- <p>(Zoom, Hangouts, BlueJeans etc.)</p>
- <p>Next, I’d like to talk about video calls. Doesn’t matter what
- technology you’re using. Could be Zoom, Google Hangouts, BlueJeans,
- Jitsi, whatever.</p>
- <p>And I’d like to address this specifically, given the fact that in the
- current pandemic the use of video calls appears to have skyrocketed.</p>
- <p>There’s a very good reason to use video calls: they give you the
- ability to pick up on nontextual and nonverbal cues from the call
- participants. But that’s really the only good reason to use them.</p>
- <p>Video calls have a significant drawback: until we get reliable
- automatic speech recognition and transcription, they are only
- half-on-the-record. Hardly anyone goes to the trouble of preparing a
- full transcript of a meeting, and if anything, we get perhaps a
- summary of points discussed and action items agreed to. So even if we
- keep recordings of every video call we attend, it’s practically
- impossible to discern, after the fact, what was discussed in a meeting
- <em>before</em> decisions were made.</p>
- <p>It is also practically impossible to <em>find</em> a discussion point that
- you only have a vague recollection of when it was discussed in a video
- call, whereas doing so has a much greater probability of success if
- a discussion took place on any archived text-based medium.</p>
- <blockquote>
- <p>Every video call needs an agenda.</p>
- </blockquote>
- <p>This is, of course, true for any meeting, not just those conducted by
- video call.</p>
- <p>A conversation without an agenda is useless. You want people to know
- what to expect of the call. You also want to give people the option to
- prepare for the call, such as doing some research or pulling together
- some documentation. If you fail to circulate those <em>ahead of time,</em> I
- can guarantee that the call will be ineffective, and will likely
- result in a repeat performance.</p>
- <blockquote>
- <p>Until machines get intelligent enough to automatically transcribe
- and summarise words spoken in a meeting, <strong>write notes and a summary
- of every meeting you attend,</strong> and <strong>circulate them.</strong></p>
- </blockquote>
- <p>Just as important as an agenda to set the <em>purpose</em> of the meeting, is
- a set of notes that describes its <em>outcome</em>. </p>
- <p>Effective distributed teams understand that the <em>record</em> of a call is
- what counts, not the call itself. It is not the spoken word that
- matters, but the written one.</p>
- <p>From that follows this consequence:</p>
- <blockquote>
- <p>To be useful, the write-up of a call <strong>takes more time and effort</strong>
- than the call itself.</p>
- </blockquote>
- <p>If you think that video calls are any less work than chat meetings or
- a shared document that’s being edited together or dicussed in
- comments, think again. The only way a video call is less work, is when
- everyone’s lazy and the call is, therefore, useless. Every meeting
- needs notes and a summary, and you need to circulate these notes not
- only with everyone who attended the meeting, but with everyone who has
- a need-to-know.</p>
- <p>Here’s the standard outline I use for meeting notes:</p>
- <ol>
- <li>Meeting title</li>
- <li>Date, time, attendees</li>
- <li>Summary</li>
- <li>Discussion points (tabular)</li>
- <li>Action items</li>
- </ol>
- <p>Putting an executive summary at the very top is extraordinarily
- helpful so people can decide if they</p>
- <ul>
- <li>should familiarise themselves with what was discussed, immediately,
- and possibly respond if they have objections, or</li>
- <li>only want to be aware of what was decided, or</li>
- <li>just keep in the back of their head that a meeting happened, that
- notes exist, and where they can find them when they need to refer
- back to them.</li>
- </ul>
- <blockquote>
- <p>Once you do meetings right, you no longer need most of them.</p>
- </blockquote>
- <p>The funny thing is that once you adhere to this standard — and I
- repeat, having a full and detailed record is <em>the only acceptable
- standard</em> for video meetings – you’ll note that you can actually skip
- the meeting altogether, use <em>just</em> a collaboratively edited document
- <em>instead</em> of your meeting notes, and remove your unnecessary
- synchronization point.</p>
- <h3>Video calls for recurring team meetings</h3>
- <p>There is one thing that I do believe video calls are good for, and
- that is to use them for <em>recurring</em> meetings as as an
- opportunity to feel the pulse of your team.</p>
- <p>Obviously, a distributed team has <em>few</em> recurring meetings, because
- they are synchronization points, and we’ve already discussed that we
- strive to minimize those. So the idea of having daily standups, sprint
- planning meetings, and sprint retrospectives is fundamentally
- incompatible with distributed teams. <em>Aside: in my humble opinion,
- this is also why using Scrum is a terrible idea in distributed teams —
- not to mention <a href="https://youtu.be/f-ULT_Ic4qk">that it’s a terrible idea,
- period.</a></em></p>
- <p>However, having perhaps one meeting per week (or maybe even one every
- two weeks) in a video call is useful <em>precisely for the aforementioned
- reasons</em> of being able to pick up on nonverbal clues like body
- language, posture, facial expressions, and tone. If people are
- stressed out or unhappy, it’ll show. If they are relaxed and
- productive, that will show too.</p>
- <p>Note that these meetings, which of course do follow the same rules
- about agenda and notes, are not strictly <em>necessary</em> to get the work
- done. The team I run has one one-hour meeting a week, but whenever
- that meeting conflicts with anything we skip it and divide up our
- work via just the circulated coordination notes, and that works
- too. The meeting really serves the purpose of syncing emotionally, and
- picking up on nonverbal communications.</p>
- <h2>Briefing people</h2>
- <p>Whenever you need to thoroughly <strong>brief a group of people on an
- important matter,</strong> consider using a <strong>5-paragraph format.</strong></p>
- <ol>
- <li>Situation</li>
- <li>Mission</li>
- <li>Execution</li>
- <li>Logistics</li>
- <li>Command and Signal</li>
- </ol>
- <p>This is a format as it is being used by many armed forces; in NATO
- parlance it’s called the 5-paragraph field order. Now I’m generally
- not a fan of applying military thinking to civilian life — after all
- we shouldn’t forget that the military is an institution that kills
- people and breaks things, and I say that as a commissioned officer in
- my own country’s army —, but in this case it’s actually something that
- can very much be applied to professional communications, with some
- rather minor modifications:</p>
- <ol>
- <li>Situation</li>
- <li>Objective</li>
- <li>Plan</li>
- <li>Logistics</li>
- <li>Communications</li>
- </ol>
- <p>Let’s break these down in a little detail:</p>
- <ol>
- <li>Situation is about what position we’re in, and <strong>why</strong> we set out
- to do what we want to do. You can break this down into three
- sub-points, like the customer’s situation, the situation of your
- own company, any extra help that is available, and the current
- market.</li>
- <li>Objective is <strong>what</strong> we want to achieve.</li>
- <li>Plan is <strong>how</strong> we want to achieve it.</li>
- <li>Logistics is about what budget and resources are available, and how
- they are used.</li>
- <li>Communications is about how you’ll be coordinating among yourselves
- and with others in order to achieve your goal.</li>
- </ol>
- <p>Note that people <em>always</em> have questions on what they’ve just been
- briefed about. They just might not think of them straight away. Give
- people time to think through what you’ve just briefed them on, and
- they will think of good questions. So always have a follow-up round at
- a later time (2 hours later, the following day, whatever), for which
- you <em>encourage</em> your group to come back with questions.</p>
- <p>Also, use that same follow-up for checking how your briefing came
- across, by gently quizzing people with questions like</p>
- <ul>
- <li>“by what date do we want to implement X?”, or</li>
- <li>“Joe, what things will you need to coordinate with Jane on?”</li>
- </ul>
- <p>This gives you valuable feedback on the quality of your briefing: if
- your team can’t answer these questions, chances are that you weren’t
- as clear as you should have been.</p>
- <h2>Pinching the firehose</h2>
- <p>Finally, I want to say a few words about what I like to call pinching
- the figurative firehose you might otherwise be forced to drink from:</p>
- <blockquote>
- <p>The amount of incoming information in a distributed team can be
- daunting.</p>
- </blockquote>
- <p>When you work in a distributed team, since everyone is on their own
- schedule and everything is asynchronous, you may be dealing with a
- constant incoming stream of information — from your colleagues, your
- reports, your manager, your customers. </p>
- <p>There is no way to change this, so what you need to do is apply your
- own structure to that stream. What follows is not <strong>the</strong> way to do
- that, but <em>one</em> way, and you may find another works better for
- you. But you will need to define and apply <em>some</em> structure, otherwise
- you’ll feel constantly overwhelmed and run the risk of burning out.</p>
- <blockquote>
- <p>Consider using the <strong>“4-D” approach</strong> when dealing with incoming
- information.</p>
- </blockquote>
- <p>(Hat tip to David Allen)</p>
- <p>There’s a defined approach for doing this, which I learned about from
- reading <a href="https://en.wikipedia.org/wiki/David_Allen_(author)">David
- Allen</a>’s <a href="https://www.goodreads.com/book/show/1633.Getting_Things_Done">Getting
- Things
- Done</a>. I
- don’t know if Allen invented the 4-D approach or whether someone came
- up with it before him, but that’s how I know about it.</p>
- <p>In his book, David Allen suggests to apply one of the following four
- actions to any incoming bit of information:</p>
- <ul>
- <li><strong>Drop</strong> means read, understand, and then archive. It’s what you use
- for anything that doesn’t require any action on your part.</li>
- <li><strong>Delegate</strong> is for things that do require action, but not from
- you. Make sure that it gets to the right person and is understood by
- <em>them</em>, and make a note for follow-up.</li>
- <li><strong>Defer</strong> means it needs doing, and it’s you who needs to do it, but
- it doesn’t need doing <em>immediately</em>. Enter it into your task list
- (to use a very generic term, more on this in a bit), and clear it
- from your inbox.</li>
- <li><strong>Do</strong> are the (typically very few) things that remain that need to
- be done <em>by you, and immediately.</em></li>
- </ul>
- <p>Following this approach does not mean that you’ll never be overwhelmed
- by the amount of information that you need to process. But it’ll
- greatly reduce that risk.</p>
- <h3>“Drop” rules</h3>
- <p>“Dropping” things doesn’t mean ignoring them. You still have to read
- and understand what’s in them, and be able to find them later. So:</p>
- <ul>
- <li>
- <p>Never delete things (except spam).</p>
- </li>
- <li>
- <p>Only archive them in a way that that keeps them retrievable in the
- future.</p>
- </li>
- <li>
- <p>If there something isn’t understandable to you, think it through and
- look for clarification.</p>
- </li>
- </ul>
- <h3>“Delegate” rules</h3>
- <p>Delegation obviously requires that there is a person you can delegate
- to. This is <em>not necessarily</em> someone who reports to you; indeed, it
- might be someone <strong>you</strong> report to. (You might be asked to deal with
- something that you have no control over, but your manager does.) So:</p>
- <ul>
- <li>
- <p>Find the right person that can get the task done.</p>
- </li>
- <li>
- <p>Preemptively send them <strong>all</strong> the information that you think they
- might need (and that you have access to), rather than relying on
- them to ask.</p>
- </li>
- <li>
- <p>Ask them to acknowledge that they have received what they need.</p>
- </li>
- <li>
- <p>Make a note to follow up to see if they need anything else, and
- follow through by seeing the task to completion.</p>
- </li>
- </ul>
- <p>Within your own team, <strong>you only ever delegate tasks, not
- responsibility.</strong></p>
- <blockquote>
- <p>Tasks without follow-up and follow-through are a waste of people’s
- time.</p>
- </blockquote>
- <p>Do not delegate, or even define, tasks that you are not prepared to
- follow through on. If you handwave “everyone use encrypted email from
- now on,” and you’re not even prepared to make that work for your own
- email account, you might as well just leave it.</p>
- <p>And if you do proclaim an objective or rule and <em>then</em> you find yourself
- unable to see it through — <em>this happens,</em> and is no sign of
- ineptitude or failure — then loudly and clearly rescind it. It’s far
- better for you to visibly backtrack, than to be perceived as someone
- whose pronouncements are safe to ignore.</p>
- <h3>“Defer” rules</h3>
- <p>Deferring simply means that because something you need to do doesn’t
- need doing <em>immediately,</em> you can do it at a time that suits your
- schedule.</p>
- <p>This means that you’ll need to</p>
- <ul>
- <li>
- <p>add the task immediately to some sort of queue (for email, this can
- be a folder named “Needs Reply”),</p>
- </li>
- <li>
- <p>make sure to go through that queue at a later time to prioritize
- (ideally, right after you’re done with your “Do” tasks, which we’ll
- get to in a second),</p>
- </li>
- <li>
- <p>absolutely ensure that you make time to go back and actually do your
- prioritized tasks, at a time you consider convenient.</p>
- </li>
- </ul>
- <h3>“Do” rules</h3>
- <p>And finally, there’ll be your “Do” tasks — stuff that <em>you</em> need to
- do, and do immediately.</p>
- <ul>
- <li>
- <p>Tell people that you’re doing them, because you’ll want to be
- uninterrupted. Update your chat status, put some blocked time in
- your calendar.</p>
- </li>
- <li>
- <p>Make sure you’ll be uninterrupted. For email, turn off all your
- notifications.</p>
- </li>
- <li>
- <p>Plow through all the undropped, undelegated,
- undeferred items in your inbox until it’s empty.</p>
- </li>
- </ul>
- <h2>But what about the watercooler?</h2>
- <p>The entirety of this talk, up to this point, has focused on
- professional communications. And among people unfamiliar or
- unexperienced with work in a distributed team, it is often accepted
- that teams can communicate well “professionally.” </p>
- <p>However, they frequently ask, “what about watercooler chats? What about
- the many informal discussions that happen at work while people are
- getting some water or coffee, or sit together over lunch? There’s
- always so much communication happening at work that’s informal, but is
- extremely beneficial to everyone.”</p>
- <blockquote>
- <p>Office workers often don’t habitually externalise information. A
- distributed team that tries that won’t last a week.</p>
- </blockquote>
- <p>Firstly, many companies where information exchange hinges on coffee or
- cafeteria talk simply don’t give a damn about externalising
- information. Sure, if 90% of your company’s knowledge is only in
- people’s heads, you’re dead without the lunchroom. </p>
- <p>But if the same thing happens in a distributed team, it never gets off
- the ground. So, if you have a team that’s functional and productive,
- <em>because it habitually externalises information,</em> the absence of
- chit-chat over coffee has zero negative impact on information flow.</p>
- <p>However, you may also be interested in the completely non-work-related
- talk that happens over coffee, that simply contributes to people’s
- relaxation and well-being.</p>
- <blockquote>
- <p>People working in distributed teams are often introverts. Or they
- simply choose to have their social relationships outside of work.</p>
- </blockquote>
- <p>I know this might shock some people, but there are plenty of people
- who can make a terrific contribution to your company, but who dislike
- the “social” aspect of work. They might thrive when being left
- alone, with as little small-talk as possible, and ample opportunity to
- socialize with their friends and family, away from work.</p>
- <p>But if you do have people on your team that enjoy having an entirely
- informal conversation every once in a while, there totally is room for
- that even in a distributed team. All you need to do is agree on a
- signal that means “I’m taking a break and I’d be happy to chat with
- anyone who’s inclined, preferably about non work related things” (or
- whatever meaning your group agrees on). </p>
- <p>This could be</p>
- <ul>
- <li>a keyword on IRC,</li>
- <li>a message to a specific channel, or</li>
- <li>(if you want to get fancy) a bot that updates your group calendar
- when it receives a message with a particular format.</li>
- </ul>
- <p>However, as a word of caution, I’ve actually done this with my team
- before, and it didn’t catch on — for the simple reason that we almost
- never took breaks that happened to overlap. But that doesn’t rule out
- that it works on <em>your</em> team, and also there’s always the remote
- possibility that two or more people on your team might like to
- schedule their breaks concurrently.</p>
- <p>What you can <em>also</em> do, of course, is have a channel in which you can
- discuss completely random things that are not work related. And if the
- rule is that confidential or company-proprietary discussion topics are
- off-limits there, the channel might as well be public. It might even
- be Twitter.</p>
- <h2>The antithesis: ChatOps</h2>
- <p>I do want to mention one other thing for balance. There is a complete
- alternative framework for distributed teams working together, and it’s
- what people refer to as ChatOps.</p>
- <p>To the best of my knowledge, the first company to run ChatOps on a
- large scale <em>and talk about it publicly</em> was GitHub, <a href="https://youtu.be/NST3u-GjjFw">back in
- 2013</a> in a
- <a href="https://www.rubyfuza.org/">RubyFuza</a> talk by <a href="https://twitter.com/jnewland">Jesse
- Newland</a>.</p>
- <p>If a distributed team operates on a ChatOps basis, the interactive
- text chat is where absolutely everything happens. </p>
- <ul>
- <li>
- <p>Everyone lives in chat all the time, and all issues, alerts and events are
- piped into the chat.<br>
- Everything is discussed in the chat, and everything is also
- <em>resolved</em> in the chat.</p>
- </li>
- <li>
- <p>Such a system relies on heavy use of chat bots. For example, if an
- alert lands in the channel, and the discussion then yields that the
- proper fix to the problem is to run a specific Ansible playbook,
- you send an in-chat bot command that kicks off that playbook, and
- then reports its result.</p>
- </li>
- </ul>
- <p>And this is of course very laudable, because it resolves a major issue
- with using chat, which is the classic scenario of something being
- discussed in a chat, someone else then going away for a bit and then
- coming back saying “I fixed it!”, and nobody else actually
- understanding what the problem was. </p>
- <p>If you make everything explicit and in-band, in becomes easy, in
- principle, to go back to a previously-solved problem that reappears,
- and replay the resolution.</p>
- <blockquote>
- <p>When does ChatOps make sense? Here’s a hint: It’s called Chat<strong>Ops</strong>.</p>
- </blockquote>
- <p>So can this make sense? Yes, absolutely. Under what circumstances
- though? I maintain that this is best suited for when your work tends
- to be inherently linear with respect to some dimension. For example,
- if your primary job is to keep a system operational versus the linear
- passage of <em>time,</em> ChatOps is an excellent approach.</p>
- <p>And keeping complex systems operational over time is the definition
- of, you guessed it, ops. So ChatOps may be a very suitable
- communication mode for operations, but it’s highly unlikely to be
- efficient as a generic mode of communication across distributed teams.</p>
- <p>And even then I posit it’s difficult to get right, since you’ll have
- to curb channel sprawl and threading and other things, but’s that’s a
- whole ‘nother talk and indeed a talk for another <em>speaker,</em> because I
- don’t lead an ops team.</p>
- <h2>To summarize...</h2>
- <p>So to summarize, here are my key points from this talk, in a nutshell
- — please make these your key takeaways.</p>
- <ul>
- <li>Distributed teams are better than localized teams — not because
- they’re distributed, but because they’re asynchronous.</li>
- <li>Avoid anything that makes a distributed team run synchronously.</li>
- <li>Use less chat.</li>
- <li>Have fewer meetings.</li>
- <li><strong>Write. Things. Down.</strong></li>
- </ul>
- </article>
-
-
- <hr>
-
- <footer>
- <p>
- <a href="/david/" title="Aller à l’accueil"><svg class="icon icon-home">
- <use xlink:href="/static/david/icons2/symbol-defs-2021-12.svg#icon-home"></use>
- </svg> Accueil</a> •
- <a href="/david/log/" title="Accès au flux RSS"><svg class="icon icon-rss2">
- <use xlink:href="/static/david/icons2/symbol-defs-2021-12.svg#icon-rss2"></use>
- </svg> Suivre</a> •
- <a href="http://larlet.com" title="Go to my English profile" data-instant><svg class="icon icon-user-tie">
- <use xlink:href="/static/david/icons2/symbol-defs-2021-12.svg#icon-user-tie"></use>
- </svg> Pro</a> •
- <a href="mailto:david%40larlet.fr" title="Envoyer un courriel"><svg class="icon icon-mail">
- <use xlink:href="/static/david/icons2/symbol-defs-2021-12.svg#icon-mail"></use>
- </svg> Email</a> •
- <abbr class="nowrap" title="Hébergeur : Alwaysdata, 62 rue Tiquetonne 75002 Paris, +33184162340"><svg class="icon icon-hammer2">
- <use xlink:href="/static/david/icons2/symbol-defs-2021-12.svg#icon-hammer2"></use>
- </svg> Légal</abbr>
- </p>
- <template id="theme-selector">
- <form>
- <fieldset>
- <legend><svg class="icon icon-brightness-contrast">
- <use xlink:href="/static/david/icons2/symbol-defs-2021-12.svg#icon-brightness-contrast"></use>
- </svg> Thème</legend>
- <label>
- <input type="radio" value="auto" name="chosen-color-scheme" checked> Auto
- </label>
- <label>
- <input type="radio" value="dark" name="chosen-color-scheme"> Foncé
- </label>
- <label>
- <input type="radio" value="light" name="chosen-color-scheme"> Clair
- </label>
- </fieldset>
- </form>
- </template>
- </footer>
- <script src="/static/david/js/instantpage-5.1.0.min.js" type="module"></script>
- <script>
- function loadThemeForm(templateName) {
- const themeSelectorTemplate = document.querySelector(templateName)
- const form = themeSelectorTemplate.content.firstElementChild
- themeSelectorTemplate.replaceWith(form)
-
- form.addEventListener('change', (e) => {
- const chosenColorScheme = e.target.value
- localStorage.setItem('theme', chosenColorScheme)
- toggleTheme(chosenColorScheme)
- })
-
- const selectedTheme = localStorage.getItem('theme')
- if (selectedTheme && selectedTheme !== 'undefined') {
- form.querySelector(`[value="${selectedTheme}"]`).checked = true
- }
- }
-
- const prefersColorSchemeDark = '(prefers-color-scheme: dark)'
- window.addEventListener('load', () => {
- let hasDarkRules = false
- for (const styleSheet of Array.from(document.styleSheets)) {
- let mediaRules = []
- for (const cssRule of styleSheet.cssRules) {
- if (cssRule.type !== CSSRule.MEDIA_RULE) {
- continue
- }
- // WARNING: Safari does not have/supports `conditionText`.
- if (cssRule.conditionText) {
- if (cssRule.conditionText !== prefersColorSchemeDark) {
- continue
- }
- } else {
- if (cssRule.cssText.startsWith(prefersColorSchemeDark)) {
- continue
- }
- }
- mediaRules = mediaRules.concat(Array.from(cssRule.cssRules))
- }
-
- // WARNING: do not try to insert a Rule to a styleSheet you are
- // currently iterating on, otherwise the browser will be stuck
- // in a infinite loop…
- for (const mediaRule of mediaRules) {
- styleSheet.insertRule(mediaRule.cssText)
- hasDarkRules = true
- }
- }
- if (hasDarkRules) {
- loadThemeForm('#theme-selector')
- }
- })
- </script>
- </body>
- </html>
|