Archive

Archive for February, 2020

A Complete Guide to Links and Buttons

February 14th, 2020 No comments

There is a lot to know about links and buttons in HTML. There is markup implementation and related attributes, styling best practices, things to avoid, and the even-more-nuanced cousins of the link: buttons and button-like inputs.

Let’s take a look at the whole world of links and buttons, and all the considerations at the HTML, CSS, JavaScript, design, and accessibility layers that come with them. There are plenty of pitfalls and bad practices to avoid along the way. By covering it, we’ll have a complete good UX implementation of both elements.

Quick rules of thumb on when to use each:

  • Are you giving a user a way to go to another page or a different part of the same page? Use a link (link)
  • Are you making a JavaScript-powered clickable action? Use a button ()
  • Are you submitting a form? Use a submit input ()

Links

Links are one of the most basic, yet deeply fundamental and foundational building blocks of the web. Click a link, and you move to another page or are moved to another place within the same page.

Table of Contents

HTML implementation

A basic link

<a href="https://css-tricks.com">CSS-Tricks</a>

That’s a link to a “fully qualified” or “absolute” URL.

A relative link

You can link “relatively” as well:

<!-- Useful in navigation, but be careful in content that may travel elsewhere (e.g. RSS) -->
<a href="/pages/about.html">About</a>

That can be useful, for example, in development where the domain name is likely to be different than the production site, but you still want to be able to click links. Relative URLs are most useful for things like navigation, but be careful of using them within content — like blog posts — where that content may be read off-site, like in an app or RSS feed.

A jump link

Links can also be “hash links” or “jump links” by starting with a #:

<a href="#section-2">Section Two</a>
<!-- will jump to... -->
<section id="section-2"></section>

Clicking that link will “jump” (scroll) to the first element in the DOM with an ID that matches, like the section element above.

? Little trick: Using a hash link (e.g. #0) in development can be useful so you can click the link without being sent back to the top of the page like a click on a # link does. But careful, links that don’t link anywhere should never make it to production.

? Little trick: Jump-links can sometimes benefit from smooth scrolling to help people understand that the page is moving from one place to another.

It’s a fairly common UI/UX thing to see a “Back to top” link on sites, particularly where important navigational controls are at the top but there is quite a bit of content to scroll (or otherwise navigate) through. To create a jump link, link to the ID of an element that is at the top of the page where it makes sense to send focus back to.

<a href="#top-of-page">Back to Top</a>

Jump links are sometimes also used to link to other anchor () elements that have no href attribute. Those are called “placeholder” links:

<a id="section-2"></a>
<h3>Section 2</h3>

There are accessibility considerations of these, but overall they are acceptable.

Disabled links

A link without an href attribute is the only practical way to disable a link. Why disable a link? Perhaps it’s a link that only becomes active after logging in or signing up.

a:not[href] {
  /* style a "disabled" link */
}

When a link has no href, it has no role, no focusability, and no keyboard events. This is intentional.

Do you need the link to open in a new window or tab?

You can use the target attribute for that, but it is strongly discouraged.

<a href="https://css-tricks.com" target="_blank" rel="noopener noreferrer">
  CSS-Tricks
</a>

The bit that makes it work is target="_blank", but note the extra rel attribute and values there which make it safer and faster.

Making links open in new tabs is a major UX discussion. We have a whole article about when to use it here. Summarized:

Don’t use it:

  • Because you or your client prefer it personally.
  • Because you’re trying to beef up your time on site metric.
  • Because you’re distinguishing between internal and external links or content types.
  • Because it’s your way out of dealing with infinite scroll trickiness.

Do use it:

  • Because a user is doing something on the current page, like actively playing media or has unsaved work.
  • You have some obscure technical reason where you are forced to (even then you’re still probably the rule, not the exception).

Need the link to trigger a download?

The download attribute on a link will instruct the browser to download the linked file rather than opening it within the current page/tab. It’s a nice UX touch.

<a href="/files/file.pdf" download>Download PDF</a>

The rel attribute

This attribute is for the relationship of the link to the target.

The rel attribute is also commonly used on the element (which is not used for creating hyperlinks, but for things like including CSS and preloading). We’re not including rel values for the element here, just anchor links.

Here are some basic examples:

<a href="/page/3" rel="next">Next</a>
<a href="/page/1" rel="prev">Previous</a>

<a href="http://creativecommons.org/licenses/by/2.0/" rel="license">cc by 2.0</a>

<a href="/topics/" rel="directory">All Topics</a>
  • rel="alternate": Alternate version of the document.
  • rel="author": Author of the document.
  • rel="help": A resource for help with the document.
  • rel="license": License and legal information.
  • rel="manifest": Web App Manifest document.
  • rel="next": Next document in the series.
  • rel="prev": Previous document in the series.
  • rel="search": A document meant to perform a search in the current document.

There are also some rel attributes specifically to inform search engines:

  • rel="sponsored": Mark links that are advertisements or paid placements (commonly called paid links) as sponsored.
  • rel="ugc": For not-particularly-trusted user-generated content, like comments and forum posts.
  • rel="nofollow": Tell the search engine to ignore this and not associate this site with where this links to.

And also some rel attributes that are most security-focused:

  • rel="noopener": Prevent a new tab from using the JavaScript window.opener feature, which could potentially access the page containing the link (your site) to perform malicious things, like stealing information or sharing infected code. Using this with target="_blank" is often a good idea.
  • rel="noreferrer": Prevent other sites or tracking services (e.g. Google Analytics) from identifying your page as the source of clicked link.

You can use multiple space-separated values if you need to (e.g. rel="noopener noreferrer")

And finally, some rel attributes come from the microformats standard, like:

  • rel="directory": Indicates that the destination of the hyperlink is a directory listing containing an entry for the current page.
  • rel="tag": Indicates that the destination of that hyperlink is an author-designated “tag” (or keyword/subject) for the current page.
  • rel="payment": Indicates that the destination of that hyperlink provides a way to show or give support for the current page.
  • rel="help": States that the resource linked to is a help file or FAQ for the current document.

ARIA roles

The default role of a link is link, so you do not need to do:

<a role="link" href="/">Link</a>

You’d only need that if you were faking a link, which would be a weird/rare thing to ever need to do, and you’d have to use some JavaScript in addition to this to make it actually follow the link.

<span class="link" tabindex="0" role="link" data-href="/">
  Fake accessible link created using a span
</span>

Just looking above you can see how much extra work faking a link is, and that is before you consider that is breaks right-clicking, doesn’t allow opening in a new tab, doesn’t work with Windows High Contrast Mode and other reader modes and assistive technology. Pretty bad!

A useful ARIA role to indicate the current page, like:

<a href="/" aria-current="page">Home</a>
<a href="/contact">Contact</a>
<a href="/about">About/a></a>

Should you use the title attribute?

Probably not. Save this for giving an iframe a short, descriptive title.

<a title="I don't need to be here" href="/">
  List of Concerts
</a>

title provides a hover-triggered UI popup showing the text you wrote. You can’t style it, and it’s not really that accessible.

Hover-triggered is the key phrase here. It’s unusable on any touch-only device. If a link needs more contextual information, provide that in actual content around the link, or use descriptive text the link itself (as opposed to something like “Click Here”).

Icon-only links

If a link only has an icon inside it, like:

<a href="/">😃</a>

<a href="/">
  <svg> ... </svg>
</a>

That isn’t enough contextual information about the link, particularly for accessibility reasons, but potentially for anybody. Links with text are almost always more clear. If you absolutely can’t use text, you can use a pattern like:

<a href="/">
  <!-- Hide the icon from assistive technology -->
  <svg aria-hidden="true" focusable="false"> ... </svg>
  <!-- Acts as a label that is hidden from view -->
  <span class="visually-hidden">Useful link text</span>
</a>

visually-hidden is a class used to visually hide the label text with CSS:

.visually-hidden {
  border: 0;
  clip: rect(0 0 0 0);
  height: 1px;
  margin: -1px;
  overflow: hidden;
  padding: 0;
  position: absolute;
  white-space: nowrap;
  width: 1px;
}

Unlike aria-label, visually hidden text can be translated and will hold up better in specialized browsing modes.

Links around images

Images can be links if you wrap them in a link. There is no need to use the alt text to say the image is a link, as assistive technology will do that already.

<a href="/buy/puppies/now">
  <img src="puppy.jpg" alt="A happy puppy.">
</a>

Links around bigger chunks of content

You can link a whole area of content, like:

<a href="/article/">
  <div class="card">
    <h2>Card</h2>
    <img src="..." alt="...">
    <p>Content</p>
  </div>
</a>

But it’s slightly weird, so consider the UX of it if you ever do it. For example, it can be harder to select the text, and the entire element needs styling to create clear focus and hover states.

Take this example, where the entire element is wrapped in a link, but there are no hover and focus states applied to it.

CodePen Embed Fallback

If you need a link within that card element, well, you can’t nest links. You could get a little tricky if you needed ot, like using a pseudo-element on the link which is absolutely positioned to cover the whole area.

Additionally, this approach can make really long and potentially confusing announcements for screen readers. Even though links around chunks of content is technically possible, it’s best to avoid doing this if you can.

Styling and CSS considerations

Here’s the default look of a link:

The default User-Agent styling of a link.

It’s likely you’ll be changing the style of your links, and also likely you’ll use CSS to do it. I could make all my links red in CSS by doing:

a {
  color: red;
}

Sometimes selecting and styling all links on a page is a bit heavy-handed, as links in navigation might be treated entirely differently than links within text. You can always scope selectors to target links within particular areas like:

/* Navigation links */
nav a { }

/* Links in an article */
article a { }

/* Links contained in an element with a "text" class */
.text a { }

Or select the link directly to style.

.link {
  /* For styling <a class="link" href="/"> */
}

a[aria-current="page"] {
  /* You'll need to apply this attribute yourself, but it's a great pattern to use for active navigation. */
}

Link states

Links are focusable elements. In other words, they can be selected using the Tab key on a keyboard. Links are perhaps the most common element where you’ll very consciously design the different states, including a :focus state.

  • :hover: For styling when a mouse pointer is over the link.
  • :visited: For styling when the link has been followed, as best as the browser can remember. It has limited styling ability due to security.
  • :link: For styling when a link has not been visited.
  • :active: For styling when the link is pressed (e.g. the mouse button is down or the element is being tapped on a touch screen).
  • :focus: Very important! Links should always have a focus style. If you choose to remove the default blue outline that most browsers apply, also use this selector to re-apply a visually obvious focus style.

These are chainable like any pseudo-class, so you could do something like this if it is useful for your design/UX.

/* Style focus and hover states in a single ruleset */
a:focus:hover { }

You can style a link to look button-like

Perhaps some of the confusion between links and buttons is stuff like this:

Very cool “button” style from Katherine Kato.

That certainly looks like a button! Everyone would call that a button. Even a design system would likely call that a button and perhaps have a class like .button { }. But! A thing you can click that says “Learn More” is very much a link, not a button. That’s completely fine, it’s just yet another reminder to use the semantically and functionally correct element.

Color contrast

Since we often style links with a distinct color, it’s important to use a color with sufficient color contrast for accessibility. There is a wide variety of visual impairments (see the tool WhoCanUse for simulating color combinations with different impairments) and high contrast helps nearly all of them.

Perhaps you set a blue color for links:

The blue link is #2196F3.

While that might look OK to you, it’s better to use tools for testing to ensure the color has a strong enough ratio according to researched guidelines. Here, I’ll look at Chrome DevTools and it will tell me this color is not compliant in that it doesn’t have enough contrast with the background color behind it.

Chrome DevTools is telling us this link color does not have enough contrast.

Color contrast is a big consideration with links, not just because they are often colored in a unique color that needs to be checked, but because they have all those different states (hover, focus, active, visited) which also might have different colors. Compound that with the fact that text can be selected and you’ve got a lot of places to consider contrast. Here’s an article about all that.

Styling “types” of links

We can get clever in CSS with attribute selectors and figure out what kind of resource a link is pointing to, assuming the href value has useful stuff in it.

/* Style all links that include .pdf at the end */
a[href$=".pdf"]::after {
  content: " (PDF)";
}

/* Style links that point to Google */
a[href*="google.com"] {
  color: purple;
}

Styling links for print

CSS has an “at-rule” for declaring styles that only take effect on printed media (e.g. printing out a web page). You can include them in any CSS like this:

@media print {
  /* For links in content, visually display the link */ 
  article a::after { 
    content: " (" attr(href) ")";
  }
}

Resetting styles

If you needed to take all the styling off a link (or really any other element for that matter), CSS provides a way to remove all the styles using the all property.

.special-area a {
  all: unset;
  all: revert;
  
  /* Start from scratch */
  color: purple;
}

You can also remove individual styles with keywords. (Again, this isn’t really unique to links, but is generically useful):

a {
  /* Grab color from nearest parent that sets it */
  color: inherit;

  /* Wipe out style (turn black) */
  color: initial;

  /* Change back to User Agent style (blue) */
  color: revert;
}

JavaScript considerations

Say you wanted to stop the clicking of a link from doing what it normally does: go to that link or jump around the page. In JavaScript, you can usepreventDefault to prevent jumping around.

const jumpLinks = document.querySelectorAll("a[href^='#']");

jumpLinks.forEach(link => {
 link.addEventListener('click', event => {
    event.preventDefault();
    // Do something else instead, like handle the navigation behavior yourself
  });
});

This kind of thing is at the core of how “Single Page Apps” (SPAs) work. They intercept the clicks so browsers don’t take over and handle the navigation.

SPAs see where you are trying to go (within your own site), load the data they need, replace what they need to on the page, and update the URL. It’s an awful lot of work to replicate what the browser does for free, but you get the ability to do things like animate between pages.

Another JavaScript concern with links is that, when a link to another page is clicked, the page is left and another page loads. That can be problematic for something like a page that contains a form the user is filling out but hasn’t completed. If they click the link and leave the page, they lose their work! Your only opportunity to prevent the user from leaving is by using the beforeunload event.

window.addEventListener("beforeunload", function(event) {
  // Remind user to save their work or whatever.
});

A link that has had its default behavior removed won’t announce the new destination. This means a person using assistive technology may not know where they wound up. You’ll have to do things like update the page’s title and move focus back up to the top of the document.

JavaScript frameworks

In a JavaScript framework, like React, you might sometimes see links created from something like a component rather than a native element. The custom component probably creates a native element, but with extra functionality, like enabling the JavaScript router to work, and adding attributes like aria-current="page" as needed, which is a good thing!

Ultimately, a link is a link. A JavaScript framework might offer or encourage some level of abstraction, but you’re always free to use regular links.

Accessibility considerations

We covered some accessibility in the sections above (it’s all related!), but here are some more things to think about.

Unique accessible names

Some assistive technology can create lists of interactive elements on the page. Imagine a group of four article cards that all have a “Read More”, the list of interactive elements will be like:

  • Read More
  • Read More
  • Read More
  • Read More

Not very useful. You could make use of that .visually-hidden class we covered to make the links more like:

<a href="/article">
  Read More
  <span class="visually-hidden">
    of the article "Dancing with Rabbits".
  <span>
</a>

Now each link is unique and clear. If the design can support it, do it without the visually hidden class to remove the ambiguity for everyone.

Buttons

Buttons are for triggering actions. When do you use the

The post A Complete Guide to Links and Buttons appeared first on CSS-Tricks.

Categories: Designing, Others Tags:

Designing Ethically, Optimizing Videos, And Shining The Spotlight On Our SmashingConf Speakers

February 14th, 2020 No comments
Topple the cat wearing headphones and holding a coffee-to-go cup while listening to the Smashing Podcast

Designing Ethically, Optimizing Videos, And Shining The Spotlight On Our SmashingConf Speakers

Designing Ethically, Optimizing Videos, And Shining The Spotlight On Our SmashingConf Speakers

Iris Lješnjanin

2020-02-14T14:00:00+00:002020-02-14T17:06:44+00:00

An important part of our job is staying up to date, and we know how difficult it can be. Technologies don’t really change that fast — coding languages take a long time to be specified and implemented. But the ideas surrounding these technologies and the things we can do with them are constantly evolving, and hundreds of blog posts and articles are published every day. There’s no way you can read all of those but you’ll still have to keep up to date.

Fear not, we’ve got your backs! Our bi-weekly Smashing Podcast has you covered with a variety of topics across multiple levels of expertise.

A shout-out and big thank you to both Drew McLellan and Bethany Andrew for making the episodes so brilliantly witty and informative!

Topple the cat wearing headphones and holding a coffee-to-go cup while listening to the Smashing Podcast

Catching up with what’s new in the web industry doesn’t mean you have to be tied up to a chair and desk! Do as Topple the Cat does it: grab your headphones and stretch those legs! You can subscribe and tune in anytime with any of your favorite apps.

A Lovely New Addition To The Smashing Books

We’re so proud to be introducing a new book to the Smashing bookshelf — a cover so eloquently designed and a book that covers topics that are very close to our hearts: ethics and privacy.

The “The Ethical Design Handbook” is our new guide on ethical design for digital products that respect customer choices and are built and designed with ethics in mind. It’s full of practical guidelines on how to make ethical decisions to influence positive change and help businesses grow in a sustainable way.


The cover of the Ethical Design Handbook
Written by Trine Falbe, Martin Michael Frederiksen and Kim Andersen. You can download a free PDF excerpt (5 MB) (also available as ePUB and Kindle) and get a sneakpeek beforehand!

Of course, you can jump right over to the table of contents and see for yourself, but be sure to pre-order the book while you can! There’s still a discount available before the official release — we’ll start shipping printed hardcover copies in the first two weeks of March! Stay tuned!

Learning And Networking, The Smashing Way

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

We like to bring you closer to folks working in the web industry, and so every once in a while we interview the speakers who share the stage! For SmashingConf Austin, the spotlight shined on:

  • Miriam Suzanne, who’ll be talking about the wonderful new world of CSS, new techniques and possibilities.
  • Zach Leatherman, who’ll let us in on everything we need to know about type,font performance tooling and general workflow when it comes to web fonts.
  • Rémi Parmentier, who’ll bring us closer to the good ol’ HTML Email, common techniques, state of things and what you can achieve with HTML Email today (if you are willing enough to explore its unconventional world).

Four different illustrations designed by Ricardo Gimenes dressed up in different costumes representing each city where the SmashingConf will take place this year

This year, we’re organizing SmashingConf in four cities — see you there?

Shining The Spotlight On Optimizing Video Files

Mark your calendars! In less than two weeks (Feb. 25, we’ll be hosting a Smashing TV webinar with Doug Sillars who’ll be sharing several possible scenarios to optimize video files for fast and efficient playback on the web. Join us at 17:00 London time — we’d love to hear your thoughts and experiences you’ve had in your career!

Smashing TV illustration with Topple the Cat holding a video camera

Smashing TV is a series of webinars and live streams packed with practical tips for designers and developers. Think of it as some sort of a Hollywood blockbuster with cats, but only better, because it’s for people like you!

We often get asked who the creative talent behind the illustrations is: It’s the one-and-only Ricardo Gimenes, someone we’re ever so proud to have in our team!

Trending Topics On SmashingMag

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

  • How To Create Maps With React And Leaflet
    by Shajia Abidi
    Leaflet is a very powerful tool, and we can create a lot of different kinds of maps. This tutorial will help you understand how to create an advanced map along with the help of React and Vanilla JS.
  • Understanding CSS Grid: Grid Template Areas
    by Rachel Andrew
    In a new series, Rachel Andrew breaks down the CSS Grid Layout specification. This time, she takes us through grid-template-areas and how it can be used to place items.
  • How To Create A Headless WordPress Site On The JAMstack
    by Sarah Drasner & Geoff Graham
    In this post, Sarah and Geoff set up a demo site and tutorial for headless WordPress — including a starter template! They explain how to set up a Vue application with Nuxt, pulling in the posts from our application via the WordPress API.
  • Magic Flip Cards: Solving A Common Sizing Problem
    by Dan Halliday
    In this article, Dan reviews the standard approach to creating animated flip cards and introduces an improved method which solves its sizing problem.

Best Picks From Our Newsletter

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

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

Tiny Helpers For Web Developers

Minifying an SVG, extracting CSS from HTML, or checking your color palette for accessibility — we all know those moments when we need a little tool to help us complete a task quickly and efficiently. If you ever find yourself in such a situation again, Tiny Helpers might have just the tool you’re looking for.

Tiny Helpers

Maintained by Stefan Judis, Tiny Helpers is a collection of free, single-purpose online tools for web developers. The tools cover everything from APIs, accessibility, and color, to fonts, performance, regular expressions, SVG, and unicode. And if you know of a useful tool that isn’t featured yet, you can submit a pull request with your suggestion. One for the bookmarks.

Real-World Color Palette Inspiration

There are a lot of fantastic sites out there that help you find inspiring color palettes. However, once you have found a palette you like, the biggest question is still left unanswered: how should you apply the colors to your design? Happy Hues is here to help.

Happy Hues

Designed by Mackenzie Child, Happy Hues gives you color palette inspiration while acting as a real-world example for how the colors could be used in your design. Just change the palette, and the Happy Hues site changes its colors to show you what your favorite palette looks like in an actual design. Clever!

Free Usability Heuristics Posters

Back in 1994, Jakob Nielsen wrote an article for Nielsen Norman Group, outlining general principles for interface design: the 10 usability heuristics. Today, decades later, these heuristics still serve as a checklist for interface designers. A fact that inspired the folks at Agente Studio to create a set of posters dedicated to them.

10 Usability Heuristics for User Interface Design

Each of the ten beautifully-designed posters illustrates and explains one of Nielsen’s heuristics. The posters are CC-licensed and can be downloaded and printed for free after you shared the page on social media. JPEG and EPS formats are available.

A Guide To Fighting Online Tracking

It’s no secret that we’re being tracked online. And while we can’t stop all of it, there are things we can do to fight back.

Illustration of a woman sweeping data away

Image credit: Rose Wong

In his New York Times article, Tim Herrera dives deeper into the data companies collect about us and how they share it with third parties, into “secret scores” and shocking third-party reports that list our delivery service orders and private Airbnb messages from years ago. Besides being a good reminder to be more wary of handing out our data, the article features links to tools and practical tips for preventing advertiser tracking. A must-read.

The Illustrated Children’s Guide To Kubernetes

Have you ever tried to explain software engineering to a child or to a friend, colleague, or relative who isn’t that tech-savvy? Well, finding easy words to explain a complex concept can be a challenge. A challenge that “The Illustrated Children’s Guide to Kubernetes” masters beautifully.

The Illustrated Children's Guide to Kubernetes

Designed as a storybook and available to be read online or as a PDF, the free guide tells the story of a PHP app named Phippy who wished she had her own environment, just her and a webserver she could call home. On her journey, she meets Captain Kube who gives her a new home on his ship Kubernetes. A beautiful metaphor to explain the core concept of Kubernetes.

Generator Of Geometric Shapes

To stand out from the crowd of a myriad of websites out there, we can define one unique thing, the signature, that brings a bit of personality into our digital products. Perhaps it’s a little glitch effect, or a pencil scribble, a game or unusual shapes. Or, it could be a set of seemingly random geometric flow lines.

Flow Lines Generator

Flow Lines Generator produces random geometric lines, and we can adjust the formulas and distances between the shapes drawn, and then export the outcome as SVG. Perhaps every single page on your site could have a variation of these lines in some way? It might be enough to stand out from the crowd, mostly because nobody else has that exact visual treatment. It might be worth looking at!

Git From Beginner To Advanced

Most of us will be dealing with Git regularly, sometimes running Git commands from terminal, and sometimes using a visual tool to pull, push, commit and merge. If you feel like you’d like to supercharge your skills and gain a few Git superpowers, where do you start?

Git Cheat Sheet

Mike Riethmueller has published a quick guide to Git, from beginner to advanced, explaining how Git works, how to configure it, aliases, important commands, staging/unstaging files, managing merge conflicts, stashing and a few advanced tips. Need more advanced stuff? Harry Roberts has published “Little Things I Like To Do With Git”, Atlassian has Advanced Git Tutorials, Bruno Passos lists useful git commands, and GitHub provides a Git Cheat Sheet PDF.

The Museum Of Obsolete Media

Do you remember the days when you listened to a music cassette on your Walkman, watched your favorite movie on video tape instead of streaming it, or stored your data on a floppy disk? The media we considered state-of-the-art back then, is obsolete today. And, well, a lot of other formats shared the same fate in the past.

The Museum Of Obsolete Media

In his Museum of Obsolete Media, Jason Curtis collects examples of media that went out of use, not just the ones you might remember, but also real curiosities and treasures dating back as far as to the middle of the 19th century. Things like the “carte de visite”, “Gould Moulded Records”, or “Magnabelt” for example. A fascinating trip back in time.

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

Smashing Newsletter

Upgrade your inbox and get our editors’ picks 2× a month — delivered right into your inbox. Earlier issues.



Useful tips for web designers. Sent 2× a month.
You can unsubscribe any time — obviously.

Smashing Editorial(cm, vf, ra, il)
Categories: Others Tags:

Pros and Cons of Using AI to Improve Road Safety

February 14th, 2020 No comments

Did you know that roads are deadlier than wars?

Throughout the entire 20th century, a period when the First and Second World Wars took place, the generally accepted death toll stemming from political conflicts was 108 million. However, around 1.35 million individuals lose their lives as a result of a road traffic accident every year, according to the World Health Organization.

Although one could argue that the fatalities on the roads are accidental and those in the battlefields are intentional, the statistics do not lie – we are likelier to get hit by a vehicle driven by a civilian than a bullet coming from a gun barrel of a state enemy.

This notion is true even in the United States, which is a high-profile target of terrorists. From 1995 to 2016, terrorism claimed the lives of just 3,277 persons in the US. But our friends at PolicyAdvice discovered that car collisions cut about 40,000 Americans off in their prime in 2018 alone.

Yet, some of us are more afraid of sitting next to a racially profiled “terrorist” than crossing an intersection.

Fortunately, road safety improvement has been getting into the consciousness of the general public of late. One of the things to thank for is the rapid advancement of artificial intelligence (AI).

After decades of receiving generous R&D funding, AI has matured and become commercially viable enough to inspire wide-scale adoption in many industries, including transportation.

Can this technology feasibly make our roads way safer? If so, how? The jury is still out on whether AI is truly the lifesaver it is billed as. But the world remains somewhat divided over its utility in road safety since it has its own share of merits and flaws.

The Pros of AI in Road Safety

Eliminating Driver-Inflicted Car Crashes

Driver error is the number one cause of road traffic crashes. It should not come as a surprise, for humans are too stubborn not to drive while distracted, intoxicated, high, or drowsy.

The obvious solution to such risky driver behavior is to pass the steering wheel to something incapable of getting distracted, intoxicated, high, and drowsy while driving the way humans do. Hence the need for vehicle autonomy.

Some technologists think that we are still decades away from seeing Level-5 autonomous vehicles (AVs) on the roads, but the tech has already been aiding motorists via advanced driver assistance system.

The ultimate goal of AV developers, however, is to put AI in the driver’s seat from the get-go. On paper, it makes total sense because computers can be better drivers than experienced human drivers themselves.

Self-driving vehicles are equipped with cutting-edge cameras, sensors, and radars to perceive the surroundings and other road users in order to predict the unpredictable in ways we can never do with our limited and inferior senses.

These futuristic cars and trucks also react to hazards more quickly. In addition, vehicle-to-vehicle communication could let them exchange information instantaneously and warn one another about nearby dangers.

Determining Dangerous Routes

AI-powered vehicles may run on gas and/or electricity, but they are fueled by data. Intelligent cars and trucks constantly gather information that can produce actionable insights with proper analytics.

Transport interests can use such findings to detect which stretches of roads are inherently dangerous due to one reason or another in order to plan safer routes for drivers.

Streamlining Traffic Patterns

AI and big data analytics can help the authorities control the flow of vehicular traffic in different areas. Traffic managers will be able to make informed decisions to prevent congestion in urban locations or at least minimize gridlocks during rush hour. That said, they would serve public transport commuters more efficiently.

Furthermore, AI plays crucial roles in predicting the paths of vulnerable road users, such as pedestrians and cyclists. AI-driven traffic management can translate to diverse mobility options, reduced number of accidents and casualties, and minimal greenhouse gas emissions.

Reacting to Emergencies

Some vehicle models use AI to better address emergencies. The tech gave birth to auto features that can detect health conditions like a heart attack, request for medical services, and give relevant parties key details like vehicle location. Such capabilities are particularly useful for truck drivers who work at night.

Identifying Driver Weaknesses

Using AI, along with other innovations like facial recognition tech, fleet managers can monitor driver performance in real time. This luxury not only enables decision-makers to dispatch relief drivers accordingly but also uncover bad driver habits. The availability of such data allows transport companies to provide proper training to certain drivers.

The Cons of AI in Road Safety

Raising Ethical Issues

AVs have the potential to save lives. But it would be naïve to think that they will never scratch or kill someone at some point. In fact, they already did.

So when it is impossible to save all potential casualties in a crash, who should decide who gets to live or who gets hit?

Are humans always more precious than animals? Is the life of a child more important than those of commuters riding a bus? Should productive adults be prioritized over old people? Should an AV swerve into the path of pedestrians to avoid a speeding motorcycle and protect its own passengers? If someone gets injured or dies, who should be held accountable for the behavior of a self-driving vehicle?

These ethical questions must be discussed by automotive industry leaders and maybe policymakers too. However, the software of AVs is designed to make judgment calls in life-threatening situations, and it is not going to please everybody.

Getting Exposed to Cyberattacks

Connected vehicles can be hacked, so cybersecurity is a serious concern. Anyone capable of hijacking the system of any specific AI-powered vehicle might choose to do so, irrespective of motivation. Such an incident could start a media frenzy and cause intense social panic.

Requiring Significant Funds to Adopt

The adoption of an AI-driven system for traffic management at any level could require enormous funds. For this reason, countries and communities with fewer resources might not be able to embrace such solutions as quickly as wealthier ones could. Without the necessary infrastructure in place, the tech can’t do much for road users.

Final Word

AI definitely has a place in future road safety. Many of its use cases in transportation are already being tested, if not implemented. We may not be able to anticipate the full extent of its impact on society in the long run, but the best we could do is to develop it with foresight in hopes of successfully solving our pressing problems with road safety without creating new ones we could not effectively remedy.

Categories: Others Tags:

Why JavaScript is Eating HTML

February 13th, 2020 No comments

Web development is always changing. One trend in particular has become very popular lately, and it fundamentally goes against the conventional wisdom about how a web page should be made. It is exciting for some but frustrating for others, and the reasons for both are difficult to explain.

A web page is traditionally made up of three separate parts with separate responsibilities: HTML code defines the structure and meaning of the content on a page, CSS code defines its appearance, and JavaScript code defines its behavior. On teams with dedicated designers, HTML/CSS developers and JavaScript developers, this separation of concerns aligns nicely with job roles: Designers determine the visuals and user interactions on a page, HTML and CSS developers reproduce those visuals in a web browser, and JavaScript developers add the user interaction to tie it all together and “make it work.” People can work on one piece without getting involved with all three.

In recent years, JavaScript developers have realized that by defining a page’s structure in JavaScript instead of in HTML (using frameworks such as React), they can simplify the development and maintenance of user interaction code that is otherwise much more complex to build. Of course, when you tell someone that the HTML they wrote needs to be chopped up and mixed in with JavaScript they don’t know anything about, they can (understandably) become frustrated and start asking what the heck we’re getting out of this.

As a JavaScript developer on a cross-functional team, I get this question occasionally and I often have trouble answering it. All of the materials I’ve found on this topic are written for an audience that is already familiar with JavaScript — which is not terribly useful to those who focus on HTML and CSS. But this HTML-in-JS pattern (or something else that provides the same benefits) will likely be around for a while, so I think it’s an important thing that everyone involved in web development should understand.

This article will include code examples for those interested, but my goal is to explain this concept in a way that can be understood without them.

Background: HTML, CSS, and JavaScript

To broaden the audience of this article as much as possible, I want to give a quick background on the types of code involved in creating a web page and their traditional roles. If you have experience with these, you can skip ahead.

HTML is for structure and semantic meaning

HTML (HyperText Markup Language) code defines the structure and meaning of the content on a page. For example, this article’s HTML contains the text you’re reading right now, the fact that it is in a paragraph, and the fact that it comes after a heading and before a CodePen.

Let’s say we want to build a simple shopping list app. We might start with some HTML like this:

CodePen Embed Fallback

We can save this code in a file, open it in a web browser, and the browser will display the rendered result. As you can see, the HTML code in this example represents a section of a page that contains a heading reading “Shopping List (2 items),” a text input box, a button reading “Add Item,” and a list with two items reading “Eggs” and “Butter.” In a traditional website, a user would navigate to an address in their web browser, then the browser would request this HTML from a server, load it and display it. If there are already items in the list, the server could deliver HTML with the items already in place, like they are in this example.

Try to type something in the input box and click the “Add Item” button. You’ll notice nothing happens. The button isn’t connected to any code that can change the HTML, and the HTML can’t change itself. We’ll get to that in a moment.

CSS is for appearance

CSS (Cascading Style Sheets) code defines the appearance of a page. For example, this article’s CSS contains the font, spacing, and color of the text you’re reading.

You may have noticed that our shopping list example looks very plain. There is no way for HTML to specify things like spacing, font sizes, and colors. This is where CSS (Cascading Style Sheets) comes in. On the same page as the HTML above, we could add CSS code to style things up a bit:

CodePen Embed Fallback

As you can see, this CSS changed the font sizes and weights and gave the section a nice background color (designers, please don’t @ me; I know this is still ugly). A developer can write style rules like these and they will be applied consistently to any HTML structure: if we add more

,

The Unseen Performance Costs of Modern CSS-in-JS Libraries

February 13th, 2020 No comments

This article is full of a bunch of data from Aggelos Arvanitakis. But lemme just focus on his final bit of advice:

Investigate whether a zero-runtime CSS-in-JS library can work for your project. Sometimes we tend to prefer writing CSS in JS for the DX (developer experience) it offers, without a need to have access to an extended JS API. If you app doesn’t need support for theming and doesn’t make heavy and complex use of the css prop, then a zero-runtime CSS-in-JS library might be a good candidate.

“Zero-runtime” meaning you author your styles in a CSS-in-JS syntax, but what is produced is .css files like any other CSS preprocessor would produce. This shifts the tool into a totally different category. It’s a developer tool only, rather than a tool where the user of the website pays the price of using it.

The flagship zero-runtime CSS-in-JS library is Linaria. I think the syntax looks really nice.

import { css } from 'linaria';
import fonts from './fonts';

const header = css`
  text-transform: uppercase;
  font-family: ${fonts.heading};
`;

<h1 className={header}>Hello world</h1>;

I’m also a fan of the just do scoping for me ability that CSS modules brings, which can be done zero-runtime style.

Direct Link to ArticlePermalink

The post The Unseen Performance Costs of Modern CSS-in-JS Libraries appeared first on CSS-Tricks.

Categories: Designing, Others Tags:

A Headless CMS for You and Your Web Development Agency

February 13th, 2020 No comments

(This is a sponsored post.)

Storyblok is a headless but component-based CMS with a built-in live-preview. You can use it for building fast and reliable websites and power native apps with your favorite technology.

Let us start with the basics and what a headless CMS is:

A headless content management system is a back-end only content management system (CMS) built from the ground up as a content repository that makes content accessible via a RESTful or GraphQL API for display on any device.

At Storyblok, you can select from a large amount of already existing tutorials that will get you started. Jump into the free plan and start modeling your content. Each space can have an unlimited amount of content types and components that you can define.

Storyblok also enables you with more built-in tools like the free image optimization service to speed up your website performance and overall progress.

As a web development agency, you can also sign-up for the partner program. This will allow you and your team to have an unlimited amount of free staff members. You will be able to create as many development spaces for pitches and proof of concepts as you like. The best thing, you will not only get those users and spaces for free – you will also earn a monthly revenue share for every subscription your customers do at Storyblok.

Try Storyblok yourself

Direct Link to ArticlePermalink

The post A Headless CMS for You and Your Web Development Agency appeared first on CSS-Tricks.

Categories: Designing, Others Tags:

Setting Up API Mocking With Mirage JS And Vue.js

February 13th, 2020 No comments
Smashing Editorial

Setting Up API Mocking With Mirage JS And Vue.js

Setting Up API Mocking With Mirage JS And Vue.js

Kelvin Omereshone

2020-02-13T11:00:00+00:002020-02-13T12:08:27+00:00

In the era of SPA and the JAMstack, there has always been a separation of concern between the APIs and front-end development. Almost all JavaScript projects that can be found out in the wild interact with a web service or API and either use it for authentications or getting user-related data.

So, whenever you’re working on a project and the necessary API still hasn’t been implemented by the back-end team or you need to quickly test a feature, you have some of the following options:

  • You could proxy to a locally running version of your actual backend which, in most cases as a front-end developer, you wouldn’t have.
  • You could comment out actual request and replace with mock data. (This is okay but not so great as you would need to undo that to get to production and you might not be able to deal with network states and latency.)

What Is API Mocking?

API mocking is an imitation or a simulation of an actual API. It is mostly done in order to intercept requests that are supposed to be made to an actual backend API but this mocking exist on your frontend.

Why is API Mocking Important

API mocking is significantly important in a lot of ways:

  1. It makes for a very good front-end development experience not to depend on production APIs before building out features.
  2. You could share your entire frontend and it would work without depending on an actual backend API.

What Is Mirage JS?

Mirage JS was created 5 years ago and was pretty much used in the Ember community before Sam Selikoff officially announced its release on the 24th of January, 2020 on Twitter.

Mirage JS solves the pain point for testing backend APIs without depending on those APIs. It allows for seamless front-end development experience by mocking production APIs.

Mirage JS is an API mocking library for Vue.js, React, Angular and Ember frameworks

What Makes Mirage JS A Better Choice?

There have been other options for API mocking (such as Axios interceptors, Typicode’s JSON server, and so on) but what I think is pretty interesting about Mirage is that it doesn’t get in the way of your development process (as you would see when we set it up with Vue in a bit). It is lightweight and yet powerful.

It comes with battery included out of the box that allows you to replicate real production API consumption scenarios like simulating a slow network with its timing option.

Getting Started With Mirage JS And Vue.js

So now that you know what Mirage JS is and why it’s important to your front-end development workflow, let’s look at setting it up with the progressive web framework: Vue.js.

Creating A Green-Field (Clean Installation) Vue Project

Using the Vue CLI, create a fresh Vue.js project by going into the directory you want the project to be created in and running (in your terminal):

vue create miragejs-demo-vue 

The above command would set up a new Vue project which you can now cd into and run either yarn serve or npm run serve.

#Installing Mirage JS

Now let’s install Mirage JS as a development dependency in our Vue.js project by running the following command:

yarn add -D miragejs

Or if you are using NPM, run this:

npm install --save-dev miragejs

And that’s it! Mirage JS is now installed in our Vue.js project.

Let’s Mock Out Something

With Mirage JS installed, let’s see how we configure it to talk to Vue and mock out a basic todos (an API that returns a list of todos) API.

Define Your Server

To get started, we need to create a server.js file in the /src directory of our Vue.js project. After that, add the following:

import { Server, Model } from 'miragejs'

export function makeServer({ environment = "development" } = {}) {

let server = new Server({
  environment,

    models: {
      todo: Model,
    },

  seeds(server) {
  server.create("todo", { content: "Learn Mirage JS" })
  server.create("todo", { content: "Integrate With Vue.js" })
  },

  routes() {

    this.namespace = "api"

    this.get("/todos", schema => {
      return schema.todos.all()
    })
    
  },
  })

  return server
}

Code Explained

Firstly, the server.js file is how you set up Mirage JS to create a new instance of it’s mock (fake) server which will intercept all API calls you make in your app matching the routes that you define.

Now, I agree the above may be overwhelming at first, but let’s take a closer look at what’s going on here:

import { Server, Model } from 'miragejs'

From the above code snippet, we are importing Server and Model from miragejs.

  • Server
    This is a class exposed by Mirage to helps us instantiate a new instance of a Mirage JS server to “serve” as our fake server.
  • Model
    Another class exposed by Mirage to help in creating models(a model determines the structure of a Mirage JS database entry) powered by Mirage’s ORM.
export function makeServer({ environment = "development" } = {}) {}

The above basically export a function called makeServer from the src/server.js. You could also note we are passing in an environment parameter and setting Mirage’s environment mode to development (you would see us passing test environment later on in this article).

The Body Of makeServer

Now we are doing a couple of things in the makeServer body. Let’s take a look:

let server = new Server({})

We are instantiating a new instance of the Server class and passing it a configuration option. The content of the configuration options help set up mirage:

{
  environment,

  models: {
    todo: Model,
  },

  seeds(server) {
  server.create("todo", { content: "Learn Mirage JS" })
  server.create("todo", { content: "Integrate With Vue.js" })
  },

  routes() {

    this.namespace = "api"

    this.get("/todos", schema => {
      return schema.todos.all()
    })
  },
  
  }

Firstly we are passing the environment parameter we initialized in the function definition.

models: {
    todo: Model,
  },

The next option which is the models option takes an object of the different models we want Mirage to mock.

In the above, we simply want a todo model which we are instantiating from the Model class.

seeds(server) {
server.create("todo", { content: "Learn Mirage JS" })
server.create("todo", { content: "Integrate With Vue.js" })
},

The next option is the seeds method which takes in a parameter called server. The seeds method helps create seeds(seeds are initial data or an entry into Mirage’s database) for our models. In our case to create the seeds for the todo model we do:

server.create("todo", { content: "Learn Mirage JS" })
server.create("todo", { content: "Integrate With Vue.js" })

so the server has a create method which expects as the first argument a string which corresponds to the name of the model, then an object which will contain the properties or attributes of a particular seed.

routes() {

    this.namespace = "api"

    this.get("/todos", schema => {
      return schema.todos.all()
    })
  },

finally, we have the routes method which defines the various route(routes are our mock API endpoints) Mirage JS is going to mock. Let’s look at the body of the method:

this.namespace = "api"

this line sets up the namespace for all routes that means our todo route can now be accessed from /api/todos.

this.get("/todos", schema => {
  return schema.todos.all()
})

The above creates a get route and it’s handler using the this.get() method. The get() method expects the route i.e “/todos” and a handler function that takes in schema as an argument. The schema object is how you interact with Mirage’s ORM which is powered by Mirage JS in-memory database.

Finally:

return schema.todos.all()

We are returning a list of all our todos, using the schema object made possible by Mirage’s ORM.

src/main.js

So we are done setting up src/server.js but Vue doesn’t know about it(at least not yet). So let’s import it in our main.js file like so:

import { makeServer } from "./server"

Then we call the makeServer function like so:

if (process.env.NODE_ENV === "development") {
  makeServer()
}

The above if conditional is a guard to make sure mirage only runs in development.

Set up Complete!

Now we’ve set up Miragejs with Vue. Let’s see it in action. In our App.vue file, we would clear out the content and replace with the below snippet:

<template>
  <ul id="todos">
    <li v-for="todo in todos" v-bind:key="todo.id">{{ todo.content }}</li>
  </ul>
</template>

<script>
  export default {
    name: 'app',

    data() {
      return {
        todos: []
      }
    },

    created() {
      fetch("/api/todos")
        .then(res => res.json())
        .then(json => {
          this.todos = json.todos
        })
    }
  }
</script>

If you are familiar with Vue.js, the above would be nothing new but for the sake of being total, what we are doing is making an API request using fetch when our App.vue component is created, then we pass in the returned data to the todos array in our component state. Afterward, we are using a v-for to iterate the todos array and displaying the content property of each todo.

Where Is The Mirage JS Part?

If you notice, in our App.vue component, we didn’t do anything specific to Mirage, we are just making an API call as we would normally do. This feature of Mirage is really great for DX cause under the hood, Mirage would intercept any requests that match any of the routes defined in src/server.js while you are in development.

This is pretty handy cause no work would be needed in your part to switch to an actual production server when you are in a production environment provided the routes match your production API endpoints.

So restart your Vue dev server via yarn serve to test Mirage JS.

You should see a list of two todos. One thing you’d find pretty interesting is that we did not need to run a terminal command to start up Mirage because it removes that overhead by running as a part of your Vue.js application.

Mirage JS And Vue test-utils

If you are already using Vue Test-utils in your Vue application, you’d find it exciting to know that Mirage can easily work with it to mock network requests. Let’s see an example set up using our todos application.

We would be using Jest for our unit-testing. So if you are following along, you could pretty much use the Vue CLI to install the @vue/unit-jest plugin like so:

vue add @vue/unit-jest

The above will install @vue/cli-plugin-unit-jest and @vue/test-utils development dependencies while also creating a tests directory and a jest.config.js file. It will also add the following command in our package.json scripts section (pretty neat):

"test:unit": "vue-cli-service test:unit"

Let’s Test!

We would update our App.vue to look like this:

<!-- src/App.vue -->
<template>
  <div v-if="serverError" data-testid="server-error">
    {{ serverError }}
  </div>

  <div v-else-if="todos.length === 0" data-testid="no-todos">
    No todos!
  </div>

  <div v-else>
    <ul id="todos">
      <li
        v-for="todo in todos"
        v-bind:key="todo.id"
        :data-testid="'todo-' + todo.id"
      >
        {{ todo.content }}
      </li>
    </ul>
  </div>
</template>

<script>
  export default {
    name: "app",

    data() {
      return {
        todos: [],
        serverError: null,
      }
    },

    created() {
      fetch("/api/todos")
        .then(res => res.json())
        .then(json => {
          if (json.error) {
            this.serverError = json.error
          } else {
            this.todos = json.todos
          }
        })
    },
  }
</script>

Nothing really epic is going on in the above snippet; we are just structuring to allow for the network testing we would be implementing with our unit test.

Although Vue CLI has already added a /tests folder for us, I find it to be a much better experience when my tests are placed close to the components they are testing. So create a /__tests__ folder in src/ and create an App.spec.js file inside it. (This is also the recommended approach by Jest.)

// src/__tests__/App.spec.js
import { mount } from "@vue/test-utils"
import { makeServer } from "../server"
import App from "../App.vue"

let server

beforeEach(() => {
  server = makeServer({ environment: "test" })
})

afterEach(() => {
  server.shutdown()
})

So to set up our unit testing, we are importing the mount method from @vue/test-utils, importing the Miragejs server we created earlier and finally importing the App.vue component.

Next, we are using the beforeEach life cycle function to start the Mirage JS server while passing in the test environment. (Remember, we set by default the environment to be development.)

Lastly, we are shutting down the server using server.shutdown in the afterEach lifecycle method.

Our Tests

Now let’s flesh out our test (we would be adopting the quickstart section of the Mirage js docs. So your App.spec.js would finally look like this:

// src/__tests__/App.spec.js

import { mount } from "@vue/test-utils"
import { makeServer } from "./server"
import App from "./App.vue"

let server

beforeEach(() => {
  server = makeServer({ environment: "test" })
})

it("shows the todos from our server", async () => {
  server.create("todo", { id: 1, content: "Learn Mirage JS" })
  server.create("todo", { id: 2, content: "Integrate with Vue.js" })

  const wrapper = mount(App)

  // let's wait for our vue component to finish loading data
  // we know it's done when the data-testid enters the dom.
  await waitFor(wrapper, '[data-testid="todo-1"]')
  await waitFor(wrapper, '[data-testid="todo-2"]')

  expect(wrapper.find('[data-testid="todo-1"]').text()).toBe("Learn Mirage JS")
  expect(wrapper.find('[data-testid="todo-2"]').text()).toBe("Integrate with Vue.js")
})

it("shows a message if there are no todo", async () => {
  // Don't create any todos

  const wrapper = mount(App)
  await waitFor(wrapper, '[data-testid="no-todos"]')

  expect(wrapper.find('[data-testid="no-todos"]').text()).toBe("No todos!")
})

// This helper method returns a promise that resolves
// once the selector enters the wrapper's dom.
const waitFor = function(wrapper, selector) {
  return new Promise(resolve => {
    const timer = setInterval(() => {
      const todoEl = wrapper.findAll(selector)
      if (todoEl.length > 0) {
        clearInterval(timer)
        resolve()
      }
    }, 100)
  })
}

afterEach(() => {
  server.shutdown()
})

Note: We are using a helper here (as defined in the Mirage JS docs). It returns a promise that allows us to know when the elements we are testing are already in the DOM.

Now run yarn test:unit.

All your tests should pass at this point.

Testing Different Server State With Mirage JS

We could alter our Mirage JS server to test for different server states. Let’s see how.

// src/__tests__/App.spec.js
import { Response } from "miragejs"

First, we import the Response class from Mirage, then we create a new test scenario like so:

it("handles error responses from the server", async () => {
  // Override Mirage's route handler for /todos, just for this test
  server.get("/todos", () => {
    return new Response(
      500,
      {},
      {
        error: "The database is taking a break.",
      }
    )
  })

  const wrapper = mount(App)

  await waitFor(wrapper, '[data-testid="server-error"]')

  expect(wrapper.find('[data-testid="server-error"]').text()).toBe(
    "The database is taking a break."
  )
})

Run your test and it all should pass.

Conclusion

This article aimed to introduce you to Mirage JS and show you how it makes for a better front-end development experience. We saw the problem Mirage JS created to address (building production-ready front-end without any actual backend API) and how to set it up with Vue.js.

Although this article scratched the surface of what Mirage JS can do, I believe it is enough to get you started.

  • You could go through the docs as well as join the Mirage JS discord server.
  • The supporting repo for this article is available on GitHub.

References

(dm, il)
Categories: Others Tags:

5 Pitfalls of User-Generated Content (And How to Avoid Them)

February 13th, 2020 No comments

It brings with it a host of benefits. UGC can greatly increase engagement with websites, as well as shareability and authenticity. Of course, along with benefits are a host of pitfalls, from having to take the time to moderate content, to establishing an engaged community to submit the content in the first place. It’s important to know the pitfalls of user generated content and how they can be avoided. With a clear strategy, and contingency plan in place, it can end up being a very successful and profitable way of driving engagement to a website.

Here are the pitfalls of user-generated content and how to fix them.

1. It Needs To Be Moderated

In an ideal world, all user generated content would stick to the rules and adhere to the site’s standards. Sadly, that’s not the case. Users will upload whatever they like, from inappropriate sites, to offensive words, or totally irrelevant content.

How To Avoid It

Ensure you build in features where content can be moderated. For example, review companies such as TripAdvisor rely on pre-moderation. This means that all reviews which are submitted are sent through a screening process before being put live for everyone to see. This can take a couple of days to sift through depending on the levels of content which has been uploaded, but ensures the site holds its reputation and doesn’t post offensive, random or meaningless content.

You can also implement functions for the UX of a site which means users can report content themselves. This is the system many large companies such as Facebook and Instagram have built in. The pros of this is that content is available instantly for other users to see and engage with but means unwanted content can also get through.

2. People Use It For Their Own Personal Gain

Once user generated content begins to roll in, it can soon increase the site’s popularity, raise the share count, and have numerous benefits. And this will be something others will latch onto. Users can submit their own content for personal gain, rather than that of the site. For example, a competitor could be promoting a service or running a competition and pretend to be a random user to publicise and promote their own products or services.

How To Avoid It

This comes under careful moderation again, but instead of just looking out for offensive or inappropriate content, you look at the context of what has been submitted and whether it’s for personal gain of the contributor. It’s worth adding in code so that any links submitted, automatically default to “no-follow.” Otherwise you’ll have people uploading content purely for a backlink to their own site. Also check the links they are submitting, where they are pointing to and if they are promoting, selling or advertising anything. You can build in a script that picks up certain keywords and blocks them from appearing or flags up certain comments. This can be a useful feature to easily filter through the genuine and the spam content.

3. You Need An Engaged Community To Continuously Generate New Content

It can take a while for a community to become engaged and known enough to submit content. Many companies rely on user generated content as part of their marketing strategy, yet don’t account for the initial time taken to gather loyal readers and contributors. With no users, there will be no user-submitted content. Simple, but true.

How To Avoid It

Get people to know the company and build a loyal following before requesting content. If those wanting to submit something stumble across your site and see it is under-developed, you have hardly any social media followers and no presence, they won’t see the worth in submitting anything. Build a solid base and learn what motivates people to want to submit content and get them excited about joining part of your community. Users want to have their work, ideas and submissions featured on an aesthetically pleasing site that has been well-designed and feels premium. Ensure plenty of thought has gone into the design process of the look of the site, as well as making the user journey to actually submit the content an easy one. People that find the process easy and rewarding will be likely to return and recommend it to others.

4. Copyright Infringement

With an in-house content creation team, submissions usually have to go through a process before they reach publication. They will be checked, assets confirmed as royalty-free and they will have a knowledge of what you can and what you can’t do. By allowing users to submit content you can be opening yourself to a myriad of copyright infringements on everything from duplicate content to image usage.

How To Avoid It

To avoid receiving a hefty copyright infringement lawsuit in your inbox, it’s important you put certain steps into place. With user generated content there are many questions about who is liable for third-party content if it turns out to be false, improper or harmful; unless you make it clear initially, the blame could fall on the website owner. Ensure you have a contract and guidelines in place that stipulates any content users submit is their own responsibility and they are liable should any issues arise. Make guidelines that states images should be royalty-free and available for re-use before they submit them.

5. Unverified Sources Can Damage Website Credibility

When users are free to submit whatever content they like, there is bound to be a fair amount of fake news. You can never really know who every person who submits something is, nor where they are getting their facts and statements from. Negative comments or sources can damage a brand, particularly when other users have no way of knowing if the contributor is trustworthy or not. After all, “If it’s on the internet, it must be true…”

How To Avoid It

Many sites have come across issues with this, with popular social media sites having many users create fake profiles of companies or celebrities. This can be very damaging to a brand and is why it is an idea to have verified users. Twitter and Instagram are known by the well-recognised blue tick which ensures other users know exactly who is posting content. Other sites such as Waze and TripAdvisor award badges to those who are loyal and regular contributors. Not only does this give an incentive to continually contribute, but other users (and moderators) know they are more trustworthy and less likely to post spam or malicious content that could damage the reputation of a site.

Featured image via Unsplash.

Source

Categories: Designing, Others Tags:

2020 Stack

February 12th, 2020 No comments

In an article with the most clickbaity article ever, Joe Honton does a nice job of talking about the evolving landscape of web development. “Full-stack” perhaps had its day as a useful term, but since front-end development touches so many parts of the stack now, it’s not a particularly useful term. Joe himself did a lot to popularize it, so it does feel extra meaningful coming from him.

Plus the spectrum of how much there is to know is so wide we can’t all know it all, so to get things done, we take what we do know and slot ourselves into cross-functional teams.

Since no one person can handle it all, the 2020 stack must be covered by a team. Not a group of individuals, but a true team. That means that when one person is falling behind, another will pick up the slack. When one person has superior skills, there’s a mechanism in place for mentoring the others. When there’s a gap in the team’s knowledge-base, they seek out and hire a team member who’s smarter than all of them.

So the “2020 Stack” is essentially “know things and work on teams” more so than any particular combination of technologies. That said, Joe does have opinions on technologies, including writing HTML in some weird GraphQL looking syntax that I’d never seen before.

Direct Link to ArticlePermalink

The post 2020 Stack appeared first on CSS-Tricks.

Categories: Designing, Others Tags:

Toward Responsive Elements

February 12th, 2020 No comments

Hot news from Brian Kardell, regarding what we’ve been referring to as “container queries”, the most hotly requested feature in CSS:

There does seem to be some general agreement on at least one part of what I am going to call instead “Responsive Design for Components” and that is that flipping the problem on its head is better.

The flipping here sounds like instead of doing it as media query, we do it at the property level.

.foo {
  display: grid;
  grid-template-columns: switch(
    (available-inline-size > 1024px) 1fr 4fr 1fr;
    (available-inline-size > 400px) 2fr 1fr;
    (available-inline-size > 100px) 1fr;
    default 1fr;
  );
}

I think this is still in the ideation phase, and other people are ideating as well on different ideas, but this seems worth sharing to me as it sounds like it has traction and is doable because it isn’t plagued with well that’s just not how browsers work that came up a lot with container queries.

Brian also talks about “lightspeed progress” lately, for example:

Consider that we shifted the stalemate conversation and ResizeObserver was envisioned, incubated, speced, tested, agreed upon, iterated on (we got things wrong!) and implemented in all browsers in about 2 years

Two years is smokin’ in standards.

Direct Link to ArticlePermalink

The post Toward Responsive Elements appeared first on CSS-Tricks.

Categories: Designing, Others Tags: