.email::before {
content: attr(data-done) " Email: "; /* This gets inserted before the email address */
}
The property generally takes anything you drop in there. However, there are some invalid values it won’t accept. I heard from someone recently who was confused by this, so I had a little play with it myself and learned a few things.
This works fine:
/* Valid */
::after {
content: "1";
}
…but this does not:
/* Invalid, not a string */
::after {
content: 1;
}
I’m not entirely sure why, but I imagine it’s because 1 is a unit-less number (i.e. 1 vs. 1px) and not a string. You can’t trick it either! I tried to be clever like this:
But of course, you’d never use generated content for important information like a price, right?! (Please don’t. It’s not very accessible, nor is the text selectable.)
Even though you can get and display that number, it’s just a string. You can’t really do anything with it.
Heads up! Don’t try concatenating strings like you might in PHP or JavaScript:
/* These will break */
::after {
content: "1" . "2" . "3";
content: "1" + "2" + "3";
/* Use spaces */
content: "1" "2" "3";
/* Or nothing */
content: "1 2 3";
/* The type of quote (single or double) doesn't matter, but content not coming back from attr() does need to be quoted. */
}
There is a thing in the spec for converting attributes into the actual type rather than treating them all like strings…
<wood length="12" />
wood {
width: attr(length em); /* or other values like "number", "px", or "url" */
}
…but I’m fairly sure that isn’t working anywhere yet. Plus, it doesn’t help us with pseudo elements anyway, since strings already work and numbers don’t.
The person who reached out to me over email was specifically confused why they were unable to use calc() on content. I’m not sure I can help you do math in this situation, but it’s worth knowing that pseudo elements can be counters, and those counters can do their own limited form of math. For example, here’s a counter that starts at 12 and increments by -2 for each element at that level in the DOM.
The only other thing we haven’t mentioned here is that a pseudo element can be an image. For example:
p:before {
content: url(image.jpg);
}
…but it’s weirdly limited. You can’t even resize the image. ¯_(?)_/¯
Much more common is using an empty string for the value (content: "";) which can do things like clear floats but also be positioned, sized and have a background of its own.
We’ve been able to do this for years, largely for free (ignoring the costs of the computer and devices), but I’m not sure as many people know about it as they should.
TL;DR: XCode comes with a “Simulator” program you can pop open to test in virtual iOS devices. If you then open Safari’s Develop/Debug menu, you can use its DevTools to inspect right there — also true if you plug in your real iOS device.
?Pendo is a product cloud that helps create lovable products that customers can’t live without. Pendo enables product teams to understand product usage, collect user feedback, measure NPS, assist users in their apps and promote new features in product — all without requiring any engineering resources. This unique combination of capabilities is all built on a common infrastructure of product data and results in better onboarding, increased user engagement, improved customer satisfaction, reduced churn, and increased revenue.
Pendo is the proven choice of innovative product leaders at Salesforce, Marketo, Zendesk, Citrix, BMC and many more leading companies.
?Pendo is a product cloud that helps create lovable products that customers can’t live without. Pendo enables product teams to understand product usage, collect user feedback, measure NPS, assist users in their apps and promote new features in product — all without requiring any engineering resources. This unique combination of capabilities is all built on a common infrastructure of product data and results in better onboarding, increased user engagement, improved customer satisfaction, reduced churn, and increased revenue.
Pendo is the proven choice of innovative product leaders at Salesforce, Marketo, Zendesk, Citrix, BMC and many more leading companies.
My grandma makes the best, most fluffiest, go weak-in-your-knees buns that anybody has ever tasted. The problem is, there’s a ton of secret ingredients (and I’m not just talking love) that go into those buns, and those ingredients and directions are all stored in my grandma’s head.
We all have family recipes like that, and instead of possibly forgetting them, in this article we’re going to create a mobile app for iOS and Android using Xamarin.Forms that will save them for myself and future generations of my family!
So if you’re interested in writing mobile applications, but don’t have the time to write the same app over and over again for each platform, this article is for you! Don’t worry if you don’t know C# from a Strawberry Pretzel Salad; I’ve been writing Xamarin apps for over 8 years, and this article is a tour through Xamarin.Forms that intends to give you enough information to start learning on your own.
What Is This Xamarin Stuff?
More than just a fun word to say, Xamarin allows developers to create native iOS and Android applications using the exact same SDKs and UI controls available as in Swift and XCode for iOS or Java and Android Studio for Android.
The difference is that the apps are developed with C# using the .NET Framework and Visual Studio or Visual Studio for Mac. The apps that result, however, are exactly the same. They look, feel, and behave just like native apps written in Objective-C, Swift, or Java.
Xamarin shines when it comes to code sharing. A developer can create and tailor their UI for each platform using native controls and SDKs, but then write a library of shared app logic that’s shared across platforms.
It’s this code sharing where tremendous time savings can be realized.
And like the delicious buns my grandma bakes, once given the taste of sharing code — it’s hard not to crave more — and that’s where Xamarin.Forms comes in.
Xamarin.Forms
Xamarin.Forms takes the concept of traditional Xamarin development and adds a layer of abstraction to it.
Instead of developing the user interface for iOS and Android separately, Xamarin.Forms introduces a UI toolkit that enables you to write native mobile apps from a single code base.
Think of it this way: You have an app that needs a button. Each platform has the concept of a button. Why should you have to write the user interface a bunch of different times when you know all the user of your app needs to do is tap a button?
That’s one of the problems Xamarin.Forms solves.
It provides a toolkit of the most commonly used controls and user interaction events for them, so we only have to write the user interfaces for our apps once. It’s worth noting though that you’re not limited to the controls Xamarin.Forms provides either — you still can use controls found in only a single platform within a Xamarin.Forms app. Also, we can share the application logic between platforms as before.
The code sharing stats for apps developed with Xamarin.Forms can be off the charts. A conference organizing app has 93% of its code shared on iOS and 91% on Android. The app is open sourced. Take a peek at the code.
But today, we’re going to focus on the UI capabilities for building our recipe manager app.
The App We’ll Build
The recipe manager app will have a straightforward user interface. We will be working in the kitchen, so it needs to be easy to use!
It will consist of 3 screens. The first will show a list of all the recipes currently loaded in the app.
Then, by tapping on one of those recipes, you’ll be able to see its details on a second screen:
From there you can tap an edit button to make changes to the recipe on the third screen:
You can also get to this screen by tapping the add button from the recipe list screen.
The Development Environment
Xamarin apps are built with C# and .NET, using Visual Studio on Windows or Visual Studio for Mac on the Mac, but you need to have the iOS or Android SDKs and tooling installed, too. Getting everything installed, in the correct order could be a bit of an issue, however, the Visual Studio installers will take care of note only getting the IDE installed, but also the platform tooling.
Although a Mac is always required to build iOS apps, with Xamarin you can still develop and debug those apps from Visual Studio on Windows! So if Windows is your jam, there’s no need to change your environments altogether.
Now let’s see how Xamarin.Forms can help us save some family recipes from one code base!
Recipe List Page: Laying Out the UI
Let’s start with talking about how we’re going to layout the UI for our recipe saving app!
Overall each screen in Xamarin.Forms is comprised of 3 elements. A Page. At least one element called a Layout. And at least one Control.
The Page
The Page is the thing that hosts everything displayed on the screen at one time. The Page is also central in navigation within an app.
We tell Xamarin.Forms which Page to display via a Navigation Service. That service then will take care of displaying whatever page in a way that’s appropriate and native for the operating system.
In other words, the code to navigate between screens has been abstracted too!
Finally, although not the only way to do it, I code the UI of my Page‘s in XAML. (The other way would be to use C#.) XAML is a markup language that describes how a page looks. And for now, suffice it to say, it’s kinda sorta similar to HTML.
The Layout
All the controls on a page are arranged by something called a Layout.
One or more layouts can be added to a page.
There are several different types of Layouts in Forms. Some of the most common ones include Stack, Absolute, Relative, Grid, Scroll, and Flex layouts.
The Controls
Then finally there are the controls. These are the widgets of your app that the user interacts with.
Forms come with many controls that will be used no matter what type of app you’re building. Things like labels, buttons, entry boxes, images, and of course, list views.
When adding a control to a screen, you add it to a layout. It’s the layout that takes care of figuring where exactly on the screen the control should appear.
So to generate the following screens on iOS and Android respectively:
There’s a couple of important things going on here.
The first is the . This is telling Forms to arrange all the controls that follow in a stack.
There happens to only be a single control in the layout, and that’s a , and we’re going to give it a name so we can reference it later.
Then there’s a little bit of boilerplate ceremony to the ListView before we get to what we’re after: the . This is telling Forms to display simple text in each cell of the list.
We tell the the text we want it to display through a technique called Data Binding. The syntax looks like Text="{Binding Name}". Where Name is a property of a Recipe class that models… well, Recipes.
So how do the recipes get added to the list?
Along with every XAML file, there is a “code-behind” file. This code-behind allows us to do things like handle user interaction events, or perform setup, or do other app logic.
There’s a function that can be overridden in every Page called OnAppearing — which as I’m sure you guessed — gets called when the Page appears.
This is telling the ListView — “Hey! All of your data is found in the enumerable App.AllRecipes (an application-wide variable) and you can use any of its child object’s properties to bind off of!”.
A list of recipes is all well and fine — but you can’t bake anything without first seeing the recipe’s details — and we’re going to take care of that next.
Event Handling
Without responding to user touches our app is nothing more than a list of delicious sounding recipes. They sound good, but without knowing how to cook them, it’s not of much use!
Let’s make each cell in the ListView respond to taps so we can see how to make the recipe!
In the RecipeListPage code-behind file, we can add event handlers to controls to listen and react to user interaction events.
Handling tap events on the list view then:
recipesList.ItemSelected += async (sender, eventArgs) =>
{
if (eventArgs.SelectedItem != null)
{
var detailPage = new RecipeDetailPage(eventArgs.SelectedItem as Recipe);
await Navigation.PushAsync(detailPage);
recipesList.SelectedItem = null;
}
};
There’s some neat stuff going on there.
Whenever somebody selects a row, ItemSelected is fired on the ListView.
Of the arguments that get passed into the handler, the eventArgs object has a SelectedItem property that happens to be whatever is bound to the ListView from before.
In our case, that’s the Recipe class. (So we don’t have to search for the object in the master source – it gets passed to us.)
Recipe Detail Page
Of course, there’s a page that shows us the secret ingredients and directions of how to make each recipe, but how does that page get displayed?
Notice the await Navigation.PushAsync(detailPage); line from above. The Navigation object is a platform-independent object that handles page transitions in a native fashion for each platform.
Now let’s take a peek at the recipe details page:
This page is built with XAML as well. However, the Layout used (FlexLayout) is quite cool as it’s inspired by the CSS Flexbox.
The FlexLayout will arrange its controls in either rows or columns. The big benefit comes though with the fact that it can automatically detect how much room there is left on the screen to place a control, and if there’s not enough, then it can automatically create a new row or column to accommodate it!
This helps greatly when dealing with various screen sizes, which there are plenty of in mobile development.
Well, with the FlexLayout helping us keep the details screen looking good, we still need to edit those recipes, right?
That line is responsible for putting a button in the app’s toolbar. The Clicked="Edit_Clicked" tells the button that when it’s clicked, look in the code behind for a function of that name, and then execute its code.
Which in this case, would be instantiating the Recipe Edit Page, and pushing that onto our navigation stack using the Navigation object mentioned previously.
Recipe Edit Page
A page with a list of recipes: check! A page with all the details to make the recipes: check! All that’s now left is to create the page that we use to enter or change a recipe while we watch grandma work her magic!
See that TheRecipe property? It’s page level, holds all the data for a particular recipe, and gets set in the constructor of the page.
Secondly, the Clicked event handlers for the saveButton and cancelButton are totally .NET-ified (and yes, I do make my own words up quite often.)
I say they’re .NET-ified because the syntax to handle that event is not native to Java nor Objective-C. When the app runs on Android or iOS, the behavior will be exactly like an Android Click or an iOS TouchUpInside.
And as you can see, each of those click event handlers are invoking appropriate functions that either save the recipe and dismiss the page, or only dismiss the page.
There it is — we have the UI down to save the recipes from now until the end of time!
CSS Wha?!? Or Making The App Pretty
Saving the best for last: Xamarin.Forms 3.0 gives us — among other things — the ability to style controls using CSS!
The Xamarin.Forms CSS isn’t 100% what you may be used to from web development. But it’s close enough that anyone familiar with CSS will feel right at home. Just like me at grandma’s!
So let’s take the Recipe Details page and refactor it, so it uses Cascading Style Sheets to set the visual elements instead of setting everything directly inline in the XAML.
First step is to create the CSS doc! In this case it will look like the following:
For the most part, it looks like CSS. There are classes in there. There is a single selector for a class type, Image. And then a bunch of property setters.
Some of those property setters, such as flex-wrap or flex-basis are specific to Xamarin.Forms. Going forward, the team will prefix those with xf- to follow standard practices.
In Xamarin.Forms, to reference the CSS document, add a . Then you can reference the classes in each control via the StyleClass property.
It definitely cleans up the XAML, and it makes the intention of the control clearer too. For example, now it’s pretty obvious what those are up to!
And the Image gets itself styled all because it’s an Image and the way we defined the selector in the CSS.
To be sure, CSS in Xamarin.Forms isn’t as fully implemented as its web cousin, but it’s still pretty cool. You have selectors, classes, can set properties and, of course, that whole cascading thing going on!
Summary
Three screens, two platforms, one article, and endless recipes saved! And you know what else? You can build apps with Xamarin.Forms for more than Android and iOS. You can build UWP, macOS, and even Samsung Tizen platforms!
Xamarin.Forms is a UI toolkit that allows you to create apps by writing the user interface once and having the UI rendered natively across the major platforms.
It does this by providing an SDK that’s an abstraction to the most commonly used controls across the platforms. In addition to the UI goodness, Xamarin.Forms also provides a full-featured MVVM framework, a pub/sub messaging service, an animation API, and a dependency service.
Xamarin.Forms also gives you all the same code benefits that traditional Xamarin development does. Any application logic is shared across all the platforms. And you get to develop all your apps with a single IDE using a single language — that’s pretty cool!
Where to next? Download the source code for this Xamarin.Forms app to give it a spin yourself. Then to learn more about Xamarin.Forms, including the ability to create an app all within your browser, check out this online tutorial!
There’s little doubt that WordPress is one of the biggest web technologies in the world, powering around a third of the web, and growing all the time. Until recently WordPress was only for the initiated, those developers who’d spent years learning how to dig into the source code and tinker, without breaking their whole site.
In the last few years WordPress has been revolutionized by the introduction of page builders, applications that allow anyone—even someone with no design or coding knowledge—to create a professional standard WordPress site on the fly. Today, we’re talking about one of the most lightweight options on the market, with performance that outstrips many rival tools: WP Page Builder.
WP Page Builder is the perfect tool for web professionals who want to branch into WordPress, but don’t want to hire expensive designers or developers. Thanks to its intuitive drag and drop interface, WP Page Builder allows you to quickly and easily develop websites for your, or your clients’ businesses, with none of the hassle of old-school WordPress development.
Real-Time Frontend Customization for Everyone
There’s absolutely no need to hire a designer, or developer, to work with WP Page Builder. Simply create a page in WordPress, and drop your content wherever you want it.
The real-time front-end customization means that you will see exactly what you’re coding—yes, coding, because WP Page Builder generates all the code a professional developer would write, and inserts it for you.
And should you get lost at any point, Themeum’s simple to understand documentation, and friendly customer support will get you back on track.
Responsive Design with Flexible Layouts
Themeum’s WP Page Builder uses a flexible row-column layout structure, which is perfect for responsive design. Flexibly add rows and columns of content, and adjust the sizing and spacing as you like. Everything you add will be flexible across all viewport sizes, so your site will look perfect no matter what device it’s previewed on.
Feature-Rich Add-Ons
There are 30+ add-ons included with WP Page Builder, including:
Post Grid – ideal for posting a scannable grid of post thumbnails to introduce your content;
Accordion – a vertical open/close menu that’s great for discovering options;
Form – everyone needs forms for collecting information from your new-found customers;
Carousel – present your content in an attractive animated slider that users will love;
Pricing Table – the simplest way to present your pricing to new customers in a format they’ll recognize and understand;
Testimonial Carousel – boast about how great your company is, with animated reviews from other customers;
Video Popup – show videos in a pop-up modal so they don’t interfere with the rest of your content;
Flip Box – present content in an attractive 3D style, using both sides of a card;
Feature Box – easily highlight the main features of your company for customers;
and a whole load more…
In fact, WP Page Builder features so many add-ons, you can produce just about any content you can imagine. And more add-ons are being introduced all the time.
Rich Libraries
The library system allow you to design blocks within your design, and save them for reuse. Just design a section of your site, save it to the library, then access it at any time to use the same design block on any other page of your site. It’s a huge productivity gain that will help you generate sites faster, and turn projects around more quickly.
Predesigned Templates and Blocks
WP Page Builder includes a gamut of predesigned templates, so you can get a head-start on your build by selecting a template you like and modifying it to fit your preferences.
To make your flow even faster, WP Page Builder includes a host of professionally designed blocks, ready to drag and drop into your page. Simply select the block you want, drag and drop it onto your page, and it will be ready instantly.
WP Page Builder’s front-end customization is even compatible with your themes—even themes from 3rd parties—so you can really boost your site development by starting with a ready-made design from Themeum, or another provider, then customize using WP Page Builder.
Be Empowered by WP Page Builder
WP Page Builder is a professional quality drag and drop site builder, with a whole heap of add-ons to keep you happy. The visually intuitive site editor, the total lack of coding, and the predesigned blocks and templates, mean that even novices can use it.
With the library system for rapid builds, and the simple one-click duplication system, it’s a super-fast solution for anyone who wants to build a great website without hiring an expensive designer or developer.
[– This is a sponsored post on behalf of Themeum –]
By default, communication between Vue components happen with the use of props. Props are properties that are passed from a parent component to a child component. For example, here’s a component where title is a prop:
<blog-post title="My journey with Vue"></blog-post>
Props are always passed from the parent component to the child component. As your application increases in complexity, you slowly hit what is called prop drilling here’s a relate article that is React-focused, but totally applies). Prop drilling is the idea of passing props down and down and down to child components — and, as you might imagine, it’s generally a tedious process.
So, tedious prop drilling can be one potential problem in a complex. The other has to do with the communication between unrelated components. We can tackle all of this by making use of an Event Bus.
What is an Event Bus? Well, it’s kind of summed up in the name itself. It’s a mode of transportation for one component to pass props from one component to another, no matter where those components are located in the tree.
Practice task: Building a counter
Let’s build something together to demonstrate the concept of an event bus. A counter that adds or subtracts a submitted value and tallies the overall total is a good place to start:
To make use of an event bus, we first need to initialize it like so:
import Vue from 'vue';
const eventBus = new Vue();
This sets an instance of Vue to eventBus. You can name it anything you’d like, whatsoever. If you are making use of a single-file component, then you should have snippet in a separate file, since you will have to export the Vue instance assigned to eventBus anyway:
import Vue from 'vue';
export const eventBus = new Vue();
With that done, we can start making use of it in our counter component.
Here’s what we want to do:
We want to have a count with an initial value of 0.
We want an input field that accepts numeric values.
We want two buttons: one that will add the submitted numeric value to the count when clicked and the other to subtract that submitted numeric value from the count when clicked.
We want a confirmation of what happened when the count changes.
This is how the template looks with each of those elements in place:
We bind the input field to a value called entry, which we’ll use to either increase or decrease the count, depending on what is entered by the user. When either button is clicked, we trigger a method that should either increase or decrease the value of count. Finally, that {{ text }} thing contained in
tag is the message we’ll print that summarizes the change to the count.
You may have noticed that we’re about to hop on the event bus by looking at that code.
First thing we’ve got to do is establish a path for sending an event from one component to another. We can pave that path using eventBus.$emit() (with emit being a fancy word for sending out). That sending is included in two methods, handleIncrement and handleDecrement, which is listening for the input submissions. And, once they happen, our event bus races to any component requesting data and sends the props over.
You may have noticed that we are listening for both events in the created() lifecycle hook using eventBus.$on(). In both events, we have to pass in the string that corresponds to the event we emitted. This is like an identifier for the particular event and the thing that established a way for a component to receive data. When eventBus recognizes a particular event that has been announced, the function that follows is called — and we set a text to display what had happened, and make it it disappear after three seconds.
Practice task: Handling multiple components
Let’s say we are working on a profile page where users can update their name and email address for an app and then see the update without refreshing the page. This can be achieved smoothly using event bus, even though we are dealing with two components this time: the user profile and the form that submits profile changes.
We will pass the ids (user.name and user.email)to the corresponding component. First, let’s set up the template for the Edit Profile (edit__profile) component, which holds the name and email data we want to pass to the Profile component we’ll set up next. Again, we’ve established an event bus to emit that data after it detects that a submission event has taken place.
This data will be used to reactively update the profile on the user in the Profile (profile) component, which looking for name and email to come in when the bus arrives to its hub.
Their bags are packed. Now all they have to do is go home.
Pretty cool, right? Even though the Edit Profile and Profile components are unrelated — or not in a direct parent-child relationship) — it is possible for them to communicate with each other, linked by the same event.
Rollin’ right along
I have found Event Bus helpful in cases where I want to enable reactivity in my app — specifically, to update a component based on the response obtained from the server without causing the page to refresh. It is also possible that the event that gets emitted can be listened to by more than one component.
If you have other interesting scenarios of using event bus, I’ll love to hear about them in the comments. ?
It’s Wednesday, so you know what that means – font of the week! For number 12, we’ve chosen a beautiful, luxurious, and handwritten font that will be sure to make any of your projects look expensive. Opulent font caught our attention on Creativemarket and we’ve decided to give it the spotlight it deserves.
Created by Sam Parrett, Opulent font is the ideal centerpiece for any of your projects that you want to project as fancy and personal. The lettering itself is written in a very exaggerated cursive, and you can even see the brush strokes where it looks like it’s been hand painted. What makes this font so unique is that it comes with 3 different forms. Each one of these forms was created to give you options for a variety of different projects and scenarios:
Opulent SVG
This form is perfect for re-creating beautiful hand-lettering and high-definition water color textures, which is completely built-in as a transparency.
Opulent Brush
This form maintains the authentic, rustic, rough, paint brushed finish you’re looking for, but stays in traditional vector format.
Opulent Solid
Solid, as the name suggests, adds a little more solidity to the text. Instead of a ghostly, transparent look, the text is more silky smooth.
Opulent font is perfect for many types of invitations, personal business logos, book covers, business cards, packaging, posters, etc.. Anytime you want that personal, homemade touch, Opulent font is a great choice.
Sam Parrett is no stranger to being featured here on WDL. We’ve showcased a few of his fonts before, and we wouldn’t be surprised if we do it again in the near future. His profile on Creativemarket is littered with tons and tons of amazing fonts that will slide right in to any project of yours. He’s always coming up with new and creative fonts, as well as answering any questions you may have about his current ones. If you’re in the market for something new and exciting, Sam Parrett might be the guy you need to talk to. Keep it up, Sam!
Just in case you didn’t believe us when we said Sam makes amazing fonts, here are a few more examples to wet your appetite:
Forms. It’s no coincidence that the word rhymes with “yawns” — web forms are dull to code and even duller for your visitors to fill in. But without forms, the web would just be a library. They let us comment, collect, book, buy, share, and a host of other verbs. And mostly they enable us to do these things in an awkward, opaque, confusing, odd, frustrating, alarming, or alienating way. Forms are such an important part of the web, but we design them poorly all the time. When they’re not over-engineered they’re usually not engineered at all.
With the new Form Design Patterns book we want to tackle this problem. By going through common real-world problems step by step, you’ll learn how to design simple, robust, lightweight, responsive, accessible, progressively enhanced, interoperable and intuitive forms that let users get stuff done no matter what. And by the end of the book you’ll have a close-to exhaustive list of components delivered as a design system that you can use immediately in your own projects. (Jump to table of contents.)
*Form Design Patterns* contains ten chapters ([? Table of Contents](#toc)). Each one represents a common real-world problem that we’ll solve together step by step. Design is just as much about asking (and understanding) questions, as it is about creating solutions. So we’ll spend time doing just that: discussing the problem, weighing up the options, and **creating technical solutions that are simple and inclusive**.
Ultimately, the book is about understanding what users need. Users are people and people are different. So we’ll be considering multiple interaction modalities and how to help users work under situational (temporary or permanent) and environmental circumstances. We’ll be looking at every problem through an inclusive design lens. Because good design is inclusive.
–>
Table Of Contents
Each chapter revolves around a specific problem — after all, that’s how we solve problems in real life. But don’t be concerned, many of the styles, components and patterns born out of each chapter are reusable and applicable well beyond the specifics and you’ll see examples of this as we move through the book.
A Registration Form
We’ll start looking at the foundational qualities of a well-designed form and how to think about them. By applying something called a question protocol, we’ll look at how to reduce friction without even touching the interface. Then we’ll look at some crucial patterns, including validation, that we’ll want to use for every form.
A Checkout Form
We’ll consider checkout flows and look at several input types and how they affect the user experience on mobile and desktop browsers, all the while looking at ways to help both first-time and returning customers order quickly and simply.
A Flight Booking Form
We’ll dive into the world of progressively enhanced, custom form components using ARIA. We’ll do this by exploring the best way to let users select destinations, pick dates, add passengers, and choose seats. We’ll analyze native form controls, and look at breaking away from convention when it becomes necessary.
A Login Form
We’ll look at the ubiquitous login form. Despite its simple appearance, there’s a bunch of usability failures that so many sites suffer from.
An Inbox
We’ll design ways to manage email in bulk, our first look at administrative interfaces. As such, this comes with its own set of challenges and patterns, including a responsive ARIA-described action menu, multiple selection, and same-page messaging.
A Search Form
We’ll create a responsive search form that is readily available to users on all pages, and we’ll also consider the importance of the search mechanism that powers it.
A Filter Form
Users often need to filter a large set of unwieldy search results. Without a well-designed filter, users are bound to give up. Filters pose a number of interesting and unique design problems that may force us to challenge best practice to give users a better experience.
An Upload Form
Many services, like photo sharing, messaging, and many back-office applications, let users upload images and documents. We’ll study the file input and how we can use it to upload multiple files at once. Then we’ll look at the intricacies of a drag-and-drop, Ajax-enhanced interface that is inclusive of keyboard and screen reader users.
An Expense Form
We’ll investigate the special problem of needing to create and add lots of expenses (or anything else) into a system. This is really an excuse to cover the add another pattern, which is often useful in administrative interfaces.
A Really Long and Complicated Form
Some forms are very long and take hours to complete. We’ll look at some of the patterns we can use to make long forms easier to manage.
He’s particularly interested in inclusive design and design systems and writes about this on his blog and popular design publications such as A List Apart. This isn’t his first book either: he previously wrote Maintainable CSS, a book about crafting maintainable UIs with CSS.
Technical Details
384 pages, 14 × 21 cm (5.5 × 8.25 inches),
ISBN: 978-3-945749-73-9 (print),
Quality hardcover with stitched binding and a ribbon page marker,
The eBook is available in PDF, EPUB, and Amazon Kindle.
Free worldwide airmail shipping from Germany. Delivery times.
It has been our goal to make the book as practical and useful as possible. We’ve been honored to receive very positive reviews from people making websites on small and large scale.
“I have been writing forms in HTML for over 20 years. This book captures the essence of what it is to embrace standards, progressively enhance and deliver simple, accessible forms. By formalising design patterns we can all use and implement, developers and designers can focus on their website and product. I wish this was available 20 years ago!” — Paul Duncan, Design Technologists and Accessibility Teacher
“Forms. It’s no coincidence that the word rhymes with “yawns” – forms are dull to code and even duller for your visitors to fill in. So make them work better for everyone, using the concrete tips, code and microcopy in this book. And take away your own yawns, as Adam Silver has done all the research and coding for you.” — Bruce Lawson, Web standards Advocate
“Form Design Patterns is setting out common sense and inclusive solutions for forms both simple and potentially complex. It’s your companion as you strive to create a simpler and easier interactive web.” — Heydon Pickering, UX and accessibility consultant
Why This Book Is For You
This book is a practical guide for anyone who needs to design, prototype and build all sorts of forms for digital services, products and websites. You’ll learn:
Available native form elements and their powers, limitations and constraints.
When and how to create accessible custom form components that can give users a better experience in comparison to their native equivalents.
How to significantly reduce friction in forms with careful use of language, flow and order.
Ways (and ways not) to help users fix form errors easily.
How to deal with complex interfaces that let users upload files and add multiple items of any sort.
Ways to let users search and filter a large set of results according to their own mental model.
How to help customers fill out especially long and complex forms that may take weeks to fill out.
We can’t wait to hear your thoughts about the book! Happy reading, and we hope that you’ll find the book as useful as we do. Just have a cup of coffee (or tea) ready before you start reading, of course. Stay smashing and… meow!