What is an idempotent request?
A short story about idempotency
This is a nice paragraph
A Blue Button" data-copied="Copied!">#my-very-own-header { margin: 0; font-size: 36px; font-weight: 500; line-height: 1.1;}.paragraphs-on-app-screen-x { margin: 0 0 10px; font-size: 14px;}.my-blue-buttons { color: #fff; background-color: #337ab7; display: inline-block; margin-bottom: 0; font-weight: 400; text-align: center; vertical-align: middle; cursor: pointer; padding: 6px 12px; font-size: 14px; line-height: 1.42857143; border-radius: 4px;}
Suddenly I can reuse my styles across different elements and even sites and applications. I also get caching of the .css
files and lighter HTML. The main downside was that I had to come up with a bunch of different names for each element, and naming things is hard, especially considering this applies to the entire web page/app.
In 2011 Twitter released Bootstrap. We could all forget about our .css
files and just do this in HTML:
<h1>This is a nice heading.</h1><p>This is a nice paragraph.</p><a class="btn btn-default">A Blue Button</a>
And like magic a nice looking page, with sensible defaults appeared on screen. Everyone’s website looked the same, but who cares - No CSS, and No Naming Things!
Meanwhile we started to realise that CSS had some intrinsic limits, and we began using pre-processors like SCSS, Less & Sass to make CSS usable. This tied in nicely with the evolution of Javascript libraries requiring transpilation and a general standardization of having some kind of build process for web applications.
We eventually came up with ways to “import” our CSS into our Javascript world of React, Vue et al, in these pipelines, and if we’re building a Javascript SPA, we can now easily write CSS inside the JS application code, scoped locally to the current module we’re working on with all the goodies our pre-processors provided. There are some cool examples here and here.
But for me, it wasn’t quite right:
With TailwindCSS we can do things in HTML like:
<h1 class="text-2xl m-0 leading-loose">This is a nice heading.</h1><p class="mb-10">This is a nice paragraph.</p><a class="text-xl px-8 py-4 font-bold text-white bg-blue-500 shadow-lg rounded hover:underline">A Blue Button</a>
Which seems a LOT like where we were at at the start of my journey with inline CSS. Except it’s not- TailwindCSS out of the box supports a kind of curated, opinionated subset of CSS, and many of the classes available are common combinations of CSS rules that make more sense in the context of web design. We use these to compose our designs based on sensible defaults and pre-configured choices.
The result is a dramatic reduction in cognitive overhead required to style pages
For example, when I:
text-sm
and text-xl
, not an infinite font-size
scale, and even worse between em
and px
unitstext-blue-500
and change to text-blue-600
to darken or text-blue-400
to lighten. I don’t deal with Hex, RGB etc. that require switching context to another tool/conceptrounded-full
, I don’t need to remember that border-radius: 50%
is the magic CSS way to do thisThis means I now rarely name elements. I don’t have to build a semantic naming structure inside my CSS (which usually evolves into a site/brand specific framework anyway), and my HTML contains everything I need.
I can still extend the defaults with Tailwind, and if I have a specific component I am reusing (less common that you might think), I can use @apply
to extract styles, or use Template Partials / JS components to reuse my code. Together with all the pre-processing I have to do anyway, TailwindCSS slots into any modern web-app development workflow.
Using TailwindCSS means I can stay within my HTML code and get 90% design accuracy from the defaults, without having to name things or build a pseudo-mirror of my HTML in CSS (or vice versa). There’s no context switching, no need to try to remember the order of the margin
property or how to use box-shadow
.
I just code.
A short story about idempotency
An overview of the tech stack that powers MailPace!
A post mortem on a recent two hour outage for our API and Application
We saw some slow sending of a small subset of emails for about 16 hours, here's how we diagnosed and fixed the problem.