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

Aqua UI CSS Buttons

from bt RSS Feed [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: #6F6F6F; } Playing with pseudo elements Now...
28th Jun 2016

Stay updated

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

More from bt RSS Feed

Installing OpenBSD on Linveo KVM VPS

Installing OpenBSD on Linveo KVM VPS 2024-10-21 I recently came across an amazing deal for a VPS on Linveo. For just $15 a year they provide: AMD KVM 1GB 1024 MB RAM 1 CPU Core 25 GB NVMe SSD 2000 GB Bandwidth It’s a pretty great deal and I suggest you look more into it if you’re interested! But this post is more focused on setting up OpenBSD via the custom ISO option in the KVM dashboard. Linveo already provides several Linux OS options, along with FreeBSD by default (which is great!). Since there is no OpenBSD template we need to do things manually. Getting Started Once you have your initial VPS up and running, login to the main dashboard and navigate to the Media tab. Under CD/DVD-ROM you’ll want to click “Custom CD/DVD” and enter the direct link to the install76.iso: https://cdn.openbsd.org/pub/OpenBSD/7.6/amd64/install76.iso The "Media" tab of the Linveo Dashboard. Use the official ISO link and set the Boot Order to CD/DVD. Select “Insert”, then set your Boot Order to CD/DVD and click “Apply”. Once complete, Restart your server. Installing via VNC With the server rebooting, jump over to Options and click on “Browser VNC” to launch the web-based VNC client. From here we will boot into the OpenBSD installer and get things going! Follow the installer as you normally would when installing OpenBSD (if you’re unsure, I have a step-by-step walkthrough) until you reach the IPv4 selection. At this point you will want to input your servers IPv4 and IPv6 IPs found under your Network section of your dashboard. Next you will want to set the IPv6 route to first default listed option (not “none”). After that is complete, choose cd0 for your install media (don’t worry about http yet). Continue with the rest of the install (make users if desired, etc) until it tells you to reboot the machine. Go back to the Linveo Dashboard, switch your Boot Order back to “Harddrive” and reboot the machine directly. Booting into OpenBSD Load into the VNC client again. If you did everything correctly you should be greeted with the OpenBSD login prompt. There are a few tweaks we still need to make, so login as the root user. Remember how we installed our sets directly from the cd0? We’ll want to change that. Since we are running OpenBSD “virtually” through KVM, our target network interface will be vio0. Edit the /etc/hostname.vio0 file and add the following: dhcp !route add default <your_gateway_ip> The <your_gateway_ip> can be found under the Network tab of your dashboard. The next file we need to tweak is /etc/resolv.conf. Add the following to it: nameserver 8.8.8.8 nameserver 1.1.1.1 These nameservers are based on your selected IPs under the Resolvers section of Network in the Linveo dashboard. Change these as you see fit, so long as they match what you place in the resolve.conf file. Finally, the last file we need to edit is /etc/pf.conf. Like the others, add the following: pass out proto { tcp, udp } from any to any port 53 Final Stretch Now just reboot the server. Log back in as your desired user and everything should be working as expected! You can perform a simple test to check: ping openbsd.org This should work - meaning your network is up and running! Now you’re free to enjoy the beauty that is OpenBSD.

21st Oct 2024 96 votes
Burning & Playing PS2 Games without a Modded Console

Burning & Playing PS2 Games without a Modded Console 2024-09-02 Important: I do not support pirating or obtaining illegal copies of video games. This process should only be used to copy your existing PS2 games for backup, in case of accidental damage to the original disc. Requirements Note: This tutorial is tailored towards macOS users, but most things should work similar on Windows or Linux. You will need: An official PS2 game disc (the one you wish to copy) A PS2 Slim console An Apple device with a optical DVD drive (or a portable USB DVD drive) Some time and a coffee! (or tea) Create an ISO Image of Your PS2 Disc: Insert your PS2 disc into your optical drive. Open Disk Utility (Applications > Utilities) In Disk Utility, select your PS2 disc from the sidebar Click on the File menu, then select New Image > Image from [Disc Name] Choose a destination to save the ISO file and select the format as DVD/CD Master Name your file and click Save. Disk Utility will create a .cdr file, which is essentially an ISO file Before we move on, we will need to convert that newly created cdr file into ISO. Navigate to the directory where the .cdr file is located and use the hdiutil command to convert the .cdr file to an ISO file: hdiutil convert yourfile.cdr -format UDTO -o yourfile.iso You’ll end up with a file named yourfile.iso.cdr. Rename it by removing the .cdr extension to make it an .iso file: mv yourfile.iso.cdr yourfile.iso Done and done. Getting Started For Mac and Linux users, you will need to install Wine in order to run the patcher: # macOS brew install wine-stable # Linux (Debian) apt install wine Clone & Run the Patcher Clone the FreeDVDBoot ESR Patcher: git clone https://git.sr.ht/~bt/fdvdb-esr Navigate to the cloned project folder: cd /path/to/fdvdb-esr The run the executable: wine FDVDB_ESR_Patcher.exe Now you need to select your previously cloned ISO file, use the default Payload setting and then click Patch!. After a few seconds your file should be patched. Burning Our ISO to DVD It’s time for the main event! Insert a blank DVD-R into your disc drive and mount it. Then right click on your patched ISO file and run “Burn Disk Image to Disc...". From here, you want to make sure you select the slowest write speed and enable verification. Once the file is written to the disc and verified (verification might fail - it is safe to ignore) you can remove the disc from the drive. Before Playing the Game Make sure you change the PS2 disc speed from Standard to Fast in the main “Browser” setting before you put the game into your console. After that, enjoy playing your cloned PS2 game!

2nd Sep 2024 96 votes
Perspective

Perspective 2024-08-06 I recently read both Starting Hospice and No Salt posted on Jake’s blog and was quite moved. I don’t know Jake and have never met him - but his writing and shared experiences give a very real look into his mind and perspective. If you haven’t yet, I strongly recommend giving his site a read (or at the very least those two posts). It made me reflect on my own life, shift my perspective and realize how fortunate I truly am. Losing Focus I think we all find ourselves losing focus on the truly important things in life. That’s normal and expected. Maybe your house needs repairs, or you’re crunching for an upcoming deadline, or your prepping for a long a work trip, or your stressed out hunting for a job. Whatever it might be, our brains are very good at getting derailed and putting all our attention into less important things. But I believe our minds need to wander and focus on the less important. Otherwise your mental health would suffer greatly. And I should note, some of these “stresses” still require our attention. I just don’t think they should consume us. I’m not advocating that we need to constantly be obsessing over the limited time we have on this spinning rock, or that we should smother our families with over-the-top love. Just stopping and reflecting on these things can really put any worries you have into perspective. It might be cliche to state the obvious, “Be grateful for what you have!” but cliche or not - it’s true. Jake will be leaving behind not just his friends and family, but also his wife who is 7-months pregnant. I can’t begin to imagine the range of emotions everyone close to him must be feeling. I know I would be furious, which doesn’t make sense since something like this is so far removed from human control. Being angry would just be wasted energy. But that’s easier said than done. I don’t have a whole lot else to say on the matter. This post also pales in comparison to Jake’s actual experience and shared perspective on his site. I really wasn’t even sure to share this on my site, in fear that I would be somehow disrespecting Jake’s memory (along with his much better writing skills and openness). But then I thought, if anything, I could help reach Jake’s story to even one other person and help them reflect on their own perspective as well. Now if you’ll excuse me, I’m going to take a long, purposefully slow walk with my family.

6th Aug 2024 47 votes
Dual Booting OpenBSD and Alpine Linux on a X220 ThinkPad

Dual Booting OpenBSD and Alpine Linux on a X220 ThinkPad 2024-07-10 I’ve always found it useful to run both OpenBSD and some form of Linux variation on my personal machines. Most times, I would default to running one OS on bare metal, while the other would simply live in a VM. This works okay but I prefer my operating systems having a “hardware separator” - if that makes sense? So, I set off to start dual booting both OpenBSD and Alpine Linux on my X220 ThinkPad. I should mention that I planned to write this blog post a couple weeks ago, but the original Dogfish mSATA SSD I ordered wasn’t compatible with my X220 (even though they say it is supported…). Luckily, I found a replacement drive in one of my “computer parts” drawer. Hoarding tech always prevails! The original Dogfish mSATA slotted in the X220. Too bad it didn't work... I came across my old Raspberry Pi 400, which I previously wrote about when stuffing an SSD inside it, and proceeded to gut the drive. It’s a cheap KingSpec SSD with a whopping 64GB of storage space. But that didn’t matter since the plan was to install the wonderfully small Alpine Linux. 64 GB would be plenty of space for us! Getting Started I already had the Alpine Linux ISO installed on a random thumb drive, so that made things quicker right off the bat. The next step was opening up my X220 and slotting in the very tiny mSATA. This introduced the first minor issue: the drive was too small. I could have looked into something more “professional-looking” in order to seat the drive properly but I decided to stick with electrical tape. Get it?… After applying the tape I closed the machine back up. The KingSpec mSATA slotted in the X220 and secured with top-of-the-line electrical tape... Installing Alpine Linux Next, I needed to tell the BIOS to boot into my thumb drive containing the Alpine ISO. Once the proper order was set, I rebooted the machine and ran through the standard Alpine installer. No problems to report there. My X220 booting into the Alpine ISO thumb drive The Alpine Linux installer showing both disk options for installation destination. SDA is currently running OpenBSD. Once that was done, I rebooted the machine, being sure to remove the thumb drive and set the BIOS order to point to the new mSATA disk. Then I ran through my personal Alpine Suck installer to get my go-to applications installed alongside my dwm desktop environment. Again, no problems to report during this process. Alpine Linux running my personal `dwm` setup. Absolutely beautiful. Extras? That’s really it. Nothing super interesting to report, but that seems to be the running theme with these older ThinkPad machines: they were built for tinkering and taking apart regularly. If I was less lazy, I could look into setting up a boot loader to avoid swapping between disks via BIOS settings, but for my use case this setup works fine. Now I have the power of OpenBSD and Linux on my personal machine!

10th Jul 2024 46 votes
Building rbenv on OpenBSD 7.5

Building rbenv on OpenBSD 7.5 2024-06-02 I use Ruby (specifically with Jekyll) for a lot of my clubs/projects while using my personal laptop (X220 ThinkPad) which is runs OpenBSD. Since I recently upgraded to OpenBSD 7.5 I thought it could be helpful for others if I shared my process of building and using rbenv to install different Ruby versions. Before We Build First, be sure to install the required packages in order to build from source, and then clone the core rbenv repo: pkg_add git gcc gmake libffi libyaml openssl git clone https://github.com/rbenv/rbenv.git ~/.rbenv Building rbenv Add rbenv to your PATH and initialize it (place this inside your .bashrc or .zshrc etc): export PATH="$HOME/.rbenv/bin:$PATH" export PATH="$HOME/.rbenv/shims:$PATH" export RUBY_CONFIGURE_OPTS="--with-openssl-dir=/usr/local" eval "$(rbenv init -)" Then reload your shell (zsh in this example): source ~/.zshrc Next we will need to install ruby-build as a rbenv plugin. Clone the ruby-build repository into the rbenv plugins directory: git clone https://github.com/rbenv/ruby-build.git ~/.rbenv/plugins/ruby-build Installing Ruby and Setting Our Version Now use rbenv to install the desired version of Ruby (we will get an older version for this example): rbenv install 3.3.0 If you run into issues, you may need to specify your openssl directory: RUBY_CONFIGURE_OPTS="--with-openssl-dir=/usr/local" rbenv install 3.3.0 If you’re on a slower machine (like mine) this might take a little bit. Just grab a coffee or a snack while you wait! Then navigate to your project of choice and set the local Ruby version: rbenv local 3.3.0 That’s it! If you’d prefer to set this version of Ruby for all projects going forward, simply replace local with global.

2nd Jun 2024 35 votes

More in programming

Attention is all you have

The Tetris effect is one of psychology’s most easy to reproduce experiments. Simply spend a bit of time playing the eponymous game every day for a few weeks. After a little while, you’ll start recognizing familiar Tetromino shapes in clouds, buildings, and everyday objects. You might even see them appear before your eyes when you start falling asleep. Tom Tang Attention hijacking There’s one lesson the Tetris effect teaches us: whatever you focus on long enough will end up shaping your thoughts. This can be a good thing since it’s how we learn new skills and discover new ideas. Sadly, less and less of our attention is focused intentionally. Instead of picking what we want to see we let other people decide what is supposed to be good for us. Do you want to watch a video? YouTube knows you like cooking and art streams. But why not also recommend a few clips about the stock market bubble, global warming, and the war in Iran. Doomscrolling will make you stay longer and click on a few more ads. Do you want to listen to music? Just open a Spotify playlist and let the algorithm figure out what you like. Please ignore the AI slop they will insert in between real songs to avoid paying royalties to real artists. Do you want to know how your colleagues are doing? Too bad, LinkedIn will bury any relevant career news between the opinion of complete strangers. It is surely just a coincidence that those strangers happen to be shilling whatever Microsoft is invested in at the moment. Do you want the opinion of strangers on a product? Well those Redditors you wanted to ask are probably just a bunch of LLMs talking to a bunch of Russian trolls now. I hope you didn’t value their opinion too much. If, like me and most people, you spend the major part of your day focused on your device, there’s no doubt it’s affecting you. And when you let someone else dictate what appears on your screen, it’s the same as giving them the key to your brain. New York Said Back to an intentional internet The internet wasn’t always like that. Before recommendation algorithms where a thing, you had to decide what you would be doing on the computer. You didn’t really have one big app that you could open and order it to entertain you. Instead, you had a few dozen of bookmarks to websites, each with a specific idea in mind. A site for video game news, that one website with lots of tutorials, a blog about anime that didn’t update often enough, a wiki about a TV show from the 90s… Of course awful things existed on the web. We had Encyclopedia Dramatica and Rotten.com, but you actually had to put the effort to go there if you wanted. Nobody was going to put pictures of dead kids and far-right propaganda as a suggestion after a pancake recipe or a cat video. The good thing is that this intentional internet is still around. It has just been a bit buried below the corporate web, but it’s not very hard to find. After all you’re on this blog, so you probably already have a good idea about it. The main difference between this time and now is you. When you want to get back to reading blogs, RSS feeds, and finish that tutorial instead of doomscrolling shorts, you have to get used to a slower internet. One where content is not infinite and doesn’t get updated every click. But like every habit, the only thing you have to do is to keep at it. And if you pay enough attention to it, something will click in your brain.

10 hours ago 2 votes
Trying the Software factory pattern.

One of the interesting challenges of the AI ecosystem in 2026 is that new, effective patterns emerge faster than I can adopt them. I’ll find a handful, get back to work, and realize a month later that I’d missed four or five more. The adoption cycle for Imprint this year has been something like: January: get every engineer onto Claude Code every single day March: ok, let’s also get everyone else onto Claude Code or Claude Cowork every single day April: local development is bottlenecked on checkout and worktree model, instead create ~10 local workspaces which each have an independent checkout of every repository, and operate at the workspace level, not at the repository level, so it can generate cross-repository pull requests across frontend, backend, infrastructure and data monorepos June: oh boy, agent-driven development is heavily constrained by lack of a common task management system with higher visibility and less permission complexity than Jira, so let’s migrate the entire company over to Linear and hard stop on Jira July: yikes, now we have visibility into all these tickets, many of them are trivial but managing them through local development isn’t scaling, let’s roll out an orchestrated harness which internally we call “Agent Fleet”, along the lines of Stripe’s Minions The most recent question for me has been figuring out how to adopt the software factory pattern. (After some light research, the specific AI-context origin of this term is slightly messy to attribute, but I think it might be Justin McCarthy in February 2026’s Software Factories And The Agentic Moment.) The software factory pattern is looping on a broad goal, and then relying on the harness to drive progress towards that goal. Our first pass at implementation is fairly basic: An agent skill /linear-project-loop which reads in a Linear project and starts by auditing that project’s goal definition on these dimensions: An RFC in Notion that describes the project’s goals, how those goals are measured, and the general approach A Datadog dashboard or Snowflake queries that measure progress against those goals If those are missing, or the Linear project is missing in its entirety, it iterates with you on creating those missing tools. Then it reviews the state of the metrics and issues for the project. If new work is identified, it adds those issues to the project. It updates the state of issues that have moved. It works on the non-blocked tasks based on the project’s current state. This is often writing a pull request, updating a pull request, pinging for review, asking a clarifying question, etc. When a task completes, if the project description is fresh, it takes on the next task. If the description hasn’t been updated in a while, it reruns the loop starting with the first step. Right now I am running this locally in a local harness, but it’s working well enough that I anticipate moving the behavior to be driven by the same orchestrated harness that we assign one-off tasks to. What I particularly like about the factory pattern is that it parallels very closely how I’ve been working locally, while forcing me to recognize the places where I was accidentally hording parts of the state for myself regarding the goals of the project. I was already asking agents to iterate on specific Linear projects, but they didn’t have the ability to evaluate if they were going in the right direction, or if it was missing necessary tasks. Now it does. The other place this has been extremely helpful for me is checking in on projects post release. For example, I shipped our passkeys implementation earlier this year, but some months go by without my checking in on how it’s going. If we saw adoption spike, or error rates start to turn, I might miss it, but running the factory in a less frequent post-release mode would catch it immediately. The final thought that’s been interesting to me is how much all of the pieces here compound only to the extent that you have the other pieces. For example, this factory pattern depends on having Datadog MCP and Snowflake access available to manage goal-tracking, but it also depends on Linear being the single source of state for the company’s work, and an orchestrated harness that can perform work independently from your laptop. Keeping up with this many migrations is a fascinating industry moment.

yesterday 2 votes
CSS-Tricks could be a co-op

I owe a lot of my professional identity and success to CSS-Tricks. CSS-Tricks repeatedly gave me the opportunity to write for them. In doing so, they helped to both socialize and normalize accessibility as a mainstream frontend concern. I’m deeply thankful to them for this. The team was also a joy to work with, notably Geoff Graham. He’s a mensch, and one of the nicest people you can interact with in the frontend web space. If you have not been following the news about the site, Kevin Powell has a good video about the whole situation: Content skipped. I’m not speaking on behalf of Geoff, Chris, or others involved with running the current version of CSS-Tricks. I’ve got skin in the game as an author. This is my personal opinion, born of my feelings and beliefs. I think a lot of the web’s infrastructure should be co-ops, and CSS-Tricks is knowledge infrastructure. To that point, I should also point out that the website covers far more than just CSS. The corporate model of ownership can be a risk. If infrastructure is not part of a corporation’s core strategy, it is not a priority. As Kevin’s video touched on, it seems like promotion via owning the frontend content space isn’t part of Digital Ocean’s strategy anymore. It is not that CSS-Tricks does not have value. It is that Digital Ocean cannot see it. It is deeply, tragically ironic to me that Digital Ocean allowed this to transpire. This is because I know for a fact that the techniques and philosophies shared by CSS-Trick authors helped to shape iterations of their product’s UI. Some may be quick to point out that this knowledge now—illegally—exists inside of LLM training data, so the risk of the website going away is mitigated. To this, know that we should be striving to keep resources like CSS-Tricks going. Human creativity is the force that creates new techniques, strategies, and technologies. The web will calcify without voices sharing what they know, forever locking us into endless permutations of a fixed point in time. Unlike corporations, co-ops don’t have to be motivated by profit. By not needing to prioritize growth at all costs it means co-ops can instead prioritize and incentivise things like preservation and cultivation. It is also a successful model of operation, one that even already exists, and flourishes in the tech space. Collective ownership can also serve as checks and balances for, and protection against hierarchical decision-making. I only need to point to the chaotic and aberrant decisions many CEOs in the technology space have been making as of late to demonstrate the value of this approach. Paddy Srinivasan, if you somehow wind up reading this: Save some face and take a big swing. Give CSS-Tricks back to the people who love it.

3 days ago
fibre broadband anticlimax

How can something that “just works” be so annoying? situation We live in Cambridge off a little road down a drive in shared ownership between us and our neighbouring houses. All the utilities are buried under this drive, including the phone line. anticipation Over the last few years we have been canvassed repeatedly by CityFibre saying that they can deliver fibre all way to our house. I saw them digging trenches and leaving tails of purple fibre cladding along nearby roads, ready to hook up all the houses. I thought they would need to do something similar to deliver fibre to us. So when they turned up and knocked on our door, I talked to their salesbods and walked them up and down the drive and pointed out where the existing BT line goes. Then they gave up trying to sell to us. This happened about three times. disaffection We were not eager enough for an upgrade to deal with these impediments. notification A few months ago we were told that CityFibre would soon come and do the upgrade, since there’s a nationwide deadline for turning off the copper phone network at the end of the year. We expected that this would force them to actually plan some digging works, so we talked to our neighbours about it. We were all ready for some huge faff to follow the next visit by the CityFibre bods. installation CityFibre turned up on the promised morning bright and early. To our enormous surprise, a brown fibre housing was already poking out of the ground next to our copper phone line. It had been fed through 50 metres of 5cm duct without us being aware they were even working on the street. Within a couple of hours, the technicians had drilled through our wall, installed the ONT, blown fibre through the unexpected pipe, plugged in the CPE (superficially identical to the old one), and left telling us to anticipate that it might not work properly until tomorrow. activation Around lunch time, the copper phone line stopped working completely. Some faff ensued, switching all our devices over to the new WiFi network. For a while we thought this was the death of our land line, but in the course of debugging other issues, I realised that the router has a built-in VoIP adapter (I don’t think we were told it has a built-in VoIP adapter) so I plugged the phone in and it Just Worked: they had ported our phone number across and everything. Flawless. I was seriously impressed. rumination It has been a few weeks since the switchover, and apart from a couple of horrible Clown-afflicted IoT devices, it has been fairly smooth. What prompted me to write this up was realising that we delayed this upgrade for years because the sales people were not given enough technical information about how the installation process works: the fact that houses typically have a 5cm duct containing the copper lines (probably standard for the last 40 years) and the fact that fibre can be shoved through a few tens of metres without difficulty. And worse, the sales people didn’t have an esclation path for difficult cases: they just gave up instead. From a technical point of view, the installation was impeccable. (I guess the loose 24 hour window for the cutover time was because OpenReach and CityFibre don’t have tight requirements on ISP reconfiguration schedules.) From the sales point of view, it was crap. Maybe it would have gone faster if we offered to switch early without asking if the drive would be a problem? But I guess the difference between “yes!” and “yes, but will this be a problem?” is too much to expect from a minimum-wage door-to-door salesbod whose employer didn’t give them enough information or any escalation path.

4 days ago
📚 BoredReading

You seem to be enjoying this.

Join free to unlock everything.

Create free account

Already have an account? Sign in