Stupid jQuery and CSS tricks: Move a hidden element to the end of the parent

I just came up with a solution so simple, yet so stupid, that I had to share it.

The scenario is this: my client has some third-party JavaScript to inject a form into a page. I’ve been writing some of my own CSS to style the forms, including some crafty use of :nth-of-type(2n) and :nth-of-type(2n-1) to apply styles conditionally to adjacent fields in a two-up layout. (These are just sequential <div> tags, and I have to work with what I’ve got.) Specifically, I’m adding some right margin on the “left” element, and no right margin on the “right” element.

I noticed an instance where my margins were flipped for two fields, and when inspecting the code, I discovered why: the client has set up their form with a hidden field tucked in there before the “left” element. That’s throwing off the value for 2n in my CSS. I was going to contact them and ask them to update their form to put the hidden element at the end, but I realized this is a problem that is likely to recur, so I should just write in a workaround. (Yeah, yeah. But it’s the lesser of two evils.)

Fortunately, the site is already using jQuery, so a fix was super simple. I’m leaving the CSS class names here as they are in the actual site, but you may need to change them to suit your particular form.

jQuery('.form_container .form_page .form_question.hidden').each(function() {
    jQuery(this).appendTo(jQuery(this).parent());
});

Since the hidden field has the .hidden CSS class, it’s really easy to use the jQuery .appendTo() method to just take all of the hidden fields and shove them to the end of the container element. I used the parent and ancestor CSS classes in my jQuery selector just to be sure I’m isolating this action to these particular forms. Then of course I have to tell the page when to execute this functionality, which is ideally on the load event:

jQuery(window).on('load', function() { /* Code goes here */ });

It works!

A simple way to add responsive (breakpoint-specific) blocks in Gutenberg

The new WordPress Block Editor (a.k.a. Gutenberg) has improved immensely over the years, to the point where I am now willingly (although occasionally grudgingly) using it as my main development platform for client sites.

One area where it really falls down though is in smartly handling responsive breakpoints. There is some effort to make it responsive-friendly (though it’s definitely not “mobile first”), but there are really weird holes, like the fact that there’s no built-in way to apply consistent left and right margins on text content at smaller screen sizes; once you’re below the defined content width, if you don’t manually configure your theme to add padding/margins to headings, paragraphs, etc., and they don’t have a defined background color, the text will bump right up against the edges of the screen.

That’s not the problem I’m here to solve at the moment, however. Instead, I want to focus on a handy little tool I’ve been using in my WordPress development for over a decade: specialized CSS classes to designate blocks of content as only appearing on phones, or not appearing on phones.

By “phone” here I just mean the smallest standard breakpoint. I’m using the WordPress convention (at least it used to be the WordPress convention; I don’t feel like I can trust anything anymore) of setting that at the slightly odd (although even) value of 782 pixels.

What can you do with this? Once you have CSS classes that designate a block as only appearing on phones or not appearing on phones, then you can easily tailor your output to certain screens. Obviously (at least, I hope it’s obvious) this is not the ideal solution; it means you’re delivering HTML content — potentially redundant HTML content — that will not be seen by some users. But nothing in web development is perfect, and this can be a convenient way to get out of a pinch when, for example, you have a very complex desktop layout element that simply cannot be adapted in a usable way on phones. You can just hide that element on the phone breakpoint and, if desired, present the same content in a more simplified way to only phones. (Again… only if you can’t achieve a usable phone experience on the same HTML block via media query-specific CSS.)

OK, let’s get down to it. The first thing you need to do is register a couple of block styles. I am only making these styles applicable to the Group block, because that seems like a logical way to rein it in. Any block can easily be wrapped in a group, so if you need this feature, just do it.

register_block_style('core/group', array(
  'name' => 'no-phone',
  'label' => 'No phone'
));

register_block_style('core/group', array(
  'name' => 'phone-only',
  'label' => 'Phone only'
));

That should go into your functions.php file or wherever in your theme you are defining block characteristics. Ideally it should be in a function that is executed on the init action. Next, you need to make sure you’ve got a custom block style .css file enqueued for the Group block. You can place this wherever is appropriate within your theme; I happen to have a nested assets/css/blocks folder where I put mine. Here’s that bit of code, also for your function that runs on init.

wp_enqueue_block_style('core/group', array(
  'handle' => 'my-theme-core-group',
  'path' => get_theme_file_path('assets/css/blocks/core-group.css'),
  'src' => get_theme_file_uri('assets/css/blocks/core-group.css'),
));

And then in the referenced core-group.css file, you’ll need this:

@media screen and (max-width: 782px) {	
  .wp-block-group.is-style-no-phone {
    display: none !important;
  }
}

@media screen and (min-width: 783px) {
  .wp-block-group.is-style-phone-only {
    display: none !important;
  }
}

Now in the Block Editor, when you switch to the Styles tab when focused on a Group block, you’ll see your new style options:

A reason to install Microsoft Edge on your Mac: viewing cookies

As a web developer, I actually don’t use cookies that often (mainly because I’m not interested in tracking users’ behavior). But I do need to use them occasionally, such as to remember when they’ve clicked the “X” to close a modal alert, so I don’t keep showing it to them on each new page they visit.

That’s what led me to today’s surprising discovery. My cookie wasn’t working properly, so I wanted to investigate a) whether or not it was actually being saved, and b) what data it was saving.

I work on a Mac, and Safari is my primary browser. But I already knew Safari doesn’t let you inspect the contents of cookies, so I fired up Chrome, which is my go-to for testing anything that I can’t test with Safari. I know Chrome always used to let you inspect the contents of cookies, so imagine my surprise today when I discovered that, at some point fairly recently, Chrome apparently removed that capability. You can still see which sites have stored cookies, and how many, but you can’t investigate the details any further than that. Seriously??

Next I tried Firefox. Nope, same.

At this point I was highly dubious that the fourth browser in my testing queue would handle things any differently, but I had no alternative, so I reached for that rarely-clicked-upon blue-green swirl icon in my Dock, loaded my page in Microsoft Edge, and… what do you know, Edge does still let you inspect the exact contents of stored cookies.

But for how long?

Anyway… for now, I have a justification for keeping Edge installed on my Mac.

Vindication!

I already mentioned this in an addendum to my last blog post, but it seems to warrant its own dedicated post.

I’m a self-employed, solo developer, not very actively engaged in the WordPress “community” even though my work is 95% WordPress. So I have apparently missed the memo that shortcodes were (prior to yesterday’s release of WordPress 6.2.1, anyway) the way people were injecting PHP into their HTML-based Block Theme templates. (Silly me… I was just misusing Block Patterns to the same effect.)

Well… as it turns out, allowing shortcodes in Block Theme templates apparently was a security issue, which the WordPress core team summarily “fixed” by just outright removing shortcode support in templates in this update.

This change did break a pair of sites for me (which are still just in final testing, not live, and which I need to go fix as soon as I finish writing this), but the problem was relatively minor. It sounds like a lot of people are using shortcodes extensively as a backdoor hack for adding PHP functionality to templates, and they are… um… not happy.

At what point does the Gutenberg team collectively take a step back and realize that maybe they’ve been the ones Doing It Wrong™ all this time? I feel like that reckoning is approaching.

A Gutenberg/Block Editor revelation… just stop trying

This is not as defeatist as it seems by the title. I’ve actually had a huge breakthrough in my ongoing battle journey with the WordPress Block Editor (a.k.a. Gutenberg).

My biggest problem throughout the process of trying to build a Block Theme has been finding myself hamstrung by the lack of PHP in a Block Theme’s all-HTML template structure. I’ve ended up brute forcing my way into having access to PHP with a combination of ACF Blocks and Block Patterns. But it should have been obvious to me that both approaches were wrong, because I found myself creating ACF Blocks that didn’t have any custom fields and Block Patterns that didn’t have inserters.

The fact that I was using both of these tools in ways that they are patently not intended to be used should have been my first clue, but the problem has always been that documentation of all of this new technology is so scarce, inconsistent, poorly organized and out-of-date by the time it’s written, that it’s hard to really know in advance how they work, and whether or not you’re using them properly. And as my recent series of blog posts have indicated, I am the proud king of Doing It Wrong™.

But as I said at the beginning, I’ve had a revelation, which is this:

The only reason to create a pure “Block Theme” is if you intend to use the new Site Editor (a.k.a. Full Site Editing).

I emphatically do not intend, now or ever, to use the Site Editor, because I have always coded themes from scratch, and the people I am building sites for do not want to modify the overall design themselves, nor should they be given access to the tools to do so.

I am completely locking down access to the Site Editor on the sites I build, so why should I design my themes to work with it? Well… until now, I kind of just thought that was The Way Forward. Maybe it is, but it’s a way that does not, at all, align with how I do business or what my clients want/expect from me.

Luckily, core WordPress team member Carolina Nymark has written an excellent introduction to using PHP templates in block themes. It’s as simple as this. Just… use the old PHP-style of templates. There are a few tricks to be aware of, most of which are addressed by Carolina’s article, but some more I discovered along the way.

I’ve spent the last year and a half of building my block theme constantly butting up against this frustrating limitation. Now after about 4 hours of work, I’ve managed to convert my nascent Block Theme to using PHP templates.

I’ve eliminated my custom field-less ACF Blocks.

I’ve eliminated my un-insertable Block Patterns.

Things are working like they should. Well, mostly. This is an ongoing process. But the key test of the change has been that everything that was working in the theme before is working now, and I have the full capabilities of PHP and the long history of PHP-based WordPress development back at my disposal for future work.

I’ll write more about this in the coming weeks as I refine my process, including an overview of my general setup for a Block-friendly but PHP-rich base theme.

Update: Well, it seems rather fortuitous that I chose this undertaking when I did, because it coincides perfectly with the release of WordPress 6.2.1 which breaks shortcodes in Block Theme templates (which is even more of a shitshow for some people than it is for me, since it hadn’t occurred to me that shortcodes could be used as a workaround to the absense of PHP in Block Theme templates), including a pair of sites I’m currently developing using this theme. Switching those sites to the new PHP-based version of my theme should fix this issue automatically.