adiaz.uy (@HiroAgustin)

User Avatar

If your app has users, I bet they have avatars. Rounded avatars are pretty much a standard on any UI, so you might be inclined to code something like this:

User avatar placeholder

<img
  class="Avatar"
  src="https://placekitten.com/200/200"
  alt="User avatar"
>
.Avatar {
  height: 100px;
  border-radius: 50%;
  width: 100px;
}

Done, right? Push that commit, merge it to master, deploy it to prod, and go grab that well earned chocolate chip cookie.

What about non-square images?

Fuck.

User avatar placeholder User avatar placeholder

You could add one of those modals where the user edits their own avatar and store a cropped version of the image; I much rather use some CSS magic:

<picture class="Avatar">
  <img
    src="https://placekitten.com/200/200"
    alt="User avatar"
  >
</picture>
.Avatar {
  border-radius: 50%;
  height: 100px;
  overflow: hidden;
  width: 100px;
}

.Avatar > img {
  height: 100%;
  object-fit: cover;
  width: 100%;
}

User avatar placeholder User avatar placeholder User avatar placeholder

Using object-fit: cover on the img element makes it fit nicely inside its container, and we use overflow: hidden literally to cut corners. All achieved without the use of annoying modals or pesky JS. Now go get that cookie.

Bonus tip: use CSS Variables to create modifiers for the different types and sizes of avatars you’ll need:

.Avatar {
  --avatar-size: 100px;
  --avatar-radius: 50%;

  border-radius: var(--avatar-radius);
  height: var(--avatar-size);
  overflow: hidden;
  width: var(--avatar-size);
}

.Avatar--square { --avatar-radius: 8px; }
.Avatar--small { --avatar-size: 50px; }
.Avatar--large { --avatar-size: 150px; }

User avatar placeholder User avatar placeholder User avatar placeholder

Webpack

I was planning on writing a post on how to do a simple Webpack 4 setup, but while researching on how to actually do it, I found this amazing article by @riittagirl that does a much better job than I could ever do.

I created the repo simple-webpack-setup and made some tweaks based on my personal preferences.

Target Blank

Something I only recently came about was the vulnerability implications of target="_blank" links.

Pages opened this way have an access to the previous window context and are able to potentially inject malicious code.

The solution is simple, just add rel="noopener noreferrer" to those links and you should be good to go.

It might be worth asking if links should open in a new window at all.

Social Sharing

There’s a simple, clean, JavaScript-less way to add social sharing links to your site: both Twitter and Facebook provide url endpoints you can use without having to load their widgets.

The tradeoff being the loss of the nice on-screen pop-up windows…

Feel free to Tweet or Share this post.

Plectica

As of today I’m joining Plectica as their new Frontend Engineer! I’m really happy about this opportunity and eager to collaborate on making this awesome product even better.

Take-Home Assignments

Hot take: I love doing take home assignments when applying for a job.

Before you bite my head off let me start by saying that I understand people who don’t. This “challenges” usually take several hours to complete, which is not how anyone wants to spend their free time. They can also feel like unpaid labour if you are asked to, lets say, fix an issue on the company’s repo.

But as someone who has always worked on proprietary code and lacks a real portfolio, they provide me with the opportunity to show off my skills. I usually get to decide how much time and effort to spend based on how badly I want the job, and more often than not I end up learning some new technique or pattern I didn’t know about.

Pairing is a comparable interview method that I enjoy doing as well, but it has the added pressure of someone judging everything you say and do. When I first dive into an unfamiliar codebase I ask myself the dumbest questions and do a lot of poking around just to make sure I fully understand its behavior. I’m afraid this approach may be interpreted as a lack of basic knowledge on a short lived pairing session.

Take home assignments are not everyone’s cup of tea, but they are mine.

Pin

You can easily pin a list item to the top of the list using flexbox…

<ul class="List">
  <li class="List__Item">First</li>
  <li class="List__Item">Second</li>
  <li class="List__Item List__Item--Pinned">Pinned</li>
  <li class="List__Item">Last</li>
</ul>

…by setting the order of the pinned item to -1.

.List {
  display: flex;
  flex-direction: column;
}

.List__Item--Pinned {
  order: -1;
}

Beware of the accessibility implications this entails. The order will only change visually, not when navigating through keyboard.

Chips

’Twas an idle Sunday afternoon and I was looking for some images of Poker Chips to use on a brewing side project. After a quick search I couldn’t find any that quite fit my imaginary requirements, so as a way to procrastinate any actual work, I decided to make my own.

I found this neat tutorial and went over to SVG-Edit figuring it would be pretty straight forward. After fumbling with the editor for an hour I remembered my fondness to coding shapes, the chip is just a circle with stripes after all.

<!-- Chip -->
<circle fill="white" stroke="black" cx="100" cy="100" r="89" />
<!-- Large Stripe -->
<circle fill="none" stroke="navy" stroke-width="20" cx="100" cy="100" r="80" />
<!-- Small Stripe -->
<circle fill="none" stroke="navy" stroke-width="5" cx="100" cy="100" r="60" />

We can then use the stroke-dasharray attribute on the stripes to match the chip pattern. We want 6 painted sections and 6 white ones on the large stripe and twice as many for the small one. Given the formula to calculate the circumference (2πr) we know each section on the large stripe should be of length 42 (2π × 80 ÷ 12) and 15.7 (2π × 60 ÷ 24) for the small one. To manually tweak the alignment of the dashes we can set the stroke-dashoffset value on each stripe.

<!-- Large Stripe -->
<circle fill="none" stroke="navy" stroke-width="20" stroke-dasharray="42" stroke-dashoffset="20" cx="100" cy="100" r="80" />
<!-- Small Stripe -->
<circle fill="none" stroke="navy" stroke-width="5" stroke-dasharray="15.7" stroke-dashoffset="7" cx="100" cy="100" r="60" />

Finally, we want to be able to have multiple chips of different colors. To achieve it, we can leverage SVG’s symbol and use tags to allow for multiple copies of the same image without duplicating our code. Then using CSS variables we can set the body and stripe color for each chip.

<svg style="display: none;">
  <symbol id="Chip" viewBox="0 0 200 200">
    <!-- Chip -->
    <circle class="Chip__Body" cx="100" cy="100" r="89" />
    <!-- Large Stripe -->
    <circle class="Chip__Strip" stroke-width="20" stroke-dasharray="42" stroke-dashoffset="20" cx="100" cy="100" r="80" />
    <!-- Small Stripe -->
    <circle class="Chip__Strip" stroke-width="5" stroke-dasharray="15.7" stroke-dashoffset="7" cx="100" cy="100" r="60" />
  </symbol>
</svg>

<svg class="Chip Chip--White">
  <use xlink:href="#Chip" />
</svg>
<svg class="Chip Chip--Red">
  <use xlink:href="#Chip" />
</svg>
<svg class="Chip Chip--Green">
  <use xlink:href="#Chip" />
</svg>
<svg class="Chip Chip--Black">
  <use xlink:href="#Chip" />
</svg>
<svg class="Chip Chip--Blue">
  <use xlink:href="#Chip" />
</svg>

The reason why we need to use css variables is because of how use works. Basically we can’t just write .Chip--White .Chip__Body to set the color because that DOM structure doesn’t exist. But by setting the variables in the parent element the values are inherited.

.Chip {
  --strip-color: white;

  &__Body {
    fill: var(--chip-color);
    stroke: black;
  }

  &__Strip {
    fill: none;
    stroke: var(--strip-color);
  }

  &--White {
    --chip-color: white;
    --strip-color: navy;
  }

  &--Red { --chip-color: red; }
  &--Green { --chip-color: green; }
  &--Black { --chip-color: black; }
  &--Blue { --chip-color: blue; }
}

Checkout the Pen Chips to see the end result.

Hash

Continuing the interview questions thread, a while back I was presented with a fun take-home assignment:

Write JavaScript code to find a 9 letter string of characters that contains only letters from: ‘acdegilmnoprstuw’ such that hash(the_string) is 956446786872726.

function hash (alphabet, s) {
  let h = 7

  for (let i = 0; i < s.length; i++)
    h = h * 37 + alphabet.indexOf(s[i])

  return h
}

I needed to find a string that, given this hashing algorithm, would return a specific number. Therefore I had to build a decrypt method that would reverse the encryption so I could pass in the number and get the string.

Looking at the algorithm you can see the interval between each letter is composed of the previous number multiplied by 37 plus the index of the letter in the alphabet.

By decreasing helper until it was a multiple of 37 I was able to find that difference. Once I knew the index of the letter, I just prepended it to the resulting string.

All that remained to do then was to divide number by 37 and repeat until I hit the initial value of 7. And of course, turn the array into a string.

function decrypt(alphabet, number) {
  const result = []
  let helper = number

  while (number !== 7) {
    while (helper % 37 !== 0)
      helper--

    result.unshift(
      alphabet[number - helper]
    )

    number = helper /= 37
  }

  return result.join('')
}

uniq

Another question I’m frequently encountering is to implement a function that, given an array of integers, removes the duplicates. This can be achieved by storing the items as we filter the collection and leave out the ones that are already in our stash.

function uniq (collection = []) {
  const stash = {}

  return collection.filter(item => {
    if (stash.hasOwnProperty(item))
      return false

    stash[item] = true

    return true
  })
}

Once again underscore.js offers a more roboust solution.


A slightly different problem that can be solved with almost the same code is: Given an array of integers, of which only a single one appears an odd amount of times, return that number.

function findOdd (collection = []) {
  const stash = {}

  collection.forEach(item => {
    if (stash.hasOwnProperty(item))
      delete stash[item]
    else
      stash[item] = true
  })

  return Object.keys(stash)[0]
}

Because we are assured just one item will show up without a matching pair, by deleting the prop each time a second occurrence appears, the single remaining key will be the value we were looking for.

Flatten

Every other interview I’m asked to implement a flatten function that receives an array and returns a flattened version of it. They may request different ways to handle edge cases, but my usual answer is in the lines of…

function flatten (collection = []) {
  let result = []

  collection.forEach(item => {
    if (Array.isArray(item))
      result = result.concat(flatten(item))
    else
      result.push(item)
  })

  return result
}

Are there better ways to do it? Definitely, but at an early interview stage this is usually good enough.

I’m still glad this comes up more often than implementing mergeSort.

UYRobot

A project I’m very proud to have been involved with is finally live: UYRobot. Among other things, they teach both kids and adults how to build robots.

The site was a collaborative effort with designer Flavia Calandria.

The tech used was React (through Create React App) & SASS, with Express on the backend. Although I’m currently thinking of migrating it to Next.js to provide server side rendering. The site is also hosted on Heroku for staging.

The full source code of the site is available on GitHub.

Interview Trivia

While interviewing for a new job I was asked a few JavaScript Trivia questions. Following are my answers.

What is ES6?

ES6 (aka EcmaScript 2015) is the 6th edition of the JavaScript language specification. EcmaScript was created as a way to standardize the implementation of JavaScript across browsers and reduce its incompatibilities. ES6 defines new functionality like arrow functions, let & const variable constructs, template strings, classes, destructuring assignments and more.

Where can JavaScript be run?

Everywhere! While originally bound to the client-side of web browsers, JS can now be run on anything that has support for a JavaScript engine (usually Chrome’s V8). Also thanks to the popularity of Node.js, is now pretty common to find JS running server-side.

What is the difference between ‘currentTarget’ and ‘target’ when talking about events?

event.currentTarget identifies the DOM element to which the triggered event listener was attached to, whereas event.target references the element where the event originally occurred. Unless a different context is specifically bound to the handling function, currentTarget should match the this keyword in the handler.

What is the benefit to using a library like React/Vue/Angular vs using plain old JavaScript?

The goal of a JavaScript framework is to lay some groundwork and provide developers with building blocks that follow standardized software design patterns. This allows devs not only to get a head start on a project but to come up with (in theory) a more robust solution.

As web development grew from building simple websites to complex web apps, so did the responsibility to build maintainable, scalable code. Libraries and frameworks help with just that. Choosing one the right one for your team and project is a different story.

Can you give an example of prototypal inheritance?

Using the latest version of the spec, one can simply use the extend keyword to create a subclass and inherit the prototype of the parent class:

class Vehicle {
  constructor(wheels) {
    this.wheels = wheels
  }
}

class Car extends Vehicle {
  constructor() {
    super(4)
  }
}

Why I Hate Images

According to HTTP Archive today’s average web page size is 1.9MB. Almost 64% of that weight comes from images. As someone who is used to browsing the web on a cellphone through a 3G connection, that really sucks.

Images are one of the main reasons why the web became popular. Could you picture today’s websites without them? How many wouldn’t even exist? It’s interesting to read the history of the img element and see how the initial pitch became the standard we ended up using for the past twenty years.

Images also helped push the boundaries of what was achievable with CSS: border radius, box shadow, custom fonts, gradient backgrounds. These effects were only possible using images and were translated into web standards thanks to their popularity (and then Flat Design became a thing).

But when did image obesity started to become a problem?

The Fat Web

When the iPhone 4 came out, Apple introduced the “Retina Display”. In theory, this meant beautifully rendered images however in practice, all of the images on the web started to look fuzzy. Retina displays basically double the amount of pixels on the screen, so images now require twice as many pixels to look sharp.

Easy fix, right? Say you have a 30x60 image and you want it to look good on retina displays, just create it as a 60x120 and halve its size with some CSS magic. Do that for all the images on your site and you are done, home early for dinner. Oh, one more thing, all of your users are now complaining the site is slow, even the small ungrateful bunch that have retina displays.

Having problems because of a shift in technology is one thing, creating them ourselves to follow design trends is just irresponsible. Features such as banner sliders, cover images and image galleries done poorly come with an expensive performance cost.

Alternative Paths

Where traditionally images are used, any of the following approaches may be better suited:

Data URIs allows us to embed images inline using Base64 encoding. This should only be applied to small images as the resulting amount of characters from the encoding may not worth it. You can use this tool to convert your images.

SVGs have been widely supported for a while now. It can reduce the image size considerably and, if embedded into the HTML is one less HTTP Request. SVGs come with other advantages, as they can be styled and animated using CSS/JS.

UTF8 provides a set of symbols which, although limited, can be very useful as they can be styled as text with virtually no performance cost. You can find some of them at utf8icons or fileformat.

Icon fonts are an amazing example of developer creativity. As custom fonts were available on the web, someone decided to use a font of icons instead of text. Font Awesome is a free font with an outstanding set of icons which you can include in your website from their CDN.

Yet, you might say: “All of this is nice, but in the real world I need to use images”…

If you must, then do it right

Google released their own image format called Webp which is apparently much smaller. Although browser support comes down to Chrome and Opera, people are building tools to automatically serve webp images when supported, with fallback to regular image formats.

Progressive JPEGs are not news, yet they are still a good way to go. They don’t improve performance but the perception of speed. Where is the magic? Instead of rendering top-to-bottom they render as a low quality version of the image and improve over time as data is downloaded.

There are a few techniques to deal with the annoying retina displays: you can sniff for the user’s pixel density using media queries and based on that load the most appropriate image, and a new HTML5 spec allows us to define a set of images using the srcset attribute. There is a great article on that at Smashing Magazine.

Even if you are using regular images there’s a lot you can do to improve your page size. Addy Osmani has a list of tools for image optimization. To that list I would add his own too many images which helps developers figure out the weight of their pages.