Almost everyone who uses email knows there is a spam/junk folder, and know what it is. We love it. It keeps us sane. But the spam filters occassionally get things wrong. That's why when you sign up for a newsletter you are sometimes presented with a reminder to check your spam folder. It is common nowadays for SMS messaging apps to also have spam filtering. And similar to email spam filters, it…
For a long time Gmail Annotations was an opt-in feature brands could choose to implement. Now? Adding it is a matter of control. Gmail automatically tries to consume and understand the contents of an email, and tries to pull deal information even if you have not explicitly added these as Annotations. Free stuff is good. But automation cannot be perfect all the time. We're now seeing Gmail display…
You care about humans and want to make digital experiences accessible. Most businesses will prioritise whatever AI because it is the promised future. Good. Take advantage of that. A big chunk of accessibility work is making things accessible to machines so they can then be accessible to humans. Use their lingo. Call it machine-readable or AI-ready. That's how to make things AI-friendly 101. Take…
I wrote about how the use of the ping attribute for click tracking in HTML emails can be a more resilient for the email ecosystem. On 23 January 2026, I received an email from Salesforce about a security issue that impacted click tracking: Salesforce Security recently became aware of a security issue that affected links in emails sent through Marketing Cloud Engagement, including: Clicks,…
Working in a fast-paced, client-focused environment often means you have to keep the machine running at all times. There is little time to pause and evaluate. And even if there is general direction, you may have to go with the flow many times. You endure problems you know how to solve. In such environments, change is hard. Change here is only possible if individuals go out of their way and fight…
Many social media platforms serve small-sized content for you to get hooked on and consume more of. This is now a widely known thing and not at all ground breaking. You find yourself, and those around you, habitually wanting to consume more - regardless of what it is as long as it is short enough for their shotened attention span. Working in tech can make this worse. The industry moves incredibly…
In Wait.. Am I the third party? , I referred to HTML email code as third party code. This is because the email client (first party) has to render code (HTML email message) written by a sender (the third party) for the recpient (second party - direct user of the app). Why am I thinking about this again? Email messages may contain: dates phone numbers URLs email addresses physical addresses Some…
Jigsaw (a statitc site generator) has 3 events you can listen to and run custom code when these events fire. One thing you may want to do in an event listener is render some HTML using a templating language. It makes sense to use Blade for this just like the rest of the project. To do this, use BladeCompiler in bootstrap.php at the root directory of your Jigsaw project: 1 <?php 2 3 use Illuminate…
Tag directives are key to building Alpine.js components. However, Alpine is flexible enough that even if you don't have control over the HTML markup and cannot set directives directly on tags, you can still build Alpine components. Quick intro to Alpine directives An Alpine component must start with the x-data directive. Its value can be an inline object: 1 < div x-data = " { isOpen: false } " > 2…
When programmatically creating or updating a Collection Entry, you can lean on the Collection’s Blueprint to help you validate the fields values: 1 <?php 2 3 use Statamic \ Facades \ Blueprint ; 4 use Statamic \ Facades \ Entry ; 5 6 $ data = [ 7 ' slug ' => ' some-title ' , 8 ' title ' => ' Some title ' , 9 // more data 10 ]; 11 12 // validate the data 13 $ validated_data = Blueprint ::…
Statamic handles collection entries routing for you - given the route is set in the collection’s settings (can be done via the control panel or directly in the collection’s YAML file). When Statamic routes to a collection entry page, it automatically includes the entry variables in the view. You can access the entry’s title directly through the variable title . You don’t need to fetch the data in…
I like simple under-engineered solutions. This site was built with Jigsaw a couple of years ago, but I didn't like that I was using both PHP and Node.js (to compile assets with Laravel Mix). I switched to an all Node.js solution (Astro) for about a year, but I missed the simplicity of Jigsaw in comparison. So I switched back to Jigsaw, but decided I'd take a minimal approach this time with the…
With CSS it is not possible to transition the height property to auto : 1 . collapsible { 2 height : 0 ; 3 overflow : hidden ; 4 transition : height .3s ; 5 } 6 7 . collapsible . is-open { 8 height : auto ; 9 } For years developers relied on jQuery's (or Velocity 's) slideUp() and slideDown() methods to perform slide up/down animations without setting a fixed height. In fact, I remember being…
An "orphan word" in typography refers to a word that sits alone on the last line of a sentence. I don't know if there's a known term of the reverse of this, but it is something I needed to enforce in past projects: the first word of a sentence to sit alone on the first line . One way to achieve this is to add the line break <br> element after the first word: 1 < h1 > 2 Lorem 3 < br > ipsum dolor…
Without judgement: there are many developers who manually inline CSS in their HTML emails. This post is aimed at developers who choose or have to manually inline their CSS. If you’re reading this and not in the world of HTML email development, the short explanation is CSS has to be inlined out of necessity and not by choise. I’m not going to dive into the maintainabiliy issues of inlined CSS and…
The aspect-ratio CSS property is supported across all major browsers now: Data on support for the mdn-css__properties__aspect-ratio feature across the major browsers But most major email clients still do not support it: Yet, you can rely on it for images! Set the width and the height attributes on the img tag, and the browser handles the rest: 1 < img src = "…
Recently I visited a sort of airsoft gun range. They had rooms with different set ups and challenges. In some of these rooms, they can run different types of games. I was in one of these rooms and what caught my attention is how the operator selected and started the different games.. with a one-button interface. All he had is a yellow box with a single red button. He hits the button in different…
I used to write code for environments on which I had almost complete control. If there was third-party code running on these environments, it was because I (or the development team) explicitly allowed it to run. And that level of control felt good! However, these days I author a lot of code that run in environments on which I have very little control. This feels frustrating at times. Adding…
I've lived in 3 countries so far. And in all 3 countries I've encountered groups of people who cannot speak or read the local (or the most commonly-used) language. Between new international students, foreign workers, immigrants and refugees there are many people who won't understand the content you have on your website, or the messages you send them via email. I once was a new international…
It's no secret that support of various CSS features is fragmented and widely inconsistent. But have you thought about what it takes in order to confidently say a feature is supported in an email client? Let's go through the various technical aspects you need to consider when testing CSS in email. Browser support Let's start with the easy one. Most email clients rely on a browser to render HTML.…
A few months ago I wondered whether it was possible to use CSS to control the positioning of diacritics within Arabic script. This has led me to a very interesting read: Text Layout Requirements for the Arabic Script (W3C working draft). Even as a native Arabic speaker, there are many points in that document (or other documents it links to) I had not really thought about. The Arabic and Persian…
I have recently learned that deferred loading of <img> s with the loading attribute only works if JavaScript is enabled. 1 < img loading = " lazy " src = " /image.jpg " alt = "" /> The MDN documentation notes that this is an anti-tracking measure: Loading is only deferred when JavaScript is enabled. This is an anti-tracking measure, because if a user agent supported lazy loading when scripting is…
Recently Abdelhadi Jaffar has translated the Alpine.js documentation to Arabic, and it was added among the other translations on the Alpine.js GitHub repository , all of which are Markdown files so they are nicely rendered and can be read directly on GitHub. Arabic is written right to left, but GitHub's layout is LTR. This made the Arabic documentation hard to read on GitHub. Fortunately, we can…
I really like overflow-x: scroll and I think it is very much underused in favour for Javascript solutions when it comes to sliders on the web. I, too, used to default to Javascript solutions until I realised they created more issues in some cases (I also got one-too-many last-minute requests from agency clients to change the mobile behaviour of a section to a slider). Rely on the browser I am…
I have recently launched a new website ( wajad.art ) with an internationalised domain name (IDN) . The domain name and all the page paths are in Arabic, which makes things more fun given Arabic is written right to left (RTL). Domain name is وجد.موقع , and موقع is the top-level domain (TLD), which is the equivalent to the site TLD. A full URL example of page: 1 وجد.موقع/م/أساطير-خليجية How do IDNs…
The lang attribute is used to define the language of the document or a single element. 1 < html lang = " en " ></ html > Adding the lang attribute to an element seems to affect which glyphs in a web font some browsers render, and which system font is rendered. Here is a demo where different paragraphs have different lang values, but they all share font-family: sans-serif : See the Pen lang…
A bitmap image is one of the things you may not immediately think of when writing CSS and HTML for dark mode. Unlike an SVG, you cannot simply change the colours of the shapes in a bitmap image with CSS by specifying what colours you want them to be. And the approach you would take to handle a bitmap image in dark mode can vary depending on the type of image and the environment you are working in…
On 7 June 2020 Bulma v0.9.0 was released and while I always wanted the spacing helpers it introduced, what I was most excited about is the RTL support! Shortly after, Bootstrap 5 alpha was released and they also announced RTL support! I live in a part of the world where it is becoming extremely common for websites and web apps to offer both English (LTR) and Arabic (RTL) versions. Seeing popular…
Fontawesome added duotone support back in July 2019. So this is a little overdue, but better late than never! You can now use FontAwesomeSVG-PHP v1.2 to output Fontawesome duotone SVG icons with PHP (no JS required). Output a duoetone icon in single colour: 1 echo $ FA -> get_svg ( ' fad fa-laugh-wink ' , [ 2 ' fill ' => ' #e64980 ' , 3 ]); Swap layer opacity by adding the fa-swap-opacity class: 1…
When using Alpine.js the x-cloak attribute is removed from DOM elements when Alpine is initialised. As noted in the docs, this makes it useful for hiding elements until Alpine is initialised: x-cloak attributes are removed from elements when Alpine initializes. This is useful for hiding pre-initialized DOM. It's typical to add the following global style for this to work: 1 < style > 2 [ x-cloak ]…
I've updated FontAwesomeSVG-PHP with improved accessibility features. If you are not familiar with FontAwesomeSVG-PHP, it is a PHP class that inlines Font Awesome 's SVG icons without Javascript. It renders the icons on the server side instead of outputting something like <i class="fas fa-file"></i> and have Javascript replace that with the actualy SVG icon on the client side. What's new?…
I've been really enjoying The Art of Product podcast lately. In their latest episode of 2019 " Should We Be Setting Annual Goals? ", Derrick Reimer and Ben Orenstein discuss annual goals. What Derrick said about habits vs goals made me think about goal setting again: I think it is helpful to at least name, if not goals, then what habits I want to form.That's kind of how I'm thinking about it.…
Today I read It's okay to miss goals—if you learn from it by Hannah Herman on Zapier's blog. It is a good read. It reminded me of Syntax's epidode 67 - Goal Setting which I re-listen to from time to time. Even though Hannah's article title sounds like it is only focused about learning from missing goals, it also discusses some tips on setting goals. During Syntaxt #67 Wes Bos and Scott Tolinski…
Every now and then I listen to a podcast episode that resonates with me or changes the way I think. I end up listening to these episodes multiple times. So I've decided to blog about these episodes, and I'm starting with my all-time favourite: Full Stack Radio #102: Paul Jarvis - Staying Small Full Stack Radio's Adam Wathan "talks to Paul Jarvis about defining your own version of success and why…
The dir attribute in HTML and the dir property in CSS can be used to set the direction of text and horizontal flow. Some languages are written Left-To-Right (LTR), while others are written Right-To-Left (RTL). So having this level of control is vital for creating documents and interfaces for the web. Building an interface to support both LTR and RTL layouts is a challenge. Flexbox and Grid…
Propertybase is a real estate solution for real estate agencies. You can use it to manage your property listings and sync the listings with your website via their API . They have a nice simple API for fetching filtered property listings . However, it was unclear to me how to filter the listings by a field whose value is empty or set to a certain value. The syntax for filtering by a field that is…
"Every developer eventually builds a CMS" is a joke I came across enough times that I promised myself I wouldn't do it. Although I think the joke often comes from developers who have been in the industry for a lot longer than I have, and perhaps enough of them either built or came across custom CMS solutions. Luckily, we are no longer in the era in which building a bespoke CMS is common for…
I have recently updated my site. This is the third version of the site since I launched it in 2015. I soft-launched this version a few months ago, and while I am still polishing things I am pleased of the increase I have seen in the leads I am getting through the website so far. Blog While I have not been publishing on this blog consistently, I wrote a lot more on my Perch-focused blog, Pipits .…
Font Awesome is a popular icon library. It used to be an icon font, but now in Font Awesome 5 it also come with SVG icons. One reason of Font Awesome's popularity is the ease of use. You add a CSS file and a JS file to your document, and you're set. You can then add the icons like so: 1 < i class = " fas fa-home " ></ i > When the SVG icons option was introduced, they kept it just as simple which…
I have recently launched Pipits for Perch , a collection of Perch add-ons, aiming to help developers build feature-rich Perch websites faster. You can find out more about it and Perch on here . There's also a blog on the website about working with Perch and Perch Runway. So I may not post many Perch-related posts on this blog. The response from the Perch community has been positive and hopefully…
Many websites and apps let you sign up via social logins, signing up to the website/app using the credentials from popular social networks such as Facebook and Twitter, and rightfully so. Who wants to go through the trouble of filling in a form, remembering yet another password and verifying their email address or phone number? Instead most would rather just do it in two clicks via a social login.…
Some of your Perch templates might be quite long. For example, a typical product template (using the Perch Shop app) has 20+ Perch tags: the default tags you need to keep and the custom tags you may add. When you start mixing your HTML with so many Perch tags, it can get a little messy. Firstly, there can be a lot in there: you have Perch tags that contain many attributes that improve your edit…
The Problem You need to design a table that displays its data in two different units. You want to avoid displaying both sets at once. I came across this little problem while working on an e-commerce website. The client wanted to display the measurements in their size guide in both centimetres and inches. The user shouldn’t have to convert the measurements to their unit of preference. And…
The select Element The select element is mainly associated with drop-down menus/lists. That's the default after all. You add a select element to a page and you see a white rectangle with an arrow pointing down at one end. You click on it, and based on the default behaviour you see a drop-down list of options for you to choose from. This is the default behaviour on desktop browsers (and tablets?),…
If you are already using a JavaScript library for your animations (e.g. Velocity.js ) on your project, chances are it has a function that allows you to smooth scroll within the page and possibly even within scrollable containers. So you could just use it to add smooth scrolling. But there are cases where you find yourself working on a project that doesn’t require much JavaScript to justify using…