Bring back the visited styles

While reading the old-but-gold 37signals manifesto their use of :visited styles caught my eye. I wonder why we came to use it so sparsely these days. Is it us designers and frontend developers being lazy? Is it because it “looks nicer” when all links look the same?

Whatever the reason is that :visited got abandoned I found it vastly useful to know whether I’ve already visited a certain URL. In fact, it encouraged me to read in a non-chronological fashion because it reduced the fear of not knowing where to continue and wasting time.

I can see no valid excuse to withheld this simple and effective means of navigation from users. Yet I’m pondering about conventions that are immediately understood. Most people have learned about the meaning of purple colored links on a Google search results page. Transporting the meaning of visited links by using the same color across the entire the web is not an option. Yet wouldn’t it be great if we had a consistent way so signal URLs we’ve already visited?

Copywriting for Interfaces – Takeaways

Here’s what I’ll try to remember from UX Planet’s great article on Copywriting for Interfaces.

  • Headlines should be catchy and short so that they could quickly draw users’ attention
  • The perfect length of the headline is 6 words (underlying research)
  • Captions should provide new information so it shouldn’t describe obvious statements which users already see in the photo.
  • Keep CTAs at a minimum, usually not more than 1–2 words
  • Applying imperative case in CTA microcopy gives strong and direct instructions of what to do next.
  • Notifications with less than 25 characters perform much better than long text.
  • Error messages should be polite and friendly. A bit of humor can relax annoyed users but must be used carefully.
  • Place an UI element that offers further action close to an error message.
  • Tooltips work best when having 150 characters or less

It doesn’t have to be crazy at Work: Takeaways

Here are some notes I had to take while reading this great book. Probably more to come.

  • Asynchronous first. Emergencies that require immediate action rarely ever happen. Create an environment where people don’t feel obliged to answer immediately. Of course that doesn’t mean you shouldn’t call the fire departement if there’s a real fire to put out.
  • Office Hours. It’s great to have a lot of knowledge available in your company. Constant distractions to tap into that knowledge suck. Let everybody define their own office hours. That way you know you won’t be bugging Joe if you approach him Thursday between 9 and 12.
  • Heartbeats. Every team writes an internal blog post about what they’ve been up to the past month/week. It’s a great way to let everybody take part in past achievements and problems without having time and soul draining meetings.
  • Treat your company like a product. It needs to evolve and improve over time. Too many companies create new products but never question how they do it.
  • Present in Writing. Encourage new ideas be presented in written form. Meetings enforce immediate reactions which are often not the most thoughtful ones. Written presentations allow for more clam and substantial reactions.
  • Don’t rely on a single source of revenue. When you’re afraid of loosing the most important customer you’re in danger of letting them talk into your product and business decisions.
  • Lead by example. You cannot create a calm environment with sane hours and concentrated people if you don’t practice these values yourself
  • Encourage a calm working environment. Allow remote work and flexible working times.
  • Encourage your employees to take time off and feel good about it.
  • Trust reduces bureaucracy. For example, at Basecamp every employee gets a company credit card and doesn’t have to ask anybody permission to use it. Because if you can’t trust someone to spend $200 wisely why would you hire them in the first place? 
  • Work in clearly defined cycles and stick with them. For Basecamp,  periods of 6 weeks work best to create any new feature. If it takes more than that it’s probably to complex and should be broken in smaller chunks. Your perfect timeframe may vary – experiment and find out. If it becomes clear that a goal won’t be achieved on time the scope needs to be reduced while still creating something shippable. No crazy all-nighters and no expansion of the timeframe.

Prevent Object-fit polyfill from messing with broken image’s alternative text styling

That is a hell of a long title for a very short post.

If you’re using the Object Fit Images Polyfill you might have noticed that broken images’ alt texts render in Times New Roman. This happens because Object Fit Images  works by setting a faux font-family on the image, which is then used by JavaScript. The problem is that the browser tries to render a broken image’s alt text which, of course, doesn’t exist. So it falls back to whatever the browser uses as default. 

To prevent this we can simply add inherit to our font-stack of the image: 

// When using Object Fit Images Manually
img {
object-fit: cover;
font-family: "object-fit:cover", inherit;

So what if you’re using PostCSS Object Fit Images to automatically add that font family to any selector that employs object-fit? Luckily it respects any existing font declaration and adds it to the font stack. So we can simply add the inherit statement directly:

// When using PostCSS Object Fit Images 
img {
object-fit: cover;
font-family: inherit;

The result in both cases is: font-family: "object-fit:cover", inherit; and allows for the polyfill to do its thing while at the same time setting the font-family to the one used in the next proximate parent.

What if not Apple?

I’ve got myself a new MacBook Pro and I’m even more disappointed than I had feared. Random freezes and total shutdowns. Time machine backups that work only occassionally and almost certainly not if using encryption.

So why not leave the world of Apple behind? Looking in my Applications folder I’ve found my list of reasons. It’s even longer than I’ve had anticipated.

  • Apple Photos + iCloud Photo Library
  • Affinity Designer & Publisher
  • Day One
  • Sketch
  • IconJar
  • RightFont
  • Prizmo
  • Sip
  • Contrast
  • Things
  • Tyme
  • iA Writer
  • Paprika

Work Manifesto

We create solid websites for clients who value their users.

We believe there is no better marketing than good content presented well.

We want out relationships to be straightforward, honest and transparent.

We don’t do things we consider ethically wrong.

Stretch SVG Background Images

The next time I’m going mad when trying to stretch a SVG background image using background-size I’ll remember adding preserveAspectRatio="none" to the SVG itself. Otherwise it’s gonna stick to its original aspect ratio like its life depends on it.

MAMP MySQL repair fails with Access Denied

mysqlcheck: Got error: 1045: Access denied for user ‘root’@‘localhost’ (using password: YES) when trying to connect

I have no clue where the MAMP GUI tries to take the credentials from when running checks and repairs. It just never seems to work.

The solution that worked for me, however, is to simply run mysql_upgrade -uroot -p on the command line. Don’t forget to check that MAMP’s mysql binary is in your PATH, because it is not by default. To do so add to your shell’s config (that’s .zhsrc for me) and restart your terminal:
export PATH="/Applications/MAMP/Library/bin:$PATH"

Et voilà:

Upgrade process completed successfully.
Checking if update is needed.

Track your learning hours

Just a quick idea I find very useful to motivate myself and keep track of time spent on lerning certain things.

If you already have a system in place to track work time just use that. If not, I can recommend an app called Tyme. Nice and clean, yet it has all features I need and doensn’t get in the way. It’s available for Mac OS and iOS and offers sync via. I’ve been using it for years to track freelance work but only recently came up with the idea to also employ it to see how much time I invest to improve my skills. I simply set up a project called Learning and in there I’m having tasks for every topic or tutorial I’m working on.

It’s gratifying to see despite having had a really crazy week that I still made time to spend an hour on that Vue training I’m so into right now. It helps a lot to not starting to think I’ve accomplished nothing – and it’s hell of a motivation to not just spend that time on Netflix or Twitter.

Using CSS Blur to add full-width image background

Many designs require the implementation of full-width imagery while restricting the component’s height at the same time.

Blurred Hero Component

Today I came up with this simple idea that may help in some situations: Put a blurred version of the hero image in the background, reduce its opacity and make it span the entire width. Place the actual image above and restrict its width to a dimensions that makes it easier for content editors to find a fitting image.

Bonus points: when using a small resolution for the blurred image it could serve as a placeholder while loading the high res version.


Mir geistert schon länger die Idee einer Art „Time Bank“ im Kopf.

Die Idee: mensch bietet beliebige Leistungen für andere Menschen an. Wenn jemand etwas in Anspruch nimmt bekommt mensch die dafür aufgebrachte Zeit auf einem Konto gutgeschrieben. Man könnte es auch umständlich ausdrücken: Zeitversetzter Tauschhandel für Dienstleistungen.

Mir gefällt der Gedanke sehr gut, dass der Zeit aller Teilnehmenden der gleiche Wert zugesprochen wird. Zeit als natürlich begrenztes Gut erlaubt wenig Spielraum für Spekulationsblasen.

Nun habe ich ein wenig recherchiert und festgestellt: Zeitbanken gibt es bereits, sowohl als Konzept als auch in diversen realen Anwendungen. Die findet meist in kleineren Kreisen und häufig auf lokaler Ebene statt. Ein bisschen wie Nachbarschaftshilfe. Eine Lösung, die ich selbst gerne nutzen würde ist mir noch nicht untergekommen. Eine lokal und global funktionierende Plattform für den Austausch von Fähigkeiten, bezahlt durch das Zurückgeben von Minuten, Stunden, Tagen.

Ich werde also vorerst weiterhin Tabellen führen, wem ich Zeit schuldig bin und bei wem ich noch ein paar Stunden gut habe.

Decoupled Drupal mit Gatsby

Heute kam ich endlich mal dazu, dieses Tutorial zu Decoupled Drupal mit GatsbyJS nachzubauen. In kürzester Zeit war Folgendes möglich:

  • CMS-Setup inklusive Einrichten der JSON-API
  • Anlegen einer von Drupal völlig unabhängigen statischen Site, die CMS-Content von der API konsumiert und rendert.

Oh, ich freu mich auf die Zukunft und auf reale Projekte mit Drupal als Headless CMS. Ungeahnte Möglichkeiten öffnen sich.

A True Alternative to Instagram

The idea started with the following tweet.

Right now this is just me, thinking loudly. If you’re feeling the same itches you’re more than welcome to join scratching. Continue reading

Roll back to an older version of the Evernote Web Clipper for Chrome

There’s no nice way to say it: with the release of version 7 of the Web Clipper Evernote demonstrated that they seem either to not use their own product. Or do the least amount of testing before releasing. And they really give a rat’s ass about their frustrated customers who start to ask themselves what it is they are paying for.

The devastating reviews on the Chrome Web Store for Version 7.x speak for themselves.

Personally I’m most upset about the following regressions, but apparently there are even  more features lost and bugs introduced: Continue reading

Re-use and override TailwindCSS Configuration

TailwindCSS is hands-down my most useful CSS tool of 2017. It’s a fantastic helper to create utility-first CSS. I’ve been working with it since its first public release and I’m still more than happy to have it.

Today I found out a way to make it even more useful. Say you’re having a Parent Theme that you use for a lot of projects, where each project implements a child theme that needs to adjust properties such colors, breakpoints or font stacks. That’s as simple as requiring your Parent Theme’s tailwind.js, override or add properties and export the adapted config.

const config = require('../parent_theme/tailwind');

config.colors['grey'] = '#eee'
config.screens['md'] = '32em'

module.exports = config;