2018: A Smashing Year In Review

2018: A Smashing Year In Review

2018: A Smashing Year In Review

Rachel Andrew

2018-12-31T14:00:30+01:00
2018-12-31T13:41:33+00:00

As we come to the end of 2018, I spoke to some of the Smashing team, to get some thoughts on what the past year has been like for Smashing Magazine. We’re a small and fully remote team, communicating via Slack and Notion. Many of us only work part-time for Smashing, however, in many ways, I think that is one of our strengths.

We’re not just the publishers of an online magazine or conference organizers, we are people who work in the web industry. Among the team, products have been launched, books are being written, conferences have been spoken at, and websites launched that have nothing to do with Smashing Magazine itself. I love that. It stops us being insular, and I hope this helps us to constantly broaden our reach — bringing people together from all over the world to share ideas and inspiration as we all work together to build a better web.

As Editor in Chief of Smashing Magazine, I look after the content that goes out on the online magazine, and also our upcoming print magazine for members. This year, we have published almost every weekday — that represents over 290 articles! That’s a whole lot of content on subjects from privacy and accessibility to CSS and WordPress. While I read every article that goes out, I do not have the expertise to know everything about all of these subjects. I couldn’t do my job without the help of our talented editors who work with individual authors: Alma Hoffmann (Design), Chui Chui Tan (UX Design), Drew McLellan (Coding), Jim Dabell (Mobile), Marko Dugonjić (Typography), Michel Bozgounov (Graphics), and Rey Bango (Coding). Plus thanks to Iris Lješnjanin, Markus Seyfferth, Yana Kirilenko, Cosima Mielke, Andrew Lobo and Ricardo Gimenes for their hard work and efforts.

In Between Timezones

On a personal note, this year has once again involved a lot of travel, as I continue to tour around speaking about new CSS and CSS Layout. That has included talks and workshops for Smashing. In total (with speaking engagements, workshops and CSS Working Group meetings), I have traveled 272,865 kilometers while visiting 45 cities and 15 countries. That amounts to spending 146 days on the road.

Here’s a fun fact: My weekly standup post in our Smashing Slack usually starts with sharing the timezones I’m going to be in that week. Well, next year will involve more travel, and I’ll be bringing my new CSS Layout workshop to San Francisco, Toronto, and New York.

As for the magazine, I hope we can continue to publish great content from authors — those who are experienced writers but also folks writing for the first time. We are very happy to work with you to shape an article for publication. Personally, writing has helped boost my career more than anything else I have done. I love to help other people get started. So, if you have an idea, read this and then send over an outline.

Please don’t hesitate. Some of our most popular posts have been beginner guides to a technology, so don’t feel you need to have solved a big problem, or have some brand new technique in order to contribute. A nice technique, demonstrated and explained well, is worth a lot to someone who has just hit that same issue.

Anyway, enough from me! What were the highlights of the year for everyone else here at Smashing?

Vitaly Friedman: A Transitional Year

2018 was a quite busy and adventurous year for me, with a good number of ups and downs, challenges, surprises, and rewards. I was honored to have had the opportunity to run trainings, workshops and even offer consultancy to the European Parliament, EPAM, OTTO, Sipgate, Axel Springer and Wondrous, among others. I was happy to support dozens of local meet-ups and conferences around the world with the kind help of our Smashing Members.

Earlier this year, I explored how we can improve the level of education for front-end and design. While speaking at universities and schools, I was also teaching to get a sense of what’s required to set up a proper design school. In February, I taught at the New Digital School in Porto, Portugal, for a week, while exploring the state of front-end and responsive interface design in a class of 20 students. In June, I helped dear friends from the Projector Design School in Kiev, Ukraine, set up Berlin Design Campus, an initiative for Ukrainian students to explore how digital agencies and designers work and live in Berlin. In October, I participated in a week-long co-working co-living campus in Mokrin, Serbia.

Specifically, I was exploring the state of design and front-end in uncommon locations, mostly second- and third-largest cities: Porto and Braga in Portugal (thanks Tiago!), Yerevan in Armenia (thanks Sona and Sargis!), Gdansk in Poland (thanks Patrycja!), Salzburg in Austria (thanks Markus!), Moscow and Saint Petersburg in Russia (thanks Julia, Daria, Alex, Andrey, Vadim and Alexey!), Split and Labin in Croatia (thanks Toni, Antonio and Domagoj!), Belgrade and Mokrin in Serbia (thanks Tatjana and Marija!), Belfast in Northern Ireland (thanks Tash and Oliver!), Manila in Philippines (thanks Sophia!), Tallinn in Estonia (thanks Artur!). Much of the time in the second half of the year was spent with wonderful people at the European Parliament in Brussels, where Nicolas and Manuel were kind enough to invite me to work on refinements and improvements of UIs for election sites, media library, and a few smaller sites. That was quite a bit of traveling, with the absolute worst highlight of the last years being a massively delayed 47-hour trip to the Philippines due to a closed runway at the Manila airport (thanks for bearing with me through this, dear Sophia and the crew!)

Over the course of the year, I have spoken at 17 conferences, and was privileged to meet many — many! — remarkable people. It ended up with conversations I will remember for years to come. Some of these conversations changed me for the better as a person and professional, so I was happy to receive constructive criticism on MCing skills, writing, as well as code and design. I managed to wrap my head around the intricacies of CSS Grid Layout and Service Workers but also spent a lot of time learning about network protocols and the underlying layers of the Internet. I also attended 6 workshops to stay afloat of what’s happening in our industry these days and sharpened up my front-end/UX/communication skills. In September, I was honored to participate in the Mozilla Tech Speakers coaching, along with Ada Rose Edwards and Marc Thiele, mentoring and giving feedback to dozens of new speakers (here’s a review of the event by Havi Hoffman).

In terms of the Smashing Universe, we spent quite a bit of time revising our workflows and streamlining our processes for conferences, books, and the Smashing Membership. With fantastic event management skills of Mariona Ciller, Amanda Tamny Annandale and Charis Rooda, we’ve run 5 conferences this year: in London, San Francisco, Toronto, Freiburg and New York.

For the first time, we experimented with a ’no-slides’ format in Toronto (every speaker presented “live” on stage in front of a large screen shwoing how they build and design — with performance and accessibility audits to live designing/coding/sketching sessions on stage. In fact, that’s the format we are going to continue exploring in 2019.

Editor’s Note: If this format sounds interesting to you, you can watch all of the SmashingConf talks on Vimeo.

Nadieh Bremer presenting at SmashingConf Toronto (watch on Vimeo)

After many months of work, we finally published “Smashing Book 6” and “Form Design Patterns” by Adam Silver, but quite a bit of time was spent on the next upcoming books that will be published in the next years. For the Membership, we were able to secure Scott Whitehead and Bruce Lawson to help evolve the Membership program.

On a more personal level, I will vividly remember vacations to Morocco (Marrakesh, Fez and the Sahara desert trip) and Sardinia (Northern part) earlier this year. Also, on a sad note, I’ve moved out from Vilnius, Lithuania, where I’ve resided for the past 3 years.

Overall, I see 2018 as an important “transitional” year which took a lot of time, effort, and hard work. It feels like it’s been a transitional year between how things used to be and what’s coming up next. With this in mind, I couldn’t be more excited to see what 2019 will bring us! Expect a few new books coming up, Smashing Magazine Print edition, four Smashing Conferences (San Francisco, Toronto, Freiburg, New York) and many wonderful Smashing TV sessions!

Markus Seyfferth: Never Stand Still

Change happens everywhere and all the time — in all organizations, agencies, and businesses. If you don’t thrive change on your own, then there comes a time when change takes place on its own and things get out of control.

Looking back on the year 2018, we’ve undergone changes to even better fit the needs of our readers. We published the Smashing Book 6 named “New Frontiers in Web Design”, a book packed into the probably the most beautiful cover that we have had designed so far. It’s a book that sheds light on all kinds of upcoming challenges that await web designers and developers in the near future.


A photo of the Smashing Book 6
Smashing Book 6 (photo credit Marc Thiele)

We also published Form Design Patterns, a book that focusses on building all sorts of accessible and resilient web forms, and how to make them pretty (thanks to progressive enhancement) — a book that I personally learned a lot from. We’ve also started working on two new books that we’ll be publishing early next year: “Art Direction on the Web” by Andy Clarke, and “Inclusive Components” by Heydon Pickering. I am eagerly looking forward to holding both of them in my hands!

At the end of last year, we did something that we usually wouldn’t do because it would be too much of a risk. We launched a fully redesigned site: we migrated the entire magazine, the Job Board, and our Smashing Shop onto a new platform, and also launched our Membership initiative to reduce advertising on the site and to make Smashing more independent from ads in the long run. All of this took place at the same time. Was it worth it? A definite “Yes!” We’ve seen a noticeable uptrend in our analytics and many positive outcomes. At around mid-2018, we had already crossed the 1,000 members mark, and we look forward to breaking the next big mark in the next year (always with the long-term goal of getting fully independent within the next three years)!

That’s right; Smashing Membership continues to evolve. In the upcoming months, we’ll be introducing a new print magazine for our Members — something that is both visually appealing and also most useful to read. Rachel will be building the print magazine mostly with print.css, so I’m really looking forward to seeing how this will turn out and whether we can reuse some of it for our upcoming books!

And that’s not the only sort of change that is still ongoing at Smashing. We also tried a new live coding and design conference format at this year’s SmashingConf in Toronto; we thought that the old format had gotten a bit too much of the same, something that makes SmashingConf a bit too similar with what others already do. After all, we want to run conferences that contain content that we ourselves find most useful and interesting, and the new live format brings precisely that! It did take quite a bit of a risk though, and we’re thrilled that it turned out to be a tremendous success! So we are going to double down with this new format in the next year.

Last but not least, we also moved our smashingconf.com site to Netlify just recently, but that happened mostly in the background, so if no one really noticed the change, I guess that’s a good thing.

Yes, 2018 was a year full of transitions, but I guess you never can afford to stand still anyway? 😉

Bruce Lawson: Joining The Team

Before the end of the first year of Smashing Membership, we reached a thousand members — thank you so much, everyone! Those extra-special people who were with us for the whole year received a little thank you in the post.

I joined Scott in October, which allowed us to increase the number of Smashing TV webinars (which are free to Members and Smashing Members, of course). We’ve had sessions on coding Machine Learning, Designing with Ethics, the State of the Web in South-East Asia, and statistical techniques for collecting user data without compromising privacy. (All are recorded and available to members, if you have FOMO!)

When we set up Membership, we promised that it would be an inclusive place where lesser-heard voices (in addition to big names) would be beamed straight to your living room/ home office/ sauna over Smashing TV. While we’ve been speaking at other non-Smashing events, we’ve watched other sessions from lesser-known talents in our industry. With only $5 to $9 a month), your Membership subscription allows us to bring you even greater content, pay all our contributors fairly, and reduce advertising on the site.

Next year, we’ll be increasing the number of webinars again. Lined up is a course on how to make Progressive Web Apps, Internationalization, Semantic HTML, Houdini, as well as a monthly show hosted by me and Vitaly with industry guests. We sincerely hope you’ll join us!

Amanda Annandale: A Year Of Firsts

2018 was a year of firsts, new cities, new attendees, new speakers, and even a couple new formats. We had more than a few challenges in store, but if you have any experience with the Smashing Team, you’ll know that we thrive on challenges.

We started the year in London (our first time in the capital city and the first time in England in a couple of years). The sold-out conference took place in LSO’s St. Luke’s Church, and bathed in sunlight. This performance-based conference brought in a new crowd of attendees and speakers — all discussing why Performance Matters, the common pitfalls, and the tips and tricks for improving the day to day user experience. With Una Kravets and Patrick Hamman as MCs, the experience was new and empowering.

In April, the Smashing team headed back to San Francisco. The weather was wonderful as we returned to the bay, with 14 speakers, 8 workshops, and nearly 500 attendees. Held at the Palace of Fine Arts, Mina Markham walked us through the process of redesigning Slack, while Joe Leech broke down the process of “Designing Powerful User Experiences With Psychology.” We toured the area, competed with each other at the arcade, and came together to find new ways to solve new processes and challenges.


A photo of Amanda at a desk at the conference
Backstage at Smashing Conf Toronto (Photo credit: Marc Thiele)

A couple of months later, SmashingConf experimented with its boldest change: no slides! All of the presenters, from Aaron Draplin to Rachel Andrew, tossed out their ‘normal’ presentation format and showed the attendees how they work. The experience was enlightening, showing how similar we all are in our work processes in some ways, while approaching things from an entirely different angle in others. In fact, we loved it so much that we’ve decided 2019 should be the year of No Slides!

The end of the summer is when Smashing goes home. Set on the foothills of the Black Forest, at the infamous Markethall, SmashingConf came back to Freiburg, Germany with 14 speakers. Chui Chui Tan spoke about Designing for Global Audiences while Josh Clark talked about Design in the Era of the Algorithm. In addition, we had a new experience adding community lightning talks to our program. No matter what changes though, there’s nothing like hosting SmashingConf Freiburg and bringing people to our home.

And finally, we ended the year in the city that never sleeps — and lived up to the name! In New York City, we had 14 speakers, 8 workshops, a packed speaker panel, a couple of retro parties, and events that kept everyone busy for four days. Smashing challenged the sold-out audience with an engaging group of speakers from John Maeda to Debbie Millman and Sara Soueidan. No matter how many times we go back, the experiences always change us in a way.

But, then again, that’s how the Smashing team always feels at the end of a season: challenged, moved, and driven. We’ve learned from over 30 speakers, met over 1500 attendees, flown to 5 cities, eaten lots of incredible food, and had countless wonderful experiences. Now, the team is ready to create, improve, and progress to see what 2019 has in store for us!

Marc Thiele: Moving Closer Together

If you ask me, I think that this year went by really quickly. When I look back, I see five Smashing conferences, which took place in London, San Francisco, Toronto, Freiburg and New York, as well as many improvements which we’ve achieved in the background.

Editor’s note: Marc has taken photos of many of our conferences, you can find the albums on his Flickr account.

When I say background, I mean that maybe readers, attendees or folks who visit Smashing Magazine don’t even recognize the work we do behind the curtains. Of course, there are final products that are presented in the articles published on Smashing Magazine, the Smashing Books, or projects that have been brought to your attention via Smashing TV or while attending a Smashing conference or workshops, but there is a small team of people who work hard to continue improving workflows and experiences for our cherished customers. What you often don’t see is see the messy middle and the bumpy journey we are on — from talking about a new idea to the final product. There actually is a lot of work, a lot of failure, and many discussions and conversations involved.

From the end of April onwards, we had many meetings and conversations to see where we can improve the work that we do. Defining clear roles and tasks, checking how the many different parts of the Smashing Universe can grow closer together, and also looking for new, exciting ideas to bring to life. There are also many new faces on board of the Smashing boat — fresh energy to move forward — and I am very much looking forward to seeing the results of their passion and input. Expect the quality you know from the magazine and the events and an even better Smashing Membership, Smashing TV, and maybe the one or other new idea.

So, when I personally speak about 2018, I tend to say that this year was not too good and felt strange for a reason that I can’t really grab and describe. Perhaps it is the overall mood and spirit that comes from what you see when you turn on the news, read the newspaper in the morning or talk to your neighbor? All I know is that it is important to stay positive and have a positive look into the future. I ran three very successful beyond tellerrand shows in Munich, Dusseldorf and Berlin, and I’ve seen the success we had with all the Smashing conferences and the improvements we’ve accomplished for the overall Smashing experience.

My wish for the upcoming new year: let’s meet — even more. Let’s share ideas and what we’ve learned. Let’s not just meet on the web, but in real life. It is wonderful to teach and share and to see other people taking what they’ve learned from you and take it further to create, inspire and teach others with it. One more thing that also is important: Stay curious and ask questions. Never fear to ask a question as you “might look stupid asking.” If you have a question, then it’s stupid not to ask.

With this, I wish everyone a wonderful journey over to 2019 and I am looking forward to meeting you in 2019!

Alma Hoffmann: Reflections

Working at Smashing Magazine has been a very rewarding experience. Each time one of the articles I have edited gets published, I think I am happier than the authors.

One article, in particular, that was very meaningful to me was written by Trine Falbe and titled “Ethical Design The Practical Getting-Started Guide.” We all talk about ethical design, but not often we are provided with a way to get started. It is a good article to reflect upon as the current year ends and the new starts.

Thank you, Smashing, for keeping me around!

A Truly Smashing Year

Reading all of this certainly makes me proud to be part of the Smashing team. At the heart of everything Smashing, is an absolute focus on you, our readers, members, and conference attendees. We hope that the things we do demonstrate that, and we are always happy to listen and to learn when we get it wrong!

I’m excited for the things we will be sharing in 2019, and along with all of the team I am always happy to hear your feedback. What can we do better? What do you want to learn? How can we help? We will be opening up a survey for some more formal feedback early in 2019, but our door (or email inbox at least) is always open!

Smashing Editorial
(il)


Source: Smashing Magazine

New Year, New Beginnings (January 2019 Wallpapers Edition)

New Year, New Beginnings (January 2019 Wallpapers Edition)

New Year, New Beginnings (January 2019 Wallpapers Edition)

Cosima Mielke

2018-12-31T13:30:00+01:00
2018-12-31T13:41:33+00:00

Maybe you’ve already started into the new year when you read this, maybe you’re still waiting for the big countdown to begin. No matter what: Let’s welcome 2019 with a fresh wallpaper!

To give you a little inspiration boost, artists and designers from across the globe once again tickled their creativity and designed unique wallpapers for you to indulge in. All of them come in versions with and without a calendar for January 2019 and can be downloaded for free — just like every month since more than nine years already. At the end of this post, we also compiled some January favorites from past years that are too good not to share. Have an exciting new year!

Further Reading on SmashingMag:

Please note that:

  • All images can be clicked on and lead to the preview of the wallpaper,
  • You can feature your work in our magazine by taking part in our Desktop Wallpaper Calendar series. We are regularly looking for creative designers and artists to be featured on Smashing Magazine. Are you one of them?

Let The Magic Begin

“When the noisy holidays stay behind us, and everything calms down to a peaceful setting, it is a perfect moment for the magic to step in and start making our wishes, hopes, and decisions come true. Happy January, everyone!” — Designed by PopArt Web Design from Serbia.

Let the Magic Begin

New Year

“The dawn of January the 1st of 2019 is the beginning of a new year which gives dreams, hopes and a lot more to billions of people around the world.” — Designed by Sweans Technologies Ltd. from London.

NEW YEAR

A New Beginning

“I wanted to do a lettering-based wallpaper because I love lettering. I chose January because for a lot of people the new year is perceived as a new beginning and I wish to make them feel as positive about it as possible! The ideia is to make them feel like the new year is (just) the start of something really great.” — Designed by Carolina Sequeira from Portugal.

A New Beginning

Intense Winter

“Winter brings both Christmas & New Year together. A season which provides time for comfort, food, warmth, and touch of a friendly hand and for a talk beside the fire.” — Designed by Call Taxi Software from India.

Intense Winter

New Year, New Chances

“The climate is changing very fast. 2019 is a new chance to save the earth, the people and the animals who suffer from global warming.” — Designed by Melissa Bogemans from Belgium.

New year, new chances

A Cold But Happy 2019

“January is a cold but cozy month so i tried to make my illustrations in cold and cozy colors. Blue and white as the cold colors and red darkblue as the cozy colors. I made some small details like reindeers, clouds snowflakes and trees to make it look better.” — Designed by Vince Teckmans from Belgium.

A cold but happy 2019

Cold… Penguins!

“The new year is here! We waited for it like penguins. We look at the snow and enjoy with it!” — Designed by Veronica Valenzuela from Spain.

Cold penguins

Hidden Gem

“Kingfishers are called ‘ijsvogels’ (ice-birds) in Dutch. Not because they like winter cold, but because of the intense blue and teal colors…” — Designed by Franke Margrete from the Netherlands.

Hidden Gem

Snowman

Designed by Ricardo Gimenes from Sweden.

Snowman

Freezy Hope For 2019

“I took this photo while walking around the city where I live. It’s located in the Vosges, France. It was cold but without snow. White color is coming from freezy touchs of the fog remaining on everything. I found it amazing. White is a color for hope. Let’s have a pleasant year 2019” — Designed by Philippe Brouard from France

Freezy hope for 2019

Oldies But Goodies

The past New Year’s editions have brought forth some timeless wallpaper goodies that work equally well in 2019. Please note that they don’t come with a calendar. May we present…

Open The Doors Of The New Year

“January is the first month of the year and usually the coldest winter month in the Northern hemisphere. The name of the month of January comes from ‘ianua’, the Latin word for door, so this month denotes the door to the new year and a new beginning. Let’s open the doors of the new year together and hope it will be the best so far!” — Designed by PopArt Studio from Serbia.

Open the Doors of the New Year

Start Somewhere

“If we wait until we’re ready, we’ll be waiting for the rest of our lives. Start today – somewhere, anywhere.” — Designed by Shawna Armstrong from the United States.

Start Somewhere

Winter Leaves

Designed by Nathalie Ouederni from France.

Winter Leaves

Boom!

Designed by Elise Vanoorbeek from Belgium.

Boom.

January Fish

“My fish tank at home inspired me to make a wallpaper with a fish :)” — Designed by Arno De Decker from Belgium.

January Fish

Angel In Snow

Designed by Brainer from Ukraine.

Angel in Snow!

Happy Hot Tea Month

“You wake me up to a beautiful day; lift my spirit when I’m feeling blue. When I’m home you relieve me of the long day’s stress. You help me have a good time with my loved ones; give me company when I’m all alone. You’re none other than my favourite cup of hot tea.” — Designed by Acodez IT Solutions from India.

Happy Hot Tea Month!

Dare To Be You

“The new year brings new opportunities for each of us to become our true selves. I think that no matter what you are — like this little monster — you should dare to be the true you without caring what others may think. Happy New Year!” — Designed by Maria Keller from Mexico.

Dare To Be You

White Mountains

“In Central Europe, we’ve had a very warm beginning of winter. I hope there will be lots of powder for snowboarding soon. I’d love to see the French Alps again as white as in 2015 when I took this photo.” — Designed by Annika Oeser from Germany.

White Mountains

Winter Getaway

“What could be better, than a change of scene for a week? Even if you are too busy, just think about it.” — Designed by Igor Izhik from Canada.

Winter Getaway

Be Awesome Today

“A little daily motivation to keep your cool during the month of January.” — Designed by Amalia Van Bloom from the United States.

be awesome today

Japanese New Year

Designed by Evacomics from Singapore.

Japanese New Year

A New Start

“The new year brings hope, festivity, lots and lots of resolutions, and many more goals that need to be achieved. This wallpaper is based on the idea of ‘A New Start’.” — Designed by Damn Perfect from India.

A New Start

The Way To Get Started

“January is all about renewing efforts and making plans, but sometimes we need little reminders that plans don’t matter if you don’t do anything about them. Initially, I was inspired by the idea of a fresh sheet of paper, which became the background for some great words from Walt Disney.” — Designed by Resa Barillas from the United States.

The Way To Get Started

Three Wise Men Of The East

“In Belgium remember the Three Wise Men of the East is a tradition. It involves children going from door to door, dressed up as the three Wise Men. They sing a little song, in exchange for sweets and/or money. The design is very minimalistic and ‘flat’. I hope you like it :)” — Designed by Jeroen Bartels from Belgium.

Three Wise Men of the East

Rest Up For The New Year

“I was browsing for themes when I found this “Festival of Sleep” that takes place on the 3rd, and I’m a big fan of sleep… Especially in these cold months after the holiday craziness, it’s nice to get cozy and take a nice nap.” — Designed by Dorothy Timmer from Central Florida, USA.

Rest Up For The New Year

Hello Summer In Australia

Designed by Tazi Designs from Australia.

Hello Summer in Australia!

Join In Next Month!

Please note that we respect and carefully consider the ideas and motivation behind each and every artist’s work. This is why we give all artists the full freedom to explore their creativity and express emotions and experience throughout their works. This is also why the themes of the wallpapers weren’t anyhow influenced by us, but rather designed from scratch by the artists themselves.

Thank you to all designers for their participation. Join in next month!

Smashing Editorial
(il)


Source: Smashing Magazine

Will PWAs Replace Native Mobile Apps?

Will PWAs Replace Native Mobile Apps?

Will PWAs Replace Native Mobile Apps?

Suzanne Scacca

2018-12-28T12:30:52+01:00
2018-12-28T11:38:39+00:00

A developer friend of mine has decided to build a progressive web app for his new company. When I asked why he opted for a PWA instead of a native app, he said:

“Because the PWA is the future of the web.”

I thought that was an interesting sentiment. Until he mentioned it, I was of a similar mindset as Aaron Gustafson when he discussed the battle between the native app and PWA. In other words, I thought it really just came down to choice; not whether one was better than the other.

Now that the idea has been planted, though, I can’t help but notice a bunch of people proclaiming their support for the PWA over the native app. Not only that, many of them have gone as far as to say that the PWA will replace the native app entirely.

I’d like to see if that argument holds any water.

An Extensive Guide To PWAs

Progressive Web Applications are more of a methodology that involves a combination of technologies to make powerful web applications. Tell me more about PWAs →

Will PWAs Replace Native Apps?

I’m going to go ahead and answer that question right now:

“Yes, but not for everyone.”

Here’s the way I see it:

The mobile web has definitely improved from where it was just a couple years ago. It’s very rare to run into a website that isn’t 100% responsive in design. That said, I don’t think many mobile websites are 100% mobile-first in design (which I recently hinted at when talking about ditching design elements instead of acquiring more in 2019).

I think for an experience to be truly mobile-first, it would need to be faster and have an app shell. Which is exactly what a PWA offers.

While native apps may provide a superior experience (mostly) to other mobile experiences, I just don’t see a valid reason to spend that amount of money and time to build and manage one… unless your app sits in the top 20 of your category in an app store.

Let me break down the logic I used to come to this decision.

Reason #1: Mobile Web Is Lagging

comScore’s Global Digital Future in Focus report from 2018 makes this point painfully clear:


comScore 2018 mobile web vs. app
comScore 2018 report shows use of mobile web vs. mobile apps (Image source: comScore) (Large preview)

That said, I don’t believe native apps will make mobile websites disappear. I also don’t believe this point counteracts the argument I’m attempting to make today. If this data demonstrates anything, it’s that mobile users strongly prefer the experience of interacting with a digital property through an app interface.

Web developers recognize this preference as well, as this survey from JAXenter demonstrates:


JAXenter PWA survey
JAXenter developer survey about PWAs (Image source: JAXenter) (Large preview)

So, although the mobile web browser has proven to be the less preferred interface through which someone views a website, I don’t think that’ll be the case for much longer as more businesses build PWAs.

The PWA takes all of the things users love about native apps — the app shell, offline access, telephony features, an always-present navigation bar and so on — and gives users a more convenient means for experiencing them.

Look at a brand like Crabtree & Evelyn:


Crabtree & Evelyn PWA
Crabtree & Evelyn PWA example (Image source: Crabtree & Evelyn) (Large preview)

This major retailer has the funds to build a native app counterpart to its website, but it’s chosen not to go that route. Instead, the progressive web app experience gives mobile users the convenience of browsing the online store and making a purchase without having to leave the browser.

Or, if they’re frequent users, they can add this PWA to their home screen and treat it as they would any other app (but more on that later).

Now, let’s look at an example of a PWA that, again, has opted not to go the route of the native app. Instead, Infobae has created a PWA that beats the mobile web experience:


Infobae PWA
Infobae PWA example (Image source: Infobae) (Large preview)

According to Google data, the Infobae PWA has:

  • A 5% bounce rate. The mobile web was 51%.
  • Sessions that are 230% longer than they were on mobile web.
  • Over three times more pages viewed per session than the mobile web.

So, if you’re worried that the PWA won’t cut it as an alternative to the mobile web, you can stop right there. There are clear benefits to building a PWA.

Reason #2: Native App Stores Are Overflowing

Native apps have a lot of competition in the native app stores — many of which are heavy hitters that mobile users are all too familiar with. If your intention is to launch an app in an already congested space, is the app store really the best place for it?

comScore’s report breaks down the top 5 apps based on reach:


comScore top 5 apps
comScore data on the top 5 apps by reach in 2018 (Image source: comScore) (Large preview)

As you can see, the top 5 apps tend to be dominated by the same mobile apps, no matter what part of the world mobile users are located in.

What you might be thinking is, “But what if my app has a unique edge? Isn’t that enough to dominate our niche?”

I could see that, especially if your app is targeted to region-specific mobile users. Then again, you have to consider what sort of app types perform well with mobile app users.

comScore breaks down this point:


comScore total app minute share
comScore data on share of total app minutes (Image source: comScore) (Large preview)

Roughly 70% to 80% of all time spent in mobile apps goes to four categories:

  • Entertainment (like YouTube);
  • Social media (like Facebook);
  • Instant messaging (like Whatsapp);
  • Games (like Fortnite).

If your app concept doesn’t fall into one of those categories, is it worth all that work to place your app in the app store? While I recognize that those aren’t the only kinds of apps that succeed, I just think it would be a risky and expensive gamble to make, especially if your client’s business is brand new. Even then, there are so many cases of well-known entities that have opted not to compete in app stores, despite having a large enough audience or customer base to do so.

West Elm is a great example of a retailer who’s done this:


West Elm PWA
The West Elm PWA (Image source: West Elm) (Large preview)

If you look in the app stores, you’ll find that West Elm has developed two native apps. One is for registries. This makes sense as a mobile app could be conducive to tagging and tracking registry items. It also has one for the West Elm card. If someone is a frequent enough shopper, this type of app might make sense as well.

That said, neither of these native apps is popular with users (at least not in terms of quantity of reviews). So, it was a smart and economical move by West Elm to keep its main shopping interface in the PWA.

Reason #3: PWAs Rank In Search

On a related note, progressive web apps come with the added benefit of ranking in search engines. There are a few reasons why you and your clients should be overjoyed by this:

  1. Your app’s rank in search is contingent upon the SEO work you put into it. If you’re already doing this with your website, this should be easy!
  2. You don’t have to worry about a brand new app getting buried in app store search. Or easily dismissed because of a lack of ratings.
  3. Because a PWA can live in mobile users’ browsers as well as from a button on the home screen, it needs to have a link. And links make for much easier sharing with friends/family/colleagues than telling them the name of an app, hoping they can find it in the store on their own.

Bottom line: if you can give users a tangible link to your app, you can drastically reduce the friction often caused by having one that only exists in the app store.

Plus, I think the searchability aspect is an important one to consider when you think about how people use your app. Take micro-moments, for example.

When a consumer is inspired to:

  • Research something of interest,
  • Go somewhere,
  • Make a purchase,
  • Or do something…

Instead of opening a data-hogging application on their device, they’ll open their search browser and type or speak their query. It’s what we’re all trained to do as consumers. Have a question? Need something? Want help choosing a restaurant? Go to Google.

If your website or app provides an answer to those kinds of questions, you don’t want it hidden away in app stores. You also don’t want to give them a mobile website that offers an option to “Download the App”. You’re only creating extra work for them.

A PWA enables you to place your app directly in search results and to get your users the instant answers they require.

I think this is why e-commerce businesses have especially gravitated towards PWAs, like HobbyCraft.


HobbyCraft PWA
HobbyCraft PWA example (Image source: HobbyCraft) (Large preview)

As you can see here, HobbyCraft is a niche retailer that sells craft supplies out of the UK. It wouldn’t make much sense to put something like this in the app stores — especially when the PWA interface works well enough as it is.

Lancome is another e-tailer that’s made the conscious decision to forego the native app and keep the mobile shopping experience in a PWA format.


Lancome PWA
Lancome e-commerce PWA example (Image source: Lancome) (Large preview)

One important design element I would point you to in both these examples is the Stores icon located in the top navigation bar. For businesses with brick-and-mortar counterparts, there’s no reason to keep your app out of local search in Google.

If you design your PWA correctly, you can make it show up in relevant location-based queries. And if you present an interface that’s reminiscent of a native app — and just as secure as one (since PWAs require HTTPS) — you can compel more mobile users to make a purchase on the spot.

Reason #4: Native Apps Struggle With Retention

For app types that have a hook that compels users to spend time inside a native app and spend money to enjoy the experience further, that’s great. When you find that perfect fit, there’s good money to be made from having a native app. It’s simply a matter of having people willing to commit to the download.

However, as we recently saw, most native apps struggle to retain users.

It doesn’t matter how many initial downloads you get. If mobile users don’t return to the app to engage with your content, purchase subscriptions or upgrades or click on ads, consider it a wasted investment. Unfortunately, that’s the case with a lot of them.

PWAs, on the other hand, don’t require the lofty commitment of having to download an app to one’s device. Heck, users don’t even have to save the PWA to their home screens, if they don’t want to. It’s an overall more convenient experience.

Nevertheless, you may want to urge users to save it for instant access in the future, as The Weather Channel does:


The Weather Channel PWA message
The Weather Channel asks users to save PWA to device. (Image source: The Weather Channel) (Large preview)

Really, what it boils down to is the type of app you’ve built.

The Weather Channel, for instance, provides a service that mobile users will want to use on a daily basis. They could install a native app from the app store with up-to-date weather forecasting, but that app would likely chew through data and battery power a lot more quickly than the browser-based PWA will.

There are other business types that should consider using a PWA for this reason. Think about an online magazine like Forbes.


Forbes PWA add to homescreen
Users can add the Forbes PWA to their home screen just like a native app. (Image source: Forbes) (Large preview)

Highly specialized publications would do really well to develop PWAs for their daily readers.

Again, it provides a much lighter-weight experience for their phones. Plus, PWAs give users offline access, so they can get access to content no matter where they are or how limited their access may be to the Internet. And the home screen presence (if they choose to put the button there), provides a nice little shortcut around the mobile web browser.

Reason #5: PWAs Can Generate More Revenue

With the exception of in-app advertising, Apple and Google take a sizable cut from any sales you make through a native app. This includes paid downloads, in-app purchases or upgrades and subscription fees. At one point, these fees were as high as 30% per sale.

When you’re hoping to spend money on design tweaks, much-needed development updates and promotional advertising, that’s the last thing you want to hear. In other words, a significant portion of the money that starts to trickle in from your native app goes straight into the pockets of app store owners. That doesn’t seem right, especially if you have to pay for app store ads in order to gain visibility within them.

PWAs don’t come with fees to pay-to-play, which means all revenue generated from them go directly to you (or whoever the owner of the business is). This is especially nice if you have an app concept like a local newspaper (such as The Billings Gazette) that probably deals in smaller profit margins to begin with.


Billings Gazette PWA
The Billings Gazette PWA monetization example (Image source: The Billings Gazette) (Large preview)

That’s not the only way you can make more money from PWAs than native apps either.

To start, they’re significantly easier to build than native apps. Plus, managing them after launch requires less of a time commitment and resources from you. Yes, it still needs to be updated and maintained — just like anything else on the web — but you don’t have to deal with the obstacles that come with apps in the app store.

For example, you only have to build one progressive web app. You don’t have to create separate ones to match the guidelines for different mobile devices.

Updates are easier, too, especially if your PWA is based off of a WordPress website. You push an update through the pipeline and it shows up immediately in the live PWA. There’s no need to push updates to the app store admins and wait for their approvals. Everything happens in real time, which means getting new features and money-making initiatives out to the public more quickly.

This is helpful in the case of PWAs like Twitter Lite.


Twitter Lite PWA
The Twitter Lite PWA can stay on the cutting edge in real time (Image source: Twitter) (Large preview)

When going up against a plethora of social media giants that dominate the app stores, having the ability to keep your app updated in real time can serve as a strong competitive edge. This is in addition to all of the other benefits that come from developing your app in a progressive web format.

This is what happened when Twitter put out its PWA.

As this case study from Google shows, Twitter took an incremental approach to optimizing its PWA. As such, they’ve been able to introduce huge improvements to the user experience without much detection from the end user. Their only response to the updates, in fact, has been greater usage of the PWA.

The PWA Is The Future For (Most Of) The Web

Visibility and searchability are known problems with native mobile apps. User retainment is another. And they’re just not sustainable unless you have an idea that’s inherently meant for a native interface that’s sure to bring in money. Mobile games are one example of this. I’d argue that dating apps are another. I used to think social media fell into that category, but Twitter has since proven me wrong.

Based on what I’m seeing online and from what I’ve heard from developer friends and colleagues, I do believe the future is in the PWA.

I think app stores will slowly quiet down as developers realize there are many more benefits to putting a small- to medium-sized company’s app into a progressive web form. The major players will stay put, and companies that have outgrown the bounds of the PWA may eventually move over. But, otherwise, most apps will end up in the progressive web format.

As this trend towards the PWA continues to grow, consumers will become more accustomed to encountering it in search and know that this user-friendly interface is accessible right from their browser. In turn, they’ll only go to the app stores for the kinds of apps that belong there, i.e. messaging, games, entertainment, and some social media. This will create a clearer division between online search and app store search, and further help to improve the overall user experience online.

Smashing Editorial
(ra, yk, il)


Source: Smashing Magazine

Common CSS Issues For Front-End Projects

Common CSS Issues For Front-End Projects

Common CSS Issues For Front-End Projects

Ahmad Shadeed

2018-12-27T13:30:11+01:00
2018-12-27T14:17:22+00:00

When implementing a user interface in a browser, it’s good to minimize those differences and issues wherever you can, so that the UI is predictable. Keeping track of all of those differences is hard, so I’ve put together a list of common issues, with their solutions, as a handy reference guide for when you’re working on a new project.

Let’s begin.

1. Reset The Backgrounds Of button And input Elements

When adding a button, reset its background, or else it will look different across browsers. In the example below, the same button is shown in Chrome and in Safari. The latter adds a default gray background.



(Large preview)

Resetting the background will solve this issue:

button {
  appearance: none;
  background: transparent;
  /* Other styles */
}

See the Pen Button and Inputs by Ahmad Shadeed (@shadeed) on CodePen.

2. Overflow: scroll vs. auto

To limit the height of an element and allow the user to scroll within it, add overflow: scroll-y. This will look good in Chrome on macOS. However, on Chrome Windows, the scroll bar is always there (even if the content is short). This is because scroll-y will show a scroll bar regardless of the content, whereas overflow: auto will show a scroll bar only when needed.



Left: Chrome on macOS. Right: Chrome on Windows. (Large preview)
.element {
    height: 300px;
    overflow-y: auto;
}

See the Pen overflow-y by Ahmad Shadeed (@shadeed) on CodePen.

3. Add flex-wrap

Make an element behave as a flex container simply by adding display: flex. However, when the screen size shrinks, the browser will display a horizontal scroll bar in case flex-wrap is not added.

<div class="wrapper">
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
</div>
.wrapper {
  display: flex;
}

.item {
  flex: 0 0 120px;
  height: 100px;
}

The example above will work great on big screens. On mobile, the browser will show a horizontal scroll bar.



Left: A horizontal scroll bar is shown, and the items aren’t wrapped. Right: The items are wrapped onto two rows. (Large preview)

The solution is quite easy. The wrapper should know that when space is not available, it should wrap the items.

.wrapper {
    display: flex;
    flex-wrap: wrap;
}

See the Pen flex-wrap by Ahmad Shadeed (@shadeed) on CodePen.

4. Don’t Use justify-content: space-between When The Number Of Flex Items Is Dynamic

When justify-content: space-between is applied to a flex container, it will distribute the elements and leave an equal amount of space between them. Our example has eight card items, and they look good. What if, for some reason, the number of items was seven? The second row of elements would look different than the first one.



The wrapper with eight items. (Large preview)


The wrapper with seven items. (Large preview)

See the Pen justify-content by Ahmad Shadeed (@shadeed) on CodePen.

In this case, using CSS grid would be more suitable.

When an article is being viewed on a mobile screen, a long word or inline link might cause a horizontal scroll bar to appear. Using CSS’ word-break will prevent that from happening.

Large preview
.article-content p {
    word-break: break-all;
}   


(Large preview)

Check out CSS-Tricks for the details.

6. Transparent Gradients

When adding gradient with a transparent start and end point, it will look black-ish in Safari. That’s because Safari doesn’t recognize the keyword transparent. By substituting it with rgba(0, 0, 0, 0), it will work as expected. Note the below screenshot:



Top: Chrome 70. Bottom: Safari 12. (Large preview)
.section-hero {
  background: linear-gradient(transparent, #d7e0ef), #527ee0;
  /*Other styles*/
}

This should instead be:

.section-hero {
  background: linear-gradient(rgba(0, 0, 0,0), #d7e0ef), #527ee0;
  /*Other styles*/
}

7. The Misconception About The Difference Between auto-fit And auto-fill In CSS Grid

In CSS grid, the repeat function can create a responsive column layout without requiring the use of media queries. To achieve that, use either auto-fill or auto-fit.

.wrapper {
    grid-template-columns: repeat(auto-fill, minmax(100px, 1fr));
}


(Large preview)

In short, auto-fill will arrange the columns without expanding their widths, whereas auto-fit will collapse them to zero width but only if you have empty columns. Sara Soueidan has written an excellent article on the topic.

8. Fixing Elements To The Top Of The Screen When The Viewport Is Not Tall Enough

If you fix an element to the top of the screen, what happens if the viewport is not tall enough? Simple: It will take up screen space, and, as a result, the vertical area available for the user to browse the website will be small and uncomfortable, which will detract from the experience.

@media (min-height: 500px) {
    .site-header {
        position: sticky;
        top: 0;
        /*other styles*/
    }
}

In the snippet above, we’re telling the browser to fix the header to the top only if the viewport’s height is equal to or greater than 500 pixels.

Also important: When you use position: sticky, it won’t work unless you specify the top property.

Large preview

See the Pen Vertical media queries: Fixed Header by Ahmad Shadeed (@shadeed) on CodePen.

9. Setting max-width For Images

When adding an image, define max-width: 100%, so that the image resizes when the screen is small. Otherwise, the browser will show a horizontal scroll bar.

img {
    max-width: 100%;
}

10. Using CSS Grid To Define main And aside Elements

CSS grid can be used to define the main and aside sections of a layout, which is a perfect use for grid. As a result, the aside section’s height will be equal to that of the main element, even if it’s empty.

To fix this, align the aside element to the start of its parent, so that its height doesn’t expand.

.wrapper {
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  grid-gap: 20px;
}

// align-self will tell the aside element to align itself with the start of its parent.
aside {
  grid-column: 1 / 4;
  grid-row: 1;
  align-self: start;
}

main {
  grid-column: 4 / 13;
}


(Large preview)

See the Pen main and aside by Ahmad Shadeed (@shadeed) on CodePen.

11. Adding fill To An SVG

Sometimes, while working with SVGs, fill won’t work as expected if the fill attribute has been added inline in the SVG. To solve this, either to remove the fill attribute from the SVG itself or override fill: color.

Take this example:

.some-icon {
    fill: #137cbf;
}

This won’t work if the SVG has an inline fill. It should be this instead:

.some-icon path {
    fill: #137cbf;
}

12. Working With Pseudo-Elements

I love to use pseudo-elements whenever I can. They provide us with a way to create fake elements, mostly for decorative purposes, without adding them to the HTML.

When working with them, the author might forget to do one of the following:

  • add the content: "" property,
  • set the width and height without defining the display property for it.

In the example below, we have a title with a badge as a pseudo-element. The content: "" property should be added. Also, the element should have display: inline-block set in order for the width and height to work as expected.

Large preview

13. The Weird Space When Using display: inline-block

Setting two or more elements to display: inline-block or display: inline will create a tiny space between each one. The space is added because the browser is interpreting the elements as words, and so it’s adding a character space between each one.

In the example below, each item has a space of 8px on the right side, but the tiny space caused by using display: inline-block is making it 12px, which is not the desired result.

li:not(:last-child) {
  margin-right: 8px;
}


(Large preview)

A simple fix for this is to set font-size: 0 on the parent element.

ul {
    font-size: 0;
}

li {
    font-size: 16px; /*The font size should be reassigned here because it will inherit `font-size: 0` from its parent.*/
}


(Large preview)

See the Pen Inline Block Spacing by Ahmad Shadeed (@shadeed) on CodePen.

14. Add for="ID" When Assigning A Label Element To An Input

When working with form elements, make sure that all label elements have an ID assigned to them. This will make them more accessible, and when they’re clicked, the associated input will get focus.

<label for="emailAddress">Email address:</label>
<input type="email" id="emailAddress">
Large preview

15. Fonts Not Working With Interactive HTML Elements

When assigning fonts to the whole document, they won’t be applied to elements such as input, button, select and textarea. They don’t inherit by default because the browser applies the default system font to them.

To fix this, assign the font property manually:

input, button, select, textarea {
  font-family: your-awesome-font-name;
}

16. Horizontal Scroll Bar

Some elements will cause a horizontal scroll bar to appear, due to the width of those elements.

The easiest way to find the cause of this issue is to use CSS outline. Addy Osmani has shared a very handy script that can be added to the browser console to outline every element on the page.

[].forEach.call($$("*"), function(a) {
  a.style.outline =
    "1px solid #" + (~~(Math.random() * (1 << 24))).toString(16);
});


(Large preview)

17. Compressed Or Stretched Images

When you resize an image in CSS, it could be compressed or stretched if the aspect ratio is not consistent with the width and height of the image.

The solution is simple: Use CSS’ object-fit. Its functionality is similar to that of background-size: cover for background images.

img {
    object-fit: cover;
}


(Large preview)

Using object-fit won’t be the perfect solution in all cases. Some images need to appear without cropping or resizing, and some platforms force the user to upload or crop an image at a defined size. For example, Dribbble accepts thumbnails uploads at 800 by 600 pixels.

18. Add The Correct type For input.

Use the correct type for an input field. This will enhance the user experience in mobile browsers and make it more accessible to users.

Here is some HTML:

<form action="">
  <p>
    <label for="name">Full name</label>
    <input type="text" id="name">
  </p>
  <p>
    <label for="email">Email</label>
    <input type="email" id="email">
  </p>
  <p>
    <label for="phone">Phone</label>
    <input type="tel" id="phone">
  </p>
</form>

This is how each input will look once it’s focused:



(Large preview)

19. Phone Numbers In RTL Layouts

When adding a phone number like + 972-123555777 in a right-to-left layout, the plus symbol will be positioned at the end of the number. To fix that, reassign the direction of the phone number.

p {
    direction: ltr;
}


(Large preview)

Conclusion

All of the issues mentioned here are among the most common ones I’ve faced in my front-end development work. My goal is to keep a list to check regularly while working on a web project.

Do you have an issue that you always face in CSS? Let us know in the comments!

Smashing Editorial
(dm, ra, al, yk, il)


Source: Smashing Magazine

What We Wished For

What We Wished For

What We Wished For

Mat Marquis

2018-12-24T14:30:46+01:00
2018-12-24T14:26:29+00:00

I think we’re headed for trouble, though I can’t say for sure. Trouble — trouble I know. The on-ramp to it, though; I’ve only heard about that. I’ve only been doing this for ten years. I missed all the lead-up the last time around. What I can say for sure — what I know from experience — is that I’ve never had a wish made in anger come true without regretting it.

Ten years (I don’t mind saying) is a pretty long time. Back when I first truth-stretched my way into a web design internship, good ol’ Internet Explorer was already a laughingstock.

“If you notice that a piece of your content appears and disappears, and sections of the page only get half-drawn, these are good indications that an element requires a layout. […] A hasLayout fix involves nothing more than declaring a CSS property that causes an element to gain a layout, when it wouldn’t ordinarily have a layout by default.”

The Internet Explorer hasLayout Property

I hated IE. I feel like I can cop to that now. I tried not to; I really, sincerely did. I’d tell people it was fun to support, if you can believe it.

As all the other browsers got easier and easier to deal with, I attempted to convince myself that there was at least still a challenge to quirky old IE. That even became something of a point of pride: I had gotten so good at fixing obscure IE issues that I’d learned to dodge them during the course of my everyday development, leaving nothing (well, less) to dread come the big “open it up in IE and see what broke” phase.

It’s fun, in a way. Fun. That was the lie I told myself.

/* Fixes #2588: When Windows Phone 7.5 (Mango) tries
to calculate a numeric opacity for a select (including
“inherit”) without explicitly specifying an opacity on
the parent to give it context, a bug appears where
clicking elsewhere on the page after opening the select
will open the select again. */

jQuery Mobile source

I hated it. I full-on, bad-jokes-in-a-conference-talk hated IE, in every one of its incarnations. I hated it every bit as much everybody else did.

“Internet Explorer 6 has a puzzling bug involving multiple floated elements; text characters from the last of the floated elements are sometimes duplicated below the last float. … The direct cause is nothing more than ordinary HTML comments, such as, <!-- end left column -->, sandwiched between floats that come in sequence.”

Explorer 6 Duplicate Characters Bug

A waste of my goddamned time is what it was. All those hours I spent hunched over a janky virtual machine—reload, wait, throw a nonsense fix at a nonsense bug, reload, crash, open IE again, wait, double-check that caching wasn’t a factor, reload, wait, and repeat. I could have been doing so much more with my time — I could have learned so much more.

I was certain that it didn’t just hold back my work, and it didn’t just hold the web back, but it held me back, as a developer. On that second point, I guess I wasn’t entirely wrong — all the obscure IE 6-7 browser bug knowledge I accumulated is all useless now. All I have to show for it are an involuntary flinch at the word “filter,” an inscrutable preference for padding over margin, and a deep-seated but largely unfounded fear of z-index.

“…extra whitespace causes the wrong styles to be picked up if the actual class name is a substring (or superstring) of some other class name.”

IE5/Mac whitespace parsing bug

I wished it would go away. Uninstalled by a clever and widespread virus, banned by law, Microsoft finally deciding to cut their shoddy rendering engine’s losses and switching to Firefox’s rendering engine, Gecko — whatever — just make it go away. But… no. The web kept evolving and we developers beat on, boats against the current, borne back ceaselessly into the past.

Chrome came along, Firefox kept getting better, new features kept rolling out, the exciting and endless possibilities presented by the advent of responsive web design spread out before us, and also (quick aside) remember that you’ll only have a couple of days to make it all more-or-less work in old IE, so don’t get too carried away.

“IF you are using IE8, AND you are using the CSS ordered list numbering approach described above, AND the HTML that has the classes that use the counter-reset and counter-increment CSS attributes is HIDDEN when the page loads, THEN whenever that hidden HTML is displayed, ALL of the automatic numbers will be ZERO, BUT ONLY IF THE CSS :hover PSEUDO-CLASS IS USED ON THAT PAGE!”

The IE8 “hover” Bug: The Most Awesome IE Bug Ever?

It’s hard to imagine experiencing that kind of frustration nowadays, at least for us relatively-old-timers. Not to say that there isn’t an incredible amount of work involved in tuning things up cross-browser these days, too — I know all too well that there is. But it’s tough not to feel the occasional pang of, “back in my day, all we had were floats, and let me tell you about IE’s double margin bug,” when you hear about a little difference in how CSS Grid works from one browser to another.

I was wrong; I want to be clear on that point. Not wrong for being frustrated. I don’t think anyone should be blamed for being frustrated with those old browser bugs, same as I don’t think anyone should be blamed for their frustration with any aspect of web development now. No, I was wrong for the conclusion that anger brought me to: the desire to see Trident burned to the ground and the earth where it once stood salted.

I suspect that only one dramatically-ironic thing grows out of that salted earth: those same frustrations, born anew, for a new generation of web developers. When I started my career, scant few years after the browser wars, those seeds had already taken root. Because, for a time — a time before my own — we web developers cursed Netscape the same way. The weaker, buggier, inarguably worse browser. But Internet Explorer — developers loved that browser. And they wished those other browsers — the bad browsers — would just go away: uninstalled by a clever and widespread virus, banned by law, Netscape finally deciding to cut their shoddy rendering engine’s losses and switch to IE’s rendering engine, Trident — whatever — just make it go away. Those inscrutable Internet Explorer bugs didn’t happen by coincidence or negligence. They came about because Internet Explorer had won, and we loved it for winning.

See, our frustration and our anger lied to us, as they usually do. They told us that supporting those other, worse browsers didn’t just hold back our work, and didn’t just hold the web back, but it held us back, as developers. A waste of our goddamned time is what it was. So, we told ourselves that it wasn’t only for our own good, but for the good of the entire web.

We weighed IE just a little more heavily. We gave it just a little more say in our decisions. And so, holding so many chips, Microsoft played their cards accordingly — who could blame them? Everyone built websites for them first, and the others second. Their word wasn’t law, but it was certainly more than suggestion. Sure, they deviated from web standards here and there (just a little bit), but after all, wasn’t something implemented by The Biggest Browser a sort of de facto standard anyway? Besides, supporting the better, faster, easier browser was doing the web itself a service! Together with Microsoft, we were pushing the web forward! Everybody wins.

The rendering engine that powers Microsoft’s Edge browser today — EdgeHTML — is a fork of gnarly old Trident. It’s a stripped-down and vastly improved fork of Trident, for sure, but it isn’t, let’s say, universally judged on its own merit. The EdgeHTML team has always been working with a couple of disadvantages: the first was technical, in that it took a tremendous amount of time and effort to catch up with the likes of Safari, Firefox, and Chrome. The second was emotional. It was us — you and me — jaded from years of Internet Explorer, staring down a cheery blue lowercase “e” with cold disdain.

A few weeks ago, the Edge team announced that they’d soon be abandoning EdgeHTML in favor of Blink, the rendering engine that powers Chrome. With this change, the last few remaining embers of Trident will be snuffed out forever. The wish I’d shared with so many will finally be granted. Ironically timed — as it turns out — EdgeHTML was becoming a pretty solid rendering engine.

Blink is an open-source project led and governed by Google. It powers both Chrome and Opera, the latter of which similarly abandoned their home-grown rendering engine a few years ago.

By an overwhelming margin, Blink is (and will increasingly be) the way the web is experienced the world over. Blink is fast, stable, packed with modern features, and — by comparison to development for the still-evolving EdgeHTML — painless.

It may have happened too late to save us from those ancient IE bugs, but our work will be easier now that there’s one less rendering engine to support. You and I will lose a little more of our collective “but does it work cross-browser” burden. Our projects will go more smoothly, and the web will lose just a little more of what was once holding it back.

As stewards of the engine powering so very much of the web, well, Google’s word won’t be law, but certainly more than suggestion. And maybe over the course of the next few years, they’ll deviate from web standards here and there (whether intentionally or accidentally) in the tiniest of ways. But after all, isn’t something implemented by The Biggest Browser a sort of de facto standard itself? Besides, how could you argue? Favoring the better, faster, more powerful browser is doing the web itself a service, after all. Together with Google, we’ll be pushing the web forward. Everybody will win.

That is, as long as little standards deviations and tiny, nagging bugs don’t grow bigger over time — thanks to the twin forces of entropy and complacency. Unless the decisions we’ve made for the good of the web (hand-in-hand with a notoriously privacy-hostile advertising company) begin to feel a little darker, and a new bogeyman begins to take shape in our minds — unless we find that our old fears and frustrations have risen again (like a phoenix that renders a couple hundred pixels away from where it should and flickers in a weird way when you scroll).

It doesn’t take much imagination to see newer, more exciting rendering engines appearing over the next handful of years. It takes just as little imagination to see them failing due to lack of support, as we favor “the-browser-that-everyone-uses-first” by choice, and later perhaps in grudging service of “the bottom line”.

Again, though, I don’t know. I’ve never seen this happen with a rendering engine myself. I’ve just heard the whole story, and I only know first-hand how it ends. I know the ending from the ache of old psychic scars; from an involuntary flinch at some bits of code, and muscle-memory that compels me to avoid others. I know it from the jokes in conference talks that always felt a little tired, but still resonated just the same in a way I wouldn’t allow myself to admit and still spoke to a secret wish that I held deep in my heart. A bitter, hateful wish.

But hey, listen. Not anymore. Now, I mean — I would never. I really do love a good rendering engine bug, now. I do.

“CSS 3D transforms with perspective() are rendered inside out.”

bugs.chromium.org

I mean, that’s actually kind of a fun bug, right? Like, fun in a way. Y’know?

It’s fun.

It’ll be fun.

Smashing Editorial
(dm, ra, il)


Source: Smashing Magazine

Generic First CSS: New Thinking On Mobile First

Generic First CSS: New Thinking On Mobile First

Generic First CSS: New Thinking On Mobile First

Alastair Hodgson

2018-12-21T14:45:16+01:00
2018-12-21T14:30:45+00:00

I think it’s safe to say that Ethan Marcotte’s Responsive Web Design was a welcome revelation for web developers the world over. It triggered a whole new wave of design thinking and wonderful new front-end techniques. The reign of the oft-despised m dot websites was also over. In the same era and almost as influential was Luke Wroblewski’s Mobile First methodology — a solid improvement that built upon Marcotte’s impressive foundations.

These techniques are at the bedrock of most web developers lives, and they’ve served us well, but alas, times change, and developers constantly iterate. As we increase the efficiency of our methods and the project requirements become more complex, new frustrations emerge.

The Journey To Generic First

I can’t pinpoint exactly what made me change the way I write my CSS because it was really a natural progression for me that happened almost subconsciously. Looking back, I think it was more of a by-product of the development environment I was working in. The team I worked with had a nice SCSS workflow going on with a nifty little mixin for easily adding breakpoints within our CSS declarations. You probably use a similar technique.

This wonderful little SCSS mixin suddenly made it easy to write super granular media queries. Take a hypothetical biography block that looks a little something like this:

.bio {
  display: block;
  width: 100%;
  background-color: #ece9e9;
  padding: 20px;
  margin: 20px 0;

  @include media('>=small') {
    max-width: 400px;
    background-color: white;
    margin: 20px auto;
  }

  @include media('>=medium') {
    max-width: 600px;
    padding: 30px;
    margin: 30px auto;
  }

  @include media('>=large') {
    max-width: 800px;
    padding: 40px;
    margin: 40px auto;
  }

  @include media('>=huge') {
    max-width: 1000px;
    padding: 50px;
    margin: 50px auto;
  }
}

Fig.1. Typical mobile first with cascading media queries

This works nicely — I’ve written a lot of CSS like this in the past. However, one day it dawned upon me that overwriting CSS declarations as the device width increased just didn’t make sense. Why declare a CSS property for it only to be overwritten in the following declaration?

This is what lead me to begin writing compartmentalized media queries as opposed to the more common approach of media queries that cascade upwards (or downwards) like the example in Fig.1.

Instead of writing media queries that cascade upwards with increases in screen size, I began creating targeted media queries that would encapsulate styles at desired screen widths. The media query mixin would really come into its own here. Now my SCSS media queries are starting to look like this:

.bio {
  display: block;
  width: 100%;
  padding: 20px;
  margin: 20px 0;

  @include media('>=small', '<medium') {
    max-width: 400px;
    margin: 20px auto;
  }

  @include media('>=medium', '<large') {
    max-width: 600px;
    padding: 30px;
    margin: 30px auto;
  }

  @include media('>=large', '<huge') {
    max-width: 800px;
    padding: 40px;
    margin: 40px auto;
  }

  @include media('>=huge') {
    max-width: 1000px;
    padding: 50px;
    margin: 50px auto;
  }
}

Fig.2. An example of compartmentalized media queries

This new approach just felt more intuitive to me, it cut down on having to reset styles from the previous breakpoint, and it was making the CSS easier to read. More importantly, it was making the media queries self-documenting in a more significant way.

I still wasn’t 100% happy with the above though, It seemed like there was still a major issue to overcome.

The Problem With Mobile First

The issue with mobile first is that by definition you will most likely have to override mobile-first styles in subsequent media-queries. This feels like a bit of an anti-pattern.

So — to me — the answer was obvious: let’s take the idea of media query compartmentalization to its logical conclusion — we will also compartmentalize the mobile specific styles into their very own media queries. I know, I know, this goes against the common convention we’ve learned over the years. “Mobile First” is so ubiquitous that it’s usually one of the “skills” questions a hiring manager will ask. So surely any alternative must be wrong, shouldn’t it? This is usually the part where people shake their heads at me whilst uttering mobile first over and over.

Okay, so we’re going to break through the mobile first dogma and compartmentalize all our styles into the relevant media queries. What we’re now left with is pure generic styles declared on a CSS selector, with all other device specific styles encapsulated in media queries that only apply to the relevant screen dimensions. We now have Generic First CSS:

.bio {
  display: block;
  width: 100%;

  @include media('>=0', '<small') {
    padding: 20px;
    margin: 20px 0;
  }

  @include media('>=small', '<medium') {
    max-width: 400px;
    margin: 20px auto;
  }

  @include media('>=medium', '<large') {
    max-width: 600px;
    padding: 30px;
    margin: 30px auto;
  }

  @include media('>=large', '<huge') {
    max-width: 800px;
    padding: 40px;
    margin: 40px auto;
  }

  @include media('>=huge') {
    max-width: 1000px;
    padding: 50px;
    margin: 50px auto;
  }
}

Fig.3. An example of Generic First CSS

Yes, there are slightly more media queries, however, I see this as a benefit, any developer can now looks at this CSS and see exactly what styles are applied at each and every screen size without the cognitive overhead of having to pick apart media-query specificity.

This can be great for people unfamiliar with the code base or even the future you!

When Not To Compartmentalize

There are still times when media query compartmentalization is a burden, and in some cases a good old >= media query is fine. Remember, all we’re trying to do is avoid property overwrites.

Dev Tool Bliss

One major unintended consequence of writing compartmentalized Generic First CSS is the experience you will get from your developer tools style panel. Without the media query cascade, you will now have a clearer overview of which styles are applied — You won’t have a style panel full of struck-out declarations from overwritten media query rules — The noise is gone! This — for me — is one of the biggest benefits of the Generic First CSS technique. It brings a little extra sanity to the CSS debugging experience, and this is worth its weight in gold. Thank me later.


Before and after screenshot of how the generic first CSS approach affects chrome dev tools style panel.
Fig.4. How generic first, compartmentalized css can help bring joy and sanity to your dev console. (Large preview)

Performance Implications

So all these Generic First CSS benefits are starting to sound pretty good, but I think there is one last key question that I think needs to be addressed. It’s on the subject of performance optimization. Now I don’t know for certain yet, but I have an inkling that fully compartmentalized media queries may have a slight performance benefit.

Browsers perform a rendering task called computed style calculation. It’s the browsers way of calculating which styles need to be applied to an element at any given moment. This task is always performed on initial page load, but it can also be performed if page content changes or if other browser actions take place. Any boost you can give to the speed of the process is going to be great for initial page load, and it could have a compound effect on the lifecycle of your websites pages.

So going back to generic first CSS: Are there any performance issues related to the browser having to work out the CSS specificity of a multitude of cascading media queries?

To answer that, I’ve devised a test case that can be used to measure any speed benefits or indeed drawbacks.

The Test Case

The test case is comprised of a basic HTML page that outputs a “bio” block 5000 times, the markup is the same for each block, but the classes are slightly different (numeric differentiator), the CSS for this block is also outputted 5000 times, with class names being the only thing to differ. The outputted CSS is piped through a tool called CSS MQPacker, this helps dramatically reduce file size of CSS that uses a lot of inline media queries by combining all the separate instances of a specific media query into one — It’s a great tool that will probably benefit most modern CSS codebases — I’ve used it as a standalone cli tool via a npm task in the test projects package.json, you can also use it as a postcss plugin, which is nice and convenient!

The first test case is a mobile-first cascading media queries example, the second test case is a generic first compartmentalized variant of the CSS. The CSS for these cases is a little verbose and could probably be written in much more concise terms, but it really just serves as a rough example to test the argument.

The test was run 20 times for each CSS variation in desktop Google Chrome v70, not a massive set of data, but enough to give me a rough idea of a performance gain/loss.

The test metrics I have chosen to use are:

  • Overall page load time
    A basic metric to check page load time using the Performance API markers in the the start of the <head> and very end of <body>
  • The Recalculate Style
    Time from within the dev tools performance pane.
  • The Overall Page Rendering
    Time from within the dev tools performance pane.

Table of results from the Google Chrome performance profiler
Fig.5. The key metric being measured is “Recalculate Style”. (Large preview)

Results Table (all times in milliseconds)

@media all and (max-width: 799px) {
.break-out {
display: none;
}
}

@media all and (min-width: 800px) {
.mobiletable {
display: none;
}

@media all and (max-width: 1099px) {
.pfix {
margin-top: -12em;”
}
}

Mobile First Generic First
Load time Calculate styles Total render time Load time Calculate styles Total render time
1135 565.7 1953 1196 536.9 2012
1176 563.5 1936 1116 506.9 1929
1118 563.1 1863 1148 514.4 1853
1174 568.3 1929 1124 507.1 1868
1204 577.2 1924 1115 518.4 1854
1155 554.7 1991 1177 540.8 1905
1112 554.5 1912 1111 504.3 1886
1110 557.9 1854 1104 505.3 1954
1106 544.5 1895 1148 525.4 1881
1162 559.8 1920 1095 508.9 1941
1146 545.9 1897 1115 504.4 1968
1168 566.3 1882 1112 519.8 1861
1105 542.7 1978 1121 515.7 1905
1123 566.6 1970 1090 510.7 1820
1106 514.5 1956 1127 515.2 1986
1135 575.7 1869 1130 504.2 1882
1164 545.6 2450 1169 525.6 1934
1144 565 1894 1092 516 1822
1115 554.5 1955 1091 508.9 1986
1133 554.8 2572 1001 504.5 1812
AVG 1139.55 557.04 1980 1119.1 514.67 1903.15

Mobile First
Load time Calculate styles Total render time
1135 565.7 1953
1118 563.1 1863
1174 568.3 1929
1112 554.5 1912
1105 542.7 1978
1106 514.5 1956
1164 545.6 2450
1115 554.5 1955

Generic First
Load time Calculate styles Total render time
1196 536.9 2012
1148 514.4 1853
1124 507.1 1868
1111 504.3 1886
1121 515.7 1905
1127 515.2 1986
1169 525.6 1934
1091 508.9 1986

Fig.6. 20 test runs measuring key load/render metrics of mobile first vs generic first CSS.

From my admittedly small dataset, it does seem like my initial suspicion may be correct. On average, I see the Style Recalculation task take 42ms less time which is a 7.6% speed increase, and therefore the overall rendering time also decreases. The difference isn’t mind-blowing, but it is an improvement. I don’t think the dataset is big enough to be 100% conclusive and the test case is a little unrealistic, but I’m very glad not to be seeing a performance degradation.

I would be very interested to see the generic first methodology applied to a real-world existing codebase that has been written in the mobile-first way — the before after metrics would be much more realistic to everyday practice.

And if anyone has suggestions on how to automate this test over a broader set of iterations, please let me know in the comments! I’d imagine there must be a tool that can do this.

Conclusion

To recap on the benefits of this new development methodology…

  • CSS that does exactly as intended, no second guessing;
  • Self-documenting media-queries;
  • A better dev tools experience;
  • Pages that render faster.

I’d like to think I’m not the only person espousing the writing of CSS in this style. If you have already adopted the generic first mindset, hurray! But if not, I think you’ll really like the benefits it brings. I’ve personally benefited greatly from the uncluttered dev tools experience, which in itself will be a huge positive to a lot of devs. the self-documenting nature of this way of writing your media-queries will also have benefits to yourself and the wider team (if you have one). And finally, these benefits won’t cost you anything in performance terms, and in fact have been shown to have marginal speed gains!

Final Word

Like all development methodologies, it may not be for everyone, but I’ve fallen into Generic First CSS quite naturally, I now see it as a valuable way of working that gives me all the benefits of mobile first with some positive new additions that make the tough job of front-end development that little be easier.

Resources

Test Case Repo

If you’d like to fire up the test case and give it a go yourself, you can find it on GitHub, I’d love to see some reports from others.

Tools
Smashing Editorial
(dm, ra, yk, il)


Source: Smashing Magazine

Writing A Multiplayer Text Adventure Engine In Node.js

Writing A Multiplayer Text Adventure Engine In Node.js

Writing A Multiplayer Text Adventure Engine In Node.js

Fernando Doglio

2018-12-20T14:05:34+01:00
2018-12-20T14:16:59+00:00

Text adventures were one of the first forms of digital role-playing games out there, back when games had no graphics and all you had was your own imagination and the description you read on the black screen of your CRT monitor.

If we want to get nostalgic, maybe the name Colossal Cave Adventure (or just Adventure, as it was originally named) rings a bell. That was the very first text adventure game ever made.


A picture of an actual text adventure from back in the day
A picture of an actual text adventure from back in the day. (Large preview)

The image above is how you’d actually see the game, a far cry from our current top AAA adventure games. That being said, they were fun to play and would steal hundreds of hours of your time, as you sat in front of that text, alone, trying to figure out how to beat it.

Understandably so, text adventures have been replaced over the years by games that present better visuals (although, one could argue that a lot of them have sacrificed story for graphics) and, especially in the past few years, the increasing ability to collaborate with other friends and play together. This particular feature is one that the original text adventures lacked, and one that I want to bring back in this article.

Our Goal

The whole point of this endeavour, as you have probably guessed by now from the title of this article, is to create a text adventure engine that allows you to share the adventure with friends, enabling you to collaborate with them similarly to how you would during a Dungeons & Dragons game (in which, just like with the good ol’ text adventures, there are no graphics to look at).

In creating the engine, the chat server and the client is quite a lot of work. In this article, I’ll be showing you the design phase, explaining things like the architecture behind the engine, how the client will interact with the servers, and what the rules of this game will be.

Just to give you some visual aid of what this is going to look like, here is my goal:


General wireframe for the final UI of the game client
General wireframe for the final UI of the game client (Large preview)

That is our goal. Once we get there, you’ll have screenshots instead of quick and dirty mockups. So, let’s get down with the process. The first thing we’ll cover is the design of the whole thing. Then, we’ll cover the most relevant tools I’ll be using to code this. Finally, I’ll show you some of the most relevant bits of code (with a link to the full repository, of course).

Hopefully, by the end, you’ll find yourself creating new text adventures to try them out with friends!

Design Phase

For the design phase, I’m going to cover our overall blueprint. I’ll try my best not to bore you to death, but at the same time, I think it’s important to show some of the behind-the-scenes stuff that needs to happen before laying down your first line of code.

The four components I want to cover here with a decent amount of detail are:

  • The engine
    This is going to be the main game server. The game rules will be implemented here, and it’ll provide a technologically agnostic interface for any type of client to consume. We’ll implement a terminal client, but you could do the same with a web browser client or any other type you’d like.
  • The chat server
    Because it’s complex enough to have its own article, this service is also going to have its own module. The chat server will take care of letting players communicate with each other during the game.
  • The client
    As stated earlier, this will be a terminal client, one that, ideally, will look similar to the mockup from earlier. It will make use of the services provided by both the engine and the chat server.
  • Games (JSON files)
    Finally, I’ll go over the definition of the actual games. The whole point of this is to create an engine that can run any game, as long as your game file complies with the engine’s requirements. So, even though this will not require coding, I’ll explain how I’ll structure the adventure files in order to write our own adventures in the future.

The Engine

The game engine, or game server, will be a REST API and will provide all of the required functionality.

I went for a REST API simply because — for this type of game — the delay added by HTTP and its asynchronous nature will not cause any trouble. We will, however, have to go a different route for the chat server. But before we start defining endpoints for our API, we need to define what the engine will be capable of. So, let’s get to it.

Feature Description
Join a game A player will be able to join a game by specifying the game’s ID.
Create a new game A player can also create a new game instance. The engine should return an ID, so that others can use it to join.
Return scene This feature should return the current scene where the party is located. Basically, it’ll return the description, with all of the associated information (possible actions, objects in it, etc.).
Interact with scene This is going to be one of the most complex ones, because it will take a command from the client and perform that action — things like move, push, take, look, read, to name just a few.
Check inventory Although this is a way to interact with the game, it does not directly relate to the scene. So, checking the inventory for each player will be considered a different action.
A Word About Movement

We need a way to measure distances in the game because moving through the adventure is one of the core actions a player can take. We will be using this number as a measure of time, just to simplify the gameplay. Measuring time with an actual clock might not be the best, considering these type of games have turn-based actions, such as combat. Instead, we’ll use distance to measure time (meaning that a distance of 8 will require more time to traverse than one of 2, thus allowing us to do things like add effects to players that last for a set amount of “distance points”).

Another important aspect to consider about movement is that we’re not playing alone. For simplicity’s sake, the engine will not let players split the party (although that could be an interesting improvement for the future). The initial version of this module will only let everyone move wherever the majority of the party decides. So, moving will have to be done by consensus, meaning that every move action will wait for the majority of the party to request it before taking place.

Combat

Combat is another very important aspect of these types of games, and one that we’ll have to consider adding to our engine; otherwise, we’ll end up missing on some of the fun.

This is not something that needs to be reinvented, to be honest. Turn-based party combat has been around for decades, so we’ll just implement a version of that mechanic. We’ll be mixing it up with the Dungeons & Dragons concept of “initiative”, rolling a random number in order to keep the combat a bit more dynamic.

In other words, the order in which everyone involved in a fight gets to pick their action will be randomized, and that includes the enemies.

Finally (although I’ll go over this in more detail below), you’ll have items that you can pick up with a set “damage” number. These are the items you’ll be able to use during combat; anything that doesn’t have that property will cause 0 damage to your enemies. We’ll probably add a message when you try to use those objects to fight, so that you know that what you’re trying to do makes no sense.

Client-Server Interaction

Let’s see now how a given client would interact with our server using the previously defined functionality (not thinking about endpoints yet, but we’ll get there in a sec):



(Large preview)

The initial interaction between the client and the server (from the point of view of the server) is the start of a new game, and the steps for it are as follows:

  1. Create a new game.
    The client requests the creation of a new game from the server.
  2. Create chat room.
    Although the name doesn’t specify it, the server is not just creating a chatroom in the chat server, but also setting up everything it needs in order to allow a set of players to play through an adventure.
  3. Return game’s meta data.
    Once the game has been created by the server and the chat room is in place for the players, the client will need that information for subsequent requests. This will mostly be a set of IDs the clients can use to identify themselves and the current game they want to join (more on that in a second).
  4. Manually share game ID.
    This step will have to be done by the players themselves. We could come up with some sort of sharing mechanism, but I will leave that on the wish list for future improvements.
  5. Join the game.
    This one is pretty straightforward. Ince everyone has the game ID, they’ll join the adventure using their client applications.
  6. Join their chat room.
    Finally, the players’ client apps will use the game’s metadata to join their adventure’s chat room. This is the last step required pre-game. Once this is all done, then the players are ready to start adventuring!

Action order for an existing game
Action order for an existing game (Large preview)

Once the prerequisites have all been met, players can start playing the adventure, sharing their thoughts through the party chat, and advancing the story. The diagram above shows the four steps required for that.

The following steps will run as part of the game loop, meaning that they will be repeated constantly until the game ends.

  1. Request scene.
    The client app will request the metadata for the current scene. This is the first step in every iteration of the loop.
  2. Return the meta data.
    The server will, in turn, send back the metadata for the current scene. This information will include things like a general description, the objects found inside it, and how they relate to each other.
  3. Send command.
    This is where the fun begins. This is the main input from the player. It’ll contain the action they want to perform and, optionally, the target of that action (for example, blow candle, grab rock, and so on).
  4. Return the reaction to the command sent.
    This could simply be step two, but for clarity, I added it as an extra step. The main difference is that step two could be considered the beginning of this loop, whereas this one takes into account that you’re already playing, and, thus, the server needs to understand who this action is going to affect (either a single player or all players).

As an extra step, although not really part of the flow, the server will notify clients about status updates that are relevant to them.

The reason for this extra recurring step is because of the updates a player can receive from the actions of other players. Recall the requirement for moving from one place to another; as I said before, once the majority of the players have chosen a direction, then all players will move (no input from all players is required).

The interesting bit here is that HTTP (we’ve already mentioned that the server is going to be a REST API) does not allow for this type of behavior. So, our options are:

  1. perform polling every X amount of seconds from the client,
  2. use some sort of notification system that works in parallel with the client-server connection.

In my experience, I tend to prefer option 2. In fact, I would (and will for this article) use Redis for this kind of behavior.

The following diagram demonstrates the dependencies between services.


Interactions between an client app and the game engine
Interactions between an client app and the game engine (Large preview)

The Chat Server

I will leave the details of the design of this module for the development phase (which is not a part of this article). That being said, there are things we can decide.

One thing we can define is the set of the restrictions for the server, which will simplify our work down the line. And if we play our cards right, we might end up with a service that provides a robust interface, thus allowing us to, eventually, extend or even change the implementation to provide fewer restrictions without affecting the game at all.

  • There will be only one room per party.
    We will not let subgroups be created. This goes hand in hand with not letting the party split. Maybe once we implement that enhancement, allowing for subgroup and custom chat room creation would be a good idea.
  • There will be no private messages.
    This is purely for simplification purposes, but having a group chat is already good enough; we don’t need private messages right now. Remember that whenever you’re working on your minimum viable product, try to avoid going down the rabbit hole of unnecessary features; it’s a dangerous path and one that is hard to get out of.
  • We will not persist messages.
    In other words, if you leave the party, you’ll lose the messages. This will hugely simplify our task, because we won’t have to deal with any type of data storage, nor will we have to waste time deciding on the best data structure to store and recover old messages. It’ll all live in memory, and it will stay there for as long as the chat room is active. Once it’s closed, we’ll simply say goodbye to them!
  • Communication will be done over sockets.
    Sadly, our client will have to handle a double communication channel: a RESTful one for the game engine and a socket for the chat server. This might increase the complexity of the client a bit, but at the same time, it will use the best methods of communication for every module. (There is no real point in forcing REST on our chat server or forcing sockets on our game server. That approach would increase the complexity of the server-side code, which is the one also handling the business logic, so let’s focus on that side for now.)

That’s it for the chat server. After all, it will not be complex, at least not initially. There is more to do when it’s time to start coding it, but for this article, it is more than enough information.

The Client

This is the final module that requires coding, and it is going to be our dumbest one of the lot. As a rule of thumb, I prefer to have my clients dumb and my servers smart. That way, creating new clients for the server becomes much easier.

Just so we’re on the same page, here is the high-level architecture that we should end up with.


Final high level architecture of the entire development
Final high level architecture of the entire development (Large preview)

Our simple ClI client will not implement anything very complex. In fact, the most complicated bit we’ll have to tackle is the actual UI, because it’s a text-based interface.

That being said, the functionality that the client application will have to implement is as follows:

  1. Create a new game.
    Because I want to keep things as simple as possible, this will only be done through the CLI interface. The actual UI will only be used after joining a game, which brings us to the next point.
  2. Join an existing game.
    Given the game’s code returned from the previous point, players can use it to join in. Again, this is something you should be able to do without a UI, so this functionality will be part of the process required to start using the text UI.
  3. Parse game definition files.
    We’ll discuss these in a bit, but the client should be able to understand these files in order to know what to show and know how to use that data.
  4. Interact with the adventure.
    Basically, this gives the player the ability to interact with the environment described at any given time.
  5. Maintain an inventory for each player.
    Each instance of the client will contain an in-memory list of items. This list is going to be backed up.
  6. Support chat.
    The client app needs to also connect to the chat server and log the user into the party’s chat room.

More on the client’s internal structure and design later. In the meantime, let’s finish the design stage with the last bit of preparation: the game files.

The Game: JSON Files

This is where it gets interesting because up to now, I’ve covered basic microservices definitions. Some of them might speak REST, and others might work with sockets, but in essence, they’re all the same: You define them, you code them, and they provide a service.

For this particular component, I’m not planning on coding anything, yet we need to design it. Basically, we’re implementing a sort of protocol for defining our game, the scenes inside it and everything inside them.

If you think about it, a text adventure is, at its core, basically a set of rooms connected to each other, and inside them are “things” you can interact with, all tied together with a, hopefully, decent story. Now, our engine will not take care of that last part; that part will be up to you. But for the rest, there is hope.

Now, going back to the set of interconnected rooms, that to me sounds like a graph, and if we also add the concept of distance or movement speed that I mentioned earlier, we have a weighted graph. And that is just a set of nodes that have a weight (or just a number — don’t worry about what it’s called) that represents that path between them. Here is a visual (I love learning by seeing, so just look at the image, OK?):


A weighted graph example
A weighted graph example (Large preview)

That’s a weighted graph — that’s it. And I’m sure you’ve already figured it out, but for the sake of completeness, let me show you how you would go about it once our engine is ready.

Once you start setting up the adventure, you’ll create your map (like you see on the left of the image below). And then you’ll translate that into a weighted graph, as you can see on the right of the image. Our engine will be able to pick it up and let you walk through it in the right order.


Example graph for a given dungeon
Example graph for a given dungeon (Large preview)

With the weighted graph above, we can make sure players can’t go from the entrance all the way to the left wing. They would have to go through the nodes in between those two, and doing so will consume time, which we can measure using the weight from the connections.

Now, onto the “fun” part. Let’s see how the graph would look like in JSON format. Bear with me here; this JSON will contain a lot of information, but I’ll go through as much of it as I can:

{
    "graph": [
            { "id": "entrance", "name": "Entrance", "north": { "node": "1stroom", "distance": 1 } },
     { "id": "1st room", "name": "1st Room", "south": {"node": "entrance", "distance": 1} , "north": { "node": "bigroom", "distance": 1} } ,
     { "id": "bigroom",
       "name": "Big room",
       "south": { "node": "1stroom", "distance": 1},
       "north": { "node": "bossroom", "distance": 2},
       "east":  { "node": "rightwing", "distance": 3} ,
       "west":  { "node": "leftwing", "distance": 3}
     },
     { "id": "bossroom", "name": "Boss room", "south": {"node": "bigroom", "distance": 2} }
     { "id": "leftwing", "name": "Left Wing", "east": {"node": "bigroom", "distance": 3} }
     { "id": "rightwing", "name": "Right Wing", "west": { "node": "bigroom", "distance": 3 } }
    ],
    "game": {
     "win-condition": {
       "source": "finalboss",
       "condition": {
         "type": "comparison",
         "left": "hp",
         "right": "0",
         "symbol": "<="
       }
     },
     "lose-condition": {
       "source": "player",
       "condition": {
         "type": "comparison",
         "left": "hp",
         "right": "0",
         "symbol": "<="
       }
     }
    },
    "rooms": {
     "entrance": {
       "description": {
         "default": "You're at the entrance of the dungeon. There are two lit torches on each wall (one on your right and one on your left). You see only one path: ahead."
       },
       "items": [
         {
           "id": "littorch1",
           "name": "Lit torch on the right",  
           "triggers": [
             {
               "action": "grab", //grab Lit torch on the right
               "effect":{
                 "statusUpdate": "has light",
                 "target": "game",
               }
             }
           ] ,
           "destination": "hand"
         },
         {
           "id": "littorch2",
           "name": "Lit torch on the left",  
           "triggers": [
             {
               "action": "grab", //grab Lit torch on the left
               "effect":{
                 "statusUpdate": "has light",
                 "target": "game",
               }
             }
           ] ,
           "destination": "hand"
         
         }
       ]
     },
     "1stroom": {
       "description": {
         "default": "You're in a very dark room. There are no windows and no source of light, other than the one at the entrance. You get the feeling you're not alone here.",
         "conditionals": {
           "has light": "The room you find yourself in appears to be empty, aside from a single chair in the right corner. There appears to be only one way out: deeper into the dungeon."
         }
       },
       "items": [
         {
           "id": "chair",
           "name": "Wooden chair",
           "details": "It's a wooden chair, nothing fancy about it. It appears to have been sitting here, untouched, for a while now.",
           "subitems": [
             {    "id": "woodenleg",  
               "name": "Wooden leg",
               "triggeractions": [
                 { "action": "break", "target": "chair"},  //break 
                 { "action": "throw", "target": "chair"} //throw 
               ],
               "destination": "inventory",
               "damage": 2
             }
           ]
         }
       ]
     },
     "bigroom": {
       "description": {
         "default": "You've reached the big room. On every wall are torches lighting every corner. The walls are painted white, and the ceiling is tall and filled with painted white stars on a black background. There is a gateway on either side and a big, wooden double door in front of you."
       },
       "exits": {
         "north": { "id": "bossdoor",  "name": "Big double door", "status": "locked", "details": "A aig, wooden double door. It seems like something big usually comes through here."}
       },
       "items": []
     },
     "leftwing": {
       "description": {
         "default": "Another dark room. It doesn't look like it's that big, but you can't really tell what's inside. You do, however, smell rotten meat somewhere inside.",
         "conditionals": {
           "has light":  "You appear to have found the kitchen. There are tables full of meat everywhere, and a big knife sticking out of what appears to be the head of a cow."
         }
       },
       "items": [
         { "id": "bigknife", "name": "Big knife", "destination": "inventory", "damage": 10}
       ]
     },
     "rightwing": {
       "description": {
         "default": "This appear to be some sort of office. There is a wooden desk in the middle, torches lighting every wall, and a single key resting on top of the desk."
       },
       "items": [
         {     "id": "key",
           "name": "Golden key",
           "details": "A small golden key. What use could you have for it?",
           "destination": "inventory",
           "triggers": [{
             "action": "use", //use  on north exit (contextual)
             "target": {
               "room": "bigroom",
               "exit": "north"
             },
             "effect": {
               "statusUpdate": "unlocked",
               "target": {
                 "room": "bigroom",
                 "exit": "north"
               }
             }
           }
         ]
         }
       ]
     },
     "bossroom": {
       "description": {
         "default": "You appear to have reached the end of the dungeon. There are no exits other than the one you just came in through. The only other thing that bothers you is the hulking giant looking like it's going to kill you, standing about 10 feet from you."
       },
       "npcs": [
         {
           "id": "finalboss",
           "name": "Hulking Ogre",
           "details": "A huge, green, muscular giant with a single eye in the middle of his forehead. It doesn't just look bad, it also smells like hell.",
           "stats":  {
             "hp": 10,
             "damage": 3
           }
         }
       ]
     }
    }
}

I know it looks like a lot, but if you boil it down to a simple description of the game, you have a dungeon comprising six rooms, each one interconnected with others, as shown in the diagram above.

Your task is to move through it and explore it. You’ll find there are two different places where you can find a weapon (either in the kitchen or in the dark room, by breaking the chair). You will also be confronted with a locked door; so, once you find the key (located inside the office-like room), you’ll be able to open it and fight the boss with whatever weapon you’ve collected.

You will either win by killing it or lose by getting killed by it.

Let’s now get into a more detailed overview of the entire JSON structure and its three sections.

Graph

This one will contain the relationship between the nodes. Basically, this section directly translates into the graph we looked at before.

The structure for this section is pretty straightforward. It’s a list of nodes, where every node comprises the following attributes:

  • an ID that uniquely identifies the node among all others in the game;
  • a name, which is basically a human-readable version of the ID;
  • a set of links to the other nodes. This is evidenced by the existence of four possible keys: north”, south, east, and west. We could eventually add further directions by adding combinations of these four. Every link contains the ID of the related node and the distance (or weight) of that relation.
Game

This section will contain the general settings and conditions. In particular, in the example above, this section contains the win and lose conditions. In other words, with those two conditions, we’ll let the engine know when the game can end.

To keep things simple, I’ve added just two conditions:

  • you either win by killing the boss,
  • or lose by getting killed.
Rooms

Here is where most of the 163 lines come from, and it is the most complex of the sections. This is where we’ll describe all of the rooms in our adventure and everything inside them.

There will be a key for every room, using the ID we defined before. And every room will have a description, a list of items, a list of exits (or doors) and a list of non-playable characters (NPCs). Out of those properties, the only one that should be mandatory is the description, because that one is required for the engine to let you know what you’re seeing. The rest of them will only be there if there is something to show.

Let’s look into what these properties can do for our game.

The Description

This item is not as simple as one might think, because your view of a room can change depending on different circumstances. If, for example, you look at the description of the first room, you’ll notice that, by default, you can’t see anything, unless of course, you have a lit torch with you.

So, picking up items and using them might trigger global conditions that will affect other parts of the game.

The Items

These represent all the things” you can find inside a room. Every item shares the same ID and name that the nodes in the graph section had.

They will also have a “destination” property, which indicates where that item should be stored, once picked up. This is relevant because you will be able to have only one item in your hands, whereas you’ll be able to have as many as you’d like in your inventory.

Finally, some of these items might trigger other actions or status updates, depending on what the player decides to do with them. One example of this are the lit torches from the entrance. If you grab one of them, you’ll trigger a status update in the game, which in turn will make the game show you a different description of the next room.

Items can also have “subitems”, which come into play once the original item gets destroyed (through the “break” action, for example). An item can be broken down into several ones, and that is defined in the “subitems” element.

Essentially, this element is just an array of new items, one that also contains the set of actions that can trigger their creation. This basically opens up the possibility to create different subitems based on the actions you perform on the original item.

Finally, some items will have a “damage” property. So, if you use an item to hit an NPC, that value will be used to subtract life from them.

The Exits

This is simply a set of properties indicating the direction of the exit and the properties of it (a description, in case you want to inspect it, its name and, in some cases, its status).

Exits are a separate entity from items because the engine will need to understand if you can actually traverse them based on their status. Exits that are locked will not let you go through them unless you work out how to change their status to unlocked.

The NPCs

Finally, NPCs will be part of another list. They are basically items with statistics that the engine will use to understand how each one should behave. The ones we’ve defined in our example are “hp”, which stands for health points, and “damage”, which, just like the weapons, is the number that each hit will subtract from the player’s health.

That is it for the dungeon I created. It is a lot, yes, and in the future I might consider creating a level editor of sorts, to simplify the creation of the JSON files. But for now, that won’t be necessary.

In case you haven’t realized it yet, the main benefit of having our game defined in a file like this is that we’ll be able to switch JSON files like you did cartridges back in the Super Nintendo era. Just load up a new file and start a new adventure. Easy!

Closing Thoughts

Thanks for reading thus far. I hope you’ve enjoyed the design process I go through to bring an idea to life. Remember, though, that I’m making this up as I go, so we might realize later that something we defined today isn’t going to work, in which case we’ll have to backtrack and fix it.

I’m sure there are a ton of ways to improve the ideas presented here and to make one hell of an engine. But that would require a lot more words than I can put into an article without making it boring for everyone, so we’ll leave it at that for now.

Smashing Editorial
(rb, ra, al, il)


Source: Smashing Magazine

I Used The Web For A Day Using A Screen Reader

I Used The Web For A Day Using A Screen Reader

I Used The Web For A Day Using A Screen Reader

Chris Ashton

2018-12-19T13:30:48+01:00
2018-12-19T13:25:05+00:00

This article is part of a series in which I attempt to use the web under various constraints, representing a given demographic of user. I hope to raise the profile of difficulties faced by real people, which are avoidable if we design and develop in a way that is sympathetic to their needs. Last time, I navigated the web for a day with just my keyboard. This time around, I’m avoiding the screen and am using the web with a screen reader.

What Is A Screen Reader?

A screen reader is a software application that interprets things on the screen (text, images, links, and so on) and converts these to a format that visually impaired people are able to consume and interact with. Two-thirds of screen reader users choose speech as their screen reader output, and one-third of screen reader users choose braille.

Screen readers can be used with programs such as word processors, email clients, and web browsers. They work by mapping the contents and interface of the application to an accessibility tree that can then be read by the screen reader. Some screen readers have to manually map specific programs to the tree, whereas others are more generic and should work with most programs.

Accessibility Originates With UX

You need to ensure that your products are inclusive and usable for disabled people. A BBC iPlayer case study, by Henny Swan. Read article →


Chart showing popularity of desktop screen readers ranks JAWS first, NVDA second and VoiceOver third.
Pie chart from the Screen Reader Survey 2017, showing that JAWS, NVDA and VoiceOver are the most used screen readers on desktop. (Large preview)

On Windows, the most popular screen reader is JAWS, with almost half of the overall screen reader market. It is commercial software, costing around a thousand dollars for the home edition. An open-source alternative for Windows is NVDA, which is used by just under a third of all screen reader users on desktop.

There are other alternatives, including Microsoft Narrator, System Access, Window-Eyes and ZoomText (not a full-screen reader, but a screen magnifier that has reading abilities); the combined sum of these equates to about 6% of screen reader usage. On Linux, Orca is bundled by default on a number of distributions.

The screen reader bundled into macOS, iOS and tvOS is VoiceOver. VoiceOver makes up 11.7% of desktop screen reader users and rises to 69% of screen reader users on mobile. The other major screen readers in the mobile space are Talkback on Android (29.5%) and Voice Assistant on Samsung (5.2%), which is itself based on Talkback, but with additional gestures.


Table showing popularity of mobile screen readers. Ranks VoiceOver first, Talkback second, Voice Assistant third.
Popularity of mobile screen readers: Ranks VoiceOver first, Talkback second, Voice Assistant third. (Large preview)

I have a MacBook and an iPhone, so will be using VoiceOver and Safari for this article. Safari is the recommended browser to use with VoiceOver, since both are maintained by Apple and should work well together. Using VoiceOver with a different browser can lead to unexpected behaviors.

How To Enable And Use Your Screen Reader

My instructions are for VoiceOver, but there should be equivalent commands for your screen reader of choice.

VoiceOver On Desktop

If you’ve never used a screen reader before, it can be a daunting experience. It’s a major culture shock going to an auditory-only experience, and not knowing how to control the onslaught of noise is unnerving. For this reason, the first thing you’ll want to learn is how to turn it off.

The shortcut for turning VoiceOver off is the same as the shortcut for turning it on: + F5 ( is also known as the Cmd key). On newer Macs with a touch bar, the shortcut is to hold the command key and triple-press the Touch ID button. Is VoiceOver speaking too fast? Open VoiceOver Utility, hit the ‘Speech’ tab, and adjust the rate accordingly.

Once you’ve mastered turning it on and off, you’ll need to learn to use the “VoiceOver key” (which is actually two keys pressed at the same time): Ctrl and (the latter key is also known as “Option” or the Alt key). Using the VO key in combination with other keys, you can navigate the web.

For example, you can use VO + A to read out the web page from the current position; in practice, this means holding Ctrl + + A. Remembering what VO corresponds to is confusing at first, but the VO notation is for brevity and consistency. It is possible to configure the VO key to be something else, so it makes sense to have a standard notation that everyone can follow.

You may use VO and arrow keys (VO + and VO + ) to go through each element in the DOM in sequence. When you come across a link, you can use VO + Space to click it — you’ll use these keys to interact with form elements too.

Huzzah! You now know enough about VoiceOver to navigate the web.

VoiceOver On Mobile

The mobile/tablet shortcut for turning on VoiceOver varies according to the device, but is generally a ‘triple click’ of the home button (after enabling the shortcut in settings).

You can read everything from the current position with a Two-Finger Swipe Down command, and you can select each element in the DOM in sequence with a Swipe Right or Left.

You now know as much about iOS VoiceOver as you do desktop!

Think about how you use the web as a sighted user. Do you read every word carefully, in sequence, from top to bottom? No. Humans are lazy by design and have learned to ‘scan’ pages for interesting information as fast as possible.

Screen reader users have this same need for efficiency, so most will navigate the page by content type, e.g. headings, links, or form controls. One way to do this is to open the shortcuts menu with VO + U, navigate to the content type you want with the and arrow keys, then navigate through those elements with the ↑↓ keys.


screenshot of 'Practice Webpage Navigation' VoiceOver tutoriasl screen
(Large preview)

Another way to do this is to enable ‘Quick Nav’ (by holding along with at the same time). With Quick Nav enabled, you can select the content type by holding the arrow alongside or . On iOS, you do this with a Two-Finger Rotate gesture.


screenshot of rota in VoiceOver, currently on 'Headings'
Setting the rotor item type using keyboard shortcuts. (Large preview)

Once you’ve selected your content type, you can skip through each rotor item with the ↑↓ keys (or Swipe Up or Down on iOS). If that feels like a lot to remember, it’s worth bookmarking this super handy VoiceOver cheatsheet for reference.

A third way of navigating via content types is to use trackpad gestures. This brings the experience closer to how you might use VoiceOver on iOS on an iPad/iPhone, which means having to remember only one set of screen reader commands!


screenshot of ‘Practice Trackpad Gestures’ VoiceOver tutorial screen
(Large preview)

You can practice the gesture-based navigation and many other VoiceOver techniques in the built-in training program on OSX. You can access it through System Preferences → Accessibility → VoiceOver → Open VoiceOver Training.

After completing the tutorial, I was raring to go!

Case Study 1: YouTube

Searching On YouTube

I navigated to the YouTube homepage in the Safari toolbar, upon which VoiceOver told me to “step in” to the web content with Ctrl + + Shift + . I’d soon get used to stepping into web content, as the same mechanism applies for embedded content and some form controls.

Using Quick Nav, I was able to navigate via form controls to easily skip to the search section at the top of the page.


screenshot of YouTube homepage
When focused on the search field, VoiceOver announced: ‘Search, search text field Search’. (Large preview)

I searched for some quality content:


Screenshot of 'impractical jokers' in input field
Who doesn’t love Impractical Jokers? (Large preview)

And I navigated to the search button:


VoiceOver announces “Press Search, button.”
VoiceOver announces “Press Search, button.” (Large preview)

However, when I activated the button with VO + Space, nothing was announced.

I opened my eyes and the search had happened and the page had populated with results, but I had no way of knowing through audio alone.

Puzzled, I reproduced my actions with devtools open, and kept an eye on the network tab.

As suspected, YouTube is making use of a performance technique called “client-side rendering” which means that JavaScript intercepts the form submission and renders the search results in-place, to avoid having to repaint the entire page. Had the search results loaded in a new page like a normal link, VoiceOver would have announced the new page for me to navigate.

There are entire articles dedicated to accessibility for client-rendered applications; in this case, I would recommend YouTube implements an aria-live region which would announce when the search submission is successful.

Tip #1: Use aria-live regions to announce client-side changes to the DOM.

<div role="region" aria-live="polite" class="off-screen" id="search-status"></div>

<form id="search-form">
  <label>
    <span class="off-screen">Search for a video</span>
    <input type="text" />
  </label>
  <input type="submit" value="Search" />
</form>

<script>
  document.getElementById('search-form').addEventListener('submit', function (e) {
    e.preventDefault();
    ajaxSearchResults(); // not defined here, for brevity
    document.getElementById('search-status').textContent = 'Search submitted. Navigate to results below.'; // announce to screen reader
  });
</script>

Now that I’d cheated and knew there were search results to look at, I closed my eyes and navigated to the first video of the results, by switching to Quick Nav’s “headings” mode and then stepping through the results from there.

Playing Video On YouTube

As soon as you load a YouTube video page, the video autoplays. This is something I value in everyday usage, but this was a painful experience when mixed with VoiceOver talking over it. I couldn’t find a way of disabling the autoplay for subsequent videos. All I could really do was load my next video and quickly hit CTRL to stop the screen reader announcements.

Tip #2: Always provide a way to suppress autoplay, and remember the user’s choice.

The video itself is treated as a “group” you have to step into to interact with. I could navigate each of the options in the video player, which I was pleasantly surprised by — I doubt that was the case back in the days of Flash!

However, I found that some of the controls in the player had no label, so ‘Cinema mode’ was simply read out as “button”.


screenshot of YouTube player
Focussing on the ‘Cinema Mode’ button, there was no label indicating its purpose. (Large preview)

Tip #3: Always label your form controls.

Whilst screen reader users are predominantly blind, about 20% are classed as “low vision”, so can see some of the page. Therefore, a screen reader user may still appreciate being able to activate “Cinema mode”.

These tips aren’t listed in order of importance, but if they were, this would be my number one:

Tip #4: Screen reader users should have functional parity with sighted users.

By neglecting to label the “cinema mode” option, we’re excluding screen reader users from a feature they might otherwise use.

That said, there are cases where a feature won’t be applicable to a screen reader — for example, a detailed SVG line chart which would read as a gobbledygook of contextless numbers. In cases such as these, we can apply the special aria-hidden="true" attribute to the element so that it is ignored by screen readers altogether. Note that we would still need to provide some off-screen alternative text or data table as a fallback.

Tip #5: Use aria-hidden to hide content that is not applicable to screen reader users.

It took me a long time to figure out how to adjust the playback position so that I could rewind some content. Once you’ve “stepped in” to the slider (VO + Shift + ), you hold + ↑↓ to adjust. It seems unintuitive to me but then again it’s not the first time Apple have made some controversial keyboard shortcut decisions.

Autoplay At End Of YouTube Video

At the end of the video I was automatically redirected to a new video, which was confusing — no announcement happened.


screenshot of autoplay screen on YouTube video
There’s a visual cue at the end of the video that the next video will begin shortly. A cancel button is provided, but users may not trigger it in time (if they know it exists at all!) (Large preview)

I soon learned to navigate to the Autoplay controls and disable them:


In-video autoplay disable
In-video autoplay disable. (Large preview)

This doesn’t prevent a video from autoplaying when I load a video page, but it does prevent that video page from auto-redirecting to the next video.

Case Study 2: BBC

As news is something consumed passively rather than by searching for something specific, I decided to navigate BBC News by headings. It’s worth noting that you don’t need to use Quick Nav for this: VoiceOver provides element search commands that can save time for the power user. In this case, I could navigate headings with the VO + + H keys.

The first heading was the cookie notice, and the second heading was a <h2> entitled ‘Accessibility links’. Under that second heading, the first link was a “Skip to content” link which enabled me to skip past all of the other navigation.


“Skip to content” link is accessible via keyboard tab and/or screen reader navigation.
“Skip to content” link is accessible via keyboard tab and/or screen reader navigation. (Large preview)

‘Skip to content’ links are very useful, and not just for screen reader users; see my previous article “I used the web for a day with just a keyboard”.

Tip #6: Provide ‘skip to content’ links for your keyboard and screen reader users.

Navigating by headings was a good approach: each news item has its own heading, so I could hear the headline before deciding whether to read more about a given story. And as the heading itself was wrapped inside an anchor tag, I didn’t even have to switch navigation modes when I wanted to click; I could just VO + Space to load my current article choice.


Headings are also links on the BBC
Headings are also links on the BBC. (Large preview)

Whereas the homepage skip-to-content shortcut linked nicely to a #skip-to-content-link-target anchor (which then read out the top news story headline), the article page skip link was broken. It linked to a different ID (#page) which took me to the group surrounding the article content, rather than reading out the headline.


“Press visited, link: Skip to content, group” &mdash; not the most useful skip link result.
“Press visited, link: Skip to content, group” — not the most useful skip link result. (Large preview)

At this point, I hit VO + A to have VoiceOver read out the entire article to me.

It coped pretty well until it hit the Twitter embed, where it started to get quite verbose. At one point, it unhelpfully read out “Link: 1068987739478130688”.


VoiceOver can read out long links with no context.
VoiceOver can read out long links with no context. (Large preview)

This appears to be down to some slightly dodgy markup in the video embed portion of the tweet:


We have an anchor tag, then a nested div, then an img with an <code>alt</code> attribute with the value: “Embedded video”.
We have an anchor tag, then a nested div, then an img with an alt attribute with the value: “Embedded video”. (Large preview)

It appears that VoiceOver doesn’t read out the alt attribute of the nested image, and there is no other text inside the anchor, so VoiceOver does the most useful thing it knows how: to read out a portion of the URL itself.

Other screen readers may work fine with this markup — your mileage may vary. But a safer implementation would be the anchor tag having an aria-label, or some off-screen visually hidden text, to carry the alternative text. Whilst we’re here, I’d probably change “Embedded video” to something a bit more helpful, e.g. “Embedded video: click to play”).

The link troubles weren’t over there:


One link simply reads out “Link: 1,887”.
One link simply reads out “Link: 1,887”. (Large preview)

Under the main tweet content, there is a ‘like’ button which doubles up as a ‘likes’ counter. Visually it makes sense, but from a screen reader perspective, there’s no context here. This screen reader experience is bad for two reasons:

  1. I don’t know what the “1,887” means.
  2. I don’t know that by clicking the link, I’ll be liking the tweet.

Screen reader users should be given more context, e.g. “1,887 users liked this tweet. Click to like.” This could be achieved with some considerate off-screen text:

<style>
  .off-screen {
    clip: rect(0 0 0 0);
    clip-path: inset(100%);
    height: 1px;
    overflow: hidden;
    position: absolute;
    white-space: nowrap;
    width: 1px;
  }
</style>

<a href="/tweets/123/like">
  <span class="off-screen">1,887 users like this tweet. Click to like</span>
  <span aria-hidden="true">1,887</span>
</a>

Tip #7: Ensure that every link makes sense when read in isolation.

I read a few more articles on the BBC, including a feature ‘long form’ piece.

Reading The Longer Articles

Look at the following screenshot from another BBC long-form article — how many different images can you see, and what should their alt attributes be?


Screenshot of BBC article containing logo, background image and foreground image (with caption).
Screenshot of BBC article containing logo, background image, and foreground image (with caption). (Large preview)

Firstly, let’s look at the foreground image of Lake Havasu in the center of the picture. It has a caption below it: “Lake Havasu was created after the completion of the Parker Dam in 1938, which held back the Colorado River”.

It’s best practice to provide an alt attribute even if a caption is provided. The alt text should describe the image, whereas the caption should provide the context. In this case, the alt attribute might be something like “Aerial view of Lake Havasu on a sunny day.”

Note that we shouldn’t prefix our alt text with “Image: ”, or “Picture of” or anything like that. Screen readers already provide that context by announcing the word “image” before our alt text. Also, keep alt text short (under 16 words). If a longer alt text is needed, e.g. an image has a lot of text on it that needs copying, look into the longdesc attribute.

Tip #8: Write descriptive but efficient alt texts.

Semantically, the screenshot example should be marked up with <figure> and <figcaption> elements:

<figure>
  <img src="https//www.smashingmagazine.com/havasu.jpg" alt="Aerial view of Lake Havasu on a sunny day" />
  <figcaption>Lake Havasu was created after the completion of the Parker Dam in 1938, which held back the Colorado River</figcaption>
</figure>

Now let’s look at the background image in that screenshot (the one conveying various drinking glasses and equipment). As a general rule, background or presentational images such as these should have an empty alt attribute (alt=""), so that VoiceOver is explicitly told there is no alternative text and it doesn’t attempt to read it.

Note that an empty alt="" is NOT the same as having no alt attribute, which is a big no-no. If an alt attribute is missing, screen readers will read out the image filenames instead, which are often not very useful!


screenshot from BBC article
My screen reader read out ‘pushbutton-mr_sjdxzwy.jpg, image’ because no `alt` attribute was provided. (Large preview)

Tip #9: Don’t be afraid to use empty alt attributes for presentational content.

Case Study 3: Facebook

Heading over to Facebook now, and I was having withdrawal symptoms from earlier, so went searching for some more Impractical Jokers.

Facebook takes things a step or two further than the other sites I’ve tried so far, and instead of a ‘Skip to content’ link, we have no less than two dropdowns that link to pages or sections of pages respectively.


Facebook offers plenty of skip link keyboard shortcuts.
Facebook offers plenty of skip link keyboard shortcuts. (Large preview)

Facebook also defines a number of keys as shortcut keys that can be used from anywhere in the page:


Keyboard shortcuts for scrolling between news feed items, making new posts, etc.
Keyboard shortcuts for scrolling between news feed items, making new posts, etc. (Large preview)

I had a play with these, and they work quite well with VoiceOver — once you know they’re there. The only problem I see is that they’re proprietary (I can’t expect these same shortcuts to work outside of Facebook), but it’s nice that Facebook is really trying hard here.

Whilst my first impression of Facebook accessibility was a good one, I soon spotted little oddities that made the site harder to navigate.

For example, I got very confused when trying to navigate this page via headings:


The “Pages Liked by This Page” heading (at the bottom right of the page) is in focus, and is a “heading level 3”.
The “Pages Liked by This Page” heading (at the bottom right of the page) is in focus, and is a “heading level 3”. (Large preview)

The very first heading in the page is a heading level 3, tucked away in the sidebar. This is immediately followed by heading level SIX in the main content column, which corresponds to a status that was shared by the Page.


‘Heading level 6’ on a status shared to the Page.
‘Heading level 6’ on a status shared to the Page. (Large preview)

This can be visualized with the Web Developer plugin for Chrome/Firefox.


h1 goes to multiple h6s, skipping h2/h3/h4/h5
h1 goes to multiple h6s, skipping h2, h3, h4, h5. (Large preview)

As a general rule, it’s a good idea to have sequential headings with a difference no higher than 1. It’s not a deal-breaker if you don’t, but it’s certainly confusing coming to it from a screen reader perspective and worrying that you’ve accidentally skipped some important information because you jumped from a h1 to a h6.

Tip #10: Validate your heading structure.

Now, onto the meat of the website: the posts. Facebook is all about staying in touch with people and seeing what they’re up to. But we live in a world where alt text is an unknown concept to most users, so how does Facebook translate those smug selfies and dog pictures to a screen reader audience?

Facebook has an Automatic Alt Text generator which uses object recognition technology to analyze what (or who) is in a photo and generate a textual description of it. So, how well does it work?


Cambridge Cathedral
How do you think this image fared with the Automatic Alt Text Generator? (Large preview)

The alt text for this image was “Image may contain: sky, grass and outdoor.” It’s a long way off recognizing “Cambridge Cathedral at dusk”, but it’s definitely a step in the right direction.

I was incredibly impressed with the accuracy of some descriptions. Another image I tried came out as “Image may contain: 3 people, including John Smith, Jane Doe and Chris Ashton, people smiling, closeup and indoor” — very descriptive, and absolutely right!

But it does bother me that memes and jokes that go viral on social media are inherently inaccessible; Facebook treats the following as “Image may contain: bird and text”, which whilst true is a long way off the true depiction!


Scientifically, a raven has 17 primary wing feathers, the big ones at the end of the wing. They are called pinion feathers. A crow has 16. So, the difference between a crown and a raven is only a matter of a pinion.
Sadly, Facebook’s alt text does not stretch to images-with-text-on. (Large preview)

Luckily, users can write their own alt text if they wish.

Case Study 4: Amazon

Something I noticed on Facebook, happens on Amazon, too. The search button appears before the search input field in the DOM. That’s despite the fact that the button appears after the input field visually.


Screenshot of Chrome inspector against Amazon search area
The ‘nav-fill’ text input appears lower in the DOM than the search button. (Large preview)

Your website is likely to be in a logical order visually. What if somebody randomly moved parts of your webpage around — would it continue to make sense?

Probably not. That’s what can happen to your screen reader experience if you aren’t disciplined about keeping your DOM structure in sync with your visual design. Sometimes it’s easier to move content with CSS, but it’s usually better to move it in the DOM.

Tip #11: Make the DOM order match the visual order.

Why these two high profile sites choose not to adopt this best practice guideline with their search navigation baffles me. However, the button and input text are not so far apart that their ordering causes a big accessibility issue.

Headings On Amazon

Again, like Facebook, Amazon has a strange headings order. I searched via headings and was most confused that the first heading in the page was a heading level 5 in the “Other Sellers on Amazon” section:


Screenshot of Amazon product page with VoiceOver overlay
‘First heading, heading level 5, Other Sellers on Amazon’. (Large preview)

I thought this must be a bug with the screen reader, so I dug into Amazon’s source code to check:


screenshot of source code
The h5 ‘Other Sellers on Amazon’ appears on line 7730 in the page source. It is the first heading in the page. (Large preview)

The h1 of the page appears almost 10,000 lines down in the source code.


screenshot of source code
The ‘Red Dead Redemption 2 PS4’ h1 appears on line 9054. (Large preview)

Not only is this poor semantically and poor for accessibility, but this is also poor for SEO. Poor SEO means fewer conversions (sales) — something I’d expect Amazon to be very on top of!

Tip #12: Accessibility and SEO are two sides of the same coin.

A lot of what we do to improve the screen reader experience will also improve the SEO. Semantically valid headings and detailed alt text are great for search engine crawlers, which should mean your site ranks more highly in search, which should mean you’ll bring in a wider audience.

If you’re ever struggling to convince your business manager that creating accessible sites is important, try a different angle and point out the SEO benefits instead.

Miscellaneous

It’s hard to condense a day’s worth of browsing and experiences into a single article. Here are some highlights and lowlights that made the cut.

You’ll Notice The Slow Sites

Screen readers cannot parse the page and create their accessibility tree until the DOM has loaded. Sighted users can scan a page while it’s loading, quickly determining if it’s worth their while and hitting the back button if not. Screen reader users have no choice but to wait for 100% of the page to load.


Screenshot of a website, with '87 percent loaded' in VoiceOver overlay
87 percent loaded. I can’t navigate until it’s finished. (Large preview)

It’s interesting to note that whilst making a performant website benefits all, it’s especially beneficial for screen reader users.

Do I Agree To What?

Form controls like this one from NatWest can be highly dependent on spacial closeness to denote relationships. In screen reader land, there is no spacial closeness — only siblings and parents — and guesswork is required to know what you’re ticking ‘yes’ to.


Screenshot of web form, ‘Tick to confirm you have read this’
Navigating by form controls, I skipped over the ‘Important’ notice and went straight to the ‘Tick to confirm’ checkbox. (Large preview)

I would have known what I was agreeing to if the disclaimer had been part of the label:

<label>
  Important: We can only hold details of one trip at a time.
  <input type="checkbox" /> Tick to confirm you have read this. *
</label>

Following Code Is A Nightmare

I tried reading a technical article on CSS Tricks using my screen reader, but honestly, found the experience totally impossible to follow. This isn’t the fault of the CSS Tricks website — I think it’s incredibly complex to explain technical ideas and code samples in a fully auditory way. How many times have you tried debugging with a partner and rather than explaining the exact syntax you need, you give them something to copy and paste or you fill it in yourself?

Look how easily you can read this code sample from the article:


Sample of code from CSS Tricks
(Large preview)

But here is the screen reader version:

slash slash first we get the viewport height and we multiple it by one [pause] percent to get a value for a vh unit let vh equals window inner height star [pause] zero zero one slash slash then we set the value in the [pause] vh custom property to the root of the document document document element style set property [pause] vh dollar left brace vh right brace px

It’s totally unreadable in the soundscape. We tend not to have punctuation in comments, and in this case, one line flows seamlessly into the next in screen reader land. camelCase text is read out as separate words as if they’d been written in a sentence. Periods such as window.innerHeight are ignored and treated as “window inner height”. The only ‘code’ read out is the curly brackets at the end.

The code is marked up using standard <pre> and <code> HTML elements, so I don’t know how this could be made better for screen reader users. Any who do persevere with coding have my total admiration.

Otherwise, the only fault I could find was that the logo of the site had a link to the homepage, but no alt text, so all I heard was “link: slash”. It’s only in my capacity as a web developer that I know if you have a link with an attribute href="/" then it takes you to the website homepage, so I figured out what the link was for — but “link: CSS Tricks homepage” would have been better!


screenshot showing markup of CSS Tricks website
(Large preview)

VoiceOver On iOS Is Trickier Than OSX

Using VoiceOver on my phone was an experience!

I gave myself the challenge of navigating the Twitter app and writing a Tweet, with the screen off and using the mobile keyboard. It was harder than expected and I made a number of spelling mistakes.

If I were a regular screen reader user, I think I’d have to join the 41% of mobile screen reader users who use an external keyboard and invest in a Bluetooth keyboard. Clara Van Gerven came to the same conclusion when she used a screen reader for forty days in 2015.

It was pretty cool to activate Screen Curtain mode with a triple-tap using three fingers. This turned the screen off but kept the phone unlocked, so I could continue to browse my phone without anyone watching. This feature is essential for blind users who might otherwise be unwittingly giving their passwords to the person watching over their shoulder, but it also has a side benefit of being great for saving the battery.

Summary

This was an interesting and challenging experience, and the hardest article of the series to write so far.

I was taken aback by little things that are obvious when you stop and think about them. For instance, when using a screen reader, it’s almost impossible to listen to music at the same time as browsing the web! Keeping the context of the page can also be difficult, especially if you get interrupted by a phone call or something; by the time you get back to the screen reader you’ve kind of lost your place.

My biggest takeaway is that there’s a big cultural shock in going to an audio-only experience. It’s a totally different way to navigate the web, and because there is such a contrast, it is difficult to even know what constitutes a ‘good’ or ‘bad’ screen reader experience. It can be quite overwhelming, and it’s no wonder a lot of developers avoid testing on them.

But we shouldn’t avoid doing it just because it’s hard. As Charlie Owen said in her talk, Dear Developer, the Web Isn’t About You: This. Is. Your. Job. Whilst it’s fun to build beautiful, responsive web applications with all the latest cutting-edge technologies, we can’t just pick and choose what we want to do and neglect other areas. We are the ones at the coal face. We are the only people in the organization capable of providing a good experience for these users. What we choose to prioritize working on today might mean the difference between a person being able to use our site, and them not being able to.

Let us do our jobs responsibly, and let’s make life a little easier for ourselves, with my last tip of the article:

Tip #13: Test on a screen reader, little and often.

I’ve tested on screen readers before, yet I was very ropey trying to remember my way around, which made the day more difficult than it needed to be. I’d have been much more comfortable using a screen reader for the day if I had been regularly using one beforehand, even for just a few minutes per week.

Test a little, test often, and ideally, test on more than one screen reader. Every screen reader is different and will read content out in different ways. Not every screen reader will read “23/10/18” as a date; some will read out “two three slash one zero slash one eight.” Get to know the difference between application bugs and screen reader quirks, by exposing yourself to both.

Did you enjoy this article? This was the third one in a series; read how I Used The Web For A Day With JavaScript Turned Off and how I Used The Web For A Day With Just A Keyboard.

Smashing Editorial
(rb, ra, yk, il)


Source: Smashing Magazine

Mixing Tangible And Intangible: Designing Multimodal Interfaces Using Adobe XD

Mixing Tangible And Intangible: Designing Multimodal Interfaces Using Adobe XD

Mixing Tangible And Intangible: Designing Multimodal Interfaces Using Adobe XD

Nick Babich

2018-12-18T15:00:04+01:00
2018-12-18T14:09:02+00:00

(This article is kindly sponsored by Adobe.) User interfaces are evolving. Voice-enabled interfaces are challenging the long dominance of graphical user interfaces and are quickly becoming a common part of our daily lives. Significant progress in automatic speech recognition (APS) and natural language processing (NLP), together with an impressive consumer base (millions of mobile devices with built-in voice assistants), have influenced the rapid development and adoption of voice-based interface.

Products that use voice as the primary interface are becoming more and more popular. In the US alone, 47.3 million adults have access to a smart speaker (that’s one fifth of the US adult population), and the number is growing. But voice interfaces have a bright future not only in personal and home use. As people become accustomed to voice interfaces, they will come to expect them in a business context as well. Just imagine that soon you’ll be able to trigger a conference-room projector by saying something like, “Show my presentation”.

It’s evident that human-machine communication is rapidly expanding to encompass both written and spoken interaction. But does it mean that future interfaces will be voice-only? Despite some science-fiction portrayals, voice won’t completely replace graphical user interfaces. Instead, we’ll have a synergy of voice, visual and gesture in a new format of interface: a voice-enabled, multimodal interface.

In this article, we’ll:

  • explore the concept of a voice-enabled interface and review different types of voice-enabled interfaces;
  • find out why voice-enabled, multimodal user interfaces will be the preferred user experience;
  • see how you can build a multimodal UI using Adobe XD.

The State Of Voice User Interfaces (VUI)

Before diving into the details of voice user interfaces, we must define what voice input is. Voice input is a human-computer interaction in which a user speaks commands instead of writing them. The beauty of voice input is that it’s a more natural interaction for people — users are not restricted to a specific syntax when interacting with a system; they can structure their input in many different ways, just as they would do in human conversation.

Voice user interfaces bring the following benefits to their users:

  • Less interaction cost
    Although using a voice-enabled interface does involve an interaction cost, this cost is smaller (in theory) than that of learning a new GUI.
  • Hands-free control
    VUIs are great for when the users hands are busy — for example, while driving, cooking or exercising.
  • Speed
    Voice is excellent when asking a question is faster than typing it and reading through the results. For example, when using voice in a car, it is faster to say the place to a navigation system, rather than type the location on a touchscreen.
  • Emotion and personality
    Even when we hear a voice but don’t see an image of a speaker, we can picture the speaker in our head. This has an opportunity to improve user engagement.
  • Accessibility
    Visually impaired users and users with a mobility impairment can use voice to interact with a system.

Three Types Of Voice-Enabled Interfaces

Depending on how voice is used, it could be one of the following types of interfaces.

Voice Agents In Screen-First Devices

Apple Siri and Google Assistant are prime examples of voice agents. For such systems, the voice acts more like an enhancement for the existing GUI. In many cases, the agent acts as the first step in the user’s journey: The user triggers the voice agent and provides a command via voice, while all other interactions are done using the touchscreen. For example, when you ask Siri a question, it will provide answers in the format of a list, and you need to interact with that list. As a result, the user experience becomes fragmented — we use voice to initiate the interaction and then shift to touch to continue it.


Siri executes a voice command to search for news, but then requires users to touch the screen in order to read the items.
Siri executes a voice command to search for news, but then requires users to touch the screen in order to read the items. (Large preview)
Voice-Only Devices

These devices don’t have visual displays; users rely on audio for both input and output. Amazon Echo and Google Home smart speakers are prime examples of products in this category. The lack of a visual display is a significant constraint on the device’s ability to communicate information and options to the user. As a result, most people use these devices to complete simple tasks, such as playing music and getting answers to simple questions.


Amazon Echo Dot is a screen-less device.
Amazon Echo Dot is a screen-less device. (Large preview)
Voice-First Devices

With voice-first systems, the device accepts user input primarily via voice commands, but also has an integrated screen display. It means that voice is the primary user interface, but not the only one. The old saying, “A picture is worth a thousand words” still applies to modern voice-enabled systems. The human ​brain​ has incredible​ ​image​-​processing​ abilities — we​ ​can​ ​understand​ ​complex​ ​information​ ​faster​ ​when we​ ​see​ ​it​ ​visually. Compared to voice-only devices, voice-first devices allow users to access a larger amount of information and make many tasks much easier.

The Amazon Echo Show is a prime example of a device that employs a voice-first system. Visual information is gradually incorporated as part of a holistic system — the screen is not loaded with app icons; rather, the system encourages users to try different voice commands (suggesting verbal commands such as, “Try ‘Alexa, show me the weather at 5:00 pm’”). The screen even makes common tasks such as checking a recipe while cooking much easier — users don’t need to listen carefully and keep all of the information in their heads; when they need the information, they simply look at the screen.


Amazon Echo Show is basically an Amazon Echo speaker with a screen.
Amazon Echo Show is basically an Amazon Echo speaker with a screen. (Large preview)

Introducing Multimodal Interfaces

When it comes to using voice in UI design, don’t think of voice as something you can use alone. Devices such as Amazon Echo Show include a screen but employ voice as the primary input method, making for a more holistic user experience. This is the first step towards a new generation of user interfaces: multimodal interfaces.

A multimodal interface is an interface that blends voice, touch, audio and different types of visuals in a single, seamless UI. Amazon Echo Show is an excellent example of a device that takes full advantage of a voice-enabled multimodal interface. When users interact with Show, they make requests just as they would with a voice-only device; however, the response they receive will likely be multimodal, containing both voice and visual responses.

Multimodal products are more complex than products that rely only on visuals or only on voice. Why should anyone create a multimodal interface in the first place? To answer that question, we need to step back and see how people perceive the environment around them. People have five senses, and the combination of our senses working together is how we perceive things. For example, our senses work together when we are listening to music at a live concert. Remove one sense (for example, hearing), and the experience takes on an entirely different context.


Our senses work together when we are listening to music at a live concert. Remove one sense (for example, hearing), and the experience takes on an entirely different context.
(Large preview)

For too long, we’ve thought about the user experience as exclusively either visual or gestural design. It’s time to change this thinking. Multimodal design is a way to think about and design for experiences that connect our sensory abilities together.

Multimodal interfaces feel like ​a more​ ​human​ ​way​ for ​user​ ​and​ machine to communicate. They open up new opportunities for deeper interactions. And today, it’s much easier to design multimodal interfaces because the technical limitations that in the past constrained interactions with products are being erased.

The Difference Between A GUI And Multimodal Interface

The key difference here is that multimodal interfaces like Amazon Echo Show sync voice and visual interfaces. As a result, when we’re designing the experience, the voice and visuals are no longer independent parts; they are integral parts of the experience that the system provides.

Visual And Voice Channel: When To Use Each

It’s important to think about voice and visuals as channels for input and output. Each channel has its own strengths and weaknesses.

Let’s start with the visuals. It’s clear that some information is just easier to understand when we see it, rather than when we hear it. Visuals work better when you need to provide:

  • a long lists of options (reading a long list will take a lot of time and be difficult to follow);
  • data-heavy information (such as diagrams and graphs);
  • product information (for example, products in online shops; most likely, you would want to see a product before buying) and product comparison (as with the long list of options, it would be hard to provide all of the information using only voice).

For some information, however, we can easily rely on verbal communication. Voice might be the right fit for the following cases:

  • user commands (voice is an efficient input modality, allowing users to give commands to the system quickly and bypassing complex navigation menus);
  • simple user instructions (for example, a routine check on a prescription);
  • warnings and notifications (for example, an audio warning paired with voice notifications during driving).

While these are a few typical cases of visual and voice combined, it’s important to know that we can’t separate the two from each other. We can create a better user experience only when both voice and visuals work together. For example, suppose we want to purchase a new pair of shoes. We could use voice to request from the system, “Show me New Balance shoes.” The system would process your request and visually provide product information (an easier way for us to compare shoes).

What You Need To Know To Design Voice-Enabled, Multimodal Interfaces

Voice is one of the most exciting challenges for UX designers. Despite its novelty, the fundamental rules for designing voice-enabled, multimodal interface are the same as those we use to create visual designs. Designers should care about their users. They should aim to reduce friction for the user by solving their problems in efficient ways and prioritize clarity to make the user’s choices clear.

But there are some unique design principles for multimodal interfaces as well.

Make Sure You Solve The Right Problem

Design should solve problems. But it’s vital to solve the right problems; otherwise, you could spend a lot of time creating an experience that doesn’t bring much value to users. Thus, make sure you’re focused on solving the right problem. Voice interactions should make sense to the user; users should have a compelling reason to use voice over other methods of interaction (such as clicking or tapping). That’s why, when you create a new product — even before starting the design — it’s essential to conduct user research and determine whether voice would improve the UX.

Start with creating a user journey map. Analyze the journey map and find places where including voice as a channel would benefit the UX.

  • Find places in the journey where users might encounter friction and frustration. Would using voice reduce the friction?
  • Think about the context of the user. Would voice work for a particular context?
  • Think about what is uniquely enabled by voice. Remember the unique benefits of using voice, such as hands-free and eyes-free interaction. Could voice add value to the experience?

Create Conversational Flows

Ideally, the interfaces you design should require zero interaction cost: Users should be able to fulfill their needs without spending extra time on learning how to interact with the system. This happens only when voice interaction resemble a real conversation, not a system dialog wrapped in the format of voice commands. The fundamental rule of a good UI is simple: Computers should adapt to humans, not the other way around.

People rarely have flat, linear conversations (conversations that only last one turn). That’s why, to make interaction with a system feel like a live conversation, designers should focus on creating conversational flows. Each conversational flow consists of dialogs — the pathways that occur between the system and the user. Each dialog would include the system’s prompts and the user’s possible responses.

A conversational flow can be presented in the form of a flow diagram. Each flow should focus on one particular use case (for example, setting an alarm clock using a system). For most dialogs in a flow, it’s vital to consider error paths, when things go off the rails.

Each voice command of the user consists of three key elements: intent, utterance and slot.

  • Intent is the objective of the user’s interaction with a voice-enabled system.
    An intent is just a fancy way of defining the purpose behind a set of words. Each interaction with a system brings the user some utility. Whether it’s information or an action, the utility is in intent. Understanding the user’s intent is a crucial part of voice-enabled interfaces. When we design VUI, we don’t always know for sure what a user’s intent is, but we can guess it with high accuracy.
  • Utterance is how the user phrases their request.
    Usually, users have more than one way to formulate a voice command. For example, we can set an alarm clock by saying “Set alarm clock to 8 am”, or “Alarm clock 8 am tomorrow” or even “I need to wake up at 8 am.” Designers need to consider every possible variation of utterance.
  • Slots are variables that users use in a command. Sometimes users need to provide additional information in the request. In our example of the alarm clock, “8 am” is a slot.

Don’t Put Words In The User’s Mouth

People know how to talk. Don’t try to teach them commands. Avoid phrases like, “To send a meeting appointment, you need to say ‘Calendar, meetings, create a new meeting’.” If you have to explain commands, you need to reconsider the way you’re designing the system. Always aim for natural language conversation, and try to accommodate diverse speaking styles).

Strive For Consistency

You need to achieve consistency in language and voice across contexts. Consistency will help to build familiarity in interactions.

Always Provide Feedback

Visibility of system status is one of the fundamental principles of good GUI design. The system should always keep users informed of what is going on through appropriate feedback within a reasonable time. The same rule applies to VUI design.

  • Make the user aware that the system is listening.
    Show visual indicators when the device is listening or processing the user’s request. Without feedback, the user can only guess whether the system is doing something. That’s why even voice-only devices such as Amazon Echo and Google Home give us nice visual feedback (flashing lights) when they are listening or searching for an answer.
  • Provide conversational markers.
    Conversational markers tell the user where they’re at in the conversation.
  • Confirm when a task is completed.
    For example, when users ask the voice-enabled smart home system “Turn off the lights in the garage”, the system should let the user know that the command has been successfully executed. Without confirmation, users will need to walk into the garage and check the lights. It defeats the purpose of the smart home system, which is to make the user’s life easier.

Avoid Long Sentences

When designing a voice-enabled system, consider the way you provide information to users. It’s relatively easy to overwhelm users with too much information when you use long sentences. First, users can’t retain a lot of information in their short-term memory, so they can easily forget some important information. Also, audio is a slow medium — most people can read much faster than they can listen.

Be respectful of your user’s time; don’t read out long audio monologues. When you’re designing a response, the fewer words you use, the better. But remember that you still need to provide enough information for the user to complete their task. Thus, if you cannot summarize an answer in a few words, display it on the screen instead.

Provide Next Steps Sequentially

Users can be overwhelmed not only by long sentences, but also their number of options at one time. It’s vital to break down the process of interaction with a voice-enabled system into bite-sized chunks. Limit the number of choices the user has at any one time, and make sure they know what to do at every moment.

When designing a complex voice-enabled system with a lot of features, you can use the technique of progressive disclosure: Present only the options or information necessary to complete the task.

Have A Strong Error-Handling Strategy

Of course, the system should prevent errors from occurring in the first place. But no matter how good your voice-enabled system is, you should always design for the scenario in which the system doesn’t understand the user. Your responsibility is to design for such cases.

Here are a few practical tips for creating a strategy:

  • Don’t blame the user.
    In conversation, there are no errors. Try to avoid reponses like, “Your answer is incorrect.”
  • Provide error-recovery flows.
    Provide an option for back-and-forths in a conversation, or even to exit the system, without losing important information. Save the user’s state in the journey, so that they can re-engage with the system right from where they left off.
  • Let users replay information.
    Provide an option to make the system repeat the question or answer. This might be helpful for complex questions or answers where it would be hard for the user to commit all of the information to their working memory.
  • Provide stop wording.
    In some cases, the user will not be interested in listening to an option and will want the system to stop talking about it. Stop wording should help them do just that.
  • Handle unexpected utterances gracefully.
    No matter how much you invest in the design of a system, there will be situations when the system doesn’t understand the user. It’s vital to handle such cases gracefully. Don’t be afraid to let the system admit a lack of understanding. The system should communicate what it has understood and provide helpful reprompts.
  • Use analytics to improve your error strategy.
    Analytics can help you identify wrong turns and misinterpretations.

Keep Track Of Context

Make sure the system understands the context of the user’s input. For example, when someone says that they want to book a flight to San Francisco next week, they might refer to “it” or “the city” during the conversational flow. The system should remember what was said and be able to match it to the newly received information.

Learn About Your Users To Create More Powerful Interactions

A voice-enabled system becomes more sophisticated when it uses additional information (such as user context or past behavior) to understand what the user wants. This technique is called intelligent interpretation, and it requires that the system actively learn about the user and be able to adjust their behavior accordingly. This knowledge will help the system to provide answers even to complex questions, such as “What gift should I buy for my wife’s birthday?”

Give Your VUI A Personality

Every voice-enabled system has an emotional impact on the user, whether you plan for it or not. People associate voice with humans rather than machines. According to Speak Easy Global Edition research, 74% of regular users of voice technology expect brands to have unique voices and personalities for their voice-enabled products. It’s possible to build empathy through personality and achieve a higher level of user engagement.

Try to reflect your unique brand and identity in the voice and tone you present. Construct a persona of your voice-enabled agent, and rely on this persona when creating dialogs.

Build Trust

When users don’t trust a system, they don’t have the motivation to use it. That’s why building trust is a requirement of product design. Two factors have a significant impact on the level of trust built: system capabilities and valid outcome.

Building trust starts with setting user expectations. Traditional GUIs have a lot of visual details to help the user understand what the system is capable of. With a voice-enabled system, designers have fewer tools to rely on. Still, it’s vital to make the system naturally discoverable; the user should understand what is and isn’t possible with the system. That’s why a voice-enabled system might require user onboarding, where it talks about what the system can do or what it knows. When designing onboarding, try to offer meaningful examples to let people know what it can do (examples work better than instructions).

When it comes to valid outcomes, people know that voice-enabled systems are imperfect. When a system provides an answer, some users might doubt that the answer is correct. this happens because users don’t have any information about whether their request was correctly understood or what algorithm was used to find the answer. To prevent trust issues, use the screen for supporting evidence — display the original query on the screen — and provide some key information about the algorithm. For example, when a user asks, “Show me the top five movies of 2018”, the system can say, “Here are top five movies of 2018 according to the box office in the US”.

Don’t Ignore Security And Data Privacy

Unlike mobile devices, which belong to the individual, voice devices tend to belong to a location, like a kitchen. And usually, there are more than one person in the same location. Just imagine that someone else can interact with a system that has access to all of your personal data. Some VUI systems such as Amazon Alexa, Google Assistant and Apple Siri can recognize individual voices, which adds a layer of security to the system. Still, it doesn’t guarantee that the system will be able to recognize users based on their unique voice signature in 100% of cases.

Voice recognition is continually improving, and it will be hard or nearly impossible to imitate a voice in the near future. However, in the current reality, it’s vital to provide an additional authentication layer to reassure the user that their data is safe. If you design an app that works with sensitive data, such as health information or banking details, you might want to include an extra authentication step, such as a password or fingerprint or face recognition.

Conduct Usability Testing

Usability testing is a mandatory requirement for any system. Test early, test often should be a fundamental rule of your design process. Gather user research data early on, and iterate your designs. But testing multimodal interfaces has its own specifics. Here are two phases that should be taken into account:

  • Ideation phase
    Test drive your sample dialogs. Practice reading sample dialogs out loud. Once you have some conversational flows, record both sides of the conversation (the user’s utterances and the system’s responses), and listen to the recording to understand whether they sound natural.
  • Early stages of product development (testing with lo-fi prototypes)
    Wizard of Oz testing is well-suited to testing conversational interfaces. Wizard of Oz testing is a type of testing in which a participant interacts with a system that they believe is operated by a computer but is in fact operated by a human. The test participant formulates a query, and a real person responds on the other end. This method gets its name from the book The Wonderful Wizard of Oz by Frank Baum. In the book, an ordinary man hides behind a curtain, pretending to be a powerful wizard. This test allows you to map out every possible scenario of interaction and, as a result, create more natural interactions. Say Wizard is a great tool to help you run a Wizard of Oz voice-interface test on macOS.
  • Designing For Voice: The ‘Wizard Of Oz’ Method (Watch on Vimeo)
  • Later stages of product development (testing with hi-fi prototypes)
    In usability testing of graphical user interfaces, we often ask users to speak out loud when they interact with a system. For a voice-enabled system, that’s not always possible because the system would be listening to that narration. So, it might be better to observe the user’s interactions with the system, rather than ask them to speak out loud.

How To Create A Multimodal Interface Using Adobe XD

Now that you have a solid understanding of what a multimodal interface is and what rules to remember when designing them, we can discuss how to make a prototype of a multimodal interface.

Prototyping is a fundamental part of the design process. Being able to bring an idea to life and share it with others is extremely important. Until now, designers who wanted to incorporate voice in prototyping had few tools to rely on, the most powerful of which was a flowchart. Picturing how a user would interact with a system required a lot of imagination from someone looking at the flowchart. With Adobe XD, designers now have access to the medium of voice and can use it in their prototypes. XD seamlessly connects screen and voice prototyping in one app.

New Experiences, Same Process

Even though voice is a totally different medium than visual, the process of prototyping for voice in Adobe XD is pretty much the same as prototyping for a GUI. The Adobe XD team integrates voice in a way that will feel natural and intuitive for any designer. Designers can use voice triggers and speech playback to interact with prototypes:

  • Voice triggers start an interaction when a user says a particular word or phrase (utterance).
  • Speech playback gives designers access to a text-to-speech engine. XD will speak words and sentences defined by a designer. Speech playback can be used for many different purposes. For example, it can act as an acknowledgment (to reassure users) or as guidance (so users know what to do next).

The great thing about XD is that it doesn’t force you to learn the complexities of each voice platform.

Enough words — let’s see how it works in action. For all of the examples you’ll see below, I’ve used artboards created using Adobe XD UI kit for Amazon Alexa (this is a link to download the kit). The kit contains all of the styles and components needed to create experiences for Amazon Alexa.

Suppose we have the following artboards:


example of an artboard
(Large preview)

Let’s go into prototyping mode to add in some voice interactions. We’ll start with voice triggers. Along with triggers such as tap and drag, we are now able to use voice as a trigger. We can use any layers for voice triggers as long as they have a handle leading to another artboard. Let’s connect the artboards together.


Connecting artboards together
Connecting artboards together. (Large preview)

Once we do that, we’ll find a new “Voice” option under the “Trigger”. When we select this option, we’ll see a “Command” field that we can use to enter an utterance — this is what XD will actually be listening for. Users will need to speak this command to activate the trigger.


Setting a voice trigger in Adobe XD.
Setting a voice trigger in Adobe XD. (Large preview)

That’s all! We’ve defined our first voice interaction. Now, users can say something, and a prototype will respond to it. But we can make this interaction much more powerful by adding speech playback. As I mentioned previously, speech playback allows a system to speak some words.

Select an entire second artboard, and click on the blue handle. Choose a “Time” trigger with a delay and set it to 0.2s. Under the action, you’ll find “Speech Playback”. We’ll write down what the virtual assistant speaks back to us.


Using the Command option to enter an utterance or speak a command to activate the trigger
(Large preview)

We’re ready to test our prototype. Select the first artboard, and clicking the play button in the top right will launch a preview window. When interacting with voice prototyping, make sure your mic is on. Then, hold down the spacebar to speak the voice command. This input triggers the next action in the prototype.

Use Auto-Animate To Make The Experience More Dynamic

Animation brings a lot of benefits to UI design. It serves clear functional purposes, such as:

  • communicating the spatial relationships between objects (Where does the object come from? Are those objects related?);
  • communicating affordance (What can I do next?)

But functional purposes aren’t the only benefits of animation; animation also makes the experience more alive and dynamic. That’s why UI animations should be a natural part of multimodal interfaces.

With “Auto-Animate” available in Adobe XD, it becomes much easier to create prototypes with immersive animated transitions. Adobe XD does all the hard work for you, so you don’t need to worry about it. All you need to do to create an animated transition between two artboards is simply duplicate an artboard, modify the object properties in the clone (properties such as size, position and rotation), and apply an Auto-Animate action. XD will automatically animate the differences in properties between each artboard.

Let’s see how it works in our design. Suppose we have an existing shopping list in Amazon Echo Show and want to add a new object to the list using voice. Duplicate the following artboard:


Artboard: shopping list.
Artboard: shopping list. (Large preview)

Let’s introduce some changes in the layout: Add a new object. We aren’t limited here, so we can easily modify any properties such as text attributes, color, opacity, position of the object — basically, any changes we make, XD will animate between them.


Two artboards: our original shopping list and its duplicate with a new item.
Two artboards: our original shopping list and its duplicate with a new item. (Large preview)

When you wire two artboards together in prototype mode using Auto-Animate in “Action”, XD will automatically animate the differences in properties between each artboard.


When you wire two artboards together in prototype mode using Auto-Animate in “Action”, XD will automatically animate the differences in properties between each artboard.
(Large preview)

And here’s how the interaction will look to users:

One crucial thing that requires mentioning: Keep the names of all of the layers the same; otherwise, Adobe XD won’t be able to apply the auto-animation.

Conclusion

We’re at the dawn of a user interface revolution. A new generation of interfaces — multimodal interfaces — not only will give users more power, but will also change the way users interact with systems. We will probably still have displays, but we won’t need keyboards to interact with the systems.

At the same time, the fundamental requirements for designing multimodal interfaces won’t be much different from those of designing modern interfaces. Designers will need to keep the interaction simple; focus on the user and their needs; design, prototype, test and iterate.

And the great thing is that you don’t need to wait to start designing for this new generation of interfaces. You can start today.

This article is part of the UX design series sponsored by Adobe. Adobe XD tool is made for a fast and fluid UX design process, as it lets you go from idea to prototype faster. Design, prototype and share — all in one app. You can check out more inspiring projects created with Adobe XD on Behance, and also sign up for the Adobe experience design newsletter to stay updated and informed on the latest trends and insights for UX/UI design.

Smashing Editorial
(ms, ra, al, yk, il)


Source: Smashing Magazine