Archive

Archive for May, 2019

Everything You Ever Wanted to Know About inputmode

May 17th, 2019 No comments

The inputmode global attribute provides a hint to browsers for devices with onscreen keyboards to help them decide which keyboard to display when a user has selected any input or textarea element.

<input type="text" inputmode="" />
<textarea inputmode="" />

Unlike changing the type of the form, inputmode doesn’t change the way the browser interprets the input — it instructs the browser which keyboard to display.

The inputmode attribute has a long history but has only very recently been adopted by the two major mobile browsers: Safari for iOS and Chrome for Android. Before that, it was implemented in Firefox for Android way back in 2012, and then subsequently removed several months later (though it is still available via a flag).

Almost six years later, Chrome for Android implemented the feature — and with the recent release of iOS 12.2, Safari now supports it too.

This browser support data is from Caniuse, which has more detail. A number indicates that browser supports the feature at that version and up.

Desktop

Chrome Opera Firefox IE Edge Safari
66 53 20 No 75 No

Mobile / Tablet

iOS Safari Opera Mobile Opera Mini Android Android Chrome Android Firefox
12.2 No No 67 74 No

But before we go deep into the ins and outs of the attribute, consider that the WHATWG living standard provides inputmode documentation while the W3C 5.2 spec no longer lists it in its contents, which suggests they consider it obsolete. Given that WHATWG has documented it and browsers have worked toward supporting it, we’re going to go assume WHATWG specifications are the standard.

inputmode accepts a number of values. Let’s go through them, one by one.

None

<input type="text" inputmode="none" />

We’re starting here because it’s very possible we don’t want any type of keyboard on an input. Using inputmode=none will not show a keyboard at all on Chrome for Android. iOS 12.2 will still show its default alphanumeric keyboard, so specifying none could be sort of a reset for iOS in that regard. Regardless, none is intended for content that renders its own keyboard control.

Numeric

<input type="text" inputmode="numeric" />

This one is probably the one of the more common inputmode values out in the wild because it’s ideal for inputs that require numbers but no letters — things like PIN entry, zip codes, credit card numbers, etc. Using the numeric value with an input of type="text" may actually make more sense than setting the input to type="number" alone because, unlike a numeric input, inputmode="numeric" can be used with maxlength, minlength and pattern attributes, making it more versatile for different use cases.

The numeric value on Chrome Android (left) and iOS 12.2 (right)

I’ve often seen sites using type=tel on an input to display a numeric keyboard, and that checks out as a workaround, but isn’t semantically correct. If that bums you out, remember that inputmode supports patterns, we can add pattern="d*" to the input for the same effect. That said, only use this if you are certain the input should only allow numeric input because Android (unlike iOS) doesn’t allow the user to change to the keyboard to use letters, which might inadvertently prevent users from submitting valid data.

Tel

<input type="text" inputmode="tel" />

Entering a telephone number using a standard alphanumeric keyboard can be a pain. For one, each number on a telephone keyboard (except 1 and 0) represents three letters (e.g. 2 represents A, B and C) which are displayed with the number. The alphanumeric keyboard does not reference those letters, so decoding a telephone number containing letters (e.g. 1-800-COLLECT) takes more mental power.

The tel value on Chrome Android (left) and iOS 12.2 (right)

Using inputmode set to tel will produce a standard-looking telephone keyboard, including keys for digits 0 to 9, the pound (#) character, and the asterisk (*) character. Plus, we get those alphabetic mnemonic labels (e.g. ABC).

Decimal

<input type="text" inputmode="decimal" />
The decimal value on Chrome Android (left) and iOS 12.2 (right)

An inputmode set to the decimal value results in a subtle change in iOS where the keyboard appears to be exactly the same as the tel value, but replaces the +*# key with a simple decimal (.). On the flip side, this has no effect on Android, which will simply use the numeric keyboard.

Email

<input type="text" inputmode="email" />

I’m sure you (and at least someone you know) has filled out a form that asks for an email address, only to make you swap keyboards to access the @ character. It’s not life-threatening or anything, but certainly not a great user experience either.

That’s where the email value comes in. It brings the @ character into the fray, as well as the decimal (.) character.

The email value on Chrome Android (left) and iOS 12.2 (right)

This could also be a useful keyboard to show users who need to enter a Twitter username, given that@ is a core Twitter character for identifying users. However, the email address suggestions that iOS display above the keyboard may cause confusion.

Another use case could be if you have your own email validation script and don’t want to use the browsers built-in email validation.

URL

<input type="text" inputmode="url" />
The url value on Chrome Android (left) and iOS 12.2 (right)

The url value provides a handy shortcut for users to append TLDs (e.g. .com or .co.uk) with a single key, as well keys typically used in web addresses, like the dot (.) and forward slash (/) characters. The exact TLD displayed on the keyboard is tied to the user’s locale.

This could also be a useful keyboard to show users if your input accepts domain names (e.g. css-tricks.com) as well as full URIs (e.g. https://css-tricks.com). Use type="url" instead if your input requires validating the input.

Search

<input type="text" inputmode="search" />
The search value on Chrome Android (left) and iOS 12.2 (right)

This displays a blue Go key on iOS and a green Enter key on Android, both in place of where Return. As you may have guessed by the value’s name, search is useful for search forms, providing that submission key to make a query.

If you’d like to showSearch instead of Enter on iOS and a magnifying glass icon on Android in place of the green arrow, use type=search instead.

Other things you oughta know

  • Chromium-based browsers on Android — such as Microsoft Edge, Brave and Opera — share the same inputmode behavior as Chrome.
  • I haven’t included details of keyboards on iPad for the sake of brevity. It’s mostly the same as iPhone but includes more keys. Same is true for Android tablets, save for third-party keyboards, which might be another topic worth covering.
  • The original proposed spec had the values kana and katakana for Japanese input but they were never implemented by any browser and have since been removed from the spec.
  • latin-name was also one of the values of the original spec and has since been removed. Interestingly, if it’s used now on Safari for iOS, it will display the user’s name as a suggestion above the keyboard.

    The latin-name value displays my name as an auto-fill suggestion

Demo

Oh, you want to see how all of these input modes work for yourself? Here’s a demo you can use on a device with a touchscreen keyboard to see the differences.

References

Categories: Designing, Others Tags:

Weekly news: PWA Issue on iOS, Performance Culture, Anti-Tracking in Browsers

May 17th, 2019 No comments

Šime posts regular content for web developers on webplatform.news. Each week, he covers timely news at the intersection of development standards and the tools that make them available on the web.

Installed PWAs cannot easily be restarted on iOS

iOS 12.2 PWAs
? In-App browser for external content (OAuth)
? New lifecycle (No Reload)
?Navigation gestures
?WebShare
??Motion Sensors disabled; old getUserMedia removed
? IntersectionObserver, ConicGradients, datalist, color picker, AbortFetchhttps://t.co/LNzq6MzqjR

— Maximiliano Firtman @ ?? Vilnius (@firt) March 26, 2019

Maximiliano Firtman: On iOS, it is not possible to restart an installed PWA by closing it from the recently used apps screen and then immediately reopening it. Instead of restarting the app, iOS restores its state. This can be a problem for users if the PWA gets stuck in a broken state.

with type ‘file’ bug on #iOS 12.2 #PWA
Open the input, put the PWA in bg by pressing home button. The input stops working. True for any input with type ‘file’ throughout the app. It works after a phone restart. pic.twitter.com/IfzsXy91RK

— Pankaj Nathani ?? (@croozeus) April 11, 2019

After some undefined time, the saved context seems to disappear. So if you get out of the PWA, do nothing with your phone and wait some hours to go back to the PWA, it restarts from scratch.

Instilling a performance culture at The Telegraph

We’ve been working hard at The Telegraph to improve third-party performance. Here is an insight into our approach – https://t.co/4hhRDYaidS #webperf ??

— Gareth Clubb (@digitalclubb) April 30, 2019

Gareth Clubb: At The Telegraph (a major UK newspaper), we set up a web performance working group to tackle our “organizational” performance challenges and instill a performance culture. The group meets regularly to review third-party tags and work on improving our site’s performance.

We’ve started deferring all JavaScript (including our own) using the attribute. This change alone nearly doubled our (un-throttled) Lighthouse performance score.

Deferring our JavaScript hasn’t skewed any existing analytics and it certainly hasn’t delayed any advertising. […] The First Ad Loaded metric improved by an average of four seconds.

We also removed 1 MB of third-party payload from our new front end. When one of our teams requests the addition of any new script, we now test the script in isolation and reject it if it degrades our metrics (first contentful paint, etc.).

When we started this process, we had a collection of very old scripts and couldn’t track the original requester. We removed those on the premise that, if they were important, people would get back in touch?—?no one did.

Microsoft plans to add tracking prevention to the Edge browser

Kyle Pflug: Microsoft has announced plans to add options for blocking trackers to the Edge browser. Malicious trackers would be blocked automatically, and the user would have the option to additionally block all potential trackers.

This would make Edge the fourth major browser with some form of built-in anti-tracking feature (two other major browsers, Opera and UC Browser, include ad blockers instead).

  1. In 2015, Firefox added Tracking Protection?—?recently renamed to Content Blocking?—?becoming the first major browser to protect users from third-party trackers (when browsing the web in private mode).
  2. Since 2017, Safari prevents cross-site tracking by default, through a feature called Intelligent Tracking Prevention (ITP). Users are prompted to allow tracking when they try to interact with third-party widgets on websites.

  3. Earlier this year, Samsung Internet added an experimental feature called Smart Anti-Tracking that denies third-party trackers access to cookies.

The post Weekly news: PWA Issue on iOS, Performance Culture, Anti-Tracking in Browsers appeared first on CSS-Tricks.

Categories: Designing, Others Tags:

Make Your Clients Love You

May 17th, 2019 No comments
Review, increase rating or ranking, evaluation and classification concept. Businessman draw five yellow star to increase rating of his company

Presentation speaks volumes. A post or a presentation with an impeccable design is deemed to be catchy in comparison to texts.

When the text fails to catch the attention of a buyer, it is the image that does the magic. However, the importance of design and visuals is often neglected in marketing. According to research, typography helps in influencing human minds greatly with high retaining capacity.

Getting to the minds of the audience is one tricky thing. No matter how impeccable of an idea you may be having, if you are unable to reach it out to the audience, it is a failure. And this very aspect of conceptualizing the idea and turning it into a marketing tool is where lies the major challenge. This is where designing does its magic.

Yes, you heard it right. While Marketing and Advertising do play a major role in terms of strong copywriting, and promotion, it is the design that plays a critical role in upscaling any campaign. The marketing strategy must not only be focussed on how to generate result but also watch out on how the business can reach to the audience and generate high ROI.

Herein we have enlisted the various advantages of design and how It can help in increasing the sales of a brand:

It helps in communicating a brand

Marketing campaigns and advertisements are all about raising the profiles of brands as well as convincing the customers in buying the company’s product or service. Brands play an essential role in fixing the offerings of companies into the minds of the target audience. More creative the campaign more the chances lie for customers in buying the product. Herein, whether it’s a creative blog, brochure or an image it indirectly aids in talking about the product. And hence it must be impeccable.

However, in comparison to wholly textual data, visuals penetrate into the minds of consumers easily. If the design is less professional and only speaks about the brand’s core messaging it will fail in creating a good impression and undermine its credibility. Hence, using the right quality, texturing and colors are essential aspects to consider for communicating a brand to the target audience.

It attracts the attention of the consumer

If you want to be successful, you must be able to stand out of the crowd. This means coming up with impeccable and out of the box ideas which is different in comparison to other brands. Your marketing campaign will fail to create the magic in it cannot raise a noise above that of other contemporaries who are also competing for a brand same as that of yours.

Thus, the design must try to meet the goal of the campaign in a proficient and finesse manner. The design must be hard-hitting that gets fixed in the mind of the customers over other advertisers.

For example – if you are talking about a health drink, you must use the perfect colorations and design which can create an impact in the minds of the consumers. Great design works as the voice of advertisers which helps one speak about the prospects in a memorable manner making it get noticed.

It aids in converting the potential audience into sales

In marketing, one must foremost be able to understand the psychology of the customers. If your client speaks about conversions, all it means is call to action. Often advertisers fail in this aspect wherein they are unable to determine how psychologically compelling design can be and how it can help in converting sales into profits.

Suppose you visit a website, what is the first thing in which your eyes fall? Is it the writing or the layout? What emotions do the photographs, colors, and use of layouts evoke? This is one such area that stands out in comparison to others. A design that is well crafted and created can masterfully craft your pitch or else pull it down in the gallows of conversion.

It helps in reinforcing the message

Good design never underplays in the game of getting noticed. It offers the best platform in conveying what the marketers wish to divulge or inform the audience. This very aspect invokes the argument on the importance of designing in marketing as well as branding on how it can powerfully evoke a message in the minds of the consumer. One need not need a set of wordings to convey an idea, a few sets of images can do the magic.

For example – In case you run a nonprofit organization. The possibility of conveying the cause is more when one chooses a few images either in animation or photographs than writing hundreds of words of copy on the same issue.

What are the elements of designing?

The designer must be knowledgeable and carry some substance surrounding the intricacies of designing. These include the use of the right color combination, texturing and typography. All these elements play an equal role in making the image stand out.

Some of the elements of designing that can make the image stand out includes:

Colorations and shades

Each color speaks a language of their own. Using the right color combination in the perfect place is an important criterion.

For example – Using a red color for love, green color for brands about health, nature, purple for showing the richness, etc. are few aspects a designer must keep a note about when developing the image.

Positioning

The image must be focused on the central character that is your brand without taking away the essence of it. The consumer’s eyes must first fall on the brand rather than wander all across the image. Thus, using minimum typographies and other elements is yet another important aspect.

Symmetry

The image must be symmetrical, this means all the elements used in the image must not be placed in a haphazard manner. They should be in sync with one another relating to each other. In short, the design or image must be able to convey the story without speaking about it loudly through words.

The right balance of idea, design, and conceptualization is the key factor of increasing sales without using words.

Categories: Others Tags:

Monthly Web Development Update 5/2019: Over-Complication And Performative Workaholism

May 17th, 2019 No comments
Stick figures showing how many people are online and how many offline in which part of the world. Most people who are online come from Asian and Pacific countries, followed by the Americas.

Monthly Web Development Update 5/2019: Over-Complication And Performative Workaholism

Monthly Web Development Update 5/2019: Over-Complication And Performative Workaholism

Anselm Hannemann

2019-05-17T14:24:00+02:002019-05-18T01:35:11+00:00

This week, I was at the amazing beyondtellerrand conference once again, and every single time I come home from such an event, I try to understand our industry and our society better. There’s so much input and inspiration around, I meet a lot of friends and people I see only once a year, I listen to great talks. People tell me how frustrated they are with their jobs, we hear amazing stories of people who seem to have an amazing life, we hear people moaning about bad players on the web, but rarely do we hear real insights or solutions.

Presentations highlighting the good parts and uncommon paths in life are quite rare, but one of the exceptions is Rob Draper’s beyondtellerand talk in which he shares his story and how an unexpected series of events created the role he is in today. And, well, I’m glad that there are amazing people who believe in humans and share how we all as individuals can do something to have a better job and life: It might be as Stephen Hay suggests to trust your own ideas, building your own website and social system, or, as my good friend Andy is doing it, building a non-profit initiative to build schools in Africa, a project into which he invests not only a lot of time but money as well.

It’s great to see these visions of a better world, and it feels like a good community to be in. The web is so much more than just a space to build technical solutions and write code; it’s a place to create helpful, meaningful, and beautiful individual things.

News

  • Let’s make things official: Safari 12.1 now supports Dark Mode. Check the full article for how to apply it to your pages or take a look at one of the sites like Twitter or Colloq that already support it. Safari’s Developer Tools feature a debug mode for Dark Mode now as well.
  • Chrome 74 is public. The new version lets us detect if a user requested reduced motion and the Feature Policy API got updates, too, so now we can request document.featurePolicy.allowedFeatures() for all allowed features, allowsFeature() for single features, or document.featurePolicy.getAllowlistForFeature() for a domain list that gets the allowed features.
  • Googlebot is evergreen now. This means that Google’s search crawler gets the newest Chromium version automatically. From now on, it supports ES6, ECMAScript Modules and newer functionality and understands lazy-loaded content via IntersectionObserver and the WebComponents v1 APIs. It might be time to drop our ES6 transpilers soon.
  • The Web Share API is a nice addition to make more use of websites. And while it has been available on Chrome for Android for quite some time now, Safari is bringing the feature to macOS and iOS in its latest version.

General

  • Stefan Judis shares a roundup article on how to keep the web a safe place, making it affordable and fast and tailoring the response to the user — all with HTTP headers. A good read for everybody as we all tend to forget about these things in our daily work.
  • The annual Mozilla 2019 Internet Health Report examines how humanity and the internet intersect. Here’s the report itself with some short answers for those who don’t want to read it completely.
  • On-call rotation is a common thing in tech, and I know that a lot of teams struggle with it. That’s why I found this guide on “On-call at any size” quite informative and useful. It explains how to prepare and what to do — no matter if you’re a small team or part of a big corporation.
  • Emily Shaffer shares how to annotate regular expressions to make them comprehensible for others as well.

Stick figures showing how many people are online and how many offline in which part of the world. Most people who are online come from Asian and Pacific countries, followed by the Americas.

If there were only 100 people in the world, who would be online? That’s only one of the questions which Mozilla’s Internet Health Report 2019 answers. (Image credit)

UI/UX

Paths to simplification illustrated with circles and arrows. Subtract, Consolidate, Redistribute, Prioritize, Clarify.

How do you fix the UX of a product that has become overly complicated? Patrick Faller shows paths to simplification. (Image credit)

Tooling

  • GitHub is completing the experience by integrating their own npm registry (but also ruby, Docker, Maven, NuGet) into the platform. This is a huge step as it makes publishing custom and private packages a lot easier.

Privacy

Security

  • The Google AMP project announced that they’re going to “simplify” AMP domains in Google Chrome. This means that users would see the original URL in the browser bar while really being on a Google AMP server. An interesting approach, given the fact that this is something that browser vendors usually don’t allow in order to prevent URL spoofing.

Accessibility

  • stylelint-a11y is a plugin for stylelint that enforces accessibility best practices via the CSS linter.

JavaScript

CSS

Work & Life

  • How do productivity and promises correlate? In times of constant demands, too much work to do, and blurry information about priorities and different senses of urgency, you can hardly blame people for breaking with their promises anymore. If we’re constantly confronted with other people’s expectations like “please get back to me by 1 PM today”, how can we stick to our original schedule for the day and be productive? Should we ignore such external demands and say “we had better things to do” than replying to the non-urgent but urgency-creating email “in time”? It definitely takes some courage to do so, but in the end, this is what productivity is about: sticking to a schedule and dedicating focus time to one single task.
  • When did performative workaholism become a lifestyle? The New York Times takes a closer at the culture of business, hustling, and the weird love we develop for working faster and more. But what about our lives when we work for 12 or 18 hours a day? And what about that promise that automation will take off the work from us?
  • Do you do standup calls? Here’s why this is a costly thing that even hurts your teammates’ efficiency.
  • Stop being so busy and just do nothing. Trust us.” This claim in the New York Times has its reasons: In a world of stress and an environment where we embrace working all day, we need to remember to stop and take time for ourselves.
  • We love to tend to make judgments about other people’s work. That’s why we tend to declare something as “low-hanging fruit,” assuming that the task is easy to do and doesn’t take much time or effort. But we forget that we might miss a couple of circumstances and it might become a bigger task than anticipated. Jason Fried says that we should be careful when we use the word “easy” to describe other people’s jobs.
  • The founder of ConvertKit, Nathan Barry, shares a couple of insights into how they run the business in an unconventional way: They pay standardized salaries, make their revenue public, and distribute 60% of company profits to the team.

Screenshot from the New York Times article ‘Why are young people pretending to love work'. Under the heading, there's a propaganda-poster style illustration of three young people holding laptops, phones, and tablets, making a fist with their right hand. The background of the poster says ‘Hustle'.

When did performative workaholism become a lifestyle? The New York Times dedicated an article to the topic. (Image credit)

Going Beyond…

  • “If anything about this age is rare, perhaps it is the possibility that our fraught networked systems have finally reached such a unique point, with their environmental and social consequences so visibly intertwined, that they have become impossible to ignore.” — Ingrid Burrington in “A rare and toxic age.”
  • Let’s hand over the best possible. The best environment for the next generation. The best work for the employees that take over work from you. Keep it at heart for every aspect of life, and you’ll see that it makes a difference. To other people and to you. It feels good to do good.
  • What’s low-tech, sustainable, and possibly the most effective thing we can do to fight climate change? Planting trees. A trillion of them.
  • What are we doing to our earth? It seems despite the rising awareness of plastic pollution, global sales of plastic and glass bottles, cans, and cartons are still rising. There are so many alternatives, can we please stop buying one-time plastic packaging and coffee to-go — each of us, now?
  • When we feel overloaded, we tend to lash out at someone in frustration and anger. This comes from the hope that things will be calm, orderly, simple, solid, and under control. However, the world doesn’t comply with this hope, as it is chaotic, constantly changing, never fixed, groundless. So we get anxious and angry at others. But we can create a habit of calm when feeling frustrated.
  • What energy impact does your phone, that small screen you hold in your hands every day, have? We use video calls, messengers, or upload our photos to the cloud. But all the cloud services, the 4G network itself use a huge amount of energy that we tend to forget about. This article dives deeper into the dependencies of using a smartphone these days, and why it matters to save data and reduce your phone usage — and if it’s just for your own sake.

One more thing: If you like my reading lists, please consider making a donation. Donating to Makuyuni counts as well.

—Anselm

(cm)
Categories: Others Tags:

5 Common Design Mistakes That Disappoint Users

May 17th, 2019 No comments

Designing an interactive interface or a website is not an easy feat. You have to analyze everything about your audience, in the first place their behavior, and then implement thorough planning. New technologies are making it easier but they are also making the users more tech savvy and hard to impress.

Glossy images and hover effects are no longer impressive to users. Neither are animations or gifs – especially when everyone can make their own in just a few steps with their phones. So, how do you go about creating a great experience for your users? How do you make them happy and keep the conversions coming?

This is only getting harder if you make mistakes in your design in order to impress your audience. So, without further ado, here are some of the mistakes designers commonly make in order to amaze visitors:

1. Innovating Too Much

Design, in itself, is a creative endeavor. Designers are artists in their own respect and they always seek to express themselves through their work. They are always innovating and making sure that their designs stand out in the sea of other designs.

But if we are talking about designing a perfect interactive experience for your users, innovation might not always be the best choice. It might not be good for the niche or even that specific website. Users need to feel comfortable when visiting a website. They need that familiarity in the ways that they work with a website — you know, the common navigation patterns. They are very used to this and going off track in order to be clever or unique can only harm you, especially if you go too far.

For instance, you may have a great project in mind, some gamification methods for example, however, if you stray too far into the unknown the user will stumble onto your website, see the thing and just walk away because they won’t know what to do with it. Especially so if they are seeking just some basic information.

2. Confusing Navigation

This is a mistake we see all too often. So many websites start out as great experiences and then mess everything up with poor navigation. Some go for strange navigation places where users won’t think to look.

And yet the biggest problem users have is not that — it’s all the weird names for common pages. So, instead of the simple and sufficient “home, about, contact, blog” pattern, you get “our universe, the theory of an artist, follow your stars, always learn more”, for instance.

The thing is that users will appreciate the creativity in naming — at some point, if they manage to figure out what name is for what. It takes them a lot of browsing to find what they need. Keep in mind that most users are not there to marvel at your skill in designing but rather to find information they need to contact the company or learn more about what they have to offer. And the very purpose of the design is to allow them to do so quickly and simply, without wandering about for too long. If they do, they will probably leave the site and then the purpose of design is defeated.

3. Hating White Space

Once upon a time, sticking as many things as possible on your website was a trend. You had boxes of information all around the place, advertisements and much, much more. But that was then and we have moved (thankfully) far, far away from that. Simplicity is in. Zen is in. Users don’t want to be overwhelmed when they enter your website. They want a clear and streamlined experience that will give them what they need.

And yet, many websites still make the mistake of cluttering, thinking that they are actually not. But, you see, sticking to a single color scheme is fine but you need to think about other elements too. Having too much information on any page will have your readers running away. It also looks very, very spammy, no matter how much you want to promote.

So, nail the basics first. Then move on to creating something impressive to look at and interact with.

4. Not Using Contrast

Honestly, without contrast – what is there left?

It’s so important to use it to establish that visual hierarchy and move the user’s attention to the places where you want them to. It’s not just colors, it’s sizes, shapes, placement. Everything on a single website needs to be in contrast to another thing to show its value and importance in a subtle way.

People automatically understand that the smaller button is less important than the bigger button. They understand that the bigger letters or more emphasized letters are more important

~ Donald Emerson, an design blogger at Writemyx

So, make sure that your design has plenty of contrast to show the user where to go and what to do.

5. Complex Forms

Forms are a pain for everyone. No one likes to fill them out. But, they are also a necessary evil if you want to get consumer data to use for further endeavors.

However, they don’t need to look ugly and be annoying. What leads to this? Well, for one, long forms that ask for too much. The user might go through with the form if they care enough. But in most cases, they don’t — especially not enough to do “where is the bus?” captchas — so, eliminate that ugly form and go for something simple and stylish.

Stick to the simple – first name, last name, email (add more basics if you need, like password, for instance) or even better, first name, email. Don’t ask for too much. And, for the love of design, test the thing. Some forms on the web ask for too much “optional” information but then when you opt out, they highlight all of the blank spaces and refuse to submit without them. Not really optional.

So, when it comes to design, it’s important to think of the user and efficiency first and then find ways to delight them without confusing them. Test everything. This is the key to having a design that’s both successful and pretty.

Featured image via DepositPhotos.

Add Realistic Chalk and Sketch Lettering Effects with Sketch’it – only $5!

Source

Categories: Designing, Others Tags:

How do you evaluate the quality of a project in graphics?

May 16th, 2019 No comments
quality of a project

How do you understand when a graphics project is effective? When it’s nice or ugly? Should it be “cute”? Should it be “fashionable”? In short: how do you assess the quality of a project? In this article I really want to talk about this topic, and try to explain how you to really evaluate the quality of a project. In an objective way. Let’s jump right into it!

How do you evaluate the quality of a project in graphic design?

When evaluating the quality of a design project, the subjective aspects and personal tastes certainly play an important role. But it is important to ensure that the evaluation of a project does not depend solely on those two things. In fact, in graphic design, a project is created to communicate a message and get specific results. And those are objective aspects: they do not depend on your personal tastes.

The aesthetic aspect is an important factor, but by itself, it will not tell you if the design is effective or not. To know if your project is a winner, you need to consider the elements of good visual communication and judge the project with respect to them. Well, keeping these things in mind, here are some questions you should ask yourself when evaluating the quality of design.

How to assess the quality of a project: the 4 questions to be asked

1. Does your project achieve its goals?

quality of a project

Let’s start with the basics: what are the goals of the project you are working on? Understanding the objectives of a project is a fundamental step in any graphic design project. This should always be your first step. A good way to understand them is to do a good design brief. We can talk specifics on a design brief another time. For now, let’s keep this train rolling. But what does understanding goals mean?

If it is a logo, for example, that logo aims to represent and communicate a corporate identity. If it’s the landing page of a website, instead, maybe the goal is to convince users to click on the “Buy” button or sign up for a newsletter. And so on. Each graphic project has a specific objective. And if it doesn’t have one, it means it’s not graphic design, but art or decoration. Always check if the target has been achieved! The first step to verify the achievement of the objectives is to make sure that all the relevant information is present to communicate the message you want to communicate.

2. Is the message easy to understand?

quality of a project

Every designer project must help to communicate a certain message correctly. Does your project do it easily? How about immediately? Here are some practical tips for building an effective graphic layout, in which the message is transmitted immediately:

Use a focal point on the page. Such as a large text or a title. Something that catches the viewer’s attention. The important thing is that attention goes to an important and useful element to convey the message. Then choose the focal point carefully!

3. Is it aesthetically pleasing?

quality of a project

Design is made to solve problems through visual solutions. But if those solutions are pleasing to look at, as well as functional, you double the strength of what you communicate, right? Is your project pleasant? Looking good? This is probably the most subjective part of evaluating graphic design. What is appealing to one person might be horrible for another. Different minds, different opinions.

However, generally, already applying the principles of graphic design, one can obtain excellent results in terms of aesthetics. Doing something beautifully does not necessarily mean doing something extremely different from what it already is. Because the result of something deliberately “different” could be too extravagant in the end.

Paul Rand, one of the most important twentieth-century logo designers, said: “Don’t try to be different, try to be good.” Wiser words have perhaps never been spoken. So try to do something that works, even if maybe it’s not something radically different from everything you’ve seen before (which is practically impossible, actually).

Are the aesthetic style and the graphic elements used suitable for the target audience? Most of the time you’re not just planning for yourself, but you’re trying to create a design that appeals to a particular audience. A rainbow color palette is not suitable for a finance website because most customers are looking for a consultant who is reassuring, loyal and trustworthy. Therefore, a more moderate and sober tone may be more appropriate. On the contrary, research shows that children prefer bright colors, so it makes more sense to turn to bright and over the top colors when it comes to children.

4. Is your project original?

quality of a project

Not different in the sense that we have never seen anything like it before, but different in the sense of creativity. The meaning of “originality” depends on the type of design you are dealing with. If it is a logo, it is better to make sure it is as unique as possible, because it is necessary to be able to register the trademark and the trademark application will be rejected if you use a copy of a design. An example of difficulties that can arise from logos that are too similar: the ongoing cause between 3M and Formula 1. It is difficult to create a logo with a simple and distinctive design that does not resemble any other existing design because so many ideas have already been taken and registered as trademarks. If a designer creates a logo that looks similar to an existing design, it’s not necessarily because he copied it, but because there are some logo concepts that are really common and that can be achieved regardless of seeing those designs.

This is why it is necessary to research other designs in your market and avoid designs that are too generic. However, in reality, beyond the logo, the true differentiation of a company over another is in the management of the brand and the complete coordinated image. When instead we talk about simpler elements, like the business card, differentiating oneself is something not very sensible and useless.

Good design is useless if it communicates something wrong

Good design can do great things for a business, but it will not work miracles. It doesn’t matter how good your job as a designer is if the company communicates to the wrong audience. A good design will not be effective if the product is poor or the communication is inadequate, and in the same way, a bad sales performance is not always a consequence of the quality of the design.

There are many ways to measure the performance of a project in the real world, such as A / B tests for web pages, product focus groups, results in social media interactions or sales. However, not everyone can test a project before putting it on the market. In most cases, the customer will trust your judgment. So it is essential that you develop a critical sense of analysis of your work and your projects. Let’s not reinvent the wheel here, maybe just try another way to use it.

Read More at How do you evaluate the quality of a project in graphics?

Categories: Designing, Others Tags:

Iterating a React Design with Styled Components

May 16th, 2019 No comments
A desktop and mobile mockup of the proposed layout for the page, side by side with the desktop mockup on the left. Both mockups use rough black and white layouts of the various components for the screen.

In a perfect world, our projects would have unlimited resources and time. Our teams would begin coding with well thought out and highly refined UX designs. There would be consensus among developers about the best way to approach styling. There’d be one or more CSS gurus on the team who could ensure that functionality and style could roll out simultaneously without it turning into a train-wreck.

I’ve actually seen this happen in large enterprise environments. It’s a beautiful thing. This article is not for those people.

On the flip side of the coin is the tiny startup that has zero funding, one or two front-end developers, and a very short timeline to demonstrate some functionality. It doesn’t have to look perfect, but it should at least render reasonably well on desktop, tablet, and mobile. This gets them to a point where it can be shown to advisors and early users; maybe even potential investors who’ve expressed an interest in the concept. Once they get some cashflow from sales and/or investment, they can get a dedicated UX designer and polish the interface.

What follows is for this latter group.

Project Kickoff Meeting

Let’s invent a company to get the ball rolling.

Solar Excursions is a small travel agency aiming to serve the near-future’s burgeoning space tourism industry.

Our tiny development team has agreed that React will be used for the UI. One of our front-end developers is big on Sass, and the other is enamored with CSS in JavaScript. But they’ll be hard pressed to knock out their initial sprint goals; there’s certainly no time for arguing about the best possible styling approach. Both coders agree the choice doesn’t matter much in the long run, as long as its consistently executed. They’re certain that implementing the styling from scratch under the gun now will incur technical debt that will have to be cleaned up later.

After some discussion, the team opts to plan for one or more “styling refactor” sprints. For now, we’ll just focus on getting something up on the screen using React-Bootstrap. That way we’ll be able to quickly build working desktop and mobile layouts without much fuss.

The less time spent on front-end styling the better, because we’ll also need the UI to hook up to the services our backend developer will be cranking out. And, as our application architecture begins to take shape, both front-enders agree it’s important that it be unit tested. They have a lot on their plate.

Based on my discussions with the Powers That Be, as a dedicated project manager, I slaved over Balsamiq for at least ten minutes to provide the team with mockups for the booking page on desktop and mobile. I assume they’ll make tablet meet in the middle and look reasonable.

Initial mockups for the Solar Excursions Trip Booking Page on desktop (left) and mobile (right).

Sprint Zero: Review Meeting

Pizza all around! The team worked really hard to hit its goals, and we now have a booking page with a layout that approximates the mockups. The infrastructure for services is coming together, but there’s quite a way to go before we can connect the UI to it. In the interim, the front-enders are using a hardcoded mock data structure.

Screenshots of the page after the first round of development on desktop (left) and mobile (right). Both are approximately the same as the earlier mockups with most components looking exactly like the default user interface provided by the Bootstrap framework.
The first iteration of the page in code using react-bootstrap.

Here’s a look at our UI code so far:

This is all straightforward React. We’re using some of that Hooks hotness, but it’s probably passé to most of you by now.

The key takeaway to notice here is how four of our five application components import and use components from react-bootstrap. Only the main App component is unaffected. That’s because it just composes the top level view with our custom components.

// App.js imports
import React, { useState } from "react";
import Navigation from "./Navigation";
import Page from "./Page";

// Navigation.js imports
import React from "react";
import { Navbar, Dropdown, Nav } from "react-bootstrap";

// Page.js imports
import React from "react";
import PosterCarousel from "./PosterCarousel";
import DestinationLayout from "./DestinationLayout";
import { Container, Row, Col } from "react-bootstrap";

// PosterCarousel.js imports
import React from "react";
import { Alert, Carousel, Image } from "react-bootstrap";

// DestinationLayout.js imports
import React, { useState, useEffect } from "react";
import {
  Button,
  Card,
  Col,
  Container,
  Dropdown,
  Jumbotron,
  ListGroup,
  Row,
  ToggleButtonGroup,
  ToggleButton
} from "react-bootstrap";

The decision to move fast with Bootstrap has allowed us to hit our sprint goals, but we’re already accumulating technical debt. This is just four affected components, but as the application grows, it’s clear the “styling refactor” sprints that we planned for are going to become exponentially harder. And we haven’t even customized these components much. Once we have tens of components, all using Bootstrap with lots of inline styling to pretty them up, refactoring them to remove react-bootstrap dependencies will be a scary proposition indeed.

Rather than building more of the booking pipeline pages, the team decides that we’ll spend the next sprint working to isolate the react-bootstrap usage in a custom component kit since our services are still under construction. Application components will only use components from this kit. That way, when it comes time to ween ourselves from react-bootstrap, the process will be much easier. We won’t have to refactor thirty usages of the react-bootstrap Button throughout the app, we’ll just rewrite the internals of our KitButton component.

Sprint One: Review Meeting

Well, that was easy. High-fives. No change to the visual appearance of the UI, but we now have a “kit” folder that’s sibling to “components” in our React source. It has a bunch of files like KitButton.js, which basically export renamed react-bootstrap components.

An example component from our kit looks like this:

// KitButton.js
import { Button, ToggleButton, ToggleButtonGroup } from "react-bootstrap";
export const KitButton = Button;
export const KitToggleButton = ToggleButton;
export const KitToggleButtonGroup = ToggleButtonGroup;

We wrap those all kit components up into a module like this:

// kit/index.js
import { KitCard } from "./KitCard";
import { KitHero } from "./KitHero";
import { KitList } from "./KitList";
import { KitImage } from "./KitImage";
import { KitCarousel } from "./KitCarousel";
import { KitDropdown } from "./KitDropdown";
import { KitAttribution } from "./KitAttribution";
import { KitNavbar, KitNav } from "./KitNavbar";
import { KitContainer, KitRow, KitCol } from "./KitContainer";
import { KitButton, KitToggleButton, KitToggleButtonGroup } from "./KitButton";
export {
  KitCard,
  KitHero,
  KitList,
  KitImage,
  KitCarousel,
  KitDropdown,
  KitAttribution,
  KitButton,
  KitToggleButton,
  KitToggleButtonGroup,
  KitContainer,
  KitRow,
  KitCol,
  KitNavbar,
  KitNav
};

And now our application components are completely free of react-bootstrap. Here are the imports for the affected components:

// Navigation.js imports
import React from "react";
import { KitNavbar, KitNav, KitDropdown } from "../kit";


// Page.js imports 
import React from "react";
import PosterCarousel from "./PosterCarousel";
import DestinationLayout from "./DestinationLayout";
import { KitContainer, KitRow, KitCol } from "../kit";


// PosterCarousel.js imports
import React from "react";
import { KitAttribution, KitImage, KitCarousel } from "../kit";


// DestinationLayout.js imports
import React, { useState, useEffect } from "react";
import {
  KitCard,
  KitHero,
  KitList,
  KitButton,
  KitToggleButton,
  KitToggleButtonGroup,
  KitDropdown,
  KitContainer,
  KitRow,
  KitCol
} from "../kit";

Here’s the front-end codebase now:

Although we’ve corralled all of the react imports into our kit components, our application components still rely a bit on the react-bootstrap implementation because the attributes we place on our kit component instances are the same as those of react-bootstrap. That constrains us when it comes to re-implementing the kit components, because we need to adhere to the same API. For instance:

// From Navigation.js
<KitNavbar bg="dark" variant="dark" fixed="top">

Ideally, we wouldn’t have to add those react-bootstrap specific attributes when we instantiate our KitNavbar.

The front-enders promise to refactor those out as we go, now that we’ve identified them as problematic. And any new references to react-bootstrap components will go into our kit instead of directly into the application components.

Meanwhile, we’ve shared our mock data with the server engineer, who is working hard to build separate server environments, implement the database schema, and expose some services to us.

That gives us time to add some gloss to our UI in the next sprint — which is good because the Powers That Be would like to see separate themes for each destination. As the user browses destinations, we need to have the UI color scheme change to match the displayed travel poster. Also, we want to try and spiff up those components a bit to begin evolving our own look and feel. Once we have some money coming in, we’ll get a designer to do a complete overhaul, but hopefully we can reach a happy medium for our early users.

Sprint Two: Review Meeting

Wow! The team really pulled out all the stops this sprint. We got per-destination themes, customized components, and a lot of the lingering react-bootstrap API implementations removed from the application components.

Here’s what the desktop looks like now:

A more complete rendering of the landing page, this time using Mars as an example to show off a bright orange and red color theme. The interface components no longer look like they came directly from Bootstrap, but are still minimal in style, like dropdowns, buttons and text.
Check out the solarized theme for the red planet!

In order to pull this off, the front-enders brought in the Styled Components library. It made styling the individual kit components a breeze, as well as adding support for multiple themes.

Let’s look at a few highlights of their changes for this sprint.

First, for global things like pulling in fonts and setting the page body styles, we have a new kit component called KitGlobal.

// KitGlobal.js
import { createGlobalStyle } from "styled-components";
export const KitGlobal = createGlobalStyle`
  body {
    @import url('https://fonts.googleapis.com/css?family=Orbitron:500|Nunito:600|Alegreya+Sans+SC:700');
    background-color: ${props => props.theme.foreground};
    overflow-x: hidden;
  }
`;

It uses the createGlobalStyle helper to define the CSS for the body element. That imports our desired web fonts from Google, sets the background color to whatever the current theme’s “foreground” value is, and turns off overflow in the x-direction to eliminate a pesky horizontal scrollbar. We use that KitGlobal component in the render method of our App component.

Also in the App component, we import ThemeProvider from styled-components, and something called “themes” from ../theme. We use React’s useState to set the initial theme to themes.luna and React’s useEffect to call setTheme whenever the “destination” changes. The returned component is now wrapped in ThemeProvider, which is passed “theme” as a prop. Here’s the App component in its entirety.

// App.js
import React, { useState, useEffect } from "react";
import { ThemeProvider } from "styled-components";
import themes from "../theme/";
import { KitGlobal } from "../kit";
import Navigation from "./Navigation";
import Page from "./Page";
export default function App(props) {
  const [destinationIndex, setDestinationIndex] = useState(0);
  const [theme, setTheme] = useState(themes.luna);
  const destination = props.destinations[destinationIndex];
  useEffect(() => {
    setTheme(themes[destination.theme]);
  }, [destination]);

  return (
    <ThemeProvider theme={theme}>
      <React.Fragment>
        <KitGlobal />
        <Navigation
          {...props}
          destinationIndex={destinationIndex}
          setDestinationIndex={setDestinationIndex}
        />
        <Page
          {...props}
          destinationIndex={destinationIndex}
          setDestinationIndex={setDestinationIndex}
        />
      </React.Fragment>
    </ThemeProvider>
  );
}

KitGlobal is rendering like any other component. Nothing special there, only that the body tag is affected. ThemeProvider is using the React Context API to pass theme down to whatever components need it (which is all of them). In order to fully understand that, we also need to take a look at what a theme actually is.

To create a theme, one of our front-enders took all the travel posters and created palettes for each by extracting the prominent colors. That was fairly simple.

A screenshot of the Tiny Eye website showing the red color palette used for the Mars page theme. There are two images on the left from the page that Tiny Eye used to create a color palette in the center containing various shades of red and the hex values for them on the right.
We used TinyEye for this.

Obviously, we weren’t going to use all the colors. The approach was mainly to dub the most used two colors foreground and background. Then we took three more colors, generally ordered from lightest to darkest as accent1, accent2, and accent3. Finally, we picked two contrasting colors to call text1 and text2. For the above destination, that looked like:

// theme/index.js (partial list)
const themes = {
  ...
  mars: {
    background: "#a53237",
    foreground: "#f66f40",
    accent1: "#f8986d",
    accent2: "#9c4952",
    accent3: "#f66f40",
    text1: "#f5e5e1",
    text2: "#354f55"
  },
  ...
};
export default themes;

Once we have a theme for each destination, and it is being passed into all the components (including the kit components that our application components are now built from), we need to use styled-components to apply those theme colors as well as our custom visual styling, like the panel corners and “border glow.”

This is a simple example where we made our KitHero component apply the theme and custom styles to the Bootstrap Jumbotron:

// KitHero.js
import styled from "styled-components";
import { Jumbotron } from "react-bootstrap";

export const KitHero = styled(Jumbotron)`
  background-color: ${props => props.theme.accent1};
  color: ${props => props.theme.text2};
  border-radius: 7px 25px;
  border-color: ${props => props.theme.accent3};
  border-style: solid;
  border-width: 1px;
  box-shadow: 0 0 1px 2px #fdb813, 0 0 3px 4px #f8986d;
  font-family: "Nunito", sans-serif;
  margin-bottom: 20px;
`;

In this case, we’re good to go with what gets returned from styled-components, so we just name it KitHero and export it.

When we use it in the application, it looks like this:

// DestinationLayout.js (partial code)
const renderHero = () => {
  return (
    <KitHero>
      <h2>{destination.header}</h2>
      <p>{destination.blurb}</p>
      <KitButton>Book Your Trip Now!</KitButton>
    </KitHero>
  );
};

Then there are more complex cases where we want to preset some attributes on the react-bootstrap component. For instance, the KitNavbar component which we identified earlier as having a bunch of react-bootstrap attributes that we’d rather not pass from the application’s declaration of the component.

Now for a look at how that was handled:

// KitNavbar.js (partial code)
import React, { Component } from "react";
import styled from "styled-components";
import { Navbar } from "react-bootstrap";

const StyledBootstrapNavbar = styled(Navbar)`
  background-color: ${props => props.theme.background};
  box-shadow: 0 0 1px 2px #fdb813, 0 0 3px 4px #f8986d;
  display: flex;
  flex-direction: horizontal;
  justify-content: space-between;
  font-family: "Nunito", sans-serif;
`;

export class KitNavbar extends Component {
  render() {
    const { ...props } = this.props;
    return <StyledBootstrapNavbar fixed="top" {...props} />;
  }
}

First, we create a component called StyledBootstrapNavbar using styled-components. We were able to handle some of the attributes with the CSS we passed to styled-components. But in order to continue leveraging (for now) the reliable stickiness of the component to the top of the screen while everything else is scrolled, our front-enders elected to continue using react-bootstrap’s fixed attribute. In order to do that, we had to create a KitNavbar component that rendered an instance of StyledBootstrapNavbar with the fixed=top attribute. We also passed through all the props, which includes its children.

We only have to create a separate class that renders styled-component’s work and passes props through to it if we want to explicitly set some attributes in our kit component by default. In most cases, we can just name and return styled-component’s output and use it as we did with KitHero above.

Now, when we render the KitNavbar in our application’s Navigation component, it looks like this:

// Navigation.js (partial code)
return (
  <KitNavbar>
    <KitNavbarBrand>
      <KitLogo />
      Solar Excursions
    </KitNavbarBrand>
    {renderDestinationMenu()}
  </KitNavbar>
);

Finally, we took our first stabs at refactoring our kit components away from react-bootstrap. The KitAttribution component is a Bootstrap Alert which, for our purposes, is little more than an ordinary div. We were able to easily refactor to remove its dependency on react-bootstrap.

This is the component as it emerged from the previous sprint:

// KitAttribution.js (using react-bootstrap)
import { Alert } from "react-bootstrap";
export const KitAttribution = Alert;

This is what it looks like now:

// KitAttribution.js
import styled from "styled-components";
export const KitAttribution = styled.div`
  text-align: center;
  background-color: ${props => props.theme.accent1};
  color: ${props => props.theme.text2};
  border-radius: 7px 25px;
  border-color: ${props => props.theme.accent3};
  border-style: solid;
  border-width: 1px;
  box-shadow: 0 0 1px 2px #fdb813, 0 0 3px 4px #f8986d;
  font-family: "Alegreya Sans SC", sans-serif;
  > a {
    color: ${props => props.theme.text2};
    font-family: "Nunito", sans-serif;
  }
  > a:hover {
    color: ${props => props.theme.background};
    text-decoration-color: ${props => props.theme.accent3};
  }
`;

Notice how we no longer import react-bootstrap and we use styled.div as the component base. They won’t all be so easy, but it’s a process.

Here are the results of our team’s styling and theming efforts in sprint 3:

Conclusion

After three sprints, our team is well on its way to having a scalable component architecture in place for the UI.

  • We are moving quickly thanks to react-bootstrap, but are no longer piling up loads of technical debt as a result of it.
  • Thanks to styled-components, we were able to implement multiple themes (like how almost every app on the Internet these days sports dark and light modes). We also don’t look like an out-of-the-box Bootstrap app anymore.
  • By implementing a custom component kit that contains all references to react-bootstrap, we can refactor away from it as time permits.

The post Iterating a React Design with Styled Components appeared first on CSS-Tricks.

Categories: Designing, Others Tags:

Evergreen Googlebot

May 16th, 2019 No comments

I’ve heard people say that the #1 most exciting and important thing that came out of Google I/O this year was the evergreen Googlebot:

Today, we are happy to announce that Googlebot now runs the latest Chromium rendering engine (74 at the time of this post) when rendering pages for Search. Moving forward, Googlebot will regularly update its rendering engine to ensure support for latest web platform features.

Before this, I guess I never even thought about it.

I guess part of it is that some people did already know that the old version didn’t support some newfangled JavaScript stuff, and thus literally packaged their app with old JavaScript to be more SEO-friendly.

A bunch of people were apparently shipping older code simply for the sake of Googlebot, and now they don’t have to. Sure, I’ll call that a win.

Don’t read this news as “don’t worry about your JavaScript-rendered pages and SEO” though, because Google Webmasters is still telling us that pages with content that requires JavaScript to render are put into a special slower queue for both initial crawling and for updates. Not necessarily a penalty, but certainly a delay. I’m sure that’s enough to make server-side rendering a priority for sites where SEO is the whole ballgame.

Direct Link to ArticlePermalink

The post Evergreen Googlebot appeared first on CSS-Tricks.

Categories: Designing, Others Tags:

Using Jetpack to Accelerate WordPress Development

May 16th, 2019 No comments

(This is a sponsored post.)

[Geoff:] I’ve built a fair number of WordPress sites in my day. It’s been my go-to since the 2.x-ish days because it works for any site, big or small. That’s the sort of solution and flexibility you like to have as a freelancer.

Boy, I wish I had Jetpack available in those early days.

Like WordPress itself, Jetpack is a good solution for many, many of the types of things clients are looking for from a WordPress site. I used to spend hours researching the right plugin for a specific feature, whether that was for comment filtering, asset caching, beefier search functionality, creating custom post types on the fly… you name it. All of that — and a heckuva lot more — is included in Jetpack right out of the box.

Here’s what I’m talking about. A friend of mine runs a pop-up gallery here locally. She displays paintings, photographs, sculptures… basically anything super artsy from super talented locals. That includes events, socials, performances and screenings. The wild thing is that it “pops” up in different spots, based on what she’s showing and what public space is available. So, you get how a website would be helpful for visitors to keep tabs on what’s coming up and where things are going to take place, not to mention getting a recap on past events.

We’ve all made sites for friends, right? It’s the kind of thing you do for free on the side. That makes it something you want to do well, but not necessarily spend a ton of time making. That’s where Jetpack really helped me out in this case.

If Jetpack is new to you, it’s a WordPress plugin that, as part of what it does, is bring features from WordPress.com and makes them available on your self-hosted WordPress sites.

For example, my friend really needed to showcase work. This is less of a content site and more of a visual experience, so media plays a big role. Photos, video, audio. You get it. Good thing Jetpack has a “Portfolio” custom post type at the ready.

That’s a perfect start for showing things off, but my friend also needed a carousel to allow visitors to browse photos from events and artist works. This would’ve been something I probably would have turned to the WordPress plugin directory for in the past, or perhaps some (back then) jQuery plugin, but thankfully Jetpack had my back there, too.

While we’re on the topic of media, we know that heavy image files are a recipe for slow sites. There’s a ton of WordPress plugins that can help with caching, gzipping, and even lazy loading, but all that’s already in Jetpack. Why go reinvent the wheel, especially on what’s supposed to be a pretty quick build?

I think you catch my drift. The fact is that Jetpack is an effective way to supercharge a self-hosted WordPress site, connecting it to many of the same powerful services that you’d otherwise need to go to WordPress.com — or gobs of third-party plugins — to get. Plus, it’s built by Automattic, so you know it integrates seamlessly with WordPress. No better confidence than going with something the primary maintainers of WordPress are willing to slap their name on!

Sure, we’ve only looked at a very simple example of how powerful Jetpack is for a small site. But don’t be fooled: Jetpack is capable of handling the needs of large-scale sites as well. In fact, we love Jetpack here at CSS-Tricks because it powers so much of what you see on the site, from social sign-in and automated sharing, to downtime monitoring and site search. It’s robust, dependable, and just gosh darn delightful to use.

And, hey, there’s a free tier you can start using right away and it includes a generous number of features that help with security, performance, analytics, and theming… and it only goes up from there. ?

Get Jetpack

Direct Link to ArticlePermalink

The post Using Jetpack to Accelerate WordPress Development appeared first on CSS-Tricks.

Categories: Designing, Others Tags:

Creating Your Own React Validation Library: The Basics (Part 1)

May 16th, 2019 No comments
Smashing Editorial

Creating Your Own React Validation Library: The Basics (Part 1)

Creating Your Own React Validation Library: The Basics (Part 1)

Kristofer Selbekk

2019-05-16T13:00:59+02:002019-05-16T13:05:59+00:00

I’ve always thought form validation libraries were pretty cool. I know, it’s a niche interest to have — but we use them so much! At least in my job — most of what I do is constructing more or less complex forms with validation rules that depend on earlier choices and paths. Understanding how a form validation library would work is paramount.

Last year, I wrote one such form validation library. I named it “Calidation”, and you can read the introductory blog post here. It’s a good library that offers a lot of flexibility and uses a slightly different approach than the other ones on the market. There are tons of other great libraries out there too, though — mine just worked well for our requirements.

Today, I’m going to show you how to write your very own validation library for React. We will go through the process step by step, and you’ll find CodeSandbox examples as we go along. By the end of this article, you will know how to write your own validation library, or at the very least have a deeper understanding of how other libraries implement “the magic of validation”.

  • Part 1: The Basics
  • Part 2: The Features
  • Part 3: The Experience

Step 1: Designing The API

The first step of creating any library is designing how it’s going to be used. It lays the foundation for a lot of the work to come, and in my opinion, it’s the single most important decision you’re going to make in your library.

It’s important to create an API that’s “easy to use”, and yet flexible enough to allow for future improvements and advanced use cases. We’ll try to hit both of these goals.

We’re going to create a custom hook that will accept a single configuration object. This will allow for future options to be passed without introducing breaking changes.

A Note On Hooks

Hooks is a pretty new way of writing React. If you’ve written React in the past, you might not recognize a few of these concepts. In that case, please have a look at the official documentation. It’s incredibly well written, and takes you through the basics you need to know.

We’re going to call our custom hook useValidation for now. Its usage might look something like this:

const config = {
  fields: {
    username: {
      isRequired: { message: 'Please fill out a username' },
    },
    password: {
      isRequired: { message: 'Please fill out a password' },
      isMinLength: { value: 6, message: 'Please make it more secure' }
    }
  },
  onSubmit: e => { /* handle submit */ }
};
const { getFieldProps, getFormProps, errors } = useValidation(config);

The config object accepts a fields prop, which sets up the validation rules for each field. In addition, it accepts a callback for when the form submits.

The fields object contains a key for each field we want to validate. Each field has its own config, where each key is a validator name, and each value is a configuration property for that validator. Another way of writing the same would be:

{
  fields: {
    fieldName: {
      oneValidator: { validatorRule: 'validator value' },
      anotherValidator: { errorMessage: 'something is not as it should' }
    }
  }
}

Our useValidation hook will return an object with a few properties — getFieldProps, getFormProps and errors. The two first functions are what Kent C. Dodds calls “prop getters” (see here for a great article on those), and is used to get the relevant props for a given form field or form tag. The errors prop is an object with any error messages, keyed per field.

This usage would look like this:

const config = { ... }; // like above
const LoginForm = props => {
  const { getFieldProps, getFormProps, errors } = useValidation(config);
  return (
    <form {...getFormProps()}>
      <label>
        Username<br/>
        <input {...getFieldProps('username')} />
        {errors.username && <div className="error">{errors.username}</div>}
      </label>
      <label>
        Password<br/>
        <input {...getFieldProps('password')} />
        {errors.password && <div className="error">{errors.password}</div>}
      </label>
      <button type="submit">Submit my form</button>
    </form>
  );
};

Alrighty! So we’ve nailed the API.

Note that we’ve created a mock implementation of the useValidation hook as well. For now, it’s just returning an object with the objects and functions we require to be there, so we don’t break our sample implementation.

Storing The Form State ?

The first thing we need to do is storing all of the form state in our custom hook. We need to remember the values of each field, any error messages and whether or not the form has been submitted. We’ll use the useReducer hook for this since it allows for the most flexibility (and less boilerplate). If you’ve ever used Redux, you’ll see some familiar concepts — and if not, we’ll explain as we go along! We’ll start off by writing a reducer, which is passed to the useReducer hook:

const initialState = {
  values: {},
  errors: {},
  submitted: false,
};

function validationReducer(state, action) {
  switch(action.type) {
    case 'change': 
      const values = { ...state.values, ...action.payload };
      return { 
        ...state, 
        values,
      };
    case 'submit': 
      return { ...state, submitted: true };
    default: 
      throw new Error('Unknown action type');
  }
}

What’s A Reducer? ?

A reducer is a function that accepts an object of values and an “action” and returns an augmented version of the values object.

Actions are plain JavaScript objects with a type property. We’re using a switch statement to handle each possible action type.

The “object of values” is often referred to as state, and in our case, it’s the state of our validation logic.

Our state consists of three pieces of data — values (the current values of our form fields), errors (the current set of error messages) and a flag isSubmitted indicating whether or not our form has been submitted at least once.

In order to store our form state, we need to implement a few parts of our useValidation hook. When we call our getFieldProps method, we need to return an object with the value of that field, a change-handler for when it changes, and a name prop to track which field is which.

function validationReducer(state, action) {
  // Like above
}

const initialState = { /* like above */ };

const useValidation = config => {
  const [state, dispatch] = useReducer(validationReducer, initialState);
  
  return {
    errors: state.errors,
    getFormProps: e => {},
    getFieldProps: fieldName => ({
      onChange: e => {
        if (!config.fields[fieldName]) {
          return;
        }
        dispatch({ 
          type: 'change', 
          payload: { [fieldName]: e.target.value } 
        });
      },
      name: fieldName,
      value: state.values[fieldName],
    }),
  };
};

The getFieldProps method now returns the props required for each field. When a change event is fired, we ensure that field is in our validation configuration, and then tell our reducer a change action took place. The reducer will handle the changes to the validation state.

Validating Our Form ?

Our form validation library is looking good, but isn’t doing much in terms of validating our form values! Let’s fix that. ?

We’re going to validate all fields on every change event. This might not sound very efficient, but in the real world applications I’ve come across, it isn’t really an issue.

Note, we’re not saying you have to show every error on every change. We’ll revisit how to show errors only when you submit or navigates away from a field, later in this article.

How To Pick Validator Functions

When it comes to validators, there are tons of libraries out there that implement all the validation methods you’d ever need. You can also write your own if you want. It’s a fun exercise!

For this project, we’re going to use a set of validators I wrote some time ago — calidators. These validators have the following API:

function isRequired(config) {
  return function(value) {
    if (value === '') {
      return config.message;
    } else {
      return null;
    }
  };
}

// or the same, but terser

const isRequired = config => value => 
    value === '' ? config.message : null;

In other words, each validator accepts a configuration object and returns a fully-configured validator. When that function is called with a value, it returns the message prop if the value is invalid, or null if it’s valid. You can look at how some of these validators are implemented by looking at the source code.

To access these validators, install the calidators package with npm install calidators.

Validate a single field

Remember the config we pass to our useValidation object? It looks like this:

{ 
  fields: {
    username: {
      isRequired: { message: 'Please fill out a username' },
    },
    password: {
      isRequired: { message: 'Please fill out a password' },
      isMinLength: { value: 6, message: 'Please make it more secure' }
    }
  },
  // more stuff
}

To simplify our implementation, let’s assume we only have a single field to validate. We’ll go through each key of the field’s configuration object, and run the validators one by one until we either find an error or are done validating.

import * as validators from 'calidators';

function validateField(fieldValue = '', fieldConfig) {
  for (let validatorName in fieldConfig) {
    const validatorConfig = fieldConfig[validatorName];
    const validator = validators[validatorName];
    const configuredValidator = validator(validatorConfig);
    const errorMessage = configuredValidator(fieldValue);

    if (errorMessage) {
      return errorMessage;
    }
  }
  return null;
}

Here, we’ve written a function validateField, which accepts the value to validate and the validator configs for that field. We loop through all of the validators, pass them the config for that validator, and run it. If we get an error message, we skip the rest of the validators and return. If not, we try the next validator.

Note: On validator APIs

If you choose different validators with different APIs (like the very popular validator.js), this part of your code might look a bit different. For brevity’s sake, however, we let that part be an exercise left to the reader.

Note: On for…in loops

Never used for...in loops before? That’s fine, this was my first time too! Basically, it iterates over the keys in an object. You can read more about them at MDN.

Validate all the fields

Now that we’ve validated one field, we should be able to validate all fields without too much trouble.

function validateField(fieldValue = '', fieldConfig) {
  // as before
}

function validateFields(fieldValues, fieldConfigs) {
  const errors = {};
  for (let fieldName in fieldConfigs) {
    const fieldConfig = fieldConfigs[fieldName];
    const fieldValue = fieldValues[fieldName];

    errors[fieldName] = validateField(fieldValue, fieldConfig);
  }
  return errors;
}

We’ve written a function validateFields that accepts all field values and the entire field config. We loop through each field name in the config and validate that field with its config object and value.

Next: Tell our reducer

Alrighty, so now we have this function that validates all of our stuff. Let’s pull it into the rest of our code!

First, we’re going to add a validate action handler to our validationReducer.

function validationReducer(state, action) {
  switch (action.type) {
    case 'change':
      // as before
    case 'submit':
      // as before
    case 'validate': 
      return { ...state, errors: action.payload };
    default:
      throw new Error('Unknown action type');
  }
}

Whenever we trigger the validate action, we replace the errors in our state with whatever was passed alongside the action.

Next up, we’re going to trigger our validation logic from a useEffect hook:

const useValidation = config => {
  const [state, dispatch] = useReducer(validationReducer, initialState);

  useEffect(() => {
    const errors = validateFields(state.fields, config.fields);
    dispatch({ type: 'validate', payload: errors });
  }, [state.fields, config.fields]);
  
  return {
    // as before
  };
};

This useEffect hook runs whenever either our state.fields or config.fields changes, in addition to on first mount.

Beware Of Bug ?

There’s a super subtle bug in the code above. We’ve specified that our useEffect hook should only re-run whenever the state.fields or config.fields change. Turns out, “change” doesn’t necessarily mean a change in value! useEffect uses Object.is to ensure equality between objects, which in turn uses reference equality. That is — if you pass a new object with the same content, it won’t be the same (since the object itself is new).

The state.fields are returned from useReducer, which guarantees us this reference equality, but our config is specified inline in our function component. That means the object is re-created on every render, which in turn will trigger the useEffect above!

To solve this, we need to use for the use-deep-compare-effect library by Kent C. Dodds. You install it with npm install use-deep-compare-effect, and replace your useEffect call with this instead. This makes sure we do a deep equality check instead of a reference equality check.

Your code will now look like this:

import useDeepCompareEffect from 'use-deep-compare-effect';

const useValidation = config => {
  const [state, dispatch] = useReducer(validationReducer, initialState);

  useDeepCompareEffect(() => {
    const errors = validateFields(state.fields, config.fields);
    dispatch({ type: 'validate', payload: errors });
  }, [state.fields, config.fields]);
  
  return {
    // as before
  };
};
A Note On useEffect

Turns out, useEffect is a pretty interesting function. Dan Abramov wrote a really nice, long article on the intricacies of useEffect if you’re interested in learning all there is about this hook.

Now things are starting to look like a validation library!

Handling Form Submission

The final piece of our basic form validation library is handling what happens when we submit the form. Right now, it reloads the page, and nothing happens. That’s not optimal. We want to prevent the default browser behavior when it comes to forms, and handle it ourselves instead. We place this logic inside the getFormProps prop getter function:

const useValidation = config => {
  const [state, dispatch] = useReducer(validationReducer, initialState);
  // as before
  return {
    getFormProps: () => ({
      onSubmit: e => {
        e.preventDefault();
        dispatch({ type: 'submit' });
        if (config.onSubmit) {
          config.onSubmit(state);
        }
      },
    }),
    // as before
  };
};

We change our getFormProps function to return an onSubmit function, that is triggered whenever the submit DOM event is triggered. We prevent the default browser behavior, dispatch an action to tell our reducer we submitted, and call the provided onSubmit callback with the entire state — if it’s provided.

Summary

We’re there! We’ve created a simple, usable and pretty cool validation library. There’s still tons of work to do before we can dominate the interwebs, though.

Stay tuned for Part 2 next week!

(dm, il)
Categories: Others Tags: