Word Labels

Working at NoRedInk, I have the opportunity to work on such a variety of challenges and puzzles! It’s a pleasure to figure out how to build ambitious and highly custom components and applications.

Recently, I built a component that will primarily be used for labeling sentences with parts of speech.

This component was supposed to show “labels” over words while guaranteeing that the labels wouldn’t cover meaningful content (including other labels). This required labels to be programmatically and dynamically repositioned to keep content readable:

Screenshot of the sentence "Dave broke his french fry so he glued it with ketchup." "Dave" and "he" have pink balloons labelling each as a "subject". "Broke" and "glued" have yellow balloons labelling each as a "verb". The "subject" labels are offset above the "verb" labels so that no content is obscured.

It takes some CSS and some measuring of rendered content to avoid overlaps:

Screenshot of the sentence "Dave broke his french fry so he glued it with ketchup." "Dave" and "he" have pink balloons labelling each as a "subject". "Broke" and "glued" have yellow balloons labelling each as a "verb". The "verb" labels partially overlap the "subject" balloons, especially the "subject" balloon over "he".

All meaningful content needs to be accessible to users, so it’s vital that content not be obscured.

In this post, I’m going to go through a simplified version of the Elm, CSS, and HTML I used to accomplish this goal. I’m going to focus primarily on the positioning styles, since they’re particularly tricky!

Custom Focus Rings

Many people who operate their devices with a keyboard need a visual indicator of keyboard focus. Without a visual indicator of which element has focus, it’s hard to know what, say, hitting enter might do. Anything might happen!

It’s reasonable to think that either the browser or the operating system should be in charge of making sure keyboard focus is perceivable to keyboard users. You might think that it’s best for devs not to overwrite focus styles at all. However, if your website is customizing the look of inputs, there’s a good chance that the default focus ring won’t actually be visible to your users.

This is the situation we found ourselves in at NoRedInk, and what follows is what we did to improve things.

Presenting Styleguide Colors

The Web Content Accessibility Guidelines (WCAG) include guidelines around how to use colors that contrast against each other so that more people can distinguish them. Color is a fuzzy topic (brains, eyes, displays, and light conditions are all complicating factors!) so it’s a good idea to rely on industry-wide standards, like WCAG. The current version of the WCAG standards define algorithms for calculating luminance & contrast and set target minimum contrasts depending on the context in which the colors are used.

These algorithms should be used for their primary purpose – ensuring that content is accessible and conforms to WCAG – but they can also be used for other purposes, like making colors in a styleguide presentable.

Funding the Roc Programming Language

At NoRedInk, we’re no strangers to cutting-edge technology or to funding open-source software. When React was released in the summer of 2013, we were early adopters. Shortly after that, we got into Elmreally into it—and we began not only sponsoring Elm conferences, but also funding Elm’s development for several years by directly paying its creator, Evan Czaplicki, to develop the language full-time.

I’m beyond thrilled to announce that NoRedInk is now making a similar investment in the Roc programming language. Beginning in April, my job at NoRedInk will become developing Roc full-time!

Haskell for the Elm Enthusiast

Many years ago NRI adopted Elm as a frontend language. We started small with a disposable proof of concept, and as the engineering team increasingly was bought into Elm being a much better developer experience than JavaScript more and more of our frontend development happened in Elm. Today almost all of our frontend is written in Elm.

Meanwhile, on the backend, we use Ruby on Rails. Rails has served us well and has supported amazing growth of our website, both in terms of the features it supports, and the number of students and teachers who use it. But we’ve come to miss some of the tools that make us so productive in Elm: Tools like custom types for modeling data, or the type checker and its helpful error messages, or the ease of writing (fast) tests.

A couple of years ago we started looking into Haskell as an alternative backend language that could bring to our backend some of the benefits we experience writing Elm in the frontend. Today some key parts of our backend code are written in Haskell. Over the years we’ve developed our style of writing Haskell, which can be described as very Elm-like (it’s also still changing!).

🌉 Bridging a typed and an untyped world

Even if you work in the orderly, bug-free, spic-and-span, statically-typed worlds of Elm and Haskell (like we do at NoRedInk, did you know we’re hiring?), you still have to talk to the wild free-wheeling dynamically-typed world sometimes. Most recently: we were trying to bridge the gap between Haskell (🧐) and Redis(🤪). Here we’ll discuss two iterations of our Redis library for Haskell, nri-redis.

All examples in this code are in Haskell and use a few functions from NoRedInk’s prelude nri-prelude. Specifically, we will use |> instead of &, Debug.toString instead of show and a few functions from Expect. Most of the example code could be real tests.

☄️ Pufferfish, please scale the site!

We created Team Pufferfish about a year ago with a specific goal: to avert the MySQL apocalypse! The MySQL apocalypse would occur when so many students would work on quizzes simultaneously that even the largest MySQL database AWS has on offer would not be able to cope with the load, bringing the site to a halt.

A little over a year ago, we forecasted our growth and load-tested MySQL to find out how much wiggle room we had. In the worst case (because we dislike apocalypses), or in the best case (because we like growing), we would have about a year’s time. This meant we needed to get going!

Looking back on our work now, the most important lesson we learned was the importance of timely and precise feedback at every step of the way. At times we built short-lived tooling and process to support a particular step forward. This made us so much faster in the long run.