Postmortem Of Gutenberg The Launch, So We Can Embrace Gutenberg The Product

dreamt up by webguru in Uncategorized | Comments Off on Postmortem Of Gutenberg The Launch, So We Can Embrace Gutenberg The Product

Postmortem Of Gutenberg The Launch, So We Can Embrace Gutenberg The Product

Postmortem Of Gutenberg The Launch, So We Can Embrace Gutenberg The Product

Leonardo Losoviz

After 10 months of being released as WordPress’s new default editor, Gutenberg is still shrugged off by a sizable amount of people from the web development community, who frequently cite as reasons to disregard it its lack of accessibility support (even though major accessibility improvements have taken place), how slow it is (even though it is running much faster now), and several other grievances. This pessimistic reaction to Gutenberg is most evident in online articles demonstrating Gutenberg’s capabilities which, instead of eliciting a positive reaction from the readers, they mostly attract contempt (as reflected in a stream of negative comments).

Many people seem to be angry “at Gutenberg” (we will see in a while what Gutenberg actually is), expressing that Gutenberg should never have happened or, at least, never have been integrated to WordPress core as its default experience, or at least not so soon. Different people have different reasons to be opposed to Gutenberg, with some of their reasons being more personally significant than others. For instance, some people have seen their livelihoods jeopardized, having worked hard to specialize on a certain solution which, due to Gutenberg’s arrival, is in peril of disappearing (such as anyone working with this brand or that brand of page builders). I can truly understand why these people are angry at Gutenberg, and I sympathize with them.

However, I do also believe that being endlessly angered by Gutenberg and dismissing the whole of it — without even considering if it may be worth using after all — is not a sensible approach. When it was initially launched, I was quite opposed to Gutenberg, thinking that it was not ready, and this stance lasted for several months. However, I have lately found myself using Gutenberg more and more, and I can even claim that, nowadays, I’m actually enjoying it. While at the beginning I was a bit angered “at Gutenberg” myself too, I let my anger go away, and now I can actually benefit from it.

Through this article, I will attempt to change the narrative under which Gutenberg is most commonly depicted. I will enumerate what went wrong in the past, and describe what Gutenberg has been and what it is, from which I can give a leap of faith to present Gutenberg in a favorable light. I will also argue that Gutenberg already is a positive force, and as such, it deserves being given another chance (if you haven’t done so yet).

What Gutenberg Actually Is

From my point of view, the most important reason why Gutenberg is not more widely accepted is that, when people talk about Gutenberg, they equal it to not one but actually two entities (which are confused with each other), namely:

  1. Gutenberg, the launch;
  2. Gutenberg, the product.

Gutenberg as “the product” is the plugin/functionality itself. Gutenberg as “the launch” was the process that involved the initial development and release of Gutenberg, possibly starting when WordPress founder Matt Mullenweg introduced Gutenberg to the wider audience in June 2017 during WordCamp Europe 2017, and ending in early December 2018 when WordPress 5.0 was released with Gutenberg merged into it.

(Once the launch was over, a new stage started which continues until today: The “Gutenberg continuous delivery cycle”. However, this stage is very different from “Gutenberg the launch”, as there have been no serious issues with it, and as such it doesn’t produce any misconception towards “Gutenberg the product”. For this reason, there is no need to talk about it in this article.)

We must distinguish between the two entities, “the launch” and “the product”. As such, from now on, I hope that when we refer to “Gutenberg” it invariably means “Gutenberg the product”, and if we want to reference “Gutenberg the launch” then we must explicitly name it (possibly using any of its variations, such as “Gutenberg’s initial development/release” or similar phrases). Most importantly, we must refrain from mixing the launch and the product in the same bag: Mentioning any factor that contributed to Gutenberg’s disappointing launch as a reason to not use Gutenberg in our projects should be phased out, and Gutenberg as a product should be judged only against its own qualities. This is being fair to Gutenberg the product.

I believe that, while “Gutenberg the launch” has been justly criticized, the constant scorn aimed at Gutenberg the product has been unfair (even if it were justified), and that Gutenberg the product is, itself, a victim from the stained reputation conferred to the name “Gutenberg” during its frustrating launch. For instance, when searching for “Gutenberg” in the WordPress plugin directory, because the algorithm deciding the plugin ranking factors in the plugins’ rating, Gutenberg appears only around the 10th position. However, many of the 1-star ratings would not have taken place if Gutenberg had not been merged into core; had it been initially released as a plugin only, and waited until the most important bugs and issues (such as the lack of accessibility) had been resolved before merging to core, then its rating would today be higher.

If we are able to split apart the two entities (the launch and the product) and deal with them separately, then, on one side, we can do a postmortem of what went wrong during Gutenberg’s launch and feed this knowledge into the current continuous delivery cycle, so that the same mistakes will not be repeated (indeed, this seems to be happening already, as I will describe below); on the other side, we can allow ourselves to appreciate Gutenberg as a product, add it to our stacks, and hopefully benefit from it.

I will do exactly this, from my own point of view.

What Went Wrong During The Launch Of Gutenberg

In a single sentence, the team leading the process messed it up (that’s the polite way to say it).

WordPress 5.0 with Gutenberg merged into it was launched in early December 2018, just before WordCamp US. Launching it then was the wrong decision, for a very simple reason: Gutenberg was not yet ready. In particular, the accessibility situation was very dire, with Gutenberg being almost useless through accessibility devices such as screen readers, effectively making anyone depending on such devices unable to use the WordPress editor. And because the WordPress community is very vocal in protecting the rights of everyone (literally everyone) to be able to access the Internet, this rushed launch was not well received.

Matt Mullenweg (who was leading the release process) may have had good reasons to be adamant about launching on that date, which could have, for instance, made sense from a business perspective. However, it certainly did not make sense from a community perspective. Indeed, many community members felt betrayed, complaining that they had to hurry to test their clients’ sites even though they were on holiday. We can safely say that, for many people, such a premature launch was perceived as a wreck (even if the software was working properly, so no Y2K actually happened), which created unnecessary discontent, and which could have perfectly been avoided by either postponing the launch, or by first releasing Gutenberg as a plugin to be merged into core at a later, more stable stage.

Was the pain, frustration and disappointment inflicted in the community really worth the cost? I believe most people will say it was not. I absolutely think it was not. In my opinion, these kind of situations in which an action is taken against the will of the majority of the community members must be avoided in the future (unless there are really good reasons for it, even if not everyone agrees on them; if that was the case concerning Gutenber’s launch I do not know, since I’m unaware of any really good reason to justify it).

In his presentation during that same WordCamp US, Matt Mullenweg did acknowledge that mistakes were made during the launch of Gutenberg, and that he had learned the lesson so that these mistakes will hopefully not be repeated. I reckon we can accept his apology and trust that his decisions will be the right ones next time (even though new quarrels on equally-important topics have taken place since then). However, the damage is already done: A wound has opened up which may take time to heal, so the community will be less trustful until confidence in the WordPress leadership is fully restored.

Why Things Seem To Be Much Better Now

Now comes the good news: The state of affairs appears to have mostly taken a positive direction, with the improvements listed below already happening.

Improved Communication

One of the loudest complaints about the Gutenberg launch was the lack of communication by the leadership. Because no proper channels to manage the project and communicate its decisions were put in place (at least not in a comprehensive manner), it was difficult to have an accurate picture of the overall situation. (For instance, information by different authors or teams was published through different avenues, including unofficial ones such as personal blogs.)

This concern has been greatly improved. In particular, the amount of information in the make blogs (where the different communities interact to take decisions concerning WordPress for different areas, such as core, accessibility, design, internationalization, and others) and the frequency with which the information is updated have been increased, and every team holds a regular Slack-based meeting (mostly taking place on a weekly or biweekly basis) in which anyone with a user account can participate. As experienced by some community members, it is now possible to reliably follow the developments on some topic, and have enough information to be able to become involved.

The fallout from Gutenberg’s launch also prompted Matt Mullenweg to expand WordPress’s leadership with two new roles: an Executive Director, to oversee and direct all contributor teams in their work to build and maintain WordPress, and a Marketing & Communications Lead, to lead the marketing team and oversee improving, related websites, and all its outlets (unfortunately, the person assigned to this role quit not long after, so somebody else must be found to take over this position).

Triage Team Formed To Tackle Open Issues

During the initial development phase of Gutenberg, several people complained that existing bugs, which had accumulated into the thousands, should be fixed before venturing out into adding new functionality to WordPress.

In March this year, a triage team was formed to clean up the open issues in the WordPress Trac bug tracker. This is hard work that has been needed for many years. If ever finished, WordPress would then have the chance to switch from Trac to a more modern bug tracker, such as GitHub.

Accessibility Is Steadily Becoming A Non-Issue

Accessibility issues are being tackled in every new Gutenberg release, with version 6.3 providing the lionshare of improvements. At the current pace of improvement, the most outstanding accessibility issues (as reported in the Gutenberg Accessibility Audit) should soon be a part of the past.

Judging Gutenberg On Its Own Merits

Now that we have split Gutenberg the launch from Gutenberg the product, we can proceed to analyze Gutenberg as a product and decide if it is worth adding to our application stack, based solely on its own merits and shortcomings. Many people do rightfully point out Gutenberg’s problems as the reason to not trust it (instead of focusing on the failed launch). However, Gutenberg has been improving by leaps and bounds, and many of the criticized issues may have been solved or may be on the brink of being solved. As such, the negative assessments should have a date of expiry and be re-evaluated. If we can give Gutenberg a new try and see where it stands nowadays, we may appreciate that, after all, it is not so bad. In my opinion, Gutenberg deserves a warmer welcome than it currently gets.

I am amazed that Gutenberg is still being compared to the previous way of editing content in WordPress (mainly through the tinymce, but also shortcodes, widgets, and others), arguing that it is more difficult to code through Gutenberg. This may be true, but it is also missing the point: Gutenberg is not here to provide a new way to code our application, producing the same features as in the past; instead, it is here to greatly enhance what can be done, offering to add features to our applications that could only be dreamt of in the past. Also, Gutenberg is not another page builder. Indeed, comparing Gutenberg to Divi or Beaver Builder is similarly missing the point, because it is like comparing a Victorinox to a regular knife: Yes, you can do site/page building with Gutenberg (actually not yet, but it is already a work in progress), but that is just one of its many uses; there are several other uses which are initially hidden, but once you pull them up from their compartment and understand how they work, a new world of possibilities will be revealed. Below, I will describe some of these new possibilities that Gutenberg brings to the table.

First, let’s discuss what’s not so great about Gutenberg. The one thing where I believe Gutenberg can be truly considered detrimental is in the steep curve of learning of React (which is the JavaScript library Gutenberg is coded with). WordPress has always been very inclusive, enabling people from any background (not only coders, but also non-techies such as bloggers, marketing people, salesmen, and the like) to create a theme or plugin or launch a site. This is beyond doubt not the case anymore, and it is unfair to expect everyone to have to learn React to create a Gutenberg block (this is not necessarily the case, since we can also create blocks using other JavaScript libraries, and even without using JavaScript, such as through ACF blocks, however using React is the most logical option if only because Gutenberg is coded with it). The only argument that could justify this disadvantage is if it makes the experience better for the user. Let’s see if this can be considered the case.

As I argued in a previous article of mine, the block-based architecture from Gutenberg radically changes the way in which applications are built: Instead of thinking in HTML code, we can now think in terms of components as the unit for building the website. This architecture is more maintainable and resilient, since each component (or block) can be independently developed and tested, and because it is easily reusable it can lower down the cost of developing several applications. Indeed, the recent popularity of JavaScript libraries such as Vue and React can be greatly attributed to their support for components. It is a great feature that developers love and which, I believe, once you start coding with, there is no turning back.

In this same article, I also describe how Gutenberg could support the “Create Once, Publish Everywhere” strategy (also known as “COPE”), enabling to produce a single source of truth of content to feed to all of our applications, for whichever medium or platform they run on: web, email/newsletters, iOS/Android apps, VR/AR, home-assistants (like Amazon Alexa), and others. Because it makes the overall content management much simpler, COPE also enables to lower the costs of producing content for different platforms. When I first wrote my article, I was theorizing that it could be done. However, I have recently implemented COPE for WordPress, and it works like a charm! (Stay tuned for another article in which I explain how it works in detail.)

The combination of COPE and the WordPress APIs (WP REST API, WPGraphQL, and my own PoP API) will provide one compelling reason for managing all of our content, for all of our applications, through WordPress. The other compelling reason will be Gutenberg’s ease of use (which is not fully here yet, but at the current pace of development, will arrive sooner than later), enabling the end-user to create elaborate content in a very simple way.

We already have access to great new features, such a real-time preview of how the content looks like, copy/pasting from Google Docs with perfect formatting, creation of intricate grid layers with nested elements inside, and many others. We can also expect new blocks to deliver utterly-unexpected features we have never imagined. My bet is that, through Gutenberg, WordPress is poised to become the digital assets manager of the web. (I’ve already written an article which will soon be published here on Smashing Magazine concerning this topic and my justification for this bold statement.)

In addition, Gutenberg allows to reuse code with other CMSs or frameworks (such as for Drupal and for Laravel), so that coding for WordPress needs not to be restricted to WordPress anymore, once again allowing us to lower the cost to develop a library that needs to run in as many systems as possible (for instance, a company providing an integration of its API for many different platforms and languages, such as Stripe, could benefit from it). Currently, only the client-side code (JavaScript and CSS) seems to be re-used, however, the server-side PHP code can also be re-used. (I will, once again, soon publish an article on Smashing explaining how to do just this.)

These features are already a reality, and we can expect Gutenberg to provide many more compelling reasons for its existence in the years to come (according to Matt Mullenweg, Gutenberg has currently implemented only some 10% of its potential).

We can finally attempt to reach a verdict on Gutenberg the product: My stance is that it establishes a higher barrier of entry to WordPress, which is regrettable, however, it also is a beautifully engineered piece of software which grants real new powers to WordPress and, due to WordPress’s prominence, to the web development world in general. And between this trade-off between costs and benefits, I believe that having Gutenberg as part of WordPress is more worth it than not. I hope you can agree with my opinion or, if not, at least the reasons against it can be based solely on the characteristics of Gutenberg as a product.


Gutenberg is currently at its best — having started to provide delightful user experiences that were not possible with WordPress before. However, not everyone is aware of this fact because not everyone can get down to embracing Gutenberg. This is an unfortunate circumstance because Gutenberg (as the product) should not be faulted for the mistakes that took place during the launch of Gutenberg. If we are able to split these two entities apart and treat each of them independently, we can then convincingly ask people to give Gutenberg another chance, suggesting that Gutenberg as a product is worth having, even if Gutenberg the launch was a failed process.

In this article, I did a postmortem of the failed Gutenberg launch, based on my own understanding of the events. Carrying out such a postmortem can help the community and the leadership make sure that those unfortunate mistakes do not happen again. After the postmortem, I proceeded to evaluate Gutenberg based on its own merits and declared my stance: I believe that Gutenberg is a great tool to have, and the WordPress community can certainly benefit from it. And because it will only be getting better and better, Gutenberg could even inaugurate a new golden era for WordPress.

Smashing Editorial
(dm, yk, il)

Source: Smashing Magazine, Postmortem Of Gutenberg The Launch, So We Can Embrace Gutenberg The Product

How Frontend Developers Can Empower Designer’s Work

dreamt up by webguru in Uncategorized | Comments Off on How Frontend Developers Can Empower Designer’s Work

How Frontend Developers Can Empower Designer’s Work

How Frontend Developers Can Empower Designer’s Work

Sandrina Pereira

This article is mostly directed at you, dear Frontend Developer, who enjoys implementing user interfaces but struggles in aligning expectations with designers you work with. Perhaps you are referred to as the “UI Developer” or “UX Engineer.” Regardless of the title that you carry around, your job (and as well as mine) consists of more than breathing life into design files. We are also responsible for filling the gap between the design and development workflows. However, when crossing that bridge, we are faced with multiple challenges.

Today, I’d like to share with you practical tips that have helped me to collaborate more efficiently with designers in the past years.

I believe it’s our job, as UI Developers, to not only help designers in their journey to learn how the web works, but also to get to know their reality and learn their language.

Understanding UX Designers’ Background

Most of the UX designers (also referred to as Web Designers or Product Designers) out there took their first steps in the design world through tools like Photoshop and Illustrator. Perhaps they were Graphic Designers: their main goal was to create logos and brand identities and to design layouts for magazines. They could also have been Marketing Designers: printing billboards, designing banners and creating infographics.

This means that most UX designers spent their early days designing for print, which is a totally different paradigm from their current medium, the screen. That was their first big challenge. When dealing with print, designers cared about pixel alignment, but on a fixed area (paper). They didn’t have to contend with a dynamic layout (screens). Thinking about text breaking or states of interactions was simply not part of their job either. Designers also had complete freedom over colors, images, and typography without performance constraints.

Fortunately, there have been many efforts from the self-taught UX designers community, to teach development fundamentals, discuss whether designers should learn to code and understand how to best perform hand-off to developers. The same held true for the development side as well (more about that in a minute.) However, there is still friction happening between the two fields.

On the one hand, designers complaining each time an implementation doesn’t match their designs or feeling misunderstood when those are rejected by the developers without a clear explanation. On the other hand, developers might take for granted that designers know something technical when that might not be true. I believe we can all do better than that.

Embracing A New Way Of Thinking

The websites and apps that we are building will be displayed on a wide range of screen sizes. Each person will use them on multiple devices. Our common goal is to create a familiar experience across their journeys.

When we, as developers, think that designers are being picky about pixel alignments, we need to understand why that is. We need to recognize that it’s beyond fidelity and consistency. It’s about the sum of all the parts working together. It’s cohesion. We have to embrace it and do our best to accomplish it. Learning the fundamentals of design principles is a good starting point. Understand the importance of selecting the right colors, how the hierarchy works, and why white space matters.

Note: There’s an online course known as “Design for Developers” and a book called “Refactoring UI” — both are great to get you started. With these, you’ll be able to implement user interfaces with a sharp eye for detail and gain significant leverage when communicating with designers.

Magnifying Your Designers’ Awareness

You might take for granted that designers know the web as much as you do. Well, they might not. Actually, they don’t have to! It’s our responsibility, as developers, to keep them updated with the current state of the web.

I’ve worked with the two sides of this spectrum: Designers who think that anything can be built (such as complex filters, new scroll behaviors or custom form inputs) without giving browser compatibility a thought. Then, there are designers with assumptions about the “low limitations of the web” and just assume by themselves that something is impossible to implement. We need to show them the true possibilities of web design and not let the limitations hold back their skills.

Teach Them Code, Not How To Code

This seems contradictory but bear with me: knowing how to code is at the core of a developer’s job. We work in a fast-paced industry with new stuff popping up every day. It would be a hypocritical request from us to demand designers to learn how to code. However, we can help them to understand code.

Sit next to the designer you work with for 15 minutes and teach them how they can see for themselves whether the specs of an element are correct and how to change them. I find Firefox Page Inspector remarkably user-friendly for this.

Nowadays, it’s a joy to visualize layouts, debug CSS animations and tweak typography. Show them a ready-to-use code playground like Codepen for them to explore. They don’t need to know all CSS specs to understand how the layout paradigm works. However, they need to know how elements are created and behave in order to empower their daily work.

Include Designers In The Development Process

Invite designers to join you in the stand-up meeting, to be part of the QA process and to sit down with you while you refine visual details in your implementations. This will make them understand the constraints of the web and, soon enough, they’ll recognize why a feature takes time to implement.

Ask Designers To Include You In Their Design Process

You’ll realize that they do much more than “make things pretty”. You’ll learn more about the research process and how user testing is done. You’ll discover that for each design proposal they show to you, several other studies were previously dropped. When designers request a change, ask the reason behind it, so you can learn more about the decisions being made. Ultimately, you’ll start to understand why they are picky about white space and alignments, and hopefully, soon you’ll be too!

I find it crucial to treat frontend development as a core part of the design process, and design as a core part of the development process. Advocating a mindset where everyone gets the chance to be involved in the design and development cycle will help us all to better understand each other’s challenges and to create great experiences as well.

We May Use Different Tools, But We Must Speak The Same Language

Now that we are starting to understand each other’s workflow a little better, it’s time for the next step: to speak the same language.

Looking Beyond The Code Editor

Once you start to pay attention to your surroundings, you’ll be better equipped to tackle problems. Get to know the business better and be willing to listen to what designers have to say. That will make you a team member with richer contributions to the project. Collaborating in areas beyond our expertise is the key to creating meaningful conversations and mutual trust.

Using UI Systems As A Contract

Ask designers to share their design system with you (and if they don’t use one, it’s never too late to start). That will save you the bother of handpicking the colors used, figuring out margins or guessing a text style. Make sure you are familiar with the UI System as much as they are.

You might already be familiar with the component-based concept. However, some designers might not perceive it in the same way as you do. Show them how components can help you to build user interfaces more efficiently. Spread that mindset and also say bye-bye to similar-but-not-equal-names: header vs hero, pricing info vs price selector. When a piece of the user interface (a.k.a ‘a component’) is built, stride to use the same names so they can be reflected in both design and code files. Then, when someone says, “We need to tweak the proposal invitation widget,” everyone knows exactly what is being talked about.

Acknowledging The Real Source Of Truth

Despite the fact that the user interface is first created in the design files, the real source of truth is on the development side. At the end of the day, it is what people actually see, right? When a design is updated, it’s a good idea to leave a side note about its development status, especially in projects where a large number of people are involved. This trick helps to keep the communication smooth, so nobody (including you) wonders: “This is different from the live version. Is it a bug or hasn’t so-and-so been implemented just yet?

Keeping The Debt Under Control

So, you know all about technical debt — it happens when the cost to implement something new is high because of a shortcut we took in the past to meet a deadline. The same can happen on the design side too and we call it design debt.

You can think about it like this: The higher the UX & UI inconsistency, the higher the debt (technical and design). One of the most common inconsistencies is in having different elements to represent the same action. This is why bad design is usually reflected in bad code. It’s up to all of us, both as designers and developers, to treat our design debt seriously.

Being Accessible Doesn’t Mean It Has To Be Ugly

I’m really pleased to see that both we, as developers and designers, are finally starting to bring accessibility into our work. However, a lot of us still think that designing accessible products is hard or limits our skills and creativity.

Let me remind you that we are not creating a product just for ourselves. We are creating a product to be used by all the people, including those who use the product in different ways from you. Take into account how individual elements can be more accessible while keeping the current userflows clear and coherent.

For example, if a designer really believes that creating an enhanced select input is necessary, stand by their side and work together to design and implement it in an accessible way to be used by a wide range of people with diverse abilities.

Giving Valuable Feedback To Designers

It’s unavoidable that questions will pop up when going through the designs. However, that’s not a reason for you to start complaining about the designers’ mistakes or about their ambitious ideas. The designers are not there to drive you mental, they just don’t always intuitively know what you need to do your job. The truth is that, in the past, you didn’t know about this stuff either, so be patient and embrace collaboration as a way of learning.

The Earlier The Feedback, The Better

The timing for feedback is crucial. The feedback workflow depends a lot on the project structure, so there isn’t a one-size-fits-all solution for it. However, when possible, I believe we should aim for a workflow of periodic feedback — starting in the early stages. Having this mindset of open collaboration is the way to reduce the possibility of unexpected big re-iterations later in the road. Keep in mind that the later you give the designer your first feedback, the higher will be the cost for them to explore a new approach if needed.

Explain Abstract Ideas In Simple Terms

Remember when I said that performance was not a concern of the designers’ previous jobs? Don’t freak out when they are not aware of how to create optimized SVGs for the web. When faced with a design that requires a lot of different fonts to be loaded, explain to them why we should minimize the number of requests, perhaps even take advantage of Variable Fonts. Asides from loading faster, it also provides a more consistent user experience. Unless designers are keen to learn, avoid using too many technical terms when explaining something. You can see this as an opportunity of improving your communication skills and clarifying your thoughts.

Don’t Let Assumptions Turn Into Decisions

Some questions about a design spec only show up when we get our hands dirty in the code. To speed things up, we might feel tempted to make decisions based on our assumptions. Please, don’t. Each time you turn an assumption into a decision, you are risking the trust that the design team puts on you to implement the UI. Whenever in doubt, reach out and clarify your doubts. This will show them that you care about the final result as much as they do.

Don’t Do Workarounds By Yourself

When you are asked to implement a design that is too hard, don’t say “It’s impossible” or start to implement a cheap alternative version of it by yourself. This immediately causes friction with the design team when they see their designs were not implemented as expected. They might react angrily, or not say anything but feel defeated or frustrated. That can all be avoided if we explain to them why something it’s not possible, in simple terms and suggest alternative approaches. Avoid dogmatic behaviors and be open to collaborating on a new solution.

Let them know about the Graceful Degradation and Progressive Enhancement techniques and build together an ideal solution and a fallback solution. For example, we can enhance a layout from flexbox to CSS Grid. This allows us to respect the core purpose of a feature and at the same time make the best use of web technologies.

When it comes to animations, let’s be real: deep down you are as thrilled to implement the next wow animation as much as the designers are to create it. The difference between us and them is that we are more aware of the web’s constraints. However, don’t let that limit your own skills! The web evolves fast, so we must use that in our favor.

The next time you are asked to bring a prototype to life, try not to reject it upfront or do it all by yourself. See it as an opportunity to push yourself. Animations are one of the pickiest parts of web development, so make sure to refine each keyframe with your designer — in person or by sharing a private synced link.

Think Beyond The Ideal State — Together

Here’s the thing: it’s not all about you. One of the designers’ challenges is to really understand their users and present the designs in the most attractive way to sell to the Product Manager. Sometimes they forget about what’s beyond the ideal state and developers forget it too.

In order to help avoid these gaps from happening, align with designers the scenario requirements:

  • The worst-case scenario
    A scenario where the worst possibilities are happening. This helps designers to say no to fixed content and let it be fluid. What happens if the title has more than 60 characters or if the list is too long? The same applies to the opposite, the empty scenario. What should the user do when the list is empty?
  • Interaction states
    The browser is more than hovering and clicking around. There are a bunch of states: default, hover, focus, active, disable, error… and some of them can happen at the same time. Let’s give them the proper attention.
  • The loading state
    When building stuff locally, we might use mocks and forget that things actually take time to load. Let designers know about that possibility too and show them that are ways to make people perceive that things don’t take that long to load.

Taking into consideration all these scenarios will save you a lot of time going back and forth during the development phase.

Note: There’s a great article by Scott Hurff about how to fix bad user interfaces that will take us a step closer to an accessible product.

Embrace Change Requests

Developers are known for not being too happy about someone finding a bug in their code — especially when it’s a design bug reported by a designer. There are a lot of memes around it, but have you ever reflected how those bugs can compoundingly rot both the quality of the experience as well as your relationship when these design bugs are casually dismissed? It happens slowly, almost like falling asleep. Bit by bit, then all at once. Designers might start out saying, “It’s just a tiny little detail,” until the indifference and resentment builds up and nothing is said. The damage has then already been done.

This situation is two-fold: both to your peers and to your work. Don’t let that happen. Work on what’s coloring your reaction. A designer being ‘picky’ can be inconvenient, but it can also be an engineer’s shallow interpretation of attentiveness and enthusiasm. When someone tells you that your implementation is not perfect (yet), put your ego aside and show them how you recognize their hard work in refining the final result.

Go Off The Record Once In A While

We all have tasks to deliver and roadmaps to finish. However, some of the best work happens off the record. It won’t be logged into the TO DO board and that’s okay. If you find a designer you have a rapport with, go sneak into their workspace and explore together new experiments. You never know what can come from there!


When you are willing to learn from the design team, you are also learning different ways of thinking. You’ll evolve your mindset of collaboration with other areas out of your experience while refining your eye for creating new experiences. Be there to help and be open to learning, because sharing is what makes us better.

This article wouldn’t be possible without the feedback of many great people. I want to gratefully thank to the designers Jasmine Meijer and Margarida Botelho for helping me to share a balanced perspective about the misunderstandings between designers and developers.

Related Reading on SmashingMag:

Smashing Editorial
(ra, yk, il)

Source: Smashing Magazine, How Frontend Developers Can Empower Designer’s Work

Should You Add WordPress Maintenance To Your Service Offering?

dreamt up by webguru in Uncategorized | Comments Off on Should You Add WordPress Maintenance To Your Service Offering?

Should You Add WordPress Maintenance To Your Service Offering?

Should You Add WordPress Maintenance To Your Service Offering?

Suzanne Scacca

(This is a sponsored article.) One of the common problems with trying to scale up when working as a solo web designer or a bootstrapping agency is that you’re limited by time. How much time it takes to:

  • Onboard new clients;
  • Build websites;
  • Put out fires;
  • Do all the other stuff that keeps your business running.

That’s not to say you can’t make good money in web design. It’s just that your time is worth money and if you’re maxed out on time, that’s it. You’ve reached peak scale.

If you’re hoping to not only sustain your design business but scale it into a money-making machine, you need to create a recurring revenue stream. Luckily for you, web designers and agencies have lots of options to choose from.

One of the most popular is WordPress maintenance and support.

Before you go diving into this new gig, really consider what this additional offering will do to your operation. Because although it will bring you more money — and a predictable stream of it, too — it’s not easy work. Especially as you offer that service to dozens and, eventually, hundreds or thousands of clients.

To help you out, today we’re going to examine:

The Benefits Of Selling WordPress Maintenance Services

There are many reasons why designers and developers choose to build websites with WordPress. But as anyone who’s spent enough time with the content management system will tell you, it’s got its flaws.

Security is a big concern. Speed can be difficult to manage. And clients don’t always take too kindly to the platform.

But that’s where WordPress maintenance services come in. Seasoned WordPress users understand the CMS’s weaknesses and are able to craft monthly maintenance and support plans to ensure that all bases are covered long after launch.

While it’s clear what sort of benefits your clients get from maintenance and support, you stand to reap a ton of benefits by adding it to your service offering, too:

Make Your Revenue Stream Predictable

Ever feel like it’s feast or famine with your business? It’s to be expected, especially if you serve smaller clients whose own revenue streams are unpredictable.

That’s one of the reasons why maintenance and support services are so great. Whether you allow clients to go month-to-month or put them on a yearly plan, your cash flow becomes more predictable and easier to manage.

Add An Extra Competitive Edge

If you’re working with the right kinds of clients, they should be asking you “What’s next?” after their website launches. These are the clients that understand the value of protecting their investment.

Wouldn’t you rather be the one who has the answer than to watch them move onto the competition for help? Plus, it’s an easy sell. You’ve already proven yourself a trustworthy designer. Why not round out your offering and become their end-to-end provider?

Make Your Portfolio Even More Impressive

You put a lot of work into the websites you build and you should be proud to show them off. But when left in the hands of your clients (or a subpar maintenance provider), you run the risk of your portfolio quickly going stale.

That’s not to say you should be in this solely to protect your reputation, but it is something to think about if you’re going to leverage those samples to build your business.

Upgrade Your Processes

One of the awesome things about performing WordPress maintenance is that a lot of it can be automated, so you’re not really “performing” much at all. It becomes more about monitoring and support.

What’s more, if you initially build security, speed and SEO automation into your websites, you’ll have even less work to do when maintenance plans kick in. And an awesome justification for raising your web design rates.

Create Additional Revenue Streams

Once you see how beneficial it is to build WordPress maintenance into your offering, you might not want to stop there. Your clients might not either. So, keep your ears peeled. If clients start asking for help with the same kinds of things (e.g. managing their hosting, handling their content marketing, running SEO audits, etc.), think about how you might add that to your offering.

The Drawbacks Of Managing WordPress Maintenance Services

WordPress maintenance is beneficial to your clients and it does a lot of good for your business, too. But there are some things you need to be aware of before you jump in.

Stiff Competition

While offering WordPress maintenance will certainly make you a competitive and formidable force in the eyes of existing and former clients, that might not be the case with newbies. Not only will you have to compete against other web designers and agencies, you’ll also have to compete with dedicated WordPress maintenance pros like WP Buffs and SkyrocketWP.

A New Offering = More Work

Without the right tools or automations in place, WordPress maintenance services could become an even greater burden on your business. Remember, you want to move away from time-based services, so this needs to be set up properly if you want to make it work.

Technical Know-How

Website maintenance is a highly technical matter. If your skillset is mainly in design or strategy, this might not be the right recurring revenue service for you. That’s why it’s important to secure the technology and process before you start selling any new solution.

Support Is Required

Although we usually just refer to these services as “maintenance plans”, support has to be baked in. You’re not just working behind the scenes to do backups or patch vulnerabilities. You have to make yourself available if a client notices that their site is down, they’ve been locked out of the admin or they simply need help editing a page. Do you have the capacity or patience for that?

A Lot At Stake

There’s a lot on the line here. If you do everything right, it could do wonders for your business and your bottom line. But if you fail to provide the right level of maintenance and support, and something happens to your client’s site, you can bet it’s going to hurt your business and reputation.

How To Do WordPress Maintenance And Support The Right Way

That said, the good does certainly outweigh the bad. You just need to handle it the right way, which means you need a plan, the right tools and a solid process.

Here’s what I suggest:

Step 1: Figure Out What Kind Of Maintenance You’ll Do

Before you add a Maintenance page to your website, first sort out what kind of maintenance you’re going to offer.

Ask yourself:

What kinds of clients do you serve? How much maintenance, on average, do you think they need each month?

For instance, a law firm website might only need:

  • Weekly software updates,
  • Monthly backups,
  • Security monitoring,
  • Uptime monitoring,
  • 2-3 small edits monthly.

But an established sales enterprise might need the whole kit and caboodle:

  • Backups and restores,
  • Software updates,
  • Security monitoring and repairs,
  • Comment moderation,
  • Downtime monitoring,
  • Performance monitoring and optimization,
  • File/plugin/theme/media cleanup,
  • Database cleanup,
  • Broken link monitoring and repair,
  • 2 hours of edits monthly,
  • Reporting.

If you’re curious about how companies that are 100% dedicated to WordPress maintenance and support do it, here’s an example of how Maintainn breaks it up:

Maintainn maintenance and support

WordPress maintenance company Maintainn offers customers three maintenance and support plans. (Source: Maintainn) (Large preview)

If you target clients at different levels, you could logically break up your plans this way. It would be a good way to form lifelong partnerships with your clients, too, as you can help them grow from fledgling startups to booming enterprises.

If you’d rather not take on a wide range of maintenance responsibilities, that’s fine. Play to your strengths. For example, digital agency Webvizion offers Basic, Advanced and Pro plans:

Webvision maintenance and support

Webvizion sells the same kinds of website maintenance and support services. The key difference between the plans is quantity though. (Source: Webvizion) (Large preview)

Each plan comes with the same kind of maintenance and support coverage. What differs is how much of it they do with each plan. This is a good option if you’re brand new to maintenance and aren’t sure how much of it you want to branch out into or how much of it your clients will even need. You can safely test the waters with this approach.

However you decide to split up and price out your maintenance services, make it clear to customers what the differences are between the plans and where they’ll get the most value. Just as you want to simplify their lives by handling their WordPress maintenance, you want to simplify this decision for them as well.

Step 2: Create Your Maintenance Toolbox

You might have already laid some of the groundwork when building your client’s website by implementing:

A solid choice in managed WordPress hosting will not only strengthen this setup, but it’ll make your job easier, too.

Managed Hosting with Kinsta

If your clients are on regular ol’ WordPress hosting, but you and they want to get serious about properly maintaining their website, it’s a good idea to get them over to managed hosting with Kinsta. And I’ll show you why.

This is Kinsta’s multi-site control panel, MyKinsta:

MyKinsta control panel

With managed WordPress hosting with Kinsta, users get access to the intuitive control panel called MyKinsta. (Source: MyKinsta) (Large preview)

As you can see in this snapshot, MyKinsta is a really well-organized control panel solution. But this isn’t just a place to manage your clients’ Kinsta accounts and billing. This is where you can set up your own WordPress maintenance services for success.

Let’s look a little more closely at what you can do:

MyKinsta backup and restore

MyKinsta automates website backups and simplifies the restore, too. (Source: MyKinsta) (Large preview)

Backups are a non-negotiable part of WordPress maintenance. You know that your clients aren’t going to do it or know how to do it and you can’t afford a security breach or human error to compromise everything you worked so hard to build for them.

From this panel, you can see that Kinsta has already taken care of this responsibility for you — and it’s doing it at a frequency you most likely couldn’t handle (at least, if you were planning to do this for dozens of clients).

Restoring a backup is just as easy and only requires a couple clicks to take your client’s website back to safety.

The Tools section of MyKinsta also simplifies website security and performance optimization for you:

MyKinsta Tools

The MyKinsta control panel’s Tools are all about improving speed and security. (Source: MyKinsta) (Large preview)

Want to instantly upgrade to the latest PHP version? Implement stronger password protection? Clear the cache? You can take care of your security and speed optimization essentials with just a click or two.

Another performance enhancer lives in this control panel, too: the Kinsta CDN.

Kinsta CDN

MyKinsta’s web hosting panel allows users to activate and use Kinsta’s own CDN. (Source: MyKinsta) (Large preview)

For clients with high volumes of traffic from around the world, you can’t afford to skimp on this. It’s nice to see that Kinsta makes it easy to add a CDN instead of forcing users to sign up for an external provider’s CDN and integrate it with their Kinsta website. Again, a lot of the work you’d have to do to set up a maintenance client is already done for you.

There’s a lot more you can do within this control panel. For example:

  • Sign clients’ up for new hosting plans.
  • Manage domain names.
  • View plugin updates.
  • Set up and use a staging environment.
  • Migrate a website.
  • Monitor performance analytics.

Once you have everything set up as you like, you can trust that Kinsta will take care of your clients’ security and performance just as well as you would. And if anything should go wrong or you need help tweaking something on the backend, Kinsta expert support is available 24/7.

Multi-site Management

Managed hosting will cover the server-side maintenance and support piece of your own maintenance care plans — which is huge. You don’t have to worry about waking up in the middle of the night to deal with downed servers and other urgent hosting-related matters.

This frees you up, then, to take care of the website side of things.

That said, don’t try and do this on your own. Setting up the plugins I mentioned earlier is a good place to start, but it’s not enough. Can you imagine having to log in and out of dozens or hundreds of clients’ websites to update their plugins, manage their backups and run security scans? Don’t even think about wasting your time on that.

Instead, find a multi-site management tool you can outsource most of these repetitive tasks to (like InfiniteWP or iThemes Sync).

Most of these tools enable you to:

  • Add all of your maintenance client sites to a single control panel.
  • Schedule backups (and do so in a safe manner).
  • Schedule and automate updates (plus, you can choose which themes and plugins get updated).
  • Automate security, uptime and performance monitoring.
  • Auto-generate weekly or monthly status update reports for clients.

This is going to take a lot of the weight off of your shoulders when it comes to managing the maintenance essentials. Knowing that tools like these exist will also help you decide how much you can reasonably offer in the way of maintenance without burning yourself out in the process.

Step 3: Create A Process

Now that you know what you’re offering and which tools you’re going to use to automate and manage at least some of the tasks, it’s time to build out a process for it.

To give you a head start, I’m going to help you create a template that will make scheduling and processizing this whole thing much easier.

First, I want you to make a list of all the maintenance services you’re going to offer. You can choose from the list below or add your own. Again, choose the services that your clients will actually need help with after launch:

Maintenance Services & Support
Backups (and restore)
Software updates
Security monitoring
Downtime monitoring
Performance monitoring
Comment moderation
Database cleanup
File cleanup
User management
Broken link monitoring
Managed hosting and domain
Keyword monitoring
Content marketing
Google Analytics review
Site audit
Website edits

Next, identify the tools you’ll use to manage these services. As you’ll see, you can actually accomplish most of this with your multi-site manager and managed hosting solution. You may need additional tools, but many of them are offered by Google for free.

Maintenance Services & Support Tools
Backups (and restore) Managed hosting + multi-site manager
Software updates Multi-site manager
Security monitoring Multi-site manager or security plugin
Downtime monitoring Multi-site manager
Performance monitoring Multi-site manager and Google PageSpeed Insights
Comment moderation Multi-site manager
Database cleanup Managed hosting
File cleanup Manual
User management Multi-site manager
Broken link monitoring Multi-site manager
Managed hosting and domain Managed hosting
Keyword monitoring Multi-site manager and SEO checker tools
Content marketing Manual
Google Analytics review Google Analytics reporting and manual
Site audit Manual
Website edits Manual
Support Manual and helpdesk solution
Reporting Multi-site manager and Google Analytics

Finally, you need to decide how frequently each of these maintenance tasks need to be completed (or how much support you’ll provide). This may vary from plan to plan, so I’m going to provide you with a few empty columns to input your responses.

For the frequency-based tasks, add one of the following:

  • Hourly,
  • Daily,
  • Weekly,
  • Monthly.

For the quantity-based tasks, add one of the following:

  • Number (like for how many website edits you’ll do in a month),
  • Hours (like for how many hours of support — remember to indicate the level of support, too!).
Maintenance Services & Support Tools Plan 1 Plan 2 Plan 3
Backups (and restore) Managed hosting + multi-site manager 1 2 3
Software updates Multi-site manager
Security monitoring Multi-site manager or security plugin
Downtime monitoring Multi-site manager
Performance monitoring Multi-site manager and Google PageSpeed Insights
Comment moderation Multi-site manager
Database cleanup Managed hosting
File cleanup Manual
User management Multi-site manager
Broken link monitoring Multi-site manager
Managed hosting and domain Managed hosting
Keyword monitoring Multi-site manager and SEO checker tools (like Moz)
Content marketing Manual
Google Analytics review Google Analytics reporting and manual
Site audit Manual (though you can use various premium tools to do most of the heavy lifting)
Website edits Manual
Support Manual with the help of a helpdesk solution
Reporting Multi-site manager and Google Analytics

Now that you have all the essentials broken out, get to work on setting it up.

If you haven’t yet signed up for any of these tools or aren’t familiar with how to use them, sign up for accounts with them now. You don’t want to be learning this on the job.

Next, configure your automations within your tools. You might even want to set up your own website as the first “client”, so you can work out all the kinks with your process safely.

Then, add all of the tasks that require your oversight and hand-holding to your project management tool. There shouldn’t be too many that fall on your plate once you have the help of a managed hosting solution like Kinsta, a multi-site manager and a variety of Google tools on your side.

The Bottom Line

Once things really begin to pick up, you can start thinking about outsourcing. This might involve hiring a contractor to manage those manual tasks for you, switching your clients to one of Kinsta’s managed hosting plans or using a service like WP Buffs to white label your maintenance services entirely.

But, for now, focus on how you can make a difference in the lives of your clients. Then, get in touch with current and former clients and work on your pitch. There’s no point in thinking about scaling and outsourcing if you don’t have clients banging down your door for help.

Once you’ve proven your value as an end-to-end provider for all things WordPress, then you can comfortably start looking at ways to lighten your burden even further while increasing the recurring revenue flowing in.

Smashing Editorial
(ms, ra, yk, il)

Source: Smashing Magazine, Should You Add WordPress Maintenance To Your Service Offering?

Collective #557

dreamt up by webguru in Uncategorized | Comments Off on Collective #557



A reusable JavaScript library for creating sketchy/hand-drawn styled charts in the browser.

Check it out


The wondrous world of CSS counters

An in-depth look at CSS counters, how they’ve expanded with better support for internationalization and how it’s possible to implement a pure CSS Fizzbuzz solution with them.

Read it


The W3C At Twenty-Five

In this article, Rachel Andrew explains how the W3C works and shares her “Web Story” to explain why the Web Standards process is so vitally important for everyone to have an open web platform where they can share their stories and build awesome things for the web together.

Read it


The Open Book Project

Joey Castillo is on a mission to create a simple book reading device that anyone with a soldering iron can build for themselves.

Check it out



Able is a bootstrapped community for people to read and write about software.

Check it out

Collective #557 was written by Pedro Botelho and published on Codrops.

Source: Codrops, Collective #557

Animating Apps With Flutter

dreamt up by webguru in Uncategorized | Comments Off on Animating Apps With Flutter

Animating Apps With Flutter

Animating Apps With Flutter


Apps for any platform are praised when they are intuitive, good-looking, and provide pleasant feedback to user interactions. Animation is one of the ways to do just that.

Flutter, a cross-platform framework, has matured in the past two years to include web and desktop support. It has garnered a reputation that apps developed with it are smooth and good-looking. With its rich animation support, declarative way of writing UI, “Hot Reload,” and other features, it is now a complete cross-platform framework.

If you are starting out with Flutter and want to learn an unconventional way of adding animation, then you are at the right place: we will explore the realm of animation and motion widgets, an implicit way of adding animations.

Flutter is based on the concept of widgets. Each visual component of an app is a widget — think of them as views in Android. Flutter provides animation support using an Animation class, an “AnimationController” object for management, and “Tween” to interpolate the range of data. These three components work together to provide smooth animation. Since this requires manual creation and management of animation, it is known as an explicit way of animating.

Now let me introduce you to animation and motion widgets. Flutter provides numerous widgets which inherently support animation. There’s no need to create an animation object or any controller, as all the animation is handled by this category of widgets. Just choose the appropriate widget for the required animation and pass in the widget’s properties values to animate. This technique is an implicit way of animating.

Animation hierarchy in Flutter. (Large preview)

The chart above roughly sets out the animation hierarchy in Flutter, how both explicit and implicit animation are supported.

Some of the animated widgets covered in this article are:

  • AnimatedOpacity
  • AnimatedCrossFade
  • AnimatedAlign
  • AnimatedPadding
  • AnimatedSize
  • AnimatedPositioned.

Flutter not only provides predefined animated widgets but also a generic widget called AnimatedWidget, which can be used to create custom implicitly animated widgets. As evident from the name, these widgets belong to the animated and motion widgets category, and so they have some common properties which allow us to make animations much smoother and better looking.

Let me explain these common properties now, as they will be used later in all examples.

  • duration
    The duration over which to animate the parameters.
  • reverseDuration
    The duration of the reverse animation.
  • curve
    The curve to apply when animating the parameters. The interpolated values can be taken from a linear distribution or, if and when specified, can be taken from a curve.

Let’s begin the journey by creating a simple app we’ll call “Quoted”. It will display a random quotation every time the app starts. Two things to note: first, all these quotations will be hardcoded in the application; and second, no user data will be saved.

Note: All of the files for these examples can be found on GitHub.

Getting Started

Flutter should be installed and you’ll need some familiarity with the basic flow before moving on. A good place to start is, “Using Google’s Flutter For Truly Cross-Platform Mobile Development”.

Create a new Flutter project in Android Studio.

New flutter project menu in Android Studio. (Large preview)

This will open a new project wizard, where you can configure the project basics.

Flutter project type selection screen. (Large preview)

In the project type selection screen, there are various types of Flutter projects, each catering to a specific scenario.. For this tutorial, choose Flutter Application and press Next.

You now need to enter some project-specific information: the project name and path, company domain, and so on. Have a look at the image below.

Flutter application configuration screen. (Large preview)

Add the project name, the Flutter SDK path, project location, and an optional project description. Press Next.

Flutter application package name screen. (Large preview)

Each application (be it Android or iOS) requires a unique package name. Typically, you use the reverse of your website domain; for example, or Press Finish to generate a working Flutter application.

The generated sample project. (Large preview)

Once the project is generated, you should see the screen shown above. Open the main.dart file (highlighted in the screenshot). This is the main application file. The sample project is complete in itself, and can be run directly on an emulator or a physical device without any modification.

Replace the content of the main.dart file with the following code snippet:

import 'package:animated_widgets/FirstPage.dart';
import 'package:flutter/material.dart';

void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
 Widget build(BuildContext context) {
   return MaterialApp(
     title: 'Animated Widgets',
     debugShowCheckedModeBanner: false,
     theme: ThemeData(
       accentColor: Colors.redAccent,
     home: FirstPage(),

This code cleans up the main.dart file by just adding simple information relevant to creating a new app. The class MyApp returns an object: a MaterialApp widget, which provides the basic structure for creating apps conforming to Material Design. To make the code more structured, create two new dart files inside the lib folder: FirstPage.dart and Quotes.dart.

The FirstPage.dart file. (Large preview)

FirstPage.dart will contain all the code responsible for all the visual elements (widgets) required for our Quoted app. All the animation is handled in this file.

Note: Later in the article, all of the code snippets for each animated widget are added to this file as children of the Scaffold widget. For more information, This example on GitHub could be useful.

Start by adding the following code to FirstPage.dart. This is the partial code where other stuff will be added later.

import 'dart:math';

import 'package:animated_widgets/Quotes.dart';
import 'package:flutter/material.dart';

class FirstPage extends StatefulWidget {
 State createState() {
   return FirstPageState();

class FirstPageState extends State with TickerProviderStateMixin {

 bool showNextButton = false;
 bool showNameLabel = false;
 bool alignTop = false;
 bool increaseLeftPadding = false;
 bool showGreetings = false;
 bool showQuoteCard = false;
 String name = '';

 double screenWidth;
 double screenHeight;
 String quote;

 void initState() {
   Random random = new Random();
   int quoteIndex = random.nextInt(Quotes.quotesArray.length);
   quote = Quotes.quotesArray[quoteIndex];

 Widget build(BuildContext context) {

   screenWidth = MediaQuery.of(context).size.width;
   screenHeight = MediaQuery.of(context).size.height;

   return Scaffold(
     appBar: _getAppBar(),
     body: Stack(
       children: [
         // All other children will be added here.
      // In this article, all the children widgets are contained
      // in their own separate methods.
      // Just method calls should be added here for the respective child.

The Quotes.dart file. (Large preview)

The Quotes.dart file contains a list of all the hardcoded quotations. One point to note here is that the list is a static object. This means it can be used at other places without creating a new object of the Quotes class. This is chosen by design, as the above list act simply as a utility.

Add the following code to this file:

class Quotes {
 static const quotesArray = [
   "Good, better, best. Never let it rest. 'Til your good is better and your better is best",
   "It does not matter how slowly you go as long as you do not stop.",
   "Only I can change my life. No one can do it for me."

The project skeleton is now ready, so let’s flesh out Quoted a bit more.


To lend a personal touch to the app, it would be nice to know the user’s name, so let’s ask for it and show a next button. Until the user enters their name, this button is hidden, and it will gracefully show up when a name is given. We need some kind of visibility animation for the button, but is there a widget for that? Yes, there is.

Enter AnimatedOpacity. This widget builds on the Opacity widget by adding implicit animation support. How do we use it? Remember our scenario: we need to show a next button with animated visibility. We wrap the button widget inside the AnimatedOpacity widget, feed in some proper values and add a condition to trigger the animation — and Flutter can handle the rest.

_getAnimatedOpacityButton() {
  return AnimatedOpacity(
    duration: Duration(seconds: 1),
    reverseDuration: Duration(seconds: 1),
    curve: Curves.easeInOut,
    opacity: showNextButton ? 1 : 0,
    child: _getButton(),
Opacity animation of next button. (Large preview)

The AnimatedOpacity widget has two mandatory properties:

  • opacity
    A value of 1 means completely visible; 0 (zero) means hidden. While animating, Flutter interpolates values between these two extremes. You can see how a condition is placed to change the visibility, thus triggering animation.
  • child
    The child widget that will have its visibility animated.

You should now understand how really simple it is to add visibility animation with the implicit widget. And all such widgets follow the same guidelines and are easy to use. Let’s move on to the next one.


We have the user’s name, but the widget is still waiting for input. In the previous step, as the user enters their name, we display the next button. Now, when the user presses the button, I want to stop accepting input and show the entered name. There are many ways to do it, of course, but perhaps we can hide away the input widget and show an uneditable text widget. Let’s try it out using the AnimatedCrossFade widget.

This widget requires two children, as the widget crossfades between them based on some condition. One important thing to keep in mind while using this widget is that both of the children should be the same width. If the height is different, then the taller widget gets clipped from the bottom. In this scenario, two widgets will be used as children: input and label.

_getAnimatedCrossfade() {

  return AnimatedCrossFade(

    duration: Duration(seconds: 1),


    reverseDuration: Duration(seconds: 1),

    firstChild: _getNameInputWidget(),

    firstCurve: Curves.easeInOut,

    secondChild: _getNameLabelWidget(),

    secondCurve: Curves.easeInOut,

    crossFadeState: showNameLabel ? CrossFadeState.showSecond : CrossFadeState.showFirst,


Cross-fading between the input widget and name widget. (Large preview)

This widget requires a different set of mandatory parameters:

  • crossFadeState
    This state works out which child to show.
  • firstChild
    Specifies the first child for this widget.
  • secondChild
    Specifies the second child.


At this point, the name label is positioned at the center of the screen. It will look much better at the top, as we need the center of the screen to show quotes. Simply put, the alignment of the name label widget should be changed from center to top. And wouldn’t it be nice to animate this alignment change along with the previous cross-fade animation? Let’s do it.

As always, several techniques can be used to achieve this. Since the name label widget is already center-aligned, animating its alignment would be much simpler than manipulating the top and left values of the widget. The AnimatedAlign widget is perfect for this job.

To initiate this animation, a trigger is required. The sole purpose of this widget is to animate alignment change, so it has only a few properties: add a child, set its alignment, trigger the alignment change, and that’s it.

_getAnimatedAlignWidget() {

  return AnimatedAlign(

duration: Duration(seconds: 1),

curve: Curves.easeInOut,

alignment: alignTop ? Alignment.topLeft :,

child: _getAnimatedCrossfade(),


Alignment animation of the name widget. (Large preview)

It has only two mandatory properties:

  • child:
    The child whose alignment will be modified.
  • alignment:
    Required alignment value.

This widget is really simple but the results are elegant. Moreover, we saw how easily we can use two different animated widgets to create a more complex animation. This is the beauty of animated widgets.


Now we have the user’s name at the top, smoothly animated without much effort, using different kinds of animated widgets. Let’s add a greeting, “Hi,” before the name. Adding a text widget with value “Hi,” at the top will make it overlap the greeting text widget, looking like the image below.

The greeting and name widgets overlap. (Large preview)

What if the name text widget had some padding on the left? Increasing the left padding will definitely work, but wait: can we increase the padding with some animation? Yes, and that is what AnimatedPadding does. To make all this much better looking, let’s have the greetings text widget fade in and the name text widget’s padding increase at the same time.

_getAnimatedPaddingWidget() {

  return AnimatedPadding(

    duration: Duration(seconds: 1),

    curve: Curves.fastOutSlowIn,

    padding: increaseLeftPadding ? EdgeInsets.only(left: 28.0) : EdgeInsets.only(left: 0),

    child: _getAnimatedCrossfade(),



Since the animation above should occur only after the previous animated alignment is complete, we need to delay triggering this animation. Digressing from the topic briefly, this is a good moment to talk about a popular mechanism to add delay. Flutter provides several such techniques, but the Future.delayed constructor is one of the simpler, cleaner and more readable approaches. For instance, to execute a piece of code after 1 second:

Future.delayed(Duration(seconds: 1), (){
    sum = a + b;    // This sum will be calculated after 1 second.

Since the delay duration is already known (calculated from previous animation durations), the animation can be triggered after this interval.

// Showing “Hi” after 1 second - greetings visibility trigger.
_showGreetings() {
  Future.delayed(Duration(seconds: 1), () {
    setState(() {
        showGreetings = true;

// Increasing the padding for name label widget after 1 second - increase padding trigger.
_increaseLeftPadding() {
  Future.delayed(Duration(seconds: 1), () {
    setState(() {
    increaseLeftPadding = true;
Padding animation of the name widget. (Large preview)

This widget has only two mandatory properties:

  • child
    The child inside this widget, which padding will be applied to.
  • padding
    The amount of space to add.


Today, any app having some kind of animation will include zooming in to or out of visual components to grab user attention (commonly called scaling animation). Why not use the same technique here? We can show the user a motivational quote that zooms in from the center of the screen. Let me introduce you to the AnimatedSize widget, which enables the zoom-in and zoom-out effects, controlled by changing the size of its child.

This widget is a bit different from the others when it comes to the required parameters. We need what Flutter calls a “Ticker.” Flutter has a method to let objects know whenever a new frame event is triggered. It can be thought of as something that sends a signal saying, “Do it now! … Do it now! … Do it now! …”

The AnimatedSize widget requires a property — vsync — which accepts a ticker provider. The easiest way to get a ticker provider is to add a Mixin to the class. There are two basic ticker provider implementations: SingleTickerProviderStateMixin, which provides a single ticker; and TickerProviderStateMixin, which provides several.

The default implementation of a Ticker is used to mark the frames of an animation. In this case, the latter is employed. More about mixins.

// Helper method to create quotes card widget.
_getQuoteCardWidget() {
  return Card(
    elevation: 8.0,
    child: _getAnimatedSizeWidget(),
// Helper method to create animated size widget and set its properties.
_getAnimatedSizeWidget() {
  return AnimatedSize(
    duration: Duration(seconds: 1),
    curve: Curves.easeInOut,
    vsync: this,
    child: _getQuoteContainer(),
// Helper method to create the quotes container widget with different sizes.
_getQuoteContainer() {
  return Container(
    height: showQuoteCard ? 100 : 0,
    width: showQuoteCard ? screenWidth - 32 : 0,
    child: Center(
    child: Padding(
        padding: EdgeInsets.symmetric(horizontal: 16),
        child: Text(quote, style: TextStyle(color: Colors.white, fontWeight: FontWeight.w400, fontSize: 14),),
// Trigger used to show the quote card widget.
_showQuote() {
  Future.delayed(Duration(seconds: 2), () {
    setState(() {
        showQuoteCard = true;
Scaling animation of the quotes widget. (Large preview)

Mandatory properties for this widget:

  • vsync
    The required ticker provider to coordinate animation and frame changes.<
  • child
    The child whose size changes will be animated.

The zoom in and zoom out animation is now easily tamed.


Great! The quotes zoom in from the center to grab the user’s attention. What if it slid up from the bottom while zooming in? Let’s try it. This motion involves playing with the position of the quote widget and animating the changes in position properties. AnimatedPositioned is the perfect candidate.

This widget automatically transitions the child’s position over a given duration whenever the specified position changes. One point to note: it works only if its parent widget is a “Stack.” This widget is pretty simple and straightforward to use. Let’s see.

// Helper method to create the animated positioned widget.
// With position changes based on “showQuoteCard” flag.
_getAnimatedPositionWidget() {
  return AnimatedPositioned(
    duration: Duration(seconds: 1),
    curve: Curves.easeInOut,
    child: _getQuoteCardWidget(),
    top: showQuoteCard ? screenHeight/2 - 100 : screenHeight,
    left: !showQuoteCard ? screenWidth/2 : 12,
Position with scaling animation of quotes. (Large preview)

This widget has only one mandatory property:

  • child
    The widget whose position will be changed.

If the size of the child is not expected to change along with its position, a more performative alternative to this widget would be SlideTransition.

Here is our complete animation:

All the animated widgets together. (Large preview)


Animations are an integral part of user experience. Static apps or apps with janky animation not only lower user retention but also a developer’s reputation to deliver results.

Today, most popular apps have some kind of subtle animation to delight users. Animated feedback to user requests can also engage them to explore more. Flutter offers a lot of features for cross-platform development, including rich support for smooth and responsive animations.

Flutter has great plug-in support which allows us to use animations from other developers. Now that it has matured to version 1.9, with so much love from the community, Flutter is bound to get better in the future. I’d say now is a great time to learn Flutter!

Further Resources

Smashing Editorial
(dm, og, yk, il)

Source: Smashing Magazine, Animating Apps With Flutter

The W3C At Twenty-Five

dreamt up by webguru in Uncategorized | Comments Off on The W3C At Twenty-Five

The W3C At Twenty-Five

The W3C At Twenty-Five

Rachel Andrew

Last week, the World Wide Web Consortium (W3C) celebrated its 25th anniversary and invited folks to share why the open web platform matters to them via the hashtag #WebStories. As I’m both a member of the CSS Working Group at W3C and the representative for Fronteers, I think it’s a good time to explain a bit more about the role of the W3C in the work that we all do.

What Exactly Is The W3C?

On the W3C website, the About page describes the W3C as:

“… an international community where Member organizations, a full-time staff, and the public work together to develop Web standards. Led by Web inventor and Director Tim Berners-Lee and CEO Jeffrey Jaffe, W3C’s mission is to lead the Web to its full potential.”

There are links on that page to details of the mission and vision of the W3C, however, the key motivation of the organization is to ensure that the web is for everybody — and on everything.

Access to the web should not be limited by who you are, where you are, or the device you are using.

Who Are The Member Organizations?

A W3C Member is an organization who pays a membership fee to be part of the W3C. At the time of writing, there are 449 members, and you can see the full list here. If you read through this list, you will find that the majority of members are very large companies. Some are names that we as web developers readily recognize: browser vendors such as Google and Mozilla, large internet companies such as Airbnb and Facebook. However, there are members from many different industries. The web touches pretty much every area of life and business, and there are companies doing interesting things in the space that we might not think of as web companies. For example, people working in traditional publishing (a lot of books are formatted using web technologies) and the automotive industry.

What all the members have in common is that the web impacts the work that they do, and they are keen to have a say in the direction things move, and even to play a part in creating and specifying web technologies.

I represent Fronteers (the Dutch organization of web developers) in the W3C. This year, Fronteers took the unusual* step of becoming a W3C Member Organization.

* “Unusual” because they are a voluntary organization representing web developers, rather than a big company representing the interests of a big company.

The Advisory Committee (AC)

Member organizations take part in the business of the W3C by having a vote on various matters. This is organized by the organization’s AC representative whose job it is to ferry information from the W3C to the organization, and also bring the point of view of the organization to relevant topics being discussed at the W3C.

I’m the rep for Fronteers and so I attend two AC meetings a year — and get a lot of emails! On voting matters, I have to find out from Fronteers how they want to vote and then cast the Fronteers vote. In the last year, one important voting matter was the election of Advisory Board (AB) members; Fronteers held an internal vote, and I took the results back to make the official vote at the W3C.

W3C Groups

Most web developers are probably more aware of the W3C working groups than the rest of the organization, as it is through these groups that most of the work we care about goes on. Any member organization can opt people from their organization onto a working group. In addition, the groups may invite certain people (known as Invited Experts) to participate in that group. I was an Invited Expert on the CSS Working Group, and now am part of the group as the representative for Fronteers. In practical terms, my interaction with the CSS Working Group remains the same, however, I now have a role to play in the W3C as a whole as the W3C rep for Fronteers.

There are a large number of working groups, covering a whole range of technologies. These groups typically work on some kind of deliverable, such as the specifications produced by the CSS Working Group. There are also a number of Interest Groups, which allow for the exchange of ideas around particular topics which may also fall partly into the remit of some of the working groups.

The above groups require a significant time commitment and either a W3C membership or Invited Expert status, however, there are a number of Community and Business Groups that are open to any interested person and do not impose a particular time commitment. The Web Platform Incubator Community Group is one such group and has a Discourse forum for the discussion of new web features, and also various proposals on GitHub. Many of these features ultimately become CSS or other language specifications and therefore part of the platform.

Getting Involved And Following Along

In addition to joining a community group, it is worth noting that anyone can become involved in the work of the W3C, i.e. you don’t need to be an Invited Expert, part of a member organization, or have any special qualifications. For example, if you want to know what is happening at the CSS Working Group, you can take a look at our Issues on GitHub. Anyone can comment on these issues to offer new use cases for a feature and can even raise an issue for a feature they feel should be part of a CSS specification.

As with most W3C groups, the CSS WG uses IRC to minute meetings; any discussion on an issue will be posted back to the issue afterward so anyone who is interested can follow along.

A GitHub message auto-generated to link IRC minutes to the issue

An example of a message that was auto-generated regarding an issue that had been discussed in a meeting.

If you are keen to know what the wider W3C is doing, then the strategic highlights document is a good place to look. The latest document was produced in September, and exposes some of the key work recently achieved by W3C groups. Scrolling through that document demonstrates the wide range of activities that the W3C is involved with. It is so important for the web community to engage with standards, as we’ve already seen examples in the past of what happens when vendors control the direction of the web.

This history is explained beautifully by Amy Dickens in her post, “Web Standards: The What, The Why, And The How”:

“Without the Web Standards community, browser makers would be the ones making decisions on what should and shouldn’t be features of the world wide web. This could lead to the web becoming a monopolized commodity, where only the largest players would have a say in what the future holds.”

My #WebStory

Why does all of this matter to me? One of the reasons I care so much about the web platform remaining open and accessible to new people who want to publish on and build things for the web is because of the route I took to get here.

As mentioned earlier, the W3C is celebrating their anniversary by inviting people to share stories of how they became involved in the web.* In that spirit (and perhaps to encourage Smashing readers to share their stories), here is mine.

* So many folks have already shared their journey on the W3C Blog of how they were first amazed by the web and continue to be in awe of its potential. Join in and share your story!

I had never intended to work with computers. I intended to become a dancer and singer, and I left school at 16 to go to dance college. My father is a programmer, however, so we were fairly unusual at the time as we had a computer in the house by 1985 when I was 10.

As a child, I liked typing in the code of “choose your own adventure” games, which appeared in books and magazines. I liked spotting the strings of text which would then show up in the game I would later play (usually, once my dad had fixed it up) on our Amstrad CPC464. I liked to visit the computer lab at Newcastle University, see the huge computers, and talk to the women who worked on them. Perhaps most importantly (and despite my arty interests), I never grew up thinking I couldn’t use computers. I just wasn’t especially interested.

A book with lines of code intending to be typed out to make a text game

The books I copied games out of as a child.

At school, I learned to type on an electronic typewriter, and the only computer in evidence was in the art room that was used for basic drawing applications. As we did have computers at home, I had used them for schoolwork, despite some teachers not being happy about printed essays.

I ultimately left dance and went backstage, working in the West-End of London. Moving lights, automated sets, and show control systems were about to make huge changes to an industry that had seen little change in years. We were seeing the beginnings of that change when I was in the West End; I remember laughing with the crew as we heard news about some show with a “fancy computer system” which had lots of problems that our traditional production didn’t have. None of us could have imagined the changes that were coming.

Then I became pregnant with my daughter and had to leave the theatre. I was good at crewing and loved the theatre, but it was heavy and sometimes dangerous work with unsociable hours — not really a job for someone with a baby. I didn’t know what I would do, but I could type so I thought that perhaps I could type up essays for people. I was upsold to a computer — having gone into PC World looking for a wordprocessor. It was a Packard Bell 486 with a built-in 640×480 screen — a terrible machine that would allow me to either get the sound card working or the modem, but not both at once. I chose the modem and this is where my web story really begins. Even getting this modem working and getting the computer onto the Internet was something of a challenge and, once I did, I went looking for information about… babies.

I didn’t know anything about babies. All my friends were men who worked backstage in theatre. I had no support network, no family around me to help, and so I logged onto ParentsPlace and found people who didn’t mind my questions and were happy to help. At the time, there obviously was no Facebook. This meant that if you wanted to share photos and stories, you built a website. So among the forums about childbirth and toddler tantrums, there were people teaching each other HTML and sharing sets of graphics along with the code to place them. It was like typing out those “choose your own adventure” books again. I was amazed that I didn’t need anyone to fix my code — it just worked!

A screenshot of the 1997 ParentsPlace website

Pulled out from the Internet Archive, this was a website named ‘ParentsPlace’ that existed around the time I was pregnant with my daughter. link

Before long, people would pay me to build them a website, and I felt that I should repay at least in some way for all of the questions I had asked. So, I started to answer questions in the forums. That was how it seemed to work. People would learn and move one step up the ladder, the new people would come in with the same questions and the people a step ahead would answer — all the while asking their own questions of those further along. I loved this. I could never have afforded lessons, but I had time. I could help others, and in return, people helped me. I discovered through this that I was quite good at explaining technical things in a straightforward way — an ability I have always accredited to the fact that I struggled to learn these new things myself. It was never easy. I was willing to spend the time, however, and found it interesting.

With my daughter on my knee, I started to teach myself Perl because I didn’t like any of the off-the-shelf guestbooks and wanted to write my own. I installed Linux on a second-hand Compaq, and learned the basics of systems administration, how to compile Apache, wrapped my head round file permissions, and so by the time my daughter was three years old, I got a job heading up a technical team in a property “dot com” company.

I became interested in web standards essentially because it made no sense to me that we would have to build the same website twice — in order that it would work in both browsers. At the time, Dreamweaver was the tool of choice for many web developers, as it made dealing with the mess of nested tables we had to battle with much easier. So, influenced by the work of The Web Standards Project, I (along with my then-boyfriend, now-husband Drew McLellan) began sharing tips and Dreamweaver extensions with the Dreamweaver Usenet group, while all along explaining why web standards were important and showing how to make Dreamweaver support standards.

A screenshot of my bio on the WaSP site retrieved from the Internet Archive

My bio on the WaSP site in 2002 — there wasn’t much to say! ( link)

Ultimately, we both ended up on the Macromedia Beta, helping to make Dreamweaver itself more standards-compliant. We were also invited to join the Web Standards Project — specifically to be part of the Dreamweaver Task Force. I couldn’t believe that Jeffrey Zeldman emailed me, asking me to join WaSP! These were the people I looked up to and had learned so much from. The fact that they wanted me to be part of the organization was amazing and gave me so much confidence to continue with the work I was already doing.

That involvement became the bedrock of my career; I realized that my ability to explain technical things could help other web developers learn these new technologies and understand the need for standards. I also discovered that being able to explain things clearly was useful in raising bug reports, and writing up use cases for new software features (in browsers or tools such as Dreamweaver). Two decades after discovering web standards, I am still doing this work. It continues to interest me, and I think it is more important than ever.

The open nature of the web, the relative simplicity of the technologies, and the helpful, sharing attitude of the community is why I am here at all. One of the biggest reasons why I have stayed after all these years is because of Web standards and the continued fight for the open web. That’s why I think that the W3C and the standards process is vitally important, and why I think it so important that web developers get involved in the process, too.

I want to help ensure that the voice of the web developer working on small projects is heard, and that the direction of the web isn’t dictated by a few giant companies. The web is where we have made our careers, and often even our social lives; it is the way that we communicate with each other. I want it to stay a place where I want to be. I want it to remain open enough that the next person without a technical background can pitch up and start publishing and creating, and find it a place they want to establish a career, too.

What’s Your Web Story?

Whether you have been working on the web for over 20 years or only one, please share your stories on the W3C blog, on your own site, or perhaps write up something in the comments section here below. I’d love to hear your journey!

Smashing Editorial

Source: Smashing Magazine, The W3C At Twenty-Five

Collective #556

dreamt up by webguru in Uncategorized | Comments Off on Collective #556


Top-level await

Read about top-level await that makes it possible to use the await keyword outside of async functions in JavaScript modules.

Read it


Dark mode

Jeremy Keith shares how he implemented a dark mode for his website.

Read it



Dashdash is a new spreadsheet tool with access to business data and APIs through integrations with Crunchbase, LinkedIn, Mailchimp, Google Maps data, easily usable with the fresh templates feature.

Check it out



In case you didn’t know about it: Moveable is draggable, resizable, scalable, rotatable, warpable, pinchable, groupable and snappable. A super useful script.

Check it out



Tania Rascia’s plain text notes app in progress. Built with React, Redux and TypeScript.

Check it out



After the release of Wasmer-JS, Aaron Turner now introduces, an online WebAssembly Terminal to run WASI modules directly in your browser.

Read it


The box model is not layout

Kilian Valkhof argues that if we keep referring to our imaginary perfect layout system in design tools as “box model”, we risk getting the wrong thing.

Read it



A Figma-ready collection of original macOS cursors to be used in design projects.

Check it out

Collective #556 was written by Pedro Botelho and published on Codrops.

Source: Codrops, Collective #556

A Guide To New And Experimental CSS DevTools In Firefox

dreamt up by webguru in Uncategorized | Comments Off on A Guide To New And Experimental CSS DevTools In Firefox

A Guide To New And Experimental CSS DevTools In Firefox

A Guide To New And Experimental CSS DevTools In Firefox

Victoria Wang

Over the last few years, our team at Firefox has been working on new CSS tools that address both cutting-edge techniques and age-old frustrations. We’re the Layout Tools team, a subset of Firefox Developer Tools, and our quest is to improve the modern web design workflow.

The web has seen an incredible evolution in the last decade: new HTML/CSS features, browser improvements, and design techniques. Our team is devoted to building tools that match that innovation so that designers and developers can harness more of the efficiency and creativity that’s now possible.

In this guide, we’ll share an overview of our seven new tools, with stories from the design process and practical steps for trying out each tool.

Editorial Design Patterns

By naming lines when setting up our CSS Grid layouts, we can tap into some interesting and useful features of Grid — features that become even more powerful when we introduce subgrids. Read related article →

1. Grid Inspector

It all started three years ago when our CSS layout expert and dev advocate, Jen Simmons, worked with members of Firefox DevTools to build a tool that would aid users in examining CSS Grid layouts.

As one of the most powerful new features of the modern web, CSS Grid had quickly gained decent browser adoption, but it still had low website adoption. There’s a steep learning curve, and you still need fallbacks for certain browsers. Thus, part of our goal was to help popularize Grid by giving developers a more hands-on way to learn it.

An example of the Grid Inspector displaying an outline of the grid layout

Grid Inspector (Large preview)

The core of the tool is a grid outline, overlaid on the page, which helps devs visualize how the grid is positioning their elements, and how the layout changes when they tweak their styles. We added numbered labels to identify each grid line, the ability to view up to three grids at once, and color customization for the overlays. Recently, we also added support for subgrid, a brand new CSS specification implemented in Firefox and hopefully in more browsers soon.

Grid Inspector was an inspiration for all the tools that followed. It was even an inspiration for a new team: Layout Tools! Formed in late 2017, we’re spread across four time zones and collaborate with many others in Mozilla, like our rendering engine developers and the good folks at MDN.

Try Out The Grid Inspector

  1. In Firefox, visit our Grid example site.
  2. Open the Inspector with Cmd + Shift + C.
  3. Turn on Grid overlay via one of three ways:
    • Layout Panel:
      In the Grid section, check the checkbox next to .content.grid-content;
    • Markup View:
      Toggle the “grid” badge next to <div class="content grid-content">;
    • Rules View:
      Click the button next to display:grid; inside #page-intro .grid-content;
  4. Experiment with the Grid Inspector:
    • Change the purple overlay color to red;
    • Toggle “Line numbers” or “Extend lines infinitely”;
    • Turn on more grid overlays;
    • See what happens when you disable grid-gap: 15px in Rules.

Since Grid, we’ve been seeking to expand on the possibilities of what a browser CSS tool can be.

2. Shape Path Editor

The next project we worked on was the Shape Path Editor: our first visual editing tool.

CSS Shapes allows you to define shapes for text to flow around: a circle, a triangle, or a many-sided polygon. It can be used with the clip-path property which allows you to trim elements to any of those same shapes. These two techniques together open the possibility for some very unique graphic design-inspired layouts.

However, creating these sometimes complex shapes can be difficult. Typing all of the coordinates manually and using the right CSS units is error-prone and far removed from the creative mindset that Shapes allows. Therefore, we made a tool that allows you to edit your code by directly clicking and dragging shapes on the page.

This type of feature—visual editing—was new for us and browser tools in general. It’s an example of how we can go beyond inspecting and debugging and into the realm of design.

Try Out The Shape Path Editor

  1. In Firefox, visit this page on the An Event Apart website.
  2. Open the Inspector with Cmd + Shift + C and select the first circular image.
  3. In Rules, click on the icon next to the shape-outside property.
  4. On the page, click on the points of the shape and see what happens when you drag to make the shape huge or tiny. Change it to a size that looks good to you.

Visual editing is an example of how we can go beyond inspecting and debugging and into the realm of design.

3. Fonts Editor

For years, we’ve had a Fonts panel in Firefox that shows an informative list of all the fonts used in a website. In continuing our theme of designing in the browser, we decided to turn this into a Font Editor for fine-tuning a font’s properties.

An example of the Fonts Editor index of fonts and variable fonts editing

Fonts Editor (Large preview)

A driving force behind this project was our goal to support Variable Fonts at the same time that the Firefox rendering engine team was adding support for it. Variable Fonts gives font designers a way to offer fine-grained variations along axes, like weight, within one font file. It also supports custom axes, which give both font creators and web designers an amazing amount of flexibility. Our tool automatically detects these custom axes and gives you a way to adjust and visualize them. This would otherwise require specialized websites like Axis-Praxis.

Additionally, we added a feature that provides the ability to hover over a font name to highlight where that particular font is being used on the page. This is helpful because the way browsers select the font used to render a piece of text can be complex and depend on one’s computer. Some characters may be unexpectedly swapped out for a different font due to font subsetting.

Try Out The Fonts Editor

  1. In Firefox, visit this variable fonts demo site.
  2. Open the Inspector with Cmd + Shift + C and select the word “variable” in the title (the element’s selector is .title__variable-web__variable).
  3. In the third pane of the Inspector, navigate to the Fonts panel:
    • Hover over the font name Output Sans Regular to see what gets highlighted;
    • Try out the weight and slant sliders;
    • Take a look at the preset font variations in the Instances dropdown menu.

4. Flexbox Inspector

Our Grid, Shapes, and Variable Fonts tools can together power some very advanced graphic design on the web, but they’re still somewhat cutting-edge based on browser support. (They’re almost there, but still require fallbacks.) We didn’t want to work only on new features—we were drawn to the problems that most web developers face on a daily basis.

So we started work on the Flexbox Inspector. Design-wise, this has been our most ambitious project, and it sprouted some new user research strategies for our team.

Like Grid, CSS Flexbox has a fairly steep learning curve when you first get started. It takes time to really understand it, and many of us resort to trial and error to achieve the layouts we want. At the beginning of the project, our team wasn’t even sure if we understood Flexbox ourselves, and we didn’t know what the main challenges were. So we leveled up our understanding, and we ran a survey to discover what people needed the most when it came to Flexbox.

The results had a big effect on our plans, making the case for complicated visualizations like grow/shrink and min/max. We continued working with the community throughout the project by incorporating feedback into evolving visual prototypes and Nightly builds.

The tool includes two major parts: a highlighter that works much like the Grid Inspector’s, and a detailed Flexbox tool inside the Inspector. The core of the tool is a flex item diagram with sizing info.

An example of the flex item diagram and sizing table

Flex item diagram and sizing (Large preview)

With help from Gecko layout engineers, we were able to show the step-by-step size decisions of the rendering engine to give users a full picture of why and how a flex item ended up with a certain size.

Note: Learn the full story of our design process in “Designing the Flexbox Inspector”.

Try Out The Flexbox Inspector

  1. In Firefox, visit Mozilla’s Bugzilla.
  2. Open the Inspector with Cmd + Shift + C and select the element div.inner (just inside the header bar).
  3. Turn on the Flexbox overlay via one of three ways:
    • Layout Panel:
      In the Flex Container section, turn on the switch;
    • Markup View:
      Toggle the “flex” badge next to <div class="inner">;
    • Rules View:
      Click the button next to display:flex.
  4. Use the Flex Container panel to navigate to a Flex Item called nav#header-nav.
    • Note the sizes shown in the diagram and size chart;
    • Increase and decrease your browser’s width and see how the diagram changes.

Interlude: Doubling Down on Research

As a small team with no formal user research support, we’ve often resorted to design-by-dogfooding: basing our opinions on our own experiences in using the tools. But after our success with the Flexbox survey, we knew we wanted to be better at collecting data to guide us. We ran a new survey to help inform our next steps.

We crowdsourced a list of the 20 biggest challenges faced by web devs and asked our community to rank them using a max-diff format.

When we found that the big winner of the challenges was CSS Layout Debugging, we ran a follow-up survey on specific CSS bugs to discover the biggest pain points. We supplemented these surveys with user interviews and user testing.

We also asked folks to rank their frustrations with browser developer tools. The clear top issue was moving CSS changes back to the editor. This became our next project.

5. Changes Panel

The difficulty in transferring one’s work from a browser developer tool to the editor is one of those age-old issues that we all just got used to. We were excited to make a simple and immediately usable solution.

An example of the diff view provided by the Changes Panel

Changes Panel (Large preview)

Edge and Chrome DevTools came out with variants of this tool first. Ours is focused on assisting a wide range of CSS workflows: Launch DevTools, change any styles you want, and then export your changes by either copying the full set of changes (for collaboration) or just one changed rule (for pasting into code).

This improves the robustness of the entire workflow, including our other layout tools. And this is just a start: We know accidental refreshing and navigation from the page is a big source of data loss, so a way to bring persistence to the tool will be an important next step.

Try Out The Changes Panel

  1. In Firefox, navigate to any website.
  2. Open the Inspector with Cmd + Shift + C and select an element.
  3. Make some changes to the CSS:
    • Modify styles in the Rules pane;
    • Adjust fonts in the Fonts pane.
  4. In the right pane of the Inspector, navigate to the Changes tab and do the following:
    • Click Copy All Changes, then paste it in a text editor to view the output;
    • Hover over the selector name and click Copy Rule, then paste it to view the output.

6. Inactive CSS

Our Inactive CSS feature solves one of the top issues from our layout debugging survey on specific CSS bugs:

“Why is this CSS property not doing anything?”

Design-wise, this feature is very simple—it grays out CSS that doesn’t affect the page, and shows a tooltip to explain why the property doesn’t have an effect. But we know this can boost efficiency and cut down on frustration. We were bolstered by research from Sarah Lim and her colleagues who built a similar tool. In their studies, they found that novice developers were 50% faster at building with CSS when they used a tool that allowed them to ignore irrelevant code.

An example of an inactive CSS tooltip warning

Inactive CSS tooltip (Large preview)

In a way, this is our favorite kind of feature: A low-hanging UX fruit that barely registers as a feature, but improves the whole workflow without really needing to be discovered or learned.

Inactive CSS launches in Firefox 70 but can be used now in prerelease versions of Firefox, including Developer Edition, Beta, and Nightly.

Try Out Inactive CSS

  1. Download Firefox Developer Edition;
  2. Open Firefox and navigate to;
  3. Open the Inspector with Cmd + Shift + C and select the center content area, called central-featured;
  4. Note the grayed out vertical-align declaration;
  5. Hover over the info icon, and click “Learn more” if you’re interested.

7. Accessibility Panel

Along the way we’ve had accessibility features developed by a separate team that’s mostly one person — Yura Zenevich, this year with his intern Maliha Islam.

Together they’ve turned the new Accessibility panel in Firefox into a powerful inspection and auditing tool. Besides displaying the accessibility tree and properties, you can now run different types of checks on a page. So far the checks include color contrast, text labels, and keyboard focus styling.

An example of the Accessibility Panel’s auditing feature

Auditing in the Accessibility Panel (Large preview)

Now in Nightly, you can try the new color blindness simulator which harnesses our upcoming WebRender tech.

Try Out The Accessibility Panel

  1. Download Firefox Developer Edition;
  2. Navigate to;
  3. In the developer tools, navigate to the Accessibility tab, and click the “Turn on Accessibility Features” button;
  4. Click the drop-down menu next to “Check for issues” and select “All Issues”;
  5. Take a look at the various contrast, keyboard, and text label issues, and click the “Learn more” links if you’re interested.

Next Up

We’re currently hard at work on a browser compatibility tool that uses information from MDN to show browser-specific issues for a selected element. You can follow along on GitHub to learn more.

The Future

We’re committed to supporting the modern web, and that means continuously changing and growing.

New specifications get implemented by browser vendors all the time. Guidelines and best practices around progressive enhancement, responsiveness, and accessibility evolve constantly. Us tool makers need to keep evolving too.

And what of the long-lived, ever-present problems in creating the web? What everyday user interfaces need to be rethought? These are some of the questions that keep us going!

What about a better way to navigate the DOM tree of a page? That part of DevTools has gone essentially unchanged since the Firebug days.

We’ve been experimenting with features like back and forward buttons that would ease navigation between recently visited elements.

A more dramatic change we’re discussing is adding a compact DOM view that uses a syntax similar to HTML templating engines. The focus would be on the most common use case—navigating to CSS—rather than viewing/editing the source.

A mockup of the simplified HTML Outline View

HTML Outline View (Large preview)

We’ve also been thinking about a better element selector. We know how it can be more productive to work inside the page, with less jumping back and forth into DevTools. We could make the element selector more powerful and more persistent. Perhaps it could select whitespace on a page and tell you what causes that space, or it could shed light on the relationships between different elements.

A mockup of element overlay with collapsed margin

Visual Element Selector (Large preview)

These are just two of the many ideas we hope to explore further with the help of the community.

We Need Your Input!

We want to keep making awesome tools that make your life easier as a developer or designer.

Here’s an easy way to help: Download Firefox Developer Edition and try using it for some of your work next week.

Then, tell us what you think by taking our 1-page survey.

We’re always interested in hearing ideas for improvements, particularly any low-hanging fruit that could save us all from some regular frustration. We do our work in the open, so you can follow along and chime in. We’ll keep you updated at @FirefoxDevTools.

Thanks to Patrick Brosset for his contributions to this article.

Smashing Editorial
(dm, il)

Source: Smashing Magazine, A Guide To New And Experimental CSS DevTools In Firefox

How To Use Breadcrumbs On A PWA

dreamt up by webguru in Uncategorized | Comments Off on How To Use Breadcrumbs On A PWA

How To Use Breadcrumbs On A PWA

How To Use Breadcrumbs On A PWA

Suzanne Scacca

I’ve seen a lot of questions about whether or not breadcrumbs are necessary for PWAs. It makes sense why the question is raised. After all, PWAs have an app shell and sticky menu, so shouldn’t it be easy for users to move around it without a secondary navigation?

It’s not as simple as that.

Because PWAs often straddle the line between website and native app, navigation isn’t always minimized — especially if you’re building large e-commerce stores or blogs. Plus, don’t forget that breadcrumbs aren’t just for navigation. They’re often used to show progress.

So, today, we’re going to look at how to design breadcrumbs for PWAs and some interesting use cases where they come in handy.

Will PWAs Replace Native Mobile Apps?

When it comes to the mobile user experience, are mobile websites all that bad? You hear so much about the benefits of building a dedicated native app, but that can become an incredibly costly gamble if users don’t take to it. Read related article →

One of the reasons we build PWAs instead of websites is because they offer a better mobile experience. But that doesn’t mean you can strictly rely on your visitors to use the navigation to get around. In some cases, they’re going to need a bit of hand-holding.

Breadcrumbs are a great way to step in and say:

Did you go too far? Let us help you backtrack a step or two.

Yankee Candle shows us one way this can be done:

Yankee Candle breadcrumbs navigation

Yankee Candle displays a breadcrumbs navigation as visitors move deeper through its candle inventory and categories. (Source: Yankee Candle) (Large preview)

Or your breadcrumbs might be saying:

Not sure how much further you have to go (or how much more you can take)? Here are your remaining steps.

The checkout process can certainly get tiresome on mobile when it’s broken into multiple steps. That’s why breadcrumbs progress bars like the one Cort uses are so helpful.

Cort breadcrumbs for progress

Customers looking to rent furniture from Cort are taking through a multi-step checkout process with breadcrumb dots indicating progress. (Source: Cort) (Large preview)

These aren’t the only ways you can use breadcrumbs to improve the visitor experience with a PWA. Here are some other use cases you can take advantage of:

If you’re building a large e-commerce PWA with multiple hierarchies or categories of products, breadcrumbs are 100% necessary.

There’s just no room on mobile to display that sort of deep navigation without driving your shoppers mad.

Breadcrumbs also make it easier for shoppers to see the steps they’ve taken, so they can determine how far back they need to skip.

For example, let’s say someone were shopping for a new moisturizer on the Lancôme PWA:

Lancôme PWA breadcrumbs trail

The Lancôme PWA uses breadcrumbs to help shoppers backtrack more easily. (Source: Lancôme) (Large preview)

But let’s say they were looking for something they could wear during the day and hadn’t paid enough attention to the name of the product before clicking on it. Breadcrumbs, then, allow them to go to the exact spot they need to be (i.e. “Moisturizers”) to find the right category (“Day Creams”).

This type of breadcrumbs navigation becomes especially important the deeper the navigation goes.

Just be careful.

Although Yankee Candle has an example of what to do above, if you pry deeper into its inventory, you’ll find that it’s breadcrumbing is somewhat compromised:

Yankee Candle offscreen breadcrumbs

As visitors go deeper into Yankee Candle’s store, the breadcrumbs go offscreen. (Source: Yankee Candle) (Large preview)

You might not be able to tell from the screenshot above, but the breadcrumbs go offscreen. And if you can’t tell that, then the visitors of the PWA aren’t going to be able to tell that either.

The extra breadcrumbs do exist. They just require visitors to scroll to the right to find them:

Yankee Candle breadcrumb scroll

Yankee Candle adds a scroll to its breadcrumb trail. (Source: Yankee Candle) (Large preview)

Realistically, this could cause problems for visitors who are familiar with scrolling, but not with having to scroll individual elements like a breadcrumbs navigation.

One thing that Yankee Candle has done well in this example is that it’s preserved the size of its breadcrumbs so that they remain readable and clickable. That’s something that doesn’t always happen if you add a wrap function to the navigation.

I’ll show you why the matter of size might come up when you’re designing this element.

This is the Bed Bath & Beyond website:

Bed Bath & Beyond’s oversized breadcrumbs

Bed Bath & Beyond’s breadcrumbs take up about a quarter of the mobile web page. (Source: Bed Bath & Beyond) (Large preview)

This is certainly a neat way to design your breadcrumbs, especially since the last crumb enables users to dig even deeper to categories like:

  • Casual Dinnerware,
  • Fine China,
  • Charger Plates.

Once the visitor selects one of the products, they’re shown a standard plain-text breadcrumbs along the top of the page. That said, this in-between “Dining | Dinnerware | Dinnerware Sets” breadcrumbs trail takes up nearly a quarter of the page. It doesn’t totally compromise the shopping experience, but it might cause undue irritation since visitors have to do a lot of scrolling to see each of the available dinnerware sets now.

Your best bet? Visitors know to look for breadcrumbs in e-commerce, whether it’s on desktop, mobile or PWA. So, don’t try and get creative with it. Place them where they belong (i.e. just under the header) and use uniform typography. If your breadcrumbs have a tendency to run on the long side, you can wrap them or, better yet, reduce how many are displayed at once.

In the Yankee Candle example above, this is what visitors see when they scroll the full width of the breadcrumb:

Home / Seasonal Candles / Fall Candles / Fall Jar Candles / Sweet Maple Chai Large Fall Jar Candles

This is what it could be instead:

Seasonal Candles / Fall Candles / Fall Jar Candles

There’s really no need to include the “Home” attribute as everyone knows the logo points there. And there’s no need to spell out the name of the product since it’s right below the breadcrumb. When you do this for your PWA, just remember to trim it back so that only the essentials appear.

2. Improve the Browsability of Blogs

When someone reads a blog from the comfort of their desktop or laptop, they usually have the convenience of a sidebar that shows them other recent or relevant articles. On mobile, though, that’s impossible. Instead, they have to:

  • Scroll to the bottom of the post and see if related links are available there,
  • Use the blog’s search function (if there is one),
  • Or go to a relevant category or date using breadcrumbs.

Scrolling isn’t ideal, especially if your readers don’t always get through the full post. Search would be fine, but it requires them to have a very clear idea of what they’re looking for. Breadcrumbs, on the other hand, provides some context about what they’re reading as well as guidance for what else they can find.

The Cooking Light blog handles this well:

Cooking Light content

The Cooking Light blog uses a simplified breadcrumbs to help users find related content. (Source: Cooking Light) (Large preview)

Let’s say a visitor lands on the Cooking Light home page and sees this article about measuring how much pumpkin comes in a can. They click on it and find it a worthwhile read.

Now, someone who clicks on an article like this is likely to be a novice cook, so they’d most definitely be interested in picking up other beginner tips and insights. That’s why Cooking Light’s breadcrumb is so useful. This could’ve ended up being something like this:

Home > Cooking > Thanksgiving > Pies > Pumpkin Pie

Instead, the article was properly and simply categorized so that the kinds of readers it attracts can find other useful and relevant content.

While you might be tempted to categorize blog posts a different way, it can over-complicate the breadcrumbs. Case in point, this is how the Transportation Security Administration (TSA) does theirs:

TSA blog breadcrumbs

The TSA designs its blog breadcrumbs using dates (years and months). (Source: TSA) (Large preview)

In the example above, you can see that the breadcrumbs are nothing more than a breakdown of the publication date. Unless you have visitors constantly searching for time-sensitive information instead of valuable guides, this type of breadcrumb isn’t going to work very well.

Another thing I want to mention is that the inclusion of the title in the breadcrumbs is unnecessary. It’s nothing more than a duplication of the blog post title that appears directly below it. What’s more, the length of the title forces the breadcrumbs to wrap and take up more space than it needs to.

Simpler is always better, especially if the goal of the breadcrumbs is to help visitors read more of your blog content. You can use my tip from #1 about shortening your breadcrumbs to fix this issue.

3. Make It Easier to Get Help

One of the cool things about building products for the web is that it allows us to sell exponentially more than we could if we had to constantly stock a physical inventory. But that doesn’t release us from the responsibility of supporting our products. When you build a piece of software, you better be there to help customers with it.

That said, a lot of the problems SaaS users run into are commonplace and can easily be answered with a support portal. That way, you empower users to look up answers to their own problems and avoid clogging up your support queue. It’s a win-win for both sides.

Now, support portals are a lot like blogs in that they can be tough to get around if you don’t have the convenience of a sidebar or search bar to show you the way. Even if those elements are present, it’s still nice to have additional context as you go deeper and deeper into the support archives.

For instance, this is FreshWorks’ Freshsales CRM support portal:

Freshsales support portal breadcrumbs

The Freshsales support portal always keeps breadcrumbs at the top of the page for reference. (Source: FreshWorks) (Large preview)

There is a ton of documentation in this support portal. It would be silly not to have a breadcrumbs navigation available at the top of the page. And like the blog breadcrumbs examples, this one helps users in two ways.

It’s useful for backtracking, for one. It’s also helpful for users that are trying to learn a lot more about the same subject. By providing this level of support, your users will learn how to master your product more easily and be more likely to renew their subscriptions at the end of the term.

Another software that uses breadcrumbs in its support section is Calendly:

Calendly support breadcrumbs

Calendly includes too many attributes in its support breadcrumbs navigation. (Source: Calendly) (Large preview)

Notice how the name of the page and category of support topics is present just below the search bar. Now, look at the attributes included in the breadcrumbs:

Help Center > Calendly > Getting Started > Getting Started

None of these belong here except “Help Center”. Anyone who’s landed on this page knows that the support topic pertains to the product (Calendly). And they’re also going to see the page title is “Getting Started”, so the duplication of it here is of no help.

Really, the breadcrumbs shouldn’t even come into play until they dig deeper in the navigation. Even then, I don’t know if it’s necessary since the title is always present at the top of the page.

When building out your own SaaS support portal, really think about what belongs in the breadcrumbs and what doesn’t. If it’s a simple enough self-support system, you might not need it at all.

4. Improve Conversions with Progress Bars

When you give your PWA visitors a multi-step process to work through — be it an e-commerce checkout, quiz, questionnaire and so on — don’t leave them wondering whether it’s worth it to finish.

Now, that doesn’t mean you need to overwhelm them with a long form that appears all at once — that could just as well hurt your conversion rate. It’s completely fine to break longer processes into multiple steps. Just remember to use progress bar breadcrumbs to split them up.

This is something that’ll be especially useful in hospitality as the CitizenM reservation form demonstrates:

CitizenM progress bar breadcrumbs

When booking a reservation at the CitizenM hotel, visitors see exactly how much more work is ahead of them with breadcrumbs. (Source: CitizenM) (Large preview)

These breadcrumbs serve two purposes:

  1. Visitors can see how much work is actually involved in the process.
  2. They can use them to backtrack if they need to change a response.

This can make what might otherwise seem like a never-ending booking process more manageable. But that doesn’t mean that breadcrumbs, as a whole, always contribute to higher conversions.

Part of the reason the breadcrumbs example above works so well is because it’s well-labeled and simplified. When you remove the transparency and logic from breadcrumbs progress bars, though, they can end up harming your conversion rates.

For example, Ipsy is a monthly makeup subscription service. In order to get started, visitors to the PWA must fill out this quiz:

Ipsy quiz with breadcrumbs

Ipsy requires new users to fill out a beauty quiz before they can subscribe. (Source: Ipsy) (Large preview)

While the design of the quiz is certainly attractive, is it necessary to have built it this way, especially since there are 12 pages that require two clicks or more on each page? That comes to at least 24 clicks in total (one or more for the answer and one for the “Next” button).

That doesn’t even include filling out the subscription form!

That said, the breadcrumbs progress bar is there to show potential customers how much more work is to be done. However, there’s no transparency over what each of those pages involves. In fact, most of them are much longer than this first one, asking for things like favorite name brands, types of makeup they like, how frequently they wear it, etc.

In the end, it’ll probably take five minutes or more to complete the quiz and I don’t think the progress bar does any good in demonstrating that fact.

Bottom line: If you want to get visitors to the point of conversion more quickly, design it that way. And if it does require some work on their part, be honest about how much work there is. Don’t mask it with breadcrumbs.

5. Make Directories Easier to Explore

Thankfully, directories no longer live inside of massive phone books or travel guides. We now digitize those directories for quicker and more convenient consumption.

That said, online directories are a lot like big data. Now that they’re on the web, there’s almost too much information to sift through. And while most PWAs give visitors the ability to filter and sort their results, that doesn’t necessarily help with moving around the PWA itself.

What you need for that is breadcrumbs.

You’ll find a nice example of this on the OpenTable PWA:

OpenTable location breadcrumbs

OpenTable displays location breadcrumbs to users as they search for and book reservations. (Source: OpenTable) (Large preview)

There are hundreds of thousands of restaurants using OpenTable as their reservation system — and from locations all over the world.

While it might not be totally necessary to show breadcrumbs, especially if users know exactly which city they want to dine in, it’s a nice touch. It serves as a quick reminder to users that this is the location they’re searching in. If they change their mind and want to try the next town over, all it takes is a click back to the state or province to change their response.

TripAdvisor is another massive directory site, this one storing massive amounts of data on locations, places to stay, things to do, etc. There’s just so much going on inside this PWA that there’s no way to get by without breadcrumbs:

TripAdvisor PWA breadcrumbs

The TripAdvisor travel directory PWA uses breadcrumbs to break down the attributes of a search. (Source: TripAdvisor) (Large preview)

In this example, you can see how deep and specific the breadcrumbs attributes get:

Things to Do > Tickets & Tours > Water Sports > Hanauma Bay Snorkeling Service

This is useful for visitors that may have stumbled upon a particular activity or location, but, upon inspecting the breadcrumbs, realize there’s a different way to go.

For instance, let’s say someone gets to this page and starts wondering what other kinds of tours they can do in Hawaii. So, rather than restart their search (which they’d have to do if they landed on the page from the home page), they can use the breadcrumbs to backtrack.

That said, this is another one of those examples of putting too much into the breadcrumbs. There’s no need to include the name of the activity or location unless there are sub-categories beneath it. It only makes the breadcrumbs run past the width of the page, which can be distracting (and annoying).

Again, it’s a good idea to keep breadcrumbs as simple as possible when you can.

6. Convert Anchor Tags into Breadcrumbs

Earlier, I talked about how breadcrumbs can be used as progress bars on PWAs. What if we were to use them for a similar purpose, but this time to represent the anchor tags on a page?

It’s really no different than what developers do when they build a navigation into the top of a single-page website. The only difference is that the anchor tags from your page will be represented by breadcrumbs as a secondary navigation.

And if you’re publishing lengthy articles or guides on your PWA, this is something to seriously think about.

Here’s one example from the WebMD website:

WebMD breadcrumbs navigation for anchor tags

WebMD turns its anchor tags into a sort of breadcrumbs navigation. (Source: WebMD) (Large preview)

The WebMD PWA allows visitors to check their symptoms or look up medications they’re taking. As you might imagine, these pages can go on and on for a while.

Rather than force visitors to scroll through them, WebMD attaches this secondary navigation to the bottom of its header. As visitors scroll past the corresponding anchor tag and section, it gets highlighted in the breadcrumbs. Users can also use the breadcrumbs to quickly move around the page without having to scroll.

Airbnb does something similar:

Airbnb breadcrumbs navigation

Airbnb creates a breadcrumbs navigation from its anchor tags. (Source: Airbnb) (Large preview)

Airbnb could easily just leave its visitors to scroll through the page to try to pull out the details most relevant to them. Instead, it’s chosen to display a breadcrumbs navigation (built from the page’s anchor tags).

This makes it easy for them to see which section they’re in and then bounce around as they like to pick up the details they need to make their decision.

I know it’s not necessarily a common use of breadcrumbs, but I expect this one to appear more and more as the web shifts over to PWAs.

Wrapping Up

We’ve seen a lot of examples of PWAs now to know what good and bad breadcrumbs look like. Let’s sum up the basic rules:

  • Always place the breadcrumbs as close to the top of the page as possible. If the header is present, it goes directly below. If it’s not, it should take the top spot.
  • Use unique separators. The most common ones are the Guillemet (>), slash (/) and the pipe (|).
  • Build enough padding around the separators so it’s clear where the attributes start and end.
  • Make sure clickable links in breadcrumbs are big enough to tap. At minimum, they should be 1 cm x 1 cm.
  • Be careful with color. You don’t want breadcrumbs to distract from the content of the page. That said, they should at least change color or become underlined upon hover.
  • Simplify the attribute labels as much as possible.
  • Don’t include the name of the post, page, product, etc. in the breadcrumbs if it’s clearly visible on the page. “Home” probably doesn’t need to be there either.
  • If the breadcrumbs tend to run past the width of the page, wrap the text only if it doesn’t compromise clickability. It’s really best to display only the last few attributes/links.

There’s a lot you can do with breadcrumbs on PWAs and, if handled well, can help you increase your conversion rate. Just be careful with them. If they’re included without just cause or they present more work to your visitors, it’s best to just do without them.

Smashing Editorial
(ra, yk, il)

Source: Smashing Magazine, How To Use Breadcrumbs On A PWA

Developing A Custom Plugin For October CMS

dreamt up by webguru in Uncategorized | Comments Off on Developing A Custom Plugin For October CMS

Developing A Custom Plugin For October CMS

Developing A Custom Plugin For October CMS

Andriy Haydash

Last year, I did some research about new CMS systems in PHP in order to find a good alternative to WordPress. Ideally, it had to be an open-source solution with a clean and modern codebase.

One of them caught my interest: October CMS. I tried it and almost instantly liked it. The code structure was really nice and it was easy to write custom plugins.

This article aims to give you an overview of what to expect from the platform and give you a taste of it before you decide to commit to using it.

Why Choose October As Your CMS Platform?

There are a few main reasons why I have personally decided to use it for my projects.

Powered By Laravel

October is built on top of the most powerful PHP framework for creating modern web apps: Laravel. I can say with great confidence that it’s the best. It is very easy to use and understand, and has all the features that a modern framework needs, from routing, object-relational mapping (ORM), authorization, caching, and many others that provide a nice and clear MVC structure. As it is powered by Laravel, October has inherited all those features from its big brother.

Clean Code And Documentation

Unlike many other CMS solutions, October has a very clean and well-documented codebase. It’s written in using an objectoriented paradigm. Instead of plain old PHP, October uses Twig as its templating engine, which simplifies things for developers. Technical documentation is also well written, and helps you quickly find answers to most of your questions.

Great Community

Even though October’s community is not yet that big, it’s very helpful and responsive. There is a public Slack channel you can join, where you’ll find developers happy to assist you in fixing your issue.

Big Marketplace

Like WordPress and other CMSes, October has a marketplace for themes and plugins. Even though there aren’t that many good themes to choose from, there are over 700 plugins right now, so it’s very likely you’ll be able to add functionality by simply searching for and installing one of them. A great feature of plugins is that they can be easily synchronized between all your projects if you just add your project ID in the admin dashboard.

PlugIns And Components

Plugins are a foundation of adding new functionality to October. A plugin can consist of multiple files and directories that are responsible for registering custom components, models, updating database structure, or adding translations.

A plugin is usually created in the plugins/ directory of the project. Since many plugins are submitted to the marketplace for others to use, each plugin should have a custom namespace, which usually starts with the name of the company or developer that created the plug-in. So, for instance, if your name is Acme and you’ve created an awesome plugin called Blog, your plugin will live under the namespace of AcmeBlog.

Let me show you how a plugin directory structure might look like:

Sample plugin directory structure

Sample plugin directory structure (Large preview)

As you can see, there is also a file called plugin.php that is responsible for registering a plugin and all of its components in October CMS.

Another important thing to mention is that not all directories listed above are necessary for a plugin to run. Your plugin could have the following structure and still work perfectly well:

Simple plugin directory structure

Simple plugin directory structure (Large preview)

Most often, one plugin is built to add only one piece of functionality. For example, the ‘Translate’ plugin is designed to help you translate content on your website into different languages, and provide the multi-language support for the users.

October CMS has a great marketplace where you can find for your needs.

October marketplace

October marketplace (Large preview)

Unlike WordPress and other popular CMSes, October plugins can also have components. According to October’s documentation, components are “configurable building elements that can be attached to any page, partial or layout.” Examples might include: a contact form, navigation, a list of FAQs and their answers; basically anything that it makes sense to bundle together as one building block that can be reused on multiple pages.

Components are created as a part of a plugin and they exist in the components/ subdirectory:

Component directory structure

Component directory structure (Large preview)

Each component has a PHP file like componentName.php that defines the component, as well as an optional subdirectory for component partials. A component partials folder must have the same name in lowercase as the component itself.

To demonstrate how a component functions, let’s assume that our component is responsible for showing blog posts.

namespace AcmeBlogComponents;

class BlogPosts extends CmsClassesComponentBase
    public function componentDetails()
        return [
            'name' => 'Blog Posts',
            'description' => 'Displays a collection of blog posts.'

    // This array becomes available on the page as {{ component.posts }}
    public function posts()
        return ['First Post', 'Second Post', 'Third Post'];

As we can see, the component has two main functions. The first one, componentDetails(), provides information about the component to the administrator who will add and use components on their web pages.

The second function, posts(), returns dummy posts that can then be used inside a component partial (blogposts/default.htm file) like this:

url = "/blog"

{% for post in blogPosts.posts %}
    {{ post }}
{% endfor %}

For October CMS to know our component exists, we must register it using our main plugin file inside a function named registerComponents():

public function registerComponents()
    return [
        'OctoberDemoComponentsTodo' => 'demoTodo'

Creating A Custom Contact Form plugin

We’re going to create a custom contact form plug-in. Here are the assumptions about how the plugin should work:

  • The form will have the following fields: First Name, Last Name, Email, Message.
  • Data will be submitted to the server using Ajax.
  • After data is submitted, the admin will receive an email with the message sent by the user.

For the purpose of this tutorial we will use a fresh installation of October CMS:

Default view after fresh installation

Default view after fresh installation (Large preview)

Let’s start creating our plugin by running a command in a terminal that will generate the plugin structure: php artisan create:plugin progmatiq.contactform

Creating a new plugin from terminal

Creating a new plugin from terminal (Large preview)

The progmatiq.contactform argument contains the name of the author (progmatiq) and the name of the plugin (contactform).

New plugin folder structure

New plugin folder structure (Large preview)

Now we need to open our plugin.php file and modify the plugin details in the following method:

public function pluginDetails()
        return [
            'name'        => 'Contact Form',
            'description' => 'A simple contact form plug-in',
            'author'      => 'progmatiq',
            'icon'        => 'icon-leaf'

Here are a few other methods that you should take a look at:

  • registerComponents()
    Here you can define an array of components that your plugin provides.
  • registerPermissions()
    You can register custom permissions that you can then use later in other areas of the application.
  • registerNavigation()
    You can add a custom menu item with a URL to your admin dashboard menu.

Now let’s create our ContactForm component:

  1. Make a new folder named components/ inside your plug-in’s root directory.
  2. Create a file named contactForm.php inside the components/ folder.
  3. Creating a new component

    Creating a new component (Large preview)
  4. Paste the following code that will tell October what our component does. We can do it by creating a method inside our component called componentDetails().

namespace ProgmatiqContactformComponents;

use CmsClassesComponentBase;

class ContactForm extends ComponentBase
    public function componentDetails()
        return [
            'name' => 'Contact Form',
            'description' => 'A simple contact form'

Now we need to register our component inside the plug-in. To do that, we modify the registerComponents() method:

    public function registerComponents()
        return [
            'ProgmatiqContactformComponentsContactForm' => 'contactForm',

This function returns an array of components that our plugin provides. The component’s full class name is a key in this method, and a value is an alias that we’ll use to reference our component inside our Twig templates.

Once we have registered the component, we can create a new contact page and add our component (numbers in the steps refer to the screenshot):

  1. In your admin dashboard go to CMS (1) > Pages (2) and click on + Add (3).
  2. Give your page a name and a URL (4).
  3. Name your file (5) and select the default layout (6).

Creating a contact page

Creating a contact page (Large preview)

Let’s add our new component to the page:

  1. Click on Components in the left menu (1) and then select our “Contact Form” component. Once you click on it (2), it should be added to the page.
  2. We need to place a piece of code that would give our page a headline as well as render the component using the {% component ‘contactForm’ %} Twig directive:


{% component 'contactForm' %}

Adding contact form component to contact form page

Adding contact form component to contact form page (Large preview)

If you open your contact page right now, you will see the headline saying “Contact” and nothing else.

Contact page

Contact page (Large preview)

That’s because our contact form doesn’t have any HTML to render.

We need to create a contactform/default.htm file inside our components/ folder.

Adding a html view to our component

Adding an HTML view to our component (Large preview)

And add the following HTML code to the file:

<form method="POST" 
    data-request-success="this.reset(); alert('Thank you for submitting your inquiry')"


Most of this code is pretty straightforward. However, it is flavored with special data-* attributes that October allows us to use:

  1. <form> tag has three special attributes:
    • data-request="onSend". This attribute tells October that the onSend function from our component (that we’re going to create next) has to be called when the form is submitted using Ajax.
    • data-request-validate will enable form Ajax validation using errors that will be sent from the server if the form is invalid.
    • data-request-success="this.reset(); alert('Thank you for submitting your inquiry')" clears the form and then triggers the alert message if the request was successful and no validation or server-side errors were present.
  2. Every input has a following block that is responsible for displaying validation errors returned by the server for that given input:
  3. <p data-validate-for="content"  class="text-danger"></p>
  4. The submit button has the data-attach-loading attribute, which will add a spinner and disable the button while the request is being processed by the server. This is done in order to prevent the user submitting a form again until the previous request is complete.

And here is how our page looks now:

Contact page view

Contact page view (Large preview)

Let’s go back to our contactForm.php component and create the onSend() as well as validate() helper method that will be responsible for handling form submission:

public function onSend()
        // Get request data
        $data = Input::only([

        // Validate request

        // Send email
        $receiver = '';

        Mail::send('', $data, function ($message) use ($receiver) {

    protected function validate(array $data) 
        // Validate request
        $rules = [
            'first_name' => 'required|min:3|max:255',
            'last_name' => 'required|min:3|max:255',
            'email' => 'required|email',
            'content' => 'required',

        $validator = Validator::make($data, $rules);

        if ($validator->fails()) {
            throw new ValidationException($validator);

The first thing we’re doing is getting data from the request and validating it using the validate() helper method. (All the available validation rules you can use can be found in the documentation.) If validation fails, the validate() method will throw the ValidationException an exception and code execution will stop, and the server will respond with status code 406 and with validation messages.

If validation succeeds, then we will send an email to our admin.

Note: For simplicity, I’ve assumed that the email we want to send the submission to is Make sure to use your own email!

Here is the full code of your contactForm.php plug-in:


namespace ProgmatiqContactformComponents;

use CmsClassesComponentBase;
use OctoberRainExceptionValidationException;

class ContactForm extends ComponentBase
    public function componentDetails()
        return [
            'name' => 'Contact Form',
            'description' => 'A simple contact form'

    public function onSend()
        // Get request data
        $data = Input::only([

        // Validate request

        // Send email
        $receiver = '';

        Mail::send('', $data, function ($message) use ($receiver) {

    protected function validate(array $data) 
        // Validate request
        $rules = [
            'first_name' => 'required|min:3|max:255',
            'last_name' => 'required|min:3|max:255',
            'email' => 'required|email',
            'content' => 'required',

        $validator = Validator::make($data, $rules);

        if ($validator->fails()) {
            throw new ValidationException($validator);

As you can see, the first argument that the Mail::send() function accepts is the name of the email template that will be rendered for the email body. We need to create it in the admin panel. Go to Settings > Mail Templates and click on the New Template button. Then fill out the form as it is shown on the screen below:

Adding new email template

Adding new email template (Large preview)

Here is the body of the email that we’re going to be using:

You have received a new contact inquiry

**First Name**:
{{ first_name }}
**Last Name**:
{{ last_name }}
{{ email }}
{{ content }}

Now save the email template. The next thing we need to do is configure the SMTP server that will send emails.

Go to Settings > Mail Configuration and fill out all the settings.

Email server configuration

Email server configuration (Large preview)

Obviously, I won’t share my personal configuration. Use your own settings. 😉

At this stage we have everything ready to start testing our contact form component.

First, let’s check if validation works when we leave the “Content” field empty and input an invalid email:

Contact form validation

Contact form validation (Large preview)

Validation works as expected. Let’s now input correct data and see if the email will be sent successfully to our admin.

Here is the email that will receive:

Contact form submission email

Contact form submission email (Large preview)

After the form is submitted successfully, the user will see an alert message informing him that the operation was successful:

Successful submission of contact form

Successful submission of contact form (Large preview)


In this tutorial, we’ve covered what a plugin and a component are and how to use them with October CMS.

Don’t be afraid to create a custom plugin for your project if you can’t find an existing one that fits your needs. It’s not that difficult and you have full control over it, and you can update or extend it at any time. Even creating a simple contact form plugin like we’ve done today can be useful if you want to then integrate it with other services like Mailchimp or HubSpot.

I hope this tutorial was helpful to you. If you have any questions, don’t hesitate to ask in the comments section below.

Smashing Editorial
(dm, yk, il)

Source: Smashing Magazine, Developing A Custom Plugin For October CMS

1 2 3 4 5 6 7 8 9 10 ... 75 76   Next Page »