Collective #583

Inspirational Website of the Week: basement.studio Everything on basement is bold: from its striking typography to the brilliant effects and playful interactivity. Fantastic work. Get inspired This content is sponsored via Thought Leaders Clubhouse: Make 2020 your most productive year Clubhouse is a Read more

How To Empower Design Teams By Measuring Value

dreamt up by webguru in Uncategorized | Comments Off on How To Empower Design Teams By Measuring Value

How To Empower Design Teams By Measuring Value

How To Empower Design Teams By Measuring Value

Dave Cunningham



The business value of design has been proven at scale by the McKinsey Design Index. The report shows the best design performers increased their revenues and shareholder returns at nearly twice the rate of their industry counterparts.

However, we still see designers struggling with these common problems:

  • Projects are stop and start designers lose momentum and focus;
  • Potentially impactful design work isn’t put into production;
  • Designers are given solutions and have to try and bring projects back to the problem;
  • Stakeholders aren’t involved or our out of reach;
  • Business strategies and desired outcomes aren’t clear;
  • and the list goes on.

With the right people, enough rigor, patience and pragmatism. These problems can be solved, but then we often start all over again on the next project.

We are great at measuring usability and analytics. We can show how we’ve increased conversion rates on our e-commerce store, or how far people scroll down a page. In doing so we have created a culture of the world’s best design brains thinking about how to get more people to click a button.

We need to change this, we need to start measuring the potential for impact, of design, in a consistent way. We need a metric that people can see and they want to move.

Meet DIET (Design Impact Evaluation Tactic)

DIET asks key questions, that are fundamental for designers to be impactful in their work. The designer’s answers give a DIET score at the key stages of the project.

Numbers are powerful they give us an object to point at and discuss. They keep the conversation focused. The meaning behind a number is more important to designers, the why, not the what. Having the ingredients for good design baked into a number helps cross the divide of design and business metrics.

Why We Focus On Product Metrics Instead

“The first step is to measure whatever can be easily measured. This is OK as far as it goes. The second step is to disregard that which can’t be easily measured or to give it an arbitrary quantitative value. This is artificial and misleading. The third step is to presume that what can’t be measured easily really isn’t important. This is blindness. The fourth step is to say that what can’t be easily measured really doesn’t exist. This is suicide.”

— “Corporate Priorities: A continuing study of the new demands on business,” Daniel Yankelovich, 1972

Kristin Zibell’s table of UX metrics is a fantastic way to measure the customer experience, linking UX metrics directly to business goals.

Image source: Kristin Zibell (Large preview)

However, the potential value of design can’t be measured using a product metric such as conversion rate or time on task. What we are measuring here is the outcome of a product.

The product could be a square wheel or a chocolate fireguard, improving these products may show better metrics but is a means to an end.

If we as designers are spending all our time trying to move a needle how and where does innovation live in our work?

Measurements Gives Us A Language

Back in the 1700s, people were measuring temperature using cylinders of water and wine. This resulted in inaccurate measurements. It wasn’t until Fahrenheit came along and introduced constants to measure from, that things improved.

In one of his early experiments of constants, Fahrenheit used a glass of icy water as a low scale, and the upper scale being his wife’s armpit. Having the two constants meant he could measure temperatures against them. Fahrenheit went on to invent the mercury thermometer. The German’s scale of measuring temperature is still used in the United States today.

Fahrenheit gives us a consistent language to talk about the measurement of things. “It’s 120 degrees Fahrenheit outside” instantly informs you that it’s going to be very hot today, so don’t forget to wear sunscreen.

So, Like Fahrenheit, Do We Have A Glass Of Icy Water And An Armpit?

Design lives and breaths in different environments in different ways. In larger orgs projects, often balloon so get ditched or pivot. Stakeholders or key decision-makers can be out of reach. Business strategy can be unclear and not communicated well. Teams are fluid and can often be without the skills needed. All of these things are part of the ingredients which either prevent or allow design to thrive and grow.

Diagram showing how design is messy at the start but then things become clearer over time

Diagram showing how design is messy at the start but then things become clearer over time (Large preview)

The British design council suggested in 2005 that designers share similar approaches in their process, which they mapped out as the Double Diamond. The Double Diamond consists of a problem space and a solution space. The shape of the diamond is to represent divergent (thinking broadly) thinking and convergent (narrowing things down) thinking.

With designers on different projects, I mapped the journey of a design project from start to finish.

The journey of a project

(Large preview)

Here are examples of 3 projects:

  • Team 1 completely missed out the problem stage, as they didn’t have a researcher at the time. Time passes and eventually the project pivots.
  • Team 2 followed a Lean UX process and their project evolved.
  • Whereas Team 3 used a Google sprint and their project got ditched.

So, some projects evolve or pivot and some get ditched, but we don’t record why?

Looking Beyond The Double Diamond

Often projects come to a design team in the form of a brief. This will be part of the business’s overall strategy. Market research and predictions of future trends inform this strategy space.

Beyond the double diamon

Before the Double diamond we have a strategy segment and after a ship and backlog segment. (Large preview)

The ship and backlog space are often managed outside of the design team and very few designers I spoke to understood how work got prioritized here.

The View From A Stakeholder

Stakeholders are likely to be looking after many projects, which live in the strategy chain.

Strategy to delivery

The strategy segment is linked to many other strategy segments. Stakeholders often focus on delivering the strategy and want a direct path to delivery. (Large preview)

Projects in the strategy chain will be intrinsically linked, and require a holistic view of a business. So it’s not surprising that stakeholders just want to get things through to the delivery chain.

Strategically the business will look into future trends and consider finance and risk to the business. There will be a lot of technical input too, can we build this with our current infrastructure? Shall we purchase a 3rd party solution? How can we reduce the risk and cost to the business?

So what ends up happening is. Projects balloon, time in the problem and solution space increases.

Death of a project

Projects often die or change direction in the problem and solution space (Large preview)

Designers get asked questions in show-and-tells and presentations.
Like “Why are we doing research?”, “We already know this is true”, “Why is this taking so long?”

Ultimately design projects often die in these scenarios. Or can lead to poor outcomes.

A solution could be better communication, clearer strategies, shouldn’t all this be managed better in the boardroom? Perhaps but, teams change, stakeholders come and go. We fight the same fights over and over. We don’t have a common language like Fahrenheit to describe design impact.

People value data at scale, data makes decision making easier, as there is something to hang the decision off.

DIET can give you that data.

How DIET Works

At each stage of a project, the team answers 5 questions and is given a score out of 10. The questions are based on the foundations that designers need to be impactful with their work

Diet scores being recorded

Scores are recorded at each stage of the project. (Large preview)

Stage One

The strategy stage is for when you first hear about a project.

  1. We understand the business need/outcome.
  2. We understand the user needs.
  3. The subject matter experts & stakeholders are involved.
  4. The constraints (financial, time & tech) of the project are clear.
  5. Do we have the skills needed?

Stage Two

The problem stage is when you have completed your research on this particular problem.

  1. We know how people currently solve the problem.
  2. The problem resonates with our users.
  3. We are solving the right problem.
  4. The subject matter experts & stakeholders are involved?
  5. Do we have the skills needed?

Stage Three

The solution stage is when you have designed and tested your solution.

  1. Our solution solved the problem.
  2. Our solution is commercially viable.
  3. Our solution is going to be put live.
  4. Have we recorded our learnings?
  5. Have we shared our story?

To be impactful we need to work within our constraints, for our projects to be viable.
If we are consistently designing stuff that can’t go live, we just build design debt and frustration.

Here are examples of two projects that have DIET scores:

The outcomes of project

Outcomes of projects are shown to be poor when the DIET score is low, when its high they are improved. (Large preview)

Project A had low scores all the way through and resulted in a poor outcome.
Project B scored highly and the outcome is good.

Having a score from teams of predicted impact and matching that against actual impact. It gives us a base to show how, why and even if our design foundations work.
Once you know a constant exists, you can make predictions about things yet to be discovered.

Over time, we have a constant to measure from. We can use this constant to learn where and why design impact succeeds and why it fails.

  • Is attrition rate (staff turnover) linked to low scores?
  • Do low-scoring projects take more time?
  • Do low-scoring projects mean poor team health?

How To Use DIET

  • At each stage of the project (Strategy, Problem & Solution);
  • Every two weeks on a Monday or at the start of a sprint cycle;
  • In the retro at the end of the project.

To get started with DIET, you’ll need a copy of our DIET score Google Sheet to record your scores. You can then start with scoring the strategy.

What We Have Learned

The feedback loop is large and the effort to constantly keep teams tracking scores is challenging. However, we have seen these benefits.

  • DIET acts as a good early warning signal;
  • DIET helps teams share knowledge earlier and on a regular basis;
  • DIET gives people the confidence to speak to their managers.

We have a long way to go and are still learning. The project is open source and we’d love to hear your thoughts and get your input to learn more.

One Voice For Design

Good communication across all levels is a common trait in successful teams. Having a tool which gives a constant to communicate design impact at scale gives consistency to our communications. Is DIET a way to do this?

Smashing Editorial
(ah, il)

Source: Smashing Magazine, How To Empower Design Teams By Measuring Value

Collective #583

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



Collective item image

The CSS Cascade

Amelia Wattenberger’s interactive article that will give you insight to how cascading works in CSS.

Read it





Collective item image

PHENOMENA

A great page with amazing effects created by Mario Carrillo for the fashion brand Phenomena.

Check it out












Collective item image

PHP in 2020

After looking at PHP in 2019, Brent from stitcher.io updated his thoughts on why PHP isn’t the same old crappy language it was ten years ago.

Read it


Collective item image

From Our Blog

Case Study: itsnotviolent.com

A case study that explores the motivation, choices and implementation of the itsnotviolent.com awareness campaign brought to live by the Locomotive web agency.

Check it out


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


Source: Codrops, Collective #583

A Complete Guide To WordPress Multisite

dreamt up by webguru in Uncategorized | Comments Off on A Complete Guide To WordPress Multisite

A Complete Guide To WordPress Multisite

A Complete Guide To WordPress Multisite

Manish Dudharejia



WordPress Multisite is a popular feature of WordPress, which enables you to create and run multiple websites using the same WordPress installation on your server. In other words, you can manage several different WordPress websites from a single dashboard.

However, people are sometimes unsure of how to use this feature. This guide will help to clear up questions related to what WordPress Multisite is, who needs it, and how to install it.

Let’s start with the basics.

1. What Is WordPress Multisite?

WordPress Multisite is a feature that allows you to create and run multiple WordPress websites from a single WordPress dashboard. It was previously called WordPress Multi-User or WPMU. WordPress Multisite is not a new feature. It is an advanced feature on the WordPress platform that has been around since the launch of WordPress 3.0. You can use it for a variety of purposes, such as updating all of your websites with a single click or charging your subscribers to create a website on your Multisite network.

2. Key Features Of WordPress Multisite

WordPress Multisite comes with various unique features. For starters, you can run a network of blogs and websites from a single WordPress installation. It enables you to create a network of subdomains, like http://john.example.com, or directories, like http://www.example.com/john/. Alternatively, you can also have a separate domain for each website on the network. It is also easier to replicate functionality across a network of websites.

In WordPress Multisite, you can control the entire network as a Super Admin. As a regular website admin, you can control only one website on the network. As a Super Admin, you control the accessibility of users who want to create an account and set up WordPress blogs or websites of their own.

A Super Admin can install new themes and plugins, make them available to the websites on the network, and also customize the themes for all websites. Another feature is the ability to create websites and online shops intended for specific languages, regions, and currencies.

Both the Super Admin and the website admin can control content. While this control extends over the entire network for a Super Admin, the website admin has the right to choose which content from the main domain gets displayed on their respective website. Plugins are also under the control of a Super Admin. However, a website admin can activate and deactivate plugins on their website if required.

3. Who Should And Shouldn’t Use WordPress Multisite?

Although WordPress Multisite offers several features, it is not always the right choice. The main concern is that the websites on a Multisite network would share the same database. In other words, you can’t back up only a single website. That’s why all of the websites on a network must belong to the same principal domain.

Let me explain with an example. A university could use WordPress Multisite to build different websites for each department, for student and faculty member blogs, and for forums. Because the websites would share their database with the university’s main domain, they would be easier to manage on a Multisite network.

Likewise, banks and financial institutions with a national or global network of branches, digital publications with multiple content sections, government offices with multiple departments, hotel chains, stores with multiple outlets, e-commerce companies, and website design companies such as Wix could also use a Multisite network to their advantage.

However, a web designer couldn’t use Multisite to manage several unrelated client projects. If one of the clients decided to move their website elsewhere, it would be a problem because the website would be sharing its database with others on the network. Multisite makes it difficult to back up an individual website on the network. You would be better off using a single installation in this case.

4. Pros And Cons Of WordPress Multisite

Now that we know who should and shouldn’t use WordPress Multisite, let’s look at the technical pros and cons. You’ll need to weigh them carefully before making a decision.

Pros

  • The main advantage is the ability to manage multiple websites from a single dashboard. This is useful if you are running multiple websites managed by different teams under one parent domain, such as an e-commerce store with different country-specific sub-sites.
  • However, you can also assign a different admin to each website on your network.
  • With a single download, you can install and activate plugins and themes for all of the websites on your network.
  • You can also manage updates with a single master installation for all of the websites on your network.

Cons

  • Because all of the websites share the same network resources, they will all go down if the network goes down.
  • A sudden increase in traffic to one website will affect all others on the network. Unfortunately, beginners often find it difficult to manage traffic and server resources on a Multisite network.
  • Similarly, if one website gets hacked, the entire network will get compromised.
  • Not all WordPress plugins support a Multisite network.
  • Likewise, not all web hosting providers have the tools necessary to support a Multisite network.
  • If your hosting provider lacks the server requirements, you won’t be able to use the Multisite feature. For example, some hosting providers might not allow you to add a domain to the same hosting server. In that case, you might need to change or upgrade your hosting plan or change providers.

5. Requirements For WordPress Multisite

Knowing the technical pros and cons, you must have decided whether Multisite is the right option for you. If you are going to use it, you will need to meet a few technical requirements first.

One of the first things you will need is a web hosting service provider that can handle multiple domains in a single web hosting plan. Although you could use shared hosting for a couple of websites with low traffic, you should use VPS hosting or a dedicated server, owing to the nature of the WordPress Multisite network.

You will also need to have the fundamental knowledge of how to install WordPress. It would be an added advantage if you already have a WordPress installation. However, you will need to back it up. You will also need to deactivate all of the plugins.

Make sure you have FTP access. You will need to know the basics of editing files using FTP as well. Finally, you will need to activate pretty permalinks. In other words, your URLs should look not like http://example.com/?p=2345, but like http://example.com/my-page.

6. Multisite Domain Mapping

By default, you can create additional websites on your Multisite network as subdomains or subfolders of the main website. They look like this:

subsite.network.com

or like this:

network.com/subsite

However, you might not always want this, because you will be required to create a unique domain name for each website. That’s where domain mapping comes to the rescue. You can use this feature within the Multisite network to map additional websites to show as domain.com. Using domain mapping, this is what you will see:

subsite.network.com = domain.com

or:

network.com/subsite = domain.com

Prior to WordPress 4.5, you had to use a domain mapping plugin to map the additional websites. However, in version 4.5+, domain mapping is a native feature.

7. Multisite Hosting And SSL

As you probably know, Secure Sockets Layer (SSL) enables you to transport data over the internet securely. The data remains undecipherable to malicious users, bots, and hackers.

However, some hosting providers offer free SSL certification for the main domain only. You might need to buy it separately for each subdomain. If one of the websites on your multisite network lacks SSL certification, it will compromise the security of all the other websites. Thus, ensure that all websites on your WordPress Multisite network have SSL certificates.

8. Installing And Setting Up WordPress Multisite For New And Existing Websites

First, you will need to install WordPress. Once it’s installed, you will need to enable the Multisite feature. You can also enable it on your existing WordPress website. Before doing so, however, back up your website.

  • Use an FTP client or the cPanel file manager to connect with your website, and open the wp-config.php file for editing.
  • Add the following code to your wp-config.php file just before the /*:
  • /* Multisite */
    define( 'WP_ALLOW_MULTISITE', true );
  • Now, save and upload your wp-config.php file back to the server.
  • That’s all!

Next, you will need to set up the Multisite network. If you are already logged into your WordPress dashboard, refresh the page to continue with the next steps. If not, you will need to log in again.

  • When setting up the Multisite network on your existing website, you will need to deactivate all plugins. Go to the “Plugins” » “Installed Plugins” page, and select all plugins. Select the “Deactivate” option from the “Bulk Actions” dropdown menu, and click “Apply”.
  • How to Deactivate Plugin

    Deactivate Plugin. (Large preview)
  • Now, go to “Tools” » “Network Setup”. If you see a notice that you need Apache’s mod_rewrite module installed on your server, don’t be alarmed. All leading WordPress hosting providers keep this module enabled.
  • How to Create a Network of WordPress Sites

    Network Setup. (Large preview)
  • Choose the domain structure for websites on your network, either subdomains or subdirectories.
  • Add a title for your network.
  • Make sure that the email address for the network admin is correct.
  • Click the “Install” button.
  • You will see some code that you have to add to the wp-config.php and .htaccess files, respectively. Use an FTP client or the file manager in cPanel to copy and paste the code.
  • Add code to wp-config.php and .htaccess file

    Complete Setup. (Large preview)

The set-up is complete. You will need to log in again to access your Multisite network.

9. WordPress Multisite Configuration And Other Settings

Hold on! You still need to configure the network settings, for which you will need to switch to the Multisite network dashboard.

  • Open the “My Sites” menu in the admin toolbar. Click the “Network Admin” option, and then click the “Dashboard” option to go to the Multisite network dashboard.
  • Click the “Settings” option in the admin sidebar. You will see your website’s title and the admin’s email address. Make sure they are correct before moving on to a few essential configuration settings.

A. Registration Settings

This setting enables you to open your website to user registration and allows existing users to create new websites on your network. Check the appropriate box.

If you check the “Registration Notification” box, you will receive an email notification whenever a new user or website gets registered. Check the “Add New Users” option to enable individual website administrators to add new users to their own websites.

Use the “Limited Email Registration” option to restrict registration to a specific domain. For example, allow only users from your company to register with your website. Likewise, you can also prevent some domains from being registered.

How to Register New Sites

Registration Settings. (Large preview)

B. New Website’s Settings

Here, you can configure the default options, such as welcome emails and the contents of the first default post, page, and comment, for every new website built on your Multisite network. You can update these settings anytime.

Make Settings For New site

New Site Settings. (Large preview)

C. Upload Settings

You can limit the total amount of space each website on your network can use for uploads. This will help you to delegate server resources judiciously. The default value is 100 MB. You can also set the type of files that users can add to their websites, such as images, .doc, .docx, and .odt files, audio and video files, and PDFs. You can also set a size limit for individual files.

Assign space for uploads of each site on your network

Upload Settings. (Large preview)

D. Menu Settings

This setting enables the administrative menu for the plugins section of your network’s websites. Once you enable this setting, users will be able to activate and deactivate plugins, but won’t be able to add new ones. Click “Save Changes” to apply the changes you have made.

10. Resources: Setting Up Themes And Plugins

Because individual website administrators can’t install themes and plugins on their own, you will need them to set up on the network.

A. Themes

Go to “My Sites” » “Network Admin” » “Themes”.

On this page, you will see a list of the themes currently installed. Use the following settings to make your desired changes.

  • “Network Enable”: Make the theme available to website administrators.
  • “Network Disable”: Disable a theme that you have previously made available.
  • “Add New”: Install a new theme on your network.

Change a Default Theme

Add the following code to your wp-config.php file to change the default theme for new websites (replacing your-theme with the name of the theme’s folder):

// Setting default theme for new sites
define( 'WP_DEFAULT_THEME', 'your-theme' );

B. Plugins

Go to “My Sites” » “Network Admin” » “Plugins”.

Click the “Network Activate” option below each plugin to add it to your network. Remember that if you have already enabled the “Plugins Menu” option for website administrators in the “Network Settings”, then admins will not be able to delete or install new plugins. However, they will be able to activate and deactivate existing plugins.

11. How To Add A New Website To The Multisite Dashboard

Go to “My Sites” » “Network Admin” » “Sites”.

How to to enable Administrative Menu for Plugins Section

Add Sites. (Large preview)

Click the “Add New” button.

How to Add New Site to the Multisite Dashboard

Add New Sites. (Large preview)

Fill in the following fields.

  • Add the address (URL) for your new website.
  • Enter your “Site Title”.
  • Enter the email address of the new website’s administrator.

Add New Site Button

Add Site Button. (Large preview)

Click the “Add Site” button to finish the process.

12. Google Analytics On WordPress Multisite

You can also generate Google Analytics code for all pages on all of the websites on your Multisite network. If you haven’t already done so, create a Google Analytics account, and sign into it.

  • Start by creating a property to set up a Google Analytics ID. You will need this ID to install your global site tag (gtag.js).
  • Next, find your Google Analytics ID in the “Property” column of the relevant account in the “Admin” section of your Analytics account.
  • Now, you can copy and paste the global site tag on the relevant web pages. Add the gtag.js tag right after the opening <head> tag. You can have different analytics code for each website on the network, and the Super Admin can manage all of them if needed.

13. Setting Up On Local Host

You can use any WAMP or LAMP software to set up WordPress Multisite on a local system. You’ll need to follow the same steps you did to host a website. However, take care with the domain mapping. You can easily set up a subdirectory website in the local system, but to set up a subdomain or a different domain, you’ll need to set up virtual host on the WAMP or LAMP server.

14. Useful Plugins For WordPress Multisite And How They Work

You can use a variety of plugins to ensure the smooth operation of your Multisite network.

A. Domain Mapping
This plugin enables you to offer each website on your network its own domain name.

B. WPForms
Create different forms using a simple drag-and-drop tool.

C. Yoast SEO
Optimize the websites on your network for better search engine results. Yoast is a well-known name in the SEO world.

D. Pro Sites
Offer paid upgrades, advertising, and more, thereby monetizing your Multisite network. You can restrict the features of the free website, encouraging users to upgrade.

E. SeedProd
Add customized “Coming soon” and “maintenance mode” landing pages. This will jazz up the network while administrators work on their websites.

F. WP Mail SMTP
Fix the “WordPress is not sending email” issue with this plugin. It allows you to use an SMTP server to send crucial Multisite registration and notification emails.

G. User Switching
Using this plugin, you can switch user accounts as network admin to see what your users are experiencing when working on their websites. It can help you to troubleshoot some functionality issues.

15. Troubleshooting And FAQs

A. Troubleshooting

When setting up a Multisite network, you might encounter a few common problems. Let’s see how to troubleshoot these issues.

I. Login Issues

You might encounter a wp-admin login issue If you are using WordPress Multisite with subdirectories, rather than subdomains. If you are not able to log into the WordPress back end for individual websites with subdirectories, you can try replacing the define ('SUBDOMAIN_INSTALL', true); line in wp-config.php file with define ('SUBDOMAIN_INSTALL', 'false');.

II. Find Unconfirmed Users

Sometimes, you might not be able to find registered users who haven’t received an activation email. Usually, poorly configured mail settings are responsible for this problem. You can use SMTP (Simple Mail Transfer Protocol) to send activation emails. The PHP Mail function might send emails to the junk folder due to unauthorized email sending. Instead, you can use SMTP with proper domain authentication to get emails delivered to the inbox. Use any SMTP service provider, such as MailGun or Gmail.

B. FAQs

1. Can I install plugin “X” in my WordPress Multisite?

Yes, you can install any plugin in Multisite. However, not all plugins support Multisite. Check the plugin’s support before installing it.

2. Can I share user logins and roles across a Multisite network?

Yes, you can share user logins and roles across multiple websites. This comes in handy if you want website admins to manage the content on their own websites in your Multisite network.

3. Is it possible to display the main website’s posts on all websites on the network?

Yes, you can show your main website’s posts across the network.

4. If I am a Super Admin, can I log into all network websites with a single ID?

Yes, Super Admins can use the same credentials to sign into all network websites.

5. As a Super Admin, can I log into another network’s websites?

No, you can’t sign into networks other than your own.

6. Can I add more websites to my network later?

Yes, you can add as many websites as you want, anytime you want.

7. Can I use different plugins for each website, such as Yoast for one and All in One SEO for another?

Yes, you can use different plugins with similar functionality for different websites. However, you must set the plugin for the specific website you want. If you activate it for the entire Multisite network, it will work on all websites automatically.

8. Can I install a plugin on an individual website?

No, you cannot install a plugin directly on an individual website. You have to install it on the network. However, you can activate or deactivate it for a specific website.

9. Can I create a theme and apply it to a specific website?

Yes, you can create as many themes as you like. You can also activate or deactivate themes as a website’s admin.

16. WordPress Multisite Examples

Here are a few well-known brands using a WordPress Multisite network.

  • OpenView Venture Partners
    OpenView Venture Partners is a venture capital firm. The company uses a Multisite installation to run three different websites, including the corporate website, the corporate blog, and a multi-author blog called Labs. The company runs the last two websites under the subdomains blog.openviewpartners.com and labs.openviewpartners.com. Each website has a centralized theme that works perfectly.
  • The University of British Columbia Blogs
    The University of British Columbia (UBC) also uses WordPress Multisite. The purpose here is to enable professors to create course websites, build blogs with multiple contributors, and create portfolios for students as well as staff members. The WordPress Multisite installation gives teachers complete control over their online communities. They can add as many students as they like and take teaching beyond the walls of the classroom.
  • Cheap Flights
    Cheapflights is a travel website, offering flight tickets, hotel bookings, and vacation packages. The website uses WordPress Multisite to power its Travel Tips section. The section covers the latest travel news, tips on flying, information on the best places to travel to, and more.

Wrapping Up

As you can see, WordPress Multisite comes with several advantages. You can control and manage several websites from a single dashboard. It can certainly reduce your legwork and make your website monitoring hassle-free. Hopefully, you now have enough knowledge on installing, troubleshooting, and working with applications on a Multisite network to take the plunge.

Have you ever used WordPress Multisite? Will you consider using it for future projects? Let us know in the comments section below.

Smashing Editorial
(dm, yk, al, il)

Source: Smashing Magazine, A Complete Guide To WordPress Multisite

How To Pass Data Between Components In Vue.js

dreamt up by webguru in Uncategorized | Comments Off on How To Pass Data Between Components In Vue.js

How To Pass Data Between Components In Vue.js

How To Pass Data Between Components In Vue.js

Matt Maribojoc



Sharing data across components is one of the core functionalities of VueJS. It allows you to design a more modular project, control data scopes, and create a natural flow of data across your app.

Unless you’re creating your entire Vue app in one component (which wouldn’t make any sense), you’re going to encounter situations where you need to share data between components.

By the end of this tutorial, you will know three ways to get this done.

Okay — let’s get right into it!

Building An App With Nuxt

With Spotify, your friends can check out what you’re jamming to. What if the rest of the Internet could experience your algo-rhythm, too? Learn how to compose your own app to share what you’re listening to on Spotify using Vue.js and Nuxt. Read more →

1. Using Props To Share Data From Parent To Child

VueJS props are the simplest way to share data between components. Props are custom attributes that we can give to a component. Then, in our template, we can give those attributes values and — BAM — we’re passing data from a parent to a child component!

For example, let’s say we’re working on a user profile page and want to have a child component accept a username prop. We’ll need two components.

  1. The child component accepting the prop, let’s call this AccountInfo.vue.
  2. The parent component passing the prop, let’s call this ProfilePage.vue.

Inside AccountInfo.vue, we can declare the props it accepts using the props option. So, inside the component options, let’s make it look like the following.

// AccountInfo.vue

<template>
 <div id='account-info'>
   {{username}}
 </div>
</template>
 
<script>
export default {
 props: ['username']
}
</script>

Then, to actually pass the data from the parent (ProfilePage.vue), we pass it like a custom attribute.

// ProfilePage.vue
 
<account-info username='matt' />

Now if we load our page, we can see that our AccountInfo component properly renders the value passed in by its parent.

As when working with other VueJS directives, we can use v-bind to dynamically pass props. For example, let’s say we want to set the username prop to be equal to a variable. We can accomplish this by using shorthand for the v-bind directive (or just : for short). The code would look a little like this:

<template>
 <div>
   <account-info :username="user.username" />
 </div>
</template>
 
<script>
import AccountInfo from "@/components/AccountInfo.vue";
 
export default {
 components: {
   AccountInfo
 },
 data() {
   return {
     user: {
       username: 'matt'
     }
   }
 }
}
</script>

This means that we can change our data and have any child props using that value will also update.

Tip: Always Verify Your Props

If you’re looking to write clearer Vue code, an important technique is to verify your props. In short, this means that you need to specify the requirements for your prop (i.e. type, format, and so on). If one of these requirements is not met (e.g. if the prop is passed an incorrect type), Vue will print out a warning.

Let’s say we want our username prop to only accept Strings. We would have to modify our props object to look like this:

export default {
 props: {
   username: String
 }
}

Verifying props is essential when working in large-scale Vue apps or when designing plugins. It helps ensure that everyone is on the same page and use props the way that they were intended.

For a full list of the verifications we can include on props, I’d definitely recommend checking out the official documentation for an in-depth review.

Tip: Follow Prop Naming Conventions

According to the VueJS style guide, the best way to name your props is by using camelCase when declaring them in your script and kebab-case when referencing them in template code.

The reasoning behind this is actually quite simple. In Javascript, camelCase is the standard naming convention and in HTML, it’s kebab-case.

So, Vue recommends that we stick to the norms of each language. Thankfully, Vue is able to automatically convert between the two styles so there’s no additional setup for developers.

// GOOD
<account-info :my-username="user.username" />
props: {
   myUsername: String
}
 
// BAD
<account-info :myUsername="user.username" />
props: {
   "my-username": String
}

2. Emitting Events To Share Data From Child To Parent

Now that we have data passing down the hierarchy, let’s pass it the other way: from a child component to a parent. We can’t use props, but we can use custom events and listeners.

Every Vue instance can call a .$emit(eventName) method that triggers an event. Then, we can listen for this event in the same way as any other, using the v-on directive.

Creating a Custom Event

Let’s build on our user profile example by adding a button that changes the username. Inside our child component (AccountInfo.vue), let’s create the button.

Then, when this button is clicked, we’ll emit an event called changeUsername.

<template>
 <div id='account-info'>
   <button @click='changeUsername()'>Change Username</button>
   {{username}}
 </div>
</template>
 
<script>
export default {
 props: {
   username: String
 },
 methods: {
   changeUsername() {
     this.$emit('changeUsername')
   }
 }
}
</script>

Inside the parent, we handle this event and change the user.username variable. Like we were discussing earlier, we can listen to events using the v-on directive or “@” for short.

<template>
 <div>
   <account-info :username="user.username" @changeUsername="user.username = 'new name'"/>
 </div>
</template>

Let’s try it out. You should see that when you click the button, the username changes to “new name”.

Tip: Custom Events Can Accept Arguments

The most common use case for passing arguments to your events is when you want a child component to be able to set a specific value for its prop. You never want to directly edit the value of a prop from the component itself.

However, luckily we can use pass arguments with our custom events to make the parent component change values.

Let’s say we want to modify the changeUsername event so that we can pass it a value.

The $emit method takes an optional second parameter for arguments. So all we do is add our new username value after the name of our event.

this.$emit('changeUsername', 'mattmaribojoc')

Then, in our parent component, we can either access these values inline by using a special $event variable, or we can write a handler method that takes a parameter.

<account-info :username="user.username" @changeUsername="user.username = $event"/>
 
OR 
 
<account-info :username="user.username" @changeUsername="changeUsername($event)"/>
 
export default {
...
methods: {
   changeUsername (username) {
     this.user.username = username;
   }
}
}

3. Using Vuex To Create An Application-Level Shared State

Okay — we know how to share data between parents/children, but what about other components? Do we have to create an extremely complex hierarchy system if we want to pass data?

Thankfully not. The wonderful Vuex state management library has been simplifying developers’ lives for years. In short, it creates a centralized data store that is accessible by all components.

In the methods we used previously (props / emitting events), each component has its own data state that we then share between components. However, Vuex lets us extract all the shared data into a single state that each component can access easily. This shared state is called a store.

Let’s try it out.

Because Vuex is separate from the core code of Vue, we’ll first have to install and import it into our project. First, we’ll have to run npm install vuex --save inside our project CLI.

Then, create a src/store folder with an index.js file that contains the following code.

// store/index.js
 
import Vue from "vue";
import Vuex from "vuex";
 
Vue.use(Vuex);
 
export default new Vuex.Store({
 state: {},
 getters: {},
 mutations: {},
 actions: {}
});

To include this in our root Vue instance, we have to import our store/index.js file and pass it in our Vue constructor.

// main.js
 
import store from "./store";
 
new Vue({
  store,
  ...

Accessing Vue Store Inside Components

Since we added our Vuex store onto our root Vue instance, it gets injected into all of the root’s children. If we want to access the store from a component, we can via this.$store.

Now, let’s dive into the specifics of each of the four parts of a Vuec store.

1. State

The Vuex state is an object that contains application-level data. All Vue instances will be able to access this data.

For our store, let’s create a user object that stores some more user profile data.

export default new Vuex.Store({
 state: {
   user: {
     username: 'matt',
     fullName: 'Matt Maribojoc'
   }
 },
 getters: {},
 mutations: {},
 actions: {}
});

We can access this data inside any instance component like this.

mounted () {
   console.log(this.$store.state.user.username);
},

2. Getters

We use Vuex getters to return a modified value of state data. A good way to think of getters is to treat them like computed properties. For example, getters, like computed properties, cache their results and only re-evaluate when a dependency is modified.

Building onto our earlier store, let’s say we want to make a method that returns a user’s first name based off the full name attribute.

getters: {
   firstName: state => {
     return state.user.fullName.split(' ')[0]
   }
 }

Vuex getter properties are available to components on the store.getters object.

mounted () {
   console.log(this.$store.getters.firstName);
}

Tip: Know the Default Getter Arguments

By default, Vuex getters accept two arguments.

  1. state — the state object for our application;
  2. getters — the store.getters object, meaning that we can call other getters in our store.

Every getter you declare will require the first state argument. And depending on how you design your code, your getters can reference each other using the second ‘getters’ argument.

Let’s make a last name getter that simply removes our first name value from our full name state property. This example would require both the state and getters objects.

lastName (state, getters) {
     return state.user.fullName.replace(getters.firstName, '');
}
Tip: Pass Custom Arguments to Vuex Getters

Another cool feature of getters is that we can pass them custom arguments by making our getter return a method.

prefixedName: (state, getters) => (prefix) => {
     return prefix + getters.lastName;
}
 
// in our component
console.log(this.$store.getters.prefixedName("Mr."));

3. Mutations

Mutations are the only way to properly change the value of the state object. An important detail to note is that mutations must be synchronous.

Like getters, mutations always accept the Vuex state property as their first argument. They also accept a custom argument — called a payload — as the second argument.

For example, let’s make a mutation to change a user’s name to a specific value.

mutations: {
   changeName (state, payload) {
     state.user.fullName = payload
   }
},

Then, we can call this method from our component using the store.commit method, with our payload as the second argument.

this.$store.commit("changeName", "New Name");

More often than not, you are going to want your payload to be an object. Not only does this mean that you can pass several arguments to a mutation, but also, it makes your code more readable because of the property names in your object.

changeName (state, payload) {
     state.user.fullName = payload.newName
}

There are two different ways to call mutations with a payload.

  1. You can have the mutation type as the first argument and the payload as the second.
  2. You can declare pass a single object, with one property for the type and another for the payload.
this.$store.commit("changeName", {
       newName: "New Name 1",
});
 
     // or
 
 this.$store.commit({
       type: "changeName",
       newName: "New Name 2"
});

There isn’t a real difference between how the two work so it’s totally up to personal preference. Remember that it’s always best to be consistent throughout your entire project, so whichever one you choose, stick with it!

4. Actions

In Vuex, actions are fairly similar to mutations because we use them to change the state. However, actions don’t change the values themselves. Instead, actions commit mutations.

Also, while Vuex mutations have to be synchronous, actions do not. Using actions, we can call a mutation after an API call, for example.

Whereas most of the Vuex handlers we’ve seen accept state as their main parameter, actions accept a context object. This context object allows us to access the properties in our Vuex store (e.g. state, commit, getters).

Here’s an example of a Vuex action that waits two seconds and then commits the changeName mutation.

actions: {
   changeName (context, payload) {
     setTimeout(() => {
       context.commit("changeName", payload);
     }, 2000);
   }
}

Inside our components, we use the store.dispatch method in order to run our function. We pass arguments just like we did with mutations. We declare the type and we pass any custom arguments in the second argument.

this.$store.dispatch("changeName", {
      newName: "New Name from Action"
});

Wrapping Up

Now, you should know three different ways to share data across components in VueJS: props, custom events, and a Vuex store.

I hope this tutorial helped give you some more insight into some different Vue methods and best practices. Let me know how you’ve implemented them into your projects!

Further Reading

If you’re interested in going even deeper into the technical side/capabilities of each technique, here are some great places to start.

Smashing Editorial
(dm, yk, il)

Source: Smashing Magazine, How To Pass Data Between Components In Vue.js

Introducing Our New SmashingConf City Of Austin

dreamt up by webguru in Uncategorized | Comments Off on Introducing Our New SmashingConf City Of Austin

Introducing Our New SmashingConf City Of Austin

Introducing Our New SmashingConf City Of Austin

Rachel Andrew



We are so excited to be bringing SmashingConf to a new city this year. We’re bringing you SmashingConf Austin where, in addition to our amazing line-up of conference talks and workshops, there will be plenty of fun and things to see and do. The team has been quite busy finding out about the local area, and we hope you’ll be as excited as we are to explore.

The Venue

We’ve found a fantastic conference venue in the Topfer Theatre at The ZACH. This 420-seat theater was constructed in 2011 as part of the complex of theater buildings belonging to the ZACH Theater company. The company was founded in 1932 as The Austin Civic Theater, and is the oldest continuously operating theater company in Texas as well as the tenth oldest in the USA.

The Conference Line-Up

Our line-up for Austin is now complete. The Smashing double-act of Vitaly Friedman and Phil Hawksworth will be making a return — guiding you through the two days and helping you to get the most out of every minute.

In Austin, we have an amazing line-up of returning Smashing friends but also new faces. The topics have been carefully curated to ensure there really is something for every member of your team!

Chris Coyier created and runs CSS-Tricks, and is also the co-founder of CodePen. In his talk “Building Websites,” he will talk about how we can build websites with almost no fancy technology at all — just raw HTML. From that point on, we complicate things as the websites we build have different needs. It’s a reminder to everyone that complications are OK when they are need-based, but also that they have costs and we should minimize the number of things we add.

Frontend UI/UX developer Sara Soueidan returns to the Smashing stage to talk about accessibility and CSS; she will build some components live in order that you can see her process as she develops accessible components for a site.

Consultant Performance Engineer Harry Roberts will take a look at some of the numbers powering the web performance industry from both sides of the table: What do performance improvements mean for your clients, and how do we translate that into a working relationship?

We loved Gemma O’Brien’s fantastic work when she spoke in Toronto, so she is returning to our Smashing stage for Austin. She makes beautiful murals and illustrations (take a look at her Instagram account to see some of her work!).

Stage with a presenter, with illustration on a large screen

Gemma on stage in Toronto (Photo credit Marc Thiele)

They will be joined by Brad Frost speaking on Design Patterns, Mandy Michael on Front-end development, Miriam Suzanne on CSS, Rémi Parmentier on HTML email, Robyn Larsen on internationalization, Luke Wroblewski on UX, metrics and conversion, and Zach Leatherman on type and performance.

Vitaly has been recording interviews with some of our speakers, to give you a taste for what they will be sharing at the conference. Enjoy this chat with Miriam Suzanne, and watch out for more interviews in the coming weeks.

Miriam will be talking about “CSS is Rad” at SmashingConf Austin. See you there?

Our Wonderful Workshops

In addition to her talk, Miriam will also be running a workshop at SmashingConf showing you how to use CSS and Sass to create resilient and maintainable design systems that scale. We have a total of 8 workshops, 4 on the day before the conference and 4 on the day after. Workshops are a full day of learning — on the subject of your choice.

Miriam will be joined by Sara Soueidan, and her front-end accessibility workshop where you can learn how to think and code inclusively. Rémi Parmentier will teach you how to build HTML emails and Brad Frost will show you how to make and maintain successful design systems. If building faster websites is your aim, register for “Front-End Performance Building Faster Websites” with Harry Roberts.

Friendly reminder: As with every SmashingConf event, booking a workshop plus a conference ticket can save you $100 on the cost of the workshop!

The Smashing team is workshopping, too! I’ll be presenting my brand new CSS Layout Masterclass while Vitaly will be presenting two workshops: New Front-End Adventures 2020 Edition and Smart Responsive UX Design Paterns. I think the hardest thing will be knowing what to choose.

Social Events And Things To Do In Austin

Attending a conference can be a great way to meet new people, or to spend some time getting to know your own team better. We believe that the social events and opportunities to explore the area are an important part of each and every one of our events.

In Austin, we will hold a pre-event on the day before the conference. There will be snacks, drinks and talks from fellow attendees. Then, between the two conference days, there will be a SmashingConf party! We try to choose a venue where you can enjoy conversations with your attendees and speakers and talk about what you have learned.

Running And Swimming

Get outside and join me for a 5k run on Tuesday and Wednesday. We’ll find a route and run at a sociable pace! We have been doing our pre-conference runs for several events now, and it’s a great way to chat and get some exercise and fresh air before the day starts.

If running isn’t your thing, how about a swim? The Barton Springs Pool is an open-air swimming pool filled with water from natural springs. The pool is open daily between 5 AM and 10 PM, and costs $9 for a swim. If you are looking for other people to swim with, why not post in the conference Slack and get a group together.

Food And Things To Do

After all that learning, networking, running and swimming, you will be hungry! We’ve created a map of recommended local restaurants and other things to do. Our conference handbook also contains some suggestions.

Something we’re quite excited about this year’s event is the idea of going bat watching! In warm months, thousands of Mexican free-tailed Bats emerge from under the Congress Avenue Bridge and form clouds in the sky. Another reason not to forget your cameras!

You can see them while standing on the bridge or from a small park located at the foot of the bridge on the south bank of the river. Learn more about this wonderful weirdness of Austin over here.

There are several great hotels in Austin, but we have arranged a special Smashing discount at The Carpenter Hotel, which is a five-minute walk to the venue. You’ll save some money to spend on BBQ or tacos and also be staying in the same place as other attendees which will make meeting up easy!

Scholarships, Student Discounts And Volunteering

We have a few ways in which we try to help folk attend our conference who don’t have the budget to do so.

Anyone from an underrepresented group in tech is invited to apply for a scholarship. We especially invite and welcome LGBTQIA+ people, people with disabilities, and people facing economic or social hardships to apply.

You can have fun being part of the team, get a behind-the-scenes look and attend some talks and a full workshop if you volunteer with us. We need lots of friendly people to help on the conference days, and it’s a great way to meet people in the industry as well as see some of the conference.

Each conference also has 20 discounted tickets for students and non-profits. For more details on each of these schemes, which run at all our events, see the Scholarships and Volunteering page.

Tickets Are On Sale Now!

If you want to join in the fun, tickets are on sale. Last year, we sold out three of our conferences well before the conference date, and popular workshops also fill up fast. Just saying!

Smashing Editorial
(il)

Source: Smashing Magazine, Introducing Our New SmashingConf City Of Austin

Collective #582

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











Collective Item image

The Apple Archive

Sam Henri Gold’s incredible yearly archive that collects all the fantastic work and resources around Apple products.

Check it out









Collective Item image

Turn of the Screw

A beautiful Three.js project realized by Lusion: Explore a haunted audio landscape in an immersive trailer for Opera North’s 2020 production of Benjamin Britten’s opera.

Check it out

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


Source: Codrops, Collective #582

Recreating The Arduino Pushbutton Using SVG And &lt;lit-element&gt;

dreamt up by webguru in Uncategorized | Comments Off on Recreating The Arduino Pushbutton Using SVG And &lt;lit-element&gt;

Recreating The Arduino Pushbutton Using SVG And &lt;lit-element&gt;

Recreating The Arduino Pushbutton Using SVG And &lt;lit-element&gt;

Uri Shaked



Today, I am going to take you through the journey of creating an HTML component that mimics a momentary pushbutton component that is commonly used with Arduino and in electronic projects. We will use technologies such as SVG, Web Components and lit-element, and learn how to make the button accessible through some JavaScript-CSS trickery.

Let’s start!

From Arduino To HTML: The Need For A Pushbutton Component

Before we embark on the journey, let’s explore what we are going to create, and more importantly, why. I’m creating an open-source Arduino simulator in JavaScript called avr8js. This simulator is able to execute Arduino code and I will be using it in a series of tutorials and courses that teach makers how to program for Arduino.

The simulator itself only takes care of the program execution — it runs the code instruction by instruction and updates its internal state and a memory buffer according to the program logic. In order to interact with the Arduino program, you need to create some virtual electronic components that can send input to the simulator or react to its outputs.

Running the simulator alone is very much like running JavaScript in isolation. You can’t really interact with the user unless you also create some HTML elements, and hook them to the JavaScript code through the DOM.

Thus, in addition to the simulator of the processor, I’m also working on a library of HTML components that mimic physical hardware, starting with the first two components that you will find in almost any electronics project: an LED and a pushbutton.

The LED and the Pushbutton elements in action
The LED and the Pushbutton elements in action

The LED is relatively simple, as it only has two output states: on and off. Behind the scenes, it uses an SVG filter to create the lighting effect.

The pushbutton is more interesting. It also has two states, but it has to react to user input and update its state accordingly, and this is where the challenge comes from, as we will shortly see. But first, let’s nail down the requirements from our component we are going to create.

Defining The Requirements For The Pushbutton

Our component will resemble a 12mm pushbutton. These buttons are very common in electronics starter kits, and come with caps in multiple colors, as you can see in the photo below:

Simon Game with Yellow, Red, Blue and Green pushbuttons

Simon Game with Yellow, Red, Blue and Green pushbuttons (Large preview)

In terms of behavior, the pushbutton should have two states: pressed and released. These are similar to the mousedown/mouseup HTML events, but we must make sure that the pushbuttons can also be used from mobile devices, and are accessible for users without a mouse.

As we will be using the state of the pushbutton as input for Arduino, there is no need to support “click” or “double click” events. It is up to the Arduino program running in the simulation to decide how to act upon the state of the button, and physical buttons do not generate click events.

If you’d like to learn more, check out a talk I held with Benjamin Gruenbaum at SmashingConf Freiburg in 2019: “Anatomy of a Click”.

To summarize our requirements, our pushbutton needs to:

  1. look similar to the physical 12mm pushbutton;
  2. have two distinct states: pressed, and released, and they should be visually discernible;
  3. support mouse interaction, mobile devices and be accessible to keyboard users;
  4. support different cap colors (at least red, green, blue, yellow, white and black).

Now that we have defined the requirements, we can start working on the implementation.

SVG For The Win

Most web components are implemented using a combination of CSS and HTML. When we need more complex graphics, we usually use raster images, in either JPG or PNG format (or GIF if you feel nostalgic).

In our case, however, we will use another approach: SVG graphics. SVG lends itself to complex graphics much more easily than CSS (yeah, I know, you can create fascinating things with CSS, but it doesn’t mean it should). But don’t worry, we are not giving up on CSS entirely. It will help us with styling the pushbuttons, and eventually even with making them accessible.

SVG has another big advantage, in comparison with raster graphics images: it is very easy to manipulate from JavaScript and can be styled through CSS. This means that we can provide a single image for the button and use JavaScript to customize the color cap, and CSS styles to indicate the state of the button. Neat, isn’t it?

Finally, SVG is just an XML document, which can be edited with text editors, and embedded directly into HTML, making it a perfect solution for creating reusable HTML components. Are you ready to draw our pushbutton?

Drawing The Pushbutton With Inkscape

Inkscape is my favorite tool for creating SVG vector graphics. It’s free and packed with powerful features, such as a large collection of built-in filter presets, bitmap tracing, and path binary operations. I started using Inkscape for creating PCB art, but in the past two years, I started using it for most of my graphic editing tasks.

Drawing the pushbutton in Inkscape is pretty straightforward. We are going to draw a top-view illustration of the button and its four metal leads that connect it to other parts, as follows:

  1. 12×12mm dark gray rectangle for the plastic case, with slightly rounded corners to make it softer.
  2. Smaller, 10.5×10.5 light gray rectangle for the metal cover.
  3. Four darker circles, one in each corner for the pins that hold the button together.
  4. A large circle in the middle, that is the contour of the button cap.
  5. A smaller circle in the middle for the top of the button cap.
  6. Four light-gray rectangles in a “T” shape for the metal leads of the button.

And the result, slightly enlarged:

Our hand-drawn Pushbutton Sketch

Our hand-drawn Pushbutton Sketch (Large preview)

As a final touch, we’ll add some SVG gradient magic to the contour of the button, to give it a 3D feel:

Adding a gradient fill for creating 3D-feel

Adding a gradient fill for creating 3D-feel (Large preview)

There we go! We have the visuals, now we need to get it to the web.

From Inkscape to Web SVG

As I mentioned above, SVGs are pretty straightforward to embed into HTML — you can just paste the content of the SVG file into your HTML document, open it in a browser, and it will be rendered on your screen. You can see it in action in the following CodePen example:

See the Pen SVG Pushbutton in HTML by @Uri Shaked

See the Pen SVG Pushbutton in HTML by @Uri Shaked

However, SVG files saved from Inkscape contain a lot of unnecessary baggage such as the Inkscape version and the window position when you last saved the file. In many cases, there are also empty elements, unused gradients and filters, and they all bloat the file size, and make it harder to work with it inside HTML.

Luckily, Inkscape can clean most of the mess for us. Here is how you do it:

  1. Go to the File menu and click on Clean up document. (This will remove unused definitions from your document.)
  2. Go again to File and click on Save as…. When saving, select Optimized SVG (*.svg) in the Save as type dropdown.
  3. You will see an “Optimized SVG Output” dialog with three tabs. Check all the options, except for “Keep editor data”, “Keep unreferenced definitions” and “Preserve manually created IDs…”.

(Large preview)

Removing all these things will create a smaller SVG file that is easier to work with. In my case, the file went from 4593 bytes down to just 2080 bytes, less than half the size. For more complex SVG files, this can be a huge saving of bandwidth and can make a notable difference in the loading time of your webpage.

The optimized SVG is also much easier to read and understand. In the following excerpt, you should be able to easily spot the two rectangles that make the body of the pushbutton:

<rect width="12" height="12" rx=".44" ry=".44" fill="#464646" stroke-width="1.0003"/>
<rect x=".75" y=".75" width="10.5" height="10.5" rx=".211" ry=".211" fill="#eaeaea"/>
<g fill="#1b1b1b">
  <circle cx="1.767" cy="1.7916" r=".37"/>
  <circle cx="10.161" cy="1.7916" r=".37"/>
  <circle cx="10.161" cy="10.197" r=".37"/>
  <circle cx="1.767" cy="10.197" r=".37"/>
</g>
<circle cx="6" cy="6" r="3.822" fill="url(#a)"/>
<circle cx="6" cy="6" r="2.9" fill="#ff2a2a" stroke="#2f2f2f" stroke-opacity=".47" stroke-width=".08"/>

You can even further shorten the code, for instance, by changing the stroke width of the first rectangle from 1.0003 to just 1. It doesn’t make a significant difference in the file size, but it makes the code easier to read.

In general, a manual pass over the generated SVG file is always useful. In many cases, you can remove empty groups or apply matrix transforms, as well as simplify gradient coordinates by mapping them from “user space on use” (global coordinates) to “object bounding box” (relative to the object). These optimizations are optional, but you get code that is easier to understand and maintain.

From this point on, we’ll put Inkscape away and work with the text representation of the SVG image.

Creating A Reusable Web Component

So far, we got the graphics for our pushbutton, ready to be inserted into our simulator. We can easily customize the color of the button by changing the fill attribute of the smaller circle, and the start color of the gradient of the larger circle.

Our next goal is to turn our pushbutton into a reusable Web Component which can be customized by passing a color attribute and reacts to user interaction (press/release events). We will use lit-element, a small library that simplifies the creation of Web Components.

lit-element excels in creating small, stand-alone component libraries. It’s built on top of the Web Components standard, which allows these components to be consumed by any web application, regardless of the framework used: Angular, React, Vue or Vanilla JS would all be able to use our component.

Creating components in lit-element is done using a class-based syntax, with a render() method that returns the HTML code for the element. A bit similar to React, if you are familiar with it. However, unlike react, lit-element uses standard Javascript tagged template literals for defining the content of the component.

Here is how you would create a simple hello-world component:

import { customElement, html, LitElement } from 'lit-element';

@customElement('hello-world')
export class HelloWorldElement extends LitElement {
  render() {
    return html`
      <h1>
        Hello, World!
      </h1>
    `;
  }
}

This component can then be used anywhere in your HTML code simply by writing <hello-world></hello-world>.

Note: Actually, our pushbutton requires just a bit more code: we need to declare an input property for the color, using the @property() decoractor (and with a default value of red), and paste the SVG code into our render() method, replacing the color of the button cap with the value of the color property (see example). The important bits are in line 5, where we define the color property: @property() color = 'red'; Also, in line 35 (where we use this property to define the fill color for the circle that makes the cap of the button), using the JavaScript template literal syntax, written as ${color}:

<circle cx="6" cy="6" r="2.9" fill="${color}" stroke="#2f2f2f" stroke-opacity=".47" stroke-width=".08" />

Making It Interactive

The last piece of the puzzle would be to make the button interactive. There are two aspects we need to consider: the visual response to the interaction as well as the programmatic response to the interaction.

For the visual part, we can simply inverse the gradient fill of the button contour, which will create the illusion the button has been pressed:

Inverting the button’s contour gradient

Inverting the button’s contour gradient (Large preview)

The gradient for the button contour is defined by the following SVG code, where ${color} is replaced with the color of the button by lit-element, as explained above:

<linearGradient id="grad-up" x1="0" x2="1" y1="0" y2="1">
  <stop stop-color="#ffffff" offset="0" />
  <stop stop-color="${color}" offset="0.3" />
  <stop stop-color="${color}" offset="0.5" />
  <stop offset="1" />
</linearGradient>

One approach for the pressed button look would be to define a second gradient, invert the order of colors, and use it as the fill of the circle whenever the button is pressed. However, there is a nice trick that allows us to reuse the same gradient: we can rotate the svg element by 180 degrees using a SVG transform:

<circle cx="6" cy="6" r="3.822" fill="url(#a)" transform="rotate(180 6 6)" />

The transformattribute tells SVG that we want to rotate the circle by 180 degrees, and that the rotation should happen about the point (6, 6) that is the center of the circle (defined by cx and cy). SVG transforms also affect the fill of the shape, and so our gradient will be rotated as well.

We only want to invert the gradient when the button is pressed, so instead of adding the transformattribute directly on the <circle>element, as we did above, we are actually going to set a CSS class for this element, and then take advantage of the fact that SVG attributes can be set through CSS, albeit using a slightly different syntax:

transform: rotate(180deg);
transform-origin: 6px 6px;

These two CSS rules do exactly the same as the transformwe had above — rotate the circle 180 degrees around its center at (6, 6). We want these rules to be applied only when the button is pressed, so we’ll add a CSS class name to our circle:

<circle class="button-contour" cx="6" cy="6" r="3.822" fill="url(#a)" />

And now we can use the :active CSS pseudo-class to apply a transform to the button-contour whenever the SVG element is clicked:

svg:active .button-contour {
  transform: rotate(180deg);
  transform-origin: 6px 6px;
}

lit-element allows us to attach a stylesheet to our component by declaring it in a static getter inside our component class, using a tagged template literal:

static get styles() {
  return css`
    svg:active .button-contour {
      transform: rotate(180deg);
      transform-origin: 6px 6px;
    }
  `;
}

Just like the HTML template, this syntax allows us to inject custom values to our CSS code, even though we don’t need it here. lit-element also takes care of creating Shadow DOM for our component, so that the CSS only affects the elements within our component and does not bleed to other parts of the application.

Now, what about the programmatic behavior of the button when pressed? We want to fire an event so that the users of our component could figure out whenever the state of the button changes. One way to do this is to listen to mousedown and mouseup events on the SVG element, and fire “button-press”/“button-release” events correspondingly. This is what it looks like with lit-element syntax:

render() {
  const { color } = this;
  return html`
    <svg
      @mousedown=${() => this.dispatchEvent(new Event('button-press'))}
      @mouseup=${() => this.dispatchEvent(new Event('button-release'))}
      ...
    </svg>
  `;
}

However, this is not the best solution, as we’ll shortly see. But first, take a quick look at the code we got so far:

import { customElement, css, html, LitElement, property } from 'lit-element';

@customElement('wokwi-pushbutton')
export class PushbuttonElement extends LitElement {
  @property() color = 'red';

  static get styles() {
    return css`
      svg:active .button-contour {
        transform: rotate(180deg);
        transform-origin: 6px 6px;
      }
    `;
  }

  render() {
    const { color } = this;
    return html` 
      <svg 
        @mousedown=${() => this.dispatchEvent(new Event('button-press'))}
        @mouseup=${() => this.dispatchEvent(new Event('button-release'))}
        width="18mm" 
        height="12mm" 
        version="1.1" 
        viewBox="-3 0 18 12"     
        xmlns="http://www.w3.org/2000/svg"
      >
        <defs>
          <linearGradient id="a" x1="0" x2="1" y1="0" y2="1">
            <stop stop-color="#ffffff" offset="0" />
            <stop stop-color="${color}" offset="0.3" />
            <stop stop-color="${color}" offset="0.5" />
            <stop offset="1" />
          </linearGradient>
        </defs>
        <rect x="0" y="0" width="12" height="12" rx=".44" ry=".44" fill="#464646" />
        <rect x=".75" y=".75" width="10.5" height="10.5" rx=".211" ry=".211" fill="#eaeaea" />
        <g fill="#1b1b1">
          <circle cx="1.767" cy="1.7916" r=".37" />
          <circle cx="10.161" cy="1.7916" r=".37" />
          <circle cx="10.161" cy="10.197" r=".37" />
          <circle cx="1.767" cy="10.197" r=".37" />
        </g>
        <g fill="#eaeaea">
          <path d="m-0.3538 1.4672c-0.058299 0-0.10523 0.0469-0.10523 0.10522v0.38698h-2.1504c-0.1166 0-0.21045 0.0938-0.21045 0.21045v0.50721c0 0.1166 0.093855 0.21045 0.21045 0.21045h2.1504v0.40101c0 0.0583 0.046928 0.10528 0.10523 0.10528h0.35723v-1.9266z" /> 
          <path d="m-0.35376 8.6067c-0.058299 0-0.10523 0.0469-0.10523 0.10523v0.38697h-2.1504c-0.1166 0-0.21045 0.0939-0.21045 0.21045v0.50721c0 0.1166 0.093855 0.21046 0.21045 0.21046h2.1504v0.401c0 0.0583 0.046928 0.10528 0.10523 0.10528h0.35723v-1.9266z" />
          <path d="m12.354 1.4672c0.0583 0 0.10522 0.0469 0.10523 0.10522v0.38698h2.1504c0.1166 0 0.21045 0.0938 0.21045 0.21045v0.50721c0 0.1166-0.09385 0.21045-0.21045 0.21045h-2.1504v0.40101c0 0.0583-0.04693 0.10528-0.10523 0.10528h-0.35723v-1.9266z" />
          <path d="m12.354 8.6067c0.0583 0 0.10523 0.0469 0.10523 0.10522v0.38698h2.1504c0.1166 0 0.21045 0.0938 0.21045 0.21045v0.50721c0 0.1166-0.09386 0.21045-0.21045 0.21045h-2.1504v0.40101c0 0.0583-0.04693 0.10528-0.10523 0.10528h-0.35723v-1.9266z" />
        </g>
        <g>
          <circle class="button-contour" cx="6" cy="6" r="3.822" fill="url(#a)" />
          <circle cx="6" cy="6" r="2.9" fill="${color}" stroke="#2f2f2f" stroke-opacity=".47" stroke-width=".08" />
        </g>
      </svg>
    `;
  }
}

You can click each of the buttons and see how they react. The red one even has some event listeners (defined in index.html), so when you click on it you should see some messages written to the console. But wait, what if you want to use the keyboard instead?

Making The Component Accessible And Mobile-Friendly

Hooray! We created a reusable pushbutton component with SVG and lit-element!

Before we sign off on our work, there are a few issues we should look at. First, the button is not accessible to people who use the keyboard. In addition, the behavior on mobile is inconsistent — the buttons do appear pressed when you hold your finger on them, but the JavaScript events are not fired if you hold your finger for more than one second.

Let’s start by tackling the keyboard issue. We could make the button keyboard-accessible by adding a tabindex attribute to the svg element, making it focusable. A better alternative, in my opinion, is just to wrap the button with a standard <button> element. By using the standard element, we also make it play nicely with screen readers and other assistive technology.

This approach has one drawback through, as you can see below:

Our pretty component encaged inside a button element

Our pretty component encaged inside a <button> element. (Large preview)

The <button> element comes with some built-in styling. This could easily be fixed by applying some CSS to remove these styles:

button {
  border: none;
  background: none;
  padding: 0;
  margin: 0;
  text-decoration: none;
  -webkit-appearance: none;
  -moz-appearance: none;
}

button:active .button-contour {
  transform: rotate(180deg);
  transform-origin: 6px 6px;
}

Note that we also replaced the selector that inverts the grid of the buttons’ contour, using button:activein place of svg:active. This ensures that the button-pressed style applies whenever the actual <button> element is pressed, regardless of the input device used.

We can even make our component more screen-reader friendly by adding an aria-label attribute that includes the color of the button:

<button aria-label="${color} pushbutton">

There is still one more thing to tackle: the “button-press” and “button-release” events. Ideally, we want to fire them based on the CSS :active pseudo-class of the button, just like we did in the CSS above. In other words, we would like to fire the “button-press” event whenever the button becomes :active, and the “button-release” event to fire whenever it is :not(:active).

But how do you listen to a CSS pseudo-class from Javascript?

Turns out, it is not so simple. I asked this question to the JavaScript Israel community, and eventually dug up one idea that worked out of the endless thread: use the :activeselector to trigger a super-short CSS animation, and then I can listen to it from JavaScript using the animationstart event.

A quick CodePen experiment proved that this actually works reliably. As much as I liked the sophistication of this idea, I decided to go with a different, simpler solution. The animationstart event isn’t available on Edge and iOS Safari, and triggering a CSS animation just for detecting the change of the button state doesn’t sound like the right way to do things.

Instead, we’re going to add three pairs of event listeners to the <button> element: mousedown/mouseup for the mouse, touchstart/touchend for mobile devices, and keyup/keydown for the keyboard. Not the most elegant solution, in my opinion, but it does the trick and works on all browsers.

<button
  aria-label="${color} pushbutton"
  @mousedown=${this.down}
  @mouseup=${this.up}
  @touchstart=${this.down}
  @touchend=${this.up}
  @keydown=${(e: KeyboardEvent) => e.keyCode === SPACE_KEY && this.down()}
  @keyup=${(e: KeyboardEvent) => e.keyCode === SPACE_KEY && this.up()}
>

Where SPACE_KEY is a constant that equals 32, and up/down are two class methods that dispatch the button-press and button-release events:

@property() pressed = false;

private down() {
  if (!this.pressed) {
    this.pressed = true;
    this.dispatchEvent(new Event('button-press'));
  }
}

private up() {
  if (this.pressed) {
    this.pressed = false;
    this.dispatchEvent(new Event('button-release'));
  }
}
  • You can find the full source code here.

We Did It!

It was a pretty long journey that started with outlining the requirements and drawing the illustration for the button in Inkscape, went through converting our SVG file to a reusable web component using lit-element, and after making sure it’s accessible and mobile-friendly, we ended up with nearly 100 lines of code of a delightful virtual pushbutton component.

This button is just a single component in an open-source library of virtual electronic components I’m building. You are invited to peek at the source code, or check out the online Storybook where you can see and interact with all the available components.

And finally, if you are interested in Arduino, take a look at the programming Simon for Arduino course I’m currently building, where you can also see the pushbutton in action.

Till next time, then!

Smashing Editorial
(dm, il)

Source: Smashing Magazine, Recreating The Arduino Pushbutton Using SVG And &lt;lit-element&gt;

All Things Smashing: Monthly Update

dreamt up by webguru in Uncategorized | Comments Off on All Things Smashing: Monthly Update

All Things Smashing: Monthly Update

All Things Smashing: Monthly Update

Iris Lješnjanin



We can’t repeat enough how wonderful the web performance community is! There are good folks who help make the web faster, and their efforts matter indeed. With the new year sinking in and everyone’s resolutions still being put to the test, personal goals such as reproducing bugs and fixing issues suddenly become something we all have in common: improving the web for everyone involved.

As various areas of performance become more and more sophisticated and complicated throughout the years, Vitaly refines and updates his front-end performance checklist every year. This guide covers pretty much everything from performance budgets to single-page apps to networking optimizations. It has proved to be quite useful to folks in the past years — anyone can edit it (PDF, MS Word Doc and Apple Pages) and adjust it to their own personal needs or even use it for their organization.

Now, without further ado, let’s see what’s been cooking at Smashing!

Exciting Times: New Smashing Book

The cover of the upcoming Smashing Book named “Ethical Design Handbook”Are you ready for the next Smashing book? Well, just like all the printed books we’ve published, each and every is crafted to deliver in-depth knowledge and expertise shared by experts and practitioners from the industry. The Ethical Design Handbook will not be any different. Written by Trine Falbe, Martin Michael Frederiksen and Kim Andersen, the book will be pre-released late January.

As always, there will be a pre-order discount available. We expect to ship printed hardcover copies late February, but in the meantime, feel free to subscribe to the book mailing list so that you can be one of the first folks to get your hands on the book!

Less Speaking, More Time For Questions

Our SmashingConfs are known to be friendly, inclusive events where front-end developers and designers come together to attend live sessions and hands-on workshops. From live designing to live debugging, we want you to ask speakers anything — from naming conventions to debugging strategies. For each talk, we’ll have enough time to go into detail, and show real examples from real work on the big screen.

A photo of Dan Mall standing on stage explaining code shown on the screen behind him

Dan Mall, Brad Frost and Ian Frost coding live on stage at SmashingConf in NYC. (Image credit: Drew McLellan) (Watch video)

If you’re eager not to miss out on one of our SmashingConfs, then early-bird tickets are still available. And if you need a lil’ help convincing your boss to send you to an event, let us know! We’ve got your back. 😉

A Taste Of Smashing… Offscreen

Smashing Podcast moderated by Drew McLellanWe’ve reached our 7th episode of the Smashing Podcast! We’re so proud and thrilled to have our dear friends and colleagues, Drew McLellan and Bethany Andrew, managing the bi-weekly interview show so brilliantly! The feedback has been overwhelmingly positive, and now we’re excited for many more!

Shining The Spotlight On TypeScript

Smashing TVIn less than two weeks (Jan. 29), we’ll be hosting a Smashing TV webinar with Stefan Baumgartner who’ll shed light on what type-checking has in store for folks creating and using the web. TypeScript has been one of the most hyped technologies in 2019 — it’s now time to look beyond the hype!

Mark your calendars and join us at 17:00 London time — we’d love to hear your thoughts and experiences you’ve had in your career.

We publish a new article every day on various topics that are current in the web industry. Here are some that our readers seemed to enjoy the most and have recommended further:

Best Picks From Our Newsletter

With the start of a brand-new decade, we decided to start off with topics dedicated to web performance. There are so many talented folks out there working on brilliant projects, and we’d love to spread the word and give them the credit they deserve!

Note: A huge thank you to Cosima Mielke for writing and preparing these posts!

Which Metrics Matter Most?

First Meaningful Paint, Time to Interactive, First Input Delay, SpeedIndex. With so many performance metrics floating around, it’s not easy to strike just the right balance for a project. And most of the time, these metrics alone will be too generic and not precise enough, so we’ll need to complement them with custom ones as well. In small and large companies it’s common to define important pixels in the UI, measure how fast we can start render them, and how quickly we can provide input responsiveness for them.

Every project could benefit from a mix of at least 4 metrics. Time To Interactive (TTI) is the key metrics for understanding how much wait a user has to experience to use the site without a lag. First Input Delay (FID) complements TTI very well as it describes the missing part of the picture: what happens when a user actually interacts with the site.

A graph showing JavaScript fetch, parse, and compile loading phases

JavaScript fetch, parse, and compile loading phases (Image credit)

Total Blocking Time (TBT) helps quantify the severity of how non-interactive a page is prior to it becoming reliably interactive. And Cumulative Layout Shift (CLS) highlights how often users experience unexpected layout shifts (reflows) when accessing the site. All these metrics will appear in Lighthouse v6 as it starts rolling out in 2020.

Additionally, you can look into FrustrationIndex that looks at the gaps between metrics instead of looking at them individually, ad weight impact and Component-Level CPU costs. Note that First Meaningful/Contentful Paint are being replaced with Largest Contentful Paint, and the role of SpeedIndex has decreased with new metrics showing up.

The Impact Of Performance Optimization

It’s no secret that performance has a direct impact on user experience and business metrics and that sometimes, even a seemingly small web performance optimization like shaving off a few milliseconds load time can lead to a better conversion rate. To demonstrate this impact, WPO Stats collects case studies and experiments from products and e-commerce sites — stories of successes and of things that went wrong. Inspiring!

UX Speed Calculator

An open-source visualization tool that helps explain the relationship between page speed, conversion and bounce rates. (Image credit)

To support your performance optimizations with some hard figures and help you better grasp their impact, Sergey Chernyshev built the UX Speed Calculator. It lets you see how speed distribution, error rate, bounce rate, and conversion rate intertwine for the values you enter. A handy little helper.

Automatically Compress The Images In Your PRs

Image optimization is probably one of the easiest tasks on your performance optimization checklist. However, if you have a lot of images to optimize, it can also take up quite some time, and in the hurry, some images might even make it into production skipping this step.

Image Actions

“State of the Web: Video Playback Metrics” by Doug Sillars (Image credit)

To change that, the team at Calibre built a GitHub action that automatically compresses all the JPEGs, PNGs, and WebP images in your pull requests. It’s fast, efficient, and, for near-lossless compression, it uses the best image compression algorithms available: mozjpeg and libvips. A real timesaver.

Resources To Stay On Top Of Performance

A lot of people in the web community are committed to performance and to helping spread the word about it. One of them is Tim Kadlec. In his podcast Chasing Waterfalls, he invites people who work to make the web faster for everyone. Three episodes have already been released, with Reefath Rajali sharing insights into PayPal’s performance journey, Malek Kalim exploring how to scale a culture of performance across an organization, and Katie Hempenius talking about performance budgets, third-party challenges, JavaScript, and a lot of other things that impact performance.

Chasing Waterfalls podcast hosted by Tim Kadlec

Conversations with the people working to make the web faster for everyone, hosted by Tim Kadlec. (Image credit)

Another handy resource to keep you on top of web performance comes from Ben Schwarz and Karolina Szczur. Together they curate the Performance Newsletter, delivering web performance tools, talks, and other resources to your inbox twice a month. There’s also an archive of previous newsletter issues for you to catch up on until the next issue will be sent out.

Each and every issue of the Smashing Newsletter is written and edited with love and care. No third-party mailings or hidden advertising — you’ve got our word.

Smashing Editorial
(cm, vf, ra, il)

Source: Smashing Magazine, All Things Smashing: Monthly Update

Collective #581

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










Collective Item image

Is reduce() bad?

Jake and Surma discuss the array function reduce() and answer the question if it’s good to use it.

Watch it



Collective Item image

CSS4 is here!

Peter-Paul Koch proposes that web developers start saying “CSS4 is here!”, for the marketing effect.

Read it










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


Source: Codrops, Collective #581

The Mythical Mythical Man-Month

dreamt up by webguru in Uncategorized | Comments Off on The Mythical Mythical Man-Month

The Mythical Mythical Man-Month

The Mythical Mythical Man-Month

John Foreman



As a product leader at a tech company, I am a bottomless pit of need. My job as the Chief Product Officer at Mailchimp is to bring the product to market that’s going to win in a very competitive space. Mailchimp’s aspirations are high, and to realize them we need to deliver a substantial amount of product to the market. Oftentimes to many at the company, it feels like we are doing too much. We’re always at the edge of the wheels coming off.

And when you’re doing too much and you decide to do more than even that, you will inevitably begin to hear The Mythical Man-Month referenced. It’s like one of those stress-relief balls where if you squeeze one end, then out pops the Mythical Man-Month at the other end.

Published by Frederick Brooks back in 1975 (you remember 1975, right? When software development 100% resembled software development in 2020?), this book is rather famous amongst software engineers. Specifically, there’s one point in the entire book that’s famous (I’m not convinced people read anything but this point if they’ve read the book at all):

“…adding more men lengthens, not shortens, the schedule.”

Easy fix. I’ll just staff women to projects from now on (see the Return of the King and the fight against the Witch King of Angmar).

But let’s assume that Brooks’ point holds regardless of the gender identification of the software engineers in question. Here’s the point: software is difficult to build with lots of complex interdependencies. And everyone needs to work together to get it done.

As I add people to a team, they need to be onboarded and grafted into the project. Someone’s gotta carve off the right work for them. The team has to communicate to make sure their stuff all works together, and each additional person increases that communication complexity geometrically. And at some point, adding people becomes a burden to the project — not a benefit.

Here’s the graph from the book illustrating that point:

As you add people to tasks with complex interdependencies, progress grinds to a halt

Add people to go slow (Large preview)

This is absolutely a fair point. That’s why I hear it so much at work. Exhausted individual contributors and exhausted leaders alike will toss it out — we can’t go faster, we can’t do more, stop the hiring, read The Mythical Man-Month and despair! The only solution is apparently to stop growing and kill some projects.

When I as CPO say, “we’re going to do this thing!” the reply then is often, “OK, so then what are we going to kill?” The Mythical Man-Month turns product development into a zero-sum game. If we want one thing, we must stop another. Now, that’s an actual myth, and I call hogwash.

And taken to its pathologically misinterpreted (we’ll get to this) conclusion, the book apparently says that the fastest tech company is one that employs all of four people — four men, apparently. Anything more just slows it all down. Someone should send Amazon, Apple, and Google copies of the book, so they can fix their obviously bloated orgs.

The only problem with this approach is that in a space where the competition is growing and iterating and executing — merely tamping organizational growth — editing and focusing the workload to match can be a recipe for extinction. You’ll be more sane and less stressed — right until you’re out of a job.

And as the owner of product management for my company, I’m not unsympathetic with this need to slow down and focus. We must ruthlessly prioritize! No doubt. But running a product is an exercise in contradiction. I must prioritize what I’ve got while simultaneously scheming to get more done. But what am I to do in the face of the Mythical Man-Month?

Surprisingly, the answer to this question comes from Brooks’ same book. Here’s another graph in the same chapter:

Partitionable tasks requiring communication can still add workers and go faster

(Large preview)

There is a battle in scaling product development. If the work you’re trying to accomplish is purely partitionable, then go ahead and add people! If your work is all connected, then at some point adding people is just wrong.

If someone says that I absolutely have to kill a project in order to start another one, that’s just not the case. If the two projects require very little communication and coordination, then we can scale away.

This is why adding cores to a CPU can increase the experienced speed of your computer or phone up to a point — something engineers should know all about. Sure, adding cores won’t help me complete a complex single-threaded computation. But it may help me run a bunch of independent tasks.

The conflict for a product executive then between scaling and ruthless prioritization can be managed.

  1. You ruthlessly prioritize in places that are single-threaded (the backlog for a product team let’s say).
  2. You scale by adding more cores to handle independent work.

Very rarely, however, is anything fully-independent of all else at a company. At the bare minimum, your company is going to centralize supporting functions (global IT, legal, HR, etc.) leading to bottlenecks.

It’s All About Dependency Management

The job of a product executive then becomes not only creating a strategy, but executing in a way that maximizes value for the customer and the business by ensuring throughput and reducing interdependency risk as much as possible. “As much as possible” being key here. That way you can make the company look as much like the latter graph rather than the former. Interdependency is a disease with no cure, but its symptoms can be managed with many treatments.

One solution is to assemble a strategic direction for the company that minimizes or limits dependency through a carefully-selected portfolio of initiatives. The funny thing here is that many folks will push back on this. Let’s say I have two options, one where I can execute projects A, B, and C that have very little coordination (let’s say they impact different products), and another option with projects D1, D2, and D3 that have tons of interdependencies (let’s say they all impact the same product). It’s often the case that the Mythical Man-Month will be invoked against the former plan rather than the latter. Because on paper it looks like more.

Indeed, it’s less “focused.” But, it’s actually less difficult from a dependency perspective and hence fairs better with added personnel.

Keep in mind, I’m not saying to choose a bunch of work for the company that’s not related. Mailchimp will not be building a microwave oven anytime soon. All work should drive in the same long-term direction. This approach can increase customer experience risk (which we’ll discuss later) as well as the burden on global functions such as customer research. Keep an eye out for that.

Another treatment is to create a product and program management process that facilitates dependency coordination and communication where necessary without over-burdening teams with coordination if not required. Sometimes in attempting to manage coordination so we can do more we end up creating such onerous processes that we end up doing less. It’s a balance between doing too little coordination causing the pieces to not inter-operate and doing too much coordination causing the pieces to never get built because we’re all in stand-ups for eternity.

The contention in the Mythical Man-Month is that as you add folks to a software project, the communication needs to increase geometrically. For example, if you have 3 people on the project, that’s 3 lines of communication. But if you have 4, that’s 6 lines of communication. One extra person, in this case, leads to double the communication! Fun. (This is, of course, an over-simplification of communication on software development projects.)

Different people have different roles and hence receive different amounts of autonomy. Perhaps the project manager needs to communicate with everyone on the team. But does an engineer working on the API need to communicate with the product marketer? Or can the marketer just go through the product manager? A good process and meeting cadence can then eliminate unnecessary communication and meetings. The point is that Brooks’ intercommunication formula is an upper bound on coordination, not a death sentence.

Finally, use tools, principles, and frameworks combined with independent work over actual collaboration to combat interdependency symptoms. For example, if I can coordinate two teams’ key performance indicators (KPIs, i.e. measurements of success) to incentivize movement in more-or-less the same direction, then their independent work is more likely to end up “closer together” than if their KPIs incentivize orthogonal movement. This won’t ensure things fit together perfectly, only that the work I need to do to make them fit together in the future is less than it might otherwise be. Other examples might include using “even-over” statements, design systems, and automated testing.

So there’s a start. But interdependencies take on lots of forms beyond code. Let me give an example from Mailchimp.

Customer Experience Risk: The Hidden (But Acceptable?) Cost Of Firewalling Work

Since Mailchimp’s customer is often a small business owner who’s a marketing novice (and there are millions of small business owners turned marketers worldwide), we must deliver an experience that is seamless and immediately understandable end-to-end. We’re not afforded the luxury of assembling a Frankenstein’s monster of clouds via acquisition the way that enterprise players can. We can’t paper over poorly-integrated software with consultants and account managers.

As a consumer product (think Instagram or a Nintendo Switch or a Roomba), we have to be usable out of the box. For an all-in-one marketing platform meant to power your business, that’s hard! And that means each thing Mailchimp builds must be seamlessly connected from an experience perspective.

But, perfectly partitioning projects then introduces experience risk. It’s not that the code can’t be written independently. That can be achieved, but there’s still a risk that the products will look like they’ve been built by different teams, and that experience can be really damn confusing for the user. We bump up against Conway’s law — our customers can tell where one team’s work ends and the other team’s work begins.

So you try to connect everyone’s work together — not just on the back-end but on the front-end, too. In the ecosystem era, dominated by CX excellence from players like Apple, this has become almost table stakes in the consumer space. But this is a Mythical Man-Month nightmare, though not from an engineering perspective this time. It’s from a service design perspective. As we add more people to all of this “end-to-end” connected work, everything slows to a collaborative crawl.

Other than the third fix I noted above, using tools and frameworks rather than over-watchers and stage-gates, there is another release valve: make some deliberate customer experience trade-offs. Specifically, where are we comfortable releasing an experience that’s disconnected from the rest (i.e. that’s sub-par)? Accepting risk and moving forward is the product leader’s job. And so you use some criteria to sort it out (perhaps it’s not holding new, low-traffic areas of the app to the same experience standards as your “cash cows”), and make a decision (e.g. iteration and learning over polish on adjacent innovations). This, of course, extends beyond design.


You can always short-circuit Brooks’ law by choosing to firewall efforts, including efforts that, in a perfect world, shouldn’t be firewalled!

I’ll caveat this by saying the software I build doesn’t kill anyone. I wouldn’t advocate this approach if I were building a medical device. But at a marketing software company, I can deliberately isolate teams knowing that I’ve increased the odds of incompatibility as a trade-off for scaling up personnel and moving faster.

I’m sad to admit that the Mythical Man-Month is a reality at my company, and I suspect at yours as well. But it’s manageable — that’s the bottom line. Parallelization and dependency mitigation offer us a way out that limits the near-mythical status of the Mythical Man-Month. So the next time the stark dichotomy is raised at your company (scale to go slower or give up your aspirations) remember that if you’re smart about how you line up the work, you can still grow big.

Don’t Forget About The Softer Side Of Scaling

Keep in mind that managing the Mythical Man-Month will not stop engineers from invoking it like dark magic. They’re invoking the principle not only because there’s some truth in it, but because scaling just sucks (always) from an emotional and cognitive perspective. If I think I’m paid to write code and solve customer problems, the last thing I wanna do is change up my routine and figure out how to work with new people and a larger team.

As you scale your company, remember to empathize with the pain of scaling and change. A team that adds even a single member becomes a whole new team from a trust and cultural perspective. People are tired of this change. That means that while you go about managing and mitigating the Mythical Man-Month, you’ll need to manage the emotions surrounding growth. That’s perhaps the most critical task of all.

Strong belief in the Mythical Man-Month by a team in and of itself can bring its conclusions into reality. It’s basically the equivalent of the belief in flying in Peter Pan. If the team believes that scaling will slow them and they don’t buy into the change, they will indeed slow down.

So as you work to manage dependencies and introduce tools to help scale, make sure you clearly communicate the why behind the practices. Get folks involved in selecting the work and processes that mitigate man-month issues, because when they’re part of the change and their outlook changes, suddenly scaling becomes at least culturally possible.

Smashing Editorial
(ra, il)

Source: Smashing Magazine, The Mythical Mythical Man-Month

1 2 3 4 5 6 7 8 9 10 ... 85 86   Next Page »