Full Width [alt+shift+f] Shortcuts [alt+shift+k]
Sign Up [alt+shift+s] Log In [alt+shift+l]
48

Aqua UI CSS Buttons

from Making software better without sacrificing user experience. [alt+shift+b] in programming

Aqua UI CSS Buttons 2016-06-28 Though it may feel like nostalgia, the old OS design for Mac was arguably better than the current iteration (as of this writing - High Sierra). I recently designed a quick Dribbble shot showcasing how the older operating system used to have so much more character and depth. My initial Dribbble shot, which can be found here. Since I've been wanting to dip my toes into more tutorial-based articles (maybe I'll even do some screencasts in the future), I decided to start out simple. Let's walk through how to implement these 'aqua' UI buttons with pure CSS. Starting with a basic foundation Since this project consists of only two buttons elements, the HTML or skeleton of this project is very straightforward: <button class="cancel">Cancel</button> <button class="confirm">Confirm</button> Styling the buttons The first step is to remove the browser's default button styling by using the appearance property. This will help avoid having to fight against the browser and minimize our CSS code. button { -webkit-appearance: none; -moz-appearance: none; } Next, we apply a fairly simple set of CSS that will be shared across both the confirm and cancel buttons: (Pay attention to the transition property as we will be returning to that shortly) button { -webkit-appearance: none; -moz-appearance: none; border: 1px solid #ccc; border-radius: 125px; box-shadow: inset 0 13px 25px rgba(255,255,255,0.5), 0 3px 5px rgba(0,0,0,0.2), 0 10px 13px rgba(0,0,0,0.1); cursor: pointer; font-family: 'Lucida Grande', Helvetica, Arial, sans-serif; font-size: 2rem; margin: 5rem 1rem; padding: 1.2rem 4rem; position: relative; transition: all ease .3s; } Then we separate the specific confirm and cancel button styles into their own class selectors: button.confirm { background: #4A90E2; border-color: #3672B6; color: #fff; } button.cancel { background: #D0D0D0; border-color: #B8B8B8; color:...
28th Jun 2016

Stay updated

Get a weekly newsletter with the top 5 articles worth reading every week.

More from Making software better without sacrificing user experience.

Bringing dwm Shortcuts to GNOME

Bringing dwm Shortcuts to GNOME 2023-11-02 The dwm window manager is my standard "go-to" for most of my personal laptop environments. For desktops with larger, higher resolution monitors I tend to lean towards using GNOME. The GNOME DE is fairly solid for my own purposes. This article isn't going to deep dive into GNOME itself, but instead highlight some minor configuration changes I make to mimic a few dwm shortcuts. For reference, I'm running GNOME 45.0 on Ubuntu 23.10 Setting Up Fixed Workspaces When I use dwm I tend to have a hard-set amount of tags to cycle through (normally 4-5). Unfortunately, dynamic rendering is the default for workspaces (ie. tags) in GNOME. For my personal preference I set this setting to fixed. We can achieve this by opening Settings > Multitasking and selecting "Fixed number of workspaces". Screenshot of GNOME's Multitasking Settings GUI Setting Our Keybindings Now all that is left is to mimic dwm keyboard shortcuts, in this case: ALT + $num for switching between workspaces and ALT + SHIFT + $num for moving windows across workspaces. These keyboard shortcuts can be altered under Settings > Keyboard > View and Customize Shortcuts > Navigation. You'll want to make edits to both the "Switch to workspace n" and "Move window to workspace n". Screenshot of GNOME's keyboard shortcut GUI: switch to workspace Screenshot of GNOME's keyboard shortcut GUI: move window to workspace That's it. You're free to include even more custom keyboard shortcuts (open web browser, lock screen, hibernate, etc.) but this is a solid starting point. Enjoy tweaking GNOME!

2nd Nov 2023 • 119 votes
Installing Older Versions of MongoDB on Arch Linux

Installing Older Versions of MongoDB on Arch Linux 2023-09-11 I've recently been using Arch Linux for my main work environment on my ThinkPad X260. It's been great. As someone who is constantly drawn to minimalist operating systems such as Alpine or OpenBSD, it's nice to use something like Arch that boasts that same minimalist approach but with greater documentation/support. Another major reason for the switch was the need to run older versions of "services" locally. Most people would simply suggest using Docker or vmm, but I personally run projects in self-contained, personalized directories on my system itself. I am aware of the irony in that statement... but that's just my personal preference. So I thought I would share my process of setting up an older version of MongoDB (3.4 to be precise) on Arch Linux. AUR to the Rescue You will need to target the specific version of MongoDB using the very awesome AUR packages: yay -S mongodb34-bin Follow the instructions and you'll be good to go. Don't forget to create the /data/db directory and give it proper permissions: mkdir -p /data/db/ chmod -R 777 /date/db What About My "Tools"? If you plan to use MongoDB, then you most likely want to utilize the core database tools (restore, dump, etc). The problem is you can't use the default mongodb-tools package when trying to work with older versions of MongoDB itself. The package will complain about conflicts and ask you to override your existing version. This is not what we want. So, you'll have to build from source locally: git clone https://github.com/mongodb/mongo-tools cd mongodb-tools ./make build Then you'll need to copy the built executables into the proper directory in order to use them from the terminal: cp bin/* /usr/local/bin/ And that's it! Now you can run mongod directly or use systemctl to enable it by default. Hopefully this helps anyone else curious about running older (or even outdated!) versions of MongoDB.

11th Sep 2023 • 81 votes
Converting HEIF Images with macOS Automator

Converting HEIF Images with macOS Automator 2023-07-21 Often times when you save or export photos from iOS to iCloud they often render themselves into heif or heic formats. Both macOS and iOS have no problem working with these formats, but a lot of software programs will not even recognize these filetypes. The obvious step would just be to convert them via an application or online service, right? Not so fast! Wouldn't it be much cleaner if we could simply right-click our heif or heic files and convert them directly in Finder? Well, I've got some good news for you... Basic Requirements You will need to have Homebrew installed You will need to install the libheif package through Homebrew: brew install libheif Creating our custom Automator script For this example script we are going to convert the image to JPG format. You can freely change this to whatever format you wish (PNG, TIFF, etc.). We're just keeping things basic for this tutorial. Don't worry if you've never worked with Automator before because setting things up is incredibly simple. Open the macOS Automator from the Applications folder Select Quick Option from the first prompt Set "Workflow receives current" to image files Set the label "in" to Finder From the left pane, select "Library > Utilities" From the presented choices in the next pane, drag and drop Run Shell Script into the far right pane Set the area "Pass input" to as arguments Enter the following code below as your script and type ⌘-S to save (name it something like "Convert HEIC/HEIF to JPG") for f in "$@" do /opt/homebrew/bin/heif-convert "$f" "${f%.*}.jpg" done Making Edits If you ever have the need to edit this script (for example, changing the default format to png), you will need to navigate to your ~/Library/Services folder and open your custom heif Quick Action in the Automator application. Simple as that. Happy converting! If you're interested, I also have some other Automator scripts available: Batch Converting Images to webp with macOS Automator Convert Files to HTML with macOS Automator Quick Actions

21st Jul 2023 • 56 votes
Running VSCode in Chromium on OpenBSD

Running VSCode in Chromium on OpenBSD 2023-06-05 VSCode and its many variations are not available on OpenBSD. This doesn't cause issue with many OpenBSD users, but those making the jump from Linux might miss access to such a popular editor. Lucky for us, there is a hacky workaround to solve this problem. VSCode in the Browser I tried my best to build something like code-server locally and run that directly in my browser - but I failed miserably. Instead, I fell back on vscode.dev which is essentially a remote version of code-server. Getting things to work seamlessly proved a little more challenging. I found the best performance was running everything through Chromium with special parameters enabled on launch. Note: The following assumes you have already installed chromium First we need to disable unveil for Chromium. This will allow us to access our system files through vscode.dev using the "Open folder..." or "Open file..." commands without issue: chrome --disable-unveil Everything should work pretty solid right out the box now - except it doesn't. Syntax highlighting does not work without enabling WASM/WebAssembly. Your experience might be different, but I had to include the following when launching Chromium from the terminal: ENABLE_WASM=1 chrome --enable-wasm Success! We can avoid typing out these complex commands everytime we want to launch our editor by setting up an alias (in my case via .zshrc): alias vscode="ENABLE_WASM=1 chrome --enable-wasm --disable-unveil" That's it! Now I can just pop open VSCode on OpenBSD by simply running vscode in my terminal. Hopefully this can help others slowly transition over to OpenBSD - which you should do because it is amazing!

5th Jun 2023 • 111 votes
Converting My X201 ThinkPad into a Slabtop

Converting My X201 ThinkPad into a Slabtop 2023-05-01 I recently wrote about physically disabling the WiFi toggle switch on my X201 which was a fun "hack" to an annoying issue I was running into. Since then, the laptop has been running flawlessly. The only other minor issue I had was the poor display quality. The screen works perfectly fine but the X201's age prevents it from being the best possible display for day-to-day tasks. Both the resolution and viewing angles are quite poor. So, what were my options to remedy this problem? Swap out and upgrade the laptop's display (not many options for this though) Connect an external display, keyboard, mouse and dock the X201 Something else? Looking into "Something Else" I found that the possible replacement screens weren't worth the cost/hassle to swap out. And setting the laptop aside, docked with external peripherals sounded fine in theory - but then I would be missing out on the X201's amazing classic keyboard... Then I thought to myself, "Why not just remove the display entirely?" So that's what I did. The X201 display (still inside the top lid) disconnected from the body of the laptop. Removing the entire top lid was easier than I initially thought it would be. The beautiful thing about these older, classic ThinkPads is the ability to completely dissemble them. I won't go into heavy details on how to take one of these machines apart, since great documentation already exists. But once you have the keyboard and hinge screws removed it is essentially as easy as lifting the lid out of the chassis. (After disconnecting the small display connectors, of course) Ditching Alpine for Debian I love Alpine Linux. It's normally my go-to distro (paired with dwm) for most of my laptop devices. Unfortunately, I find tiling window managers a slight pain to use on larger, 4K displays. I also wanted this slabtop to "just work", instead of needing to fiddle around with WiFi, xrandr, audio etc. Not to mention that Debian is rock solid stable. Defaulting to the XFCE DE was a no-brainer as well since this device is somewhat old. The X201 "slabtop" connected to my 27" 4K monitor via the ThinkPad UltraDock. Closing Thoughts This slabtop gives me those old-school "Commodore64" vibes (or more recent devices like the Raspberry Pi 400). This setup certainly isn't for everyone but for my use case it's working well. Traveling with a machine like this might prove a little more challenging - although you could simply pair it with a smaller travel monitor (I'm sure the overall carrying weight would be similar to the standard X201). If nothing else, it is good to keep this option in mind if you ever break your laptop's display and don't feel like spending the money to fix it. Just grab an external monitor you have laying around and make a slabtop!

1st May 2023 • 109 votes

More in programming

CalVer 26.0: 10th Anniversary Edition

A decade ago, a little bit of history was made. I didn't realize it, but a colleague made a great point, one of those real mind-changing points that seem too obvious to admit same-day. But, the next day, calver.org was born. At the time my team maintained the Python infrastructure for eBay and PayPal, and we were stuck deciding whether we were really ready for a "major" 1.0 release. Semantic Versioning was the only game in town and "major" means "big", right?! Thankfully, a wiser colleague mentioned: Ubuntu and Twisted don't struggle with version number debates. They slap a date on it and keep shipping. In fact, their date-based versions were even better because you always knew where it stood, in terms of updatedness and support. The only problem is that no one really knew about it. Somehow, this problem solving versioning alternative, arguably as old as history itself, had gone nameless for millenia, conspiring to make me feel foolish in an office meeting. Never again! Ten years of adoption Fast forward 10 years, we've seen CalVer adopted by Apple, Nvidia, JetBrains, and countless others. (We have a timeline!) The site may have more inbound links than any other project of mine. Apple made the biggest jump, at WWDC 2025: iOS went from 18 to 26 macOS from 15 to 26 watchOS from 11 to 26 and visionOS from 2 to 26 All landing on one, consistent number like a car's model year. I still remember the texts from the Venn diagram fanbase of my friends who love Apple and reasonable versioning. No such texts from when NVIDIA announced calendar versions across the GPU Operator, RAPIDS, and its monthly NGC containers, but still very cool. Open source, too: Home Assistant, pip, CockroachDB, and yt-dlp all ship on dates, with plenty more on the users page. The conversation even reached the language core; PEP 2026 proposed versioning CPython as 3.YY, and it almost happened, too. And it's never too late, time marches on! Fixing the notation But I don't think I got every detail right from day 1. That's the main motivator for CalVer 26. It's high time to start righting a couple idiosyncratic token design choices, starting with some additions: Meaning Before 26.0 26.0 Full year YYYY YYYY Short year (6, 16) YY YY Zero-padded year (06, 16) 0Y 0Y Short month (1 ... 12) MM M Zero-padded month (01 ... 12) 0M 0M Short week (1 ... 52) WW W Zero-padded week (01 ... 52) 0W 0W Short day (1 ... 31) DD D Zero-padded day (01 ... 31) 0D 0D Seeing double First, the doubled letters. From the first version (16.6), MM and DD meant the unpadded month and day, which reads backwards to anyone who knows date formats (ISO 8601's YYYY-MM-DD, Java, moment.js, day.js), as some community members correctly pointed out. I was ready to flip them, until I checked what people actually use: most projects with a YY.MM.MICRO badge (conda, Twisted, Ansible's tooling) don't pad, and more than a dozen other version management tools (like bumpver and bump-my-version) implement the old meaning. So, it's too late to flip MM's meaning. Instead, 26.0 deprecates it and offers a more explicit and hopefully clearer option: M is the short month, 0M the padded one, and MM is a technically-retired synonym for M. In case you're wondering, the explicit 0M was me being overinspired by Ubuntu's approach, perhaps: 6.06 pads its month but not its year, and YY.0M says exactly that. To pad or not to pad I think it's worth a detour into why padding is even a thing anyways. It's become important now that new ecosystems have emerged that enforced SemVer formatting semantics, and I wanted clear guidance about on the spec site. SemVer forbids leading zeros outright, so Cargo rejects 26.04.0 and Go modules reject v26.04.0. Even Python's packaging spec normalizes leading zeros away, so you can tag 2026.08.19 if you want, but PyPI will still show 2026.8.19. NVIDIA's GPU Operator docs put it this way: "Zero padding is omitted for month to be still compatible with semantic versioning." CalVer was always intended to drop in where SemVer was used. So 26.0 recommends unpadded (YYYY.M.D) as a sane "pure" default for software libraries. But libraries are not the only objects of versioning schemes. The exception is a version that becomes a filename, an image tag, or an object-store key that gets listed lexically. There, padding keeps 26.10 sorted after 26.09, which is why Ubuntu, NixOS, and NVIDIA's own NGC containers pad. More evidence of teams designing their versions. We love to see it. Our FAQ has a longer discussion of the padding issue, as well. Optional segments There was never any rule against them, but 26.0 makes optional trailing segments more explicit with square brackets. Now, yt-dlp's scheme can finally be written down: YYYY.0M.0D[.MICRO]. For the CalVer badges I could find on GitHub, they all stay valid for now. I've got a note on the deprecated spellings and a new copy-paste badge section for new ones. What else is new? It's always a great time to add more citations to the site. A spec changelog; the spec now versions itself: 16.6, 19.7, 26.0. A FAQ: breaking changes, same-day releases, and padding. The users page, rebuilt by category, with past users of note (schemes change; that's fine) and tooling. Case studies: Apple and NVIDIA in, yt-dlp replacing youtube-dl. Much of the thinking behind these changes happened in the GitHub issue tracker over the years, and 19 or so issues close with this release. That's where ideas for CalVer should go, so by all means, open an issue, and we'll get it sorted! In due time, of course. In closing, I can't believe I still love belaboring these numbers so much. Thanks to all (but especially Mark, Glyph, Hugo, issue reporters, translators, and maintainers) for the discussion, and ultimately making the most timely versioning system a timeless classic. See also 2016 announcement Designing a version My Yap on Why CalVer beats Semver

14 hours ago • 1 votes
"You didn't do it right"

Four sincere attempts at OKRs, four failures, and every time: "you didn't do it right." Maybe the framework doesn't fit you -- so how do you find one that does?

21 hours ago • 1 votes
We solved SQLite's single-writer limitation

Multiple concurrent writers. Multiple processes. Same SQLite. No modifications.

2 days ago • 1 votes
If your team is happy, are you doing a good job?

Brilliant jerks, ZIRP-era managers, and how psychological safety lost the plot. Part 3 of my conversation with Dr. Cat Hicks.

3 days ago • 1 votes
WTF is context engineering? (with real examples)

Say you're deploying an AI assistant that processes online order returns. For it to work, it would need access to your store's purchase policy, item…

4 days ago • 1 votes
📚 BoredReading

You seem to be enjoying this.

Join free to unlock everything.

Create free account

Already have an account? Sign in