On Apple products and the subjectivity of “expensive”

Until the Apple Watch came along, I had gone 20 years without wearing a watch. And before that, the most I had ever spent on one was $50. A watch was not an object I was willing to spend more money on than that. But then Apple released a very compelling product, and I went for it. (Even if, in retrospect, the original iteration of the Apple Watch was… underwhelming.)

I’ve owned three Apple Watches: the original (a.k.a. “Series 0”), a Series 3, and my current one, a Series 5. But after visiting a local Apple Store yesterday and looking at the latest models, I decided it was time to upgrade my Apple Watch experience once again, so today I ordered a Series 8… and for the first time, I sprung for the extra $100 to get one with cellular. Now I can finally go out running without bringing my phone. This will transform my running experience… once the snow melts and I’m back outside, that is. (But actually it will transform my experience on the indoor track too. I hate having my phone in my pocket when I run!)

Of course, running without my iPhone means that also means I need wireless earbuds. I may be willing to drop a lot of cash on a lot of Apple products, but AirPods are one area where I feel their options are way overpriced. Well… maybe not overpriced for what they offer, but more than I am willing to spend, for features I don’t really care about.

What’s worse, I can’t stand hard plastic earbuds, and Apple’s only option with silicone tips is the $250 “Pro” models. There’s no way I’m paying that much of a premium for something so easily lost. I’d rather stick with my tried-and-true $9 wired Panasonic earbuds. (But of course you can’t use wired earbuds with the watch!)

Anyway, I found these no-name Bluetooth earbuds on Amazon for $20. I’m going to give them a try before I go for anything higher-end. Hopefully they won’t explode while I’m wearing them!

Bootstrap 5 Carousel: position captions outside (i.e. below) the images

(If you want to get right to the point, a full code example is provided at the bottom of this post.)

I’m not a Bootstrap expert. During most of its evolution, I’ve mostly ignored it in favor of rolling my own… everything. I finally really embraced Bootstrap when I had a rush project in October 2022 that was way too precisely designed to work with WordPress, especially Gutenberg. (And the client didn’t need editing capabilities.) So I decided to hand-code it, but to use Bootstrap to… uh… bootstrap my HTML/CSS layouts.

I think Bootstrap 5 is excellent. I wish Gutenberg was built on top of it instead of the idiosyncratic house of cards it’s actually built on, but whatever.

As it happens, I’m actually now using Bootstrap 5 with Gutenberg for some custom blocks, specifically a Carousel block. One of the options I want to provide in my block is the ability to show the carousel’s captions and controls outside of the image, but apparently, at least with Bootstrap 5, that’s not an option.

I decided to Google for a quick solution before creating my own and I came across… this. I’m sure it gets the job done, but it seems severely over-engineered, so here I’m presenting my own comparatively simple, CSS-only solution.

Basically there are two things you need to do: 1) move the absolute-positioned caption text below the image, and 2) add padding to the bottom of the container, so the caption has somewhere to go instead of just overlapping the content below it.

Let’s start with the second item first:

.carousel { padding-bottom: 4rem; }

There may be some trial and error here, as you need to make sure you’re accommodating captions of varying length. I will admit this is not fully thought out here, and unlike the rest of what is about to follow, it may be a deal breaker under certain circumstances. But let’s assume your captions are a fairly consistent length, and you can determine how much padding you need.

Getting the caption pushed below the images is easy…

.carousel-caption { top: 100%; }

…except, oops, vertical overflow is hidden. Let’s fix that:

.carousel-inner { overflow: visible; }

Of course, if you have your transition effect set to slide (which is the default), that now spews stuff all over the page in an ugly way. But we can fix that by hiding overflow on the outer carousel element instead:

.carousel { overflow: hidden; }

You might, at this point, wonder why I didn’t just set overflow-y: visible on .carousel-inner which seems perfectly reasonable, and which, of course, I tried. But for reasons I couldn’t be bothered with investigating, that ended up causing .carousel-inner to just show a vertical scrollbar and not display the caption unless you scrolled it. Ugh. No matter, the above takes care of it.

That’s pretty much it, as far as the captions go. But if you’re using the controls (previous/next arrows) or indicators (dots/lines for the number of slides and current selection), you’ll notice there’s some weirdness to their placement, so let’s fix that too. The indicators just get shoved to the bottom of the container, so your bottom padding can accommodate that. But if you want to move them back up onto the image, you just need to offset that extra padding, like this:

.carousel-indicators { bottom: 4rem; }

Make that value the same as the bottom padding you added to .carousel itself.

As for the controls, since you’ve made the overall container taller, they’re now a bit too low rather than being vertically centered on the image. Guess what… setting their bottom value to match the extra bottom padding fixes their placement too!

.carousel-control-next, .carousel-control-prev { bottom: 4rem; }

So, putting it all together as concisely as possible, here’s what we have:

.carousel { overflow: hidden; padding-bottom: 4rem; }
.carousel-caption { top: 100%; }
.carousel-inner { overflow: visible; }
.carousel-control-next, .carousel-control-prev, .carousel-indicators { bottom: 4rem; }

On the Futility of Naming Colors

I posted this over on the ICS Calendar blog, but it’s probably of some interest to the audience of this blog, dealing with the intersection of code and design.

HTML has “named colors” which are… weird. And I have finally given up on using them in the plugin, which was a bit of a silly thing to do anyway, when there are 16 million RGB colors at one’s disposal. The post ends with swatches of both the old and the newly revised color palettes.

https://icscalendar.com/on-the-futility-of-naming-colors/

How I learned to stop worrying and embrace being a middle-aged curmudgeon

Reading John Gruber’s thoughts on the potential future existence of an iPhone SE 4, which necessarily included a note on the lack of an ongoing slot in the iPhone lineup for my beloved 13 mini, got me once again thinking more generally about something that’s been on my mind a lot lately, as my 49th birthday approaches in 2023.

That thing I have been thinking is, this is not the future I signed up for. I’m beginning to understand why older people get set in their ways and cranky about change, in ways that probably could not have occurred to me until I had lived enough to experience a lot of things firsthand.

I remember lots of things, both good and bad. Most things, in general, improve and get better over time. But some things get worse — at least, worse by my subjective standards, because there are certain things I don’t want, like a phone that’s too big for me to use with one hand, or fit comfortably in my jeans pocket.

Possibly even more frustrating than things that get worse are things that just stop existing. Things I really liked that are now gone, especially if they are gone for reasons that I do not think are sound. That happens a lot for me with styles of music or genres of video games. I want new synthwave music* that I can get as excited about as when I first heard Tycho and Com Truise in 2012, for instance, or new Castlevania games that are as good as Aria of Sorrow.

True, sometimes those glories do return, and 2021 gave me a double whammy, in the form of Mitch Murder’s Then Again album and the all-time classic Metroid Dread. But more often than not, I just have to move on and give up on dreaming of a decent modern SimCity game, or a computer Scrabble that will ever be even a fraction as “smart” as the GameHouse version I loved back in 2006.

The world is change. I get that. It’s just hard to let go of things that I know are better than what has replaced them, and that makes me cling desperately to the old things I have that I’m still able to enjoy, whether that’s 40-year-old vinyl records on my turntable or 20-year-old GameBoy Advance ROMs in an emulator.

The true nature of the curmudgeon, I think, is not borne of pessimism. The curmudgeon is not purely a crank. It’s optimism, idealism. Belief in a world that could and should be better than the one we’re living in, because you remember something that’s gone. And beyond that, you remember the trajectory those past things suggested we were on. But somehow we never got where we were going.

Now, let me be clear: I’m not one of those MAGA types who longs for a return to their fictional, idealized version of what the 1950s were (at least, for white people). I’m inspired by the progress we are making towards a more equitable society for everyone — even as I see how far we still have to go. I’m longing for a future world that never was, but that I believed we could — and would — have by now.

Ironically, it was the sci-fi dystopias that were so popular in my childhood in the 1980s, that seemed to get many of the worst things about the 21st century right. The techno-fascism of corporations more powerful than governments, spying on our every action as a way to make more money. Aggregations of the intimate details of millions of people’s personal lives have become the most valuable commodity around. I didn’t believe this was the future we would have, but here we are.

I just want a small phone, some good music to listen to on it (ideally through wired headphones and a 1/8″ jack), and maybe a couple of games that are actually mentally stimulating instead of just “idle” ways to give up money or personal information in an endless stream of “microtransactions.”

Is that too much to ask?

* Of course, synthwave itself is an appeal to the future-should-be-better-than-it-is nostalgia of people (like me) who grew up in the 1980s.

This is the kind of thing that I find maddening about Gutenberg

First off, if you are the regular reader of this blog, you are painfully aware of how much I am waffling on rejecting or embracing Gutenberg (a.k.a. the WordPress Block Editor). There are things I genuinely do like about it, but I also have some fundamental disagreements with its approach (like the facts that it writes inline CSS directly into post content, or that its templates don’t support PHP code).

And then there are the weird little quirks that just make using it much more difficult than it needs to be. In general I have learned that this comes down to the incredible finickiness of JSON. Fine. But the fact that one character out of place in the theme.json file can break everything seems a bit ridiculous… or at least, a big step backwards for usability.

Fix your syntax. Sure. I wish JSON allowed trailing commas the way PHP — and even JavaScript! — does, but I can grok the fact that it doesn’t and learn to adapt. What I have a bit more trouble with is the problem that struck yesterday, only because it was so hard to pin down.

I’m working on a new, small block theme as a one-off for a unique project — a website that will feed menu board monitors in a pizza place. Seems like a perfect opportunity to practice and experiment a bit with what Gutenberg can do. (And, after over a decade of trying to find the “right” way to give restaurant staff a reliable but still easy-to-manage web interface for updating menu information, I actually think Gutenberg’s Block Patterns might be the optimal solution.)

So here’s the maddening thing. I was setting up my theme.json file like a good Block Theme developer, defining all of my colors, typography, etc. And then I started loading in some test content. All looked fine on the back end, in the Block Editor itself. But none of the styles were getting applied on the front end!

I googled the problem, of course, and found a WordPress forum thread about this very issue.

Huh. Sure enough, what’s described in the thread was exactly what was happening in my case. I had this line in my code (font names changed to protect the innocent):

"fontFamily": "'Helvetica Neue', 'Comic Sans', 'sans-serif",

Do you see the problem there? (No, it’s not the trailing comma… that actually belongs, in context.) It’s the stray apostrophe before sans-serif. Removing that fixed the problem.

Now, if this were just in straight CSS, I would have seen the problem immediately, because the syntax highlighting in BBEdit would’ve gone all wonky. But since this was inside a text string in JSON, it looked just fine, and I didn’t notice the apostrophe was there.

I get that the parser that converts the contents of theme.json into CSS would get thrown off by this. Honestly, I’m surprised it didn’t cause the whole page to bork with a PHP fatal error… I’m pretty sure earlier versions did throw a fatal error if there was any problem parsing the theme.json file. So this is… an improvement?

I also get that the generated CSS output would not work properly. What I don’t get is that it all looked correct in the Block Editor. Why was the Block Editor on the admin side able to “fix” this issue, but on the front end it didn’t? It doesn’t make sense!

Anyway, trying to unravel that mystery wasted about an hour late yesterday afternoon, when I was finally starting to get productive after having a near existential crisis over Gutenberg for most of the week.

These are hard times to be a WordPress developer. No, strike that. These are hard times to be a generalist web developer who happened to make the fateful decision 8 years ago to go all-in on WordPress.