This version marks the 5th redesign of jdmweb.com in 15 years. I put the previous version online more than 6 years ago, so it was time for a renewal. Now that it’s live, I wanted to share how this site has been designed and built.
The previous version had made its time. It ended up looking old. I was eventually embarrassed by both its design and its content so it was time for a new departure.
This time I wanted to work on a very minimalistic design, emphasizing on typography and contrasts, that’s why I turned to my friend Adrien from Heury and Heury, whom I know is always excellent at this kind of exercise.
And I truly wasn’t disappointed at all. The first drafts looked excellent right away, and after a few adjustments, we validated the screens quite quickly.
As requested : minimalistic, nearly black and white, clean, adjusted, no unnecessary fanciness. And finally, a good focus on typography, with the use of ITC Avant Garde Gothic Pro.
This phase where the designer hands its design off the developer is an important one in the lifecycle of a project because there needs to be a communication of many information to the developer. He/she should not feel left alone in front of a photoshop or sketch file, but more importantly, he/she should not have unanswered questions about how to make the design come to life. He/she should not have to interpret or invent answers about the questions he/she’s facing.
Here are a few typical questions that get asked at this stage : Where can I find the fonts? What is the list of the color references? How does this button behave on hover? What happens when I click on this link? What are the different container sizes? What’s the size of the grid? How can I download the images? What font is being used on titles vs body text? What are the different text sizes? Etc.
Adrien uses Invision to share his designs with clients and developers alike. He also uses it to make prototypes, and did one for me. Invision has a very useful feature called Invision inspect. I encourage you to check it out because it’s very valuable in a design handoff. It can provide many useful information to the developer that can click on elements to get accurate information about it. No guessing. It can even generate some CSS code for you, or allow you to download design assets on demand or grouped together. It saved me many time, and most importantly for me, it reduced the need to get Adrien’s time to provide me precisions or assets.
Design Analysis and Development preparation
A word about components
This website is going to be both my portfolio and my blog. I’ll be using it to write content. With this goal in mind plus the fact that I’m very fluent with WordPress, and that’s a tool recommended for this kind of job, I’m going to choose this CMS to build the site. No need to add that I like to play with the Gutenberg editor, which I find particularly efficient when writing.
With the avent of Gutenberg, I’ve reinforced my component approach to transform a design to a website. In other words, when a design comes in, I analyse it to decide what should be a web component, what type of component it should be, and what properties it should have.
For a WordPress site, I usually sort components into four categories :
- Custom react blocs : These blocks deserve the best Gutenberg experience. I therefore put time and attention to code a custom React block as intended by the developer handbook. It’s blocks that usually take more time to code due to their custom nature and the quality of editing experience we want to deliver.
- Abstract backend blocks : These blocks are not custom Gutenberg blocks. These are php classes, that are automatically made available in Gutenberg, if these classes have the correct annotations that make them an Abstract Gutenberg Block. In Gutenberg, they are presented as forms to fill. You could think about it as a super shortcode enhancement. We use these blocks when the purpose of the component it serves does not deserve the full Gutenberg editing experience. Because they are Abstract and the abstraction process is well documented, these blocks are very quick for me to code and to make available in Gutenberg. I’ve written a dedicated post on the subject if you’re interested.
- Default Gutenberg blocks : These are blocks that are available by default when you install a WordPress site. It’s worth knowing them all, what you can do with them, and what you can’t. For example, I frequently use the paragraph, columns, gallery, and media ones.
- Standalone components : These are web components that are going to be used in the integration process, but not made available in Gutenberg (by choice), for example in my case : the logo component, the main nav, the footer, etc…
From the design screens and the component sorting technique explained above, here’s an example of how I organized some of my components to get you an idea :
- BackToTop : standalone
- BlogArticlesList : standalone : hydrated automatically by the backend
- BlogArticleItem : standalone : hydrated automatically by the backend
- CaseStudies : standalone : hydrated automatically by the backend
- CaseStudyItem : standalone : hydrated automatically by the backend
- Clients: standalone : administered by shortcode (could be promoted to abstract or custom block)
- Code: AbstractBlock: administered in Gutenberg (could be promoted to custom react block)
- Container : Custom react block
- Expertise : AbstractBlock, administered in Gutenberg
- Footer : standalone
- FourOFour (404 page) : standalone
- Header : standalone
- HomeSection : AbstractBlock, administered in Gutenberg
- Job : AbstractBlock, administered in Gutenberg
- Logo : standalone
- Main Nav : standalone : hydrated automatically by the administered menu
- Section (HTML section element) : Custom react block
I’ve introduced above that it would be a WordPress site. However, it’s not a default WordPress install, it’s a bedrock architecture. If you don’t know bedrock yet I encourage you to check it out because it’s a very clever architecture much more suitable for professional use than the standard version. This is not a post about bedrock per se, so I’m not going to write too deeply it, but in a nutshell :
- It opens up the possibility to use composer by default.
- It treats WordPress as a vendor dependency, which is handy in practice.
- It also eases the use of multiple environments (local, staging, production), which is a standard for us so we find it great.
When you develop for WordPress profesionnaly, you might end up frustrated by the developer experience. Thankfully, a movement emerged among WordPress pros to bridge the gap between WordPress and modern php frameworks like Laravel or Symfony. For example, you can check the work of Carl Alexander, Tom McFarlin, Alain Schlesser, Greg Rickaby, and frameworks such as Themosis, …, and WonderWp.
WonderWp is a WordPress framework whose goal is to give WordPress industrial and modern development capabilities. By default WordPress alone does not really have many characteristics of a modern php codebase. The WonderWp framework’s aim is to bridge that gap and enhance the developer experience. It also makes a step towards other frameworks and libraries by providing serveal PHP-FIG recommendations implementations, and opening the use of composer.
We use it on all the WordPress project at Wonderful, and I’m also going to use it for my personal site.
I like to keep my css focused, namespaced and organized, that’s why I usually go with SASS to code my styles. That way I can explode the CSS declarations into many small partials (at least one per component), and I always start the partial with a namespace (an indented declaration that encompasses all the others).
I see two main reasons for doing that:
- First, it helps me keep control of the cascade, by having one or several master scss files that contain only imports of the different required partials. That way it’s easy to read and see the order of things.
- Second, the namespacing technique helps me to keep CSS declaration focused, and to make sure declarations do not overflow or overwrite something else in the project. It’s also a good safeguard when doing maintenance. The namespaced declaration ensures you, that what you are coding and changing in this file, won’t harm any other part of the project. I’m aware of identation pitfalls so I try not to abuse it.
I also like SASS thanks to its variables and mixins mechanisms. As a developer it speaks to me and I can take advantage of those to make my styles more adaptable to changes.
This time though I also wanted to experiment with css variables, so I tried an hybrid approach : I use SASS variables in my code, but the sass variable value is in fact a CSS variable. That way I can benefit from both sides : the robustness, rigor and IDE integration of sass variables, and the dynamic aspect of CSS variables, allowing me to test changes from my web inspector for example.
I didn’t make anything too complex with CSS variables for the moment, but I definitely liked the hybrid approach. I’ll write a dedicated article about this soon.
Back on the subject now, for performance and good practices reasons, the CSS layer is then fed into Gulp, that processes the files to compile sass into CSS, combines files, prefix them, and minify them.
Progressive enhancement and components handling with PewJs
I’m a disciple of progressive enhancement for presentational websites like this. Even though Bedrock is an alternative backend architecture, it’s not headless, that means pages are server side rendered with PHP.
Having said that, here’s how I handle the progressive enhancement of the site. There are two main aspects in it : I use a browser / user capacity scanner (like modernizr), and a progressive enhancement library called pewJs.
I then use Pew to manage my JS components.
Basically, you write components, you register them with Pew (which works as a registrar as you can see in the documentation), and then you tell pew to enhance a dom element (the entire dom by default, or a specific piece in case of an Ajax load for example), based on this registrar. If Pew finds a Dom Element that matches a component definition inside its registrar, it creates an instance of the component class and gives it the found dom element as a parameter.
For example, if you create a component that should work with Dom elements that have a class .my-component, and there are two of those instances in the Dom, pew will create two instances, one for each.
Adding Animations with GSAP, ScrollMagic & BarbaJs
I’ve been a great fan of the GSAP animation library since I started working with it 5 years ago. I usually use it for all animation work. I like the way it helps me keep control and understanding of complex animations, or just orchestrating consistently, simpler ones.
This version of my website being rather minimalist, I took it easy on animations. No extravaganza, no long transitions, just a well balanced sprinkle here and there to either add rhythm to the reading experience, or transition smoothly from one page to another.
GSAP plays well with other libraries depending on the context. For example, on this site I’ve used it in combination with ScrollMagic to trigger animations on scroll. I’ve also used them with the excellent Barba.js library to handle the full ajax setup and page transitions. I use GSAP transitions on specific Barba events to animate the out and in page transitions.
With progressive enhancement and accessibility in mind, animations are disabled if the prefer reduced motion setting is active on your machine. You can try to toggle this setting on your machine to see the difference. And this is the article demonstrating this technique.
Web performances is at first glance not an easy thing to achieve as there are so many things at stake. Be it backend performance (php code perf, database perf), frontend perf (assets download, assets caching, critical css, preloading, lazy loading), and so on…
So to ease this part, I installed the WP Rocket caching plugin which made my life easier by taking care of many aspects right upon activation.
On the backend side, WP Rocket computes for me a static HTML version of my pages instead of having the server calculating the output on every request. This shortcuts the backend part of the request, and helps with the Ajax transitions.
On the frontend part, assets are bundled, (transpiled, concatenated, minified and timestamped) by my Gulp instance. Then WP Rocket handles the caching part of those bundles.
Overall I’m pleased with the lighthouse performance results :
Thank you for taking the time to read this case study. I hope you enjoyed it and that it shed some light on some aspects of my development process.
It’s true that it’s always difficult to balance the time you can spend on your personal site and the added value you can take out of this time to build something good enough to represent you online, but in this case I’m at peace with the result. Here’s to the next five years maybe!