Tech News

Choosing The Right UI Design Deliverables

Usability Geek - Tue, 04/23/2019 - 12:37pm
When I moved into an apartment of my own, my first purchase was a brand new, fully-stocked toolbox. After I got home and started to assemble some furniture, I opened my pristine toolbox, grabbed my...
Categories: Web Standards

Who Are Design Systems For?

Css Tricks - Tue, 04/23/2019 - 10:46am

Specific design systems, I mean. Design systems, as a concept, are something just about any site can benefit from.

A lot of hype goes into design systems these days. Just the other day, an organization's published their design system publicly and I got a slew of DMs, emails, and Slack messages encouraging me to check it out. "Looks good to me," I said. But I'm merely knocking on the hood of a new car, so to speak. I haven't sat in it. I haven't driven it around the block, let alone driven it cross-country or tried to dig Cheerios out from between the seats. I'm sure I'd have more opinions after building a site or 10 with it (excuse the mixed metaphors).

So that leads me to a few questions. Can I build a site with this design system? Should I build a site with it? Is it for me? Or wait... who is this for?

They all have accordions.

Well not all of them, but bear with me, because there is a point to be made.

Bootstrap has an accordion too! Developers totally understand Bootstrap.

Whatever you think of it, I don't see much confusion around Bootstrap. You link up the CSS, you use the HTML they give you and — 💥 — you have components that are ready to rock.

It's possible that Bootstrap is a more of a "pattern library" than a "design system." I dunno. There is probably something to that distinction, but the naming semantics (if there are any) seem to be used interchangeably, so distinguishing Bootstrap as one or the other doesn't alleviate any confusion.

Developers reach for Bootstrap because...

  • It helps them build faster.
  • They get good quality "out of the box" if they aren't particularly great at HTML and CSS themselves.
  • They want to be accessible and Bootstrap has been through the accessibility ringer.
  • [Insert your reason.]

Appealing, yet these seem to be somewhat table stakes for any design system and not exclusive to Bootstrap alone.

Hmmmm... Maybe I'll have a gander around and choose a non-Bootstrap solution for my next project.

A lot of people are in this boat.

Maybe the next project is React so we want a design system that makes React a first-class citizen. Maybe we had trouble customizing Bootstrap to our liking. Maybe we just saw the default look of another design system and thought that would be a better fit. Maybe we are just bored of Bootstrap. Lots of reasons to look outside of Bootstrap, just as there are lots of reasons to look to it.

Since other design systems have accordions, too, can't I just... pick one?

Sorta?

One immediate consideration is the license. Salesforce's Lightning Design System is often pointed to as a leader in the world of design systems and has influenced a lot of the current thinking around them. Yet, it is not open source licensed.

That's not a problem — it's probably a good thing for Lightning. It's not a general purpose grab-it-and-go for all web developers on Earth as the target audience. It's for Salesforce and the slew of teams on different development stacks building things for Salesforce. If you're not building a Salesforce thing, it's not for you.

Then why is it public and not some internal document for the Salesforce team? I can't answer for them, but as I understand it, Salesforce is so enormous that they have both internal and external teams using it. So, perhaps making Lightning a public document is the most useful way to make it available to everyone who needs it.

This is something we’re actively discussing on the SLDS team. What exactly does “open source” mean to design systems when the usage is so specific? Is it more “source available?

— Alexis Córdova (@acordova) April 9, 2019

There's also the nice side effect that they get good press for it, and that can't hurt hiring efforts. I've also heard having a public design system can spark interesting and useful conversations.

Carbon Design System, on the other hand, is open source licensed. They also have an entire section explaining who should use the system:

Carbon is the official implementation of the IBM Design Language for product and web designers, and represents an ever-growing ecosystem of design assets and guidance. With a comprehensive set of human interface guidelines, design kits, and documentation, Carbon helps designers work faster and smarter.

That doesn't quite tell me what I want to know. It looks like IBM stuff out of the box, so it's definitely for IBM.

It's open source so I can use it if I want to. But is it really for me and my random projects? Do they want me to use it for that? Am I, random developer, who they are thinking about with this project? Or is it IBM-first, random developer second?

Company first, the world second.

If a design system is by a company, then it's for the company. It might also be open source, but any ol' random developer who wants to use it isn't the target audience.

It might not even technically be a company who makes it. It could be a government!

One really great design system is the U.S. Web Design System, which just went 2.0. It's gorgeous! It looks very complete and has some great features. It's got a classy custom font, it was designed with incremental adoption in mind, it has both useful components as well as utilities, and was built atomically from design tokens. Perhaps the best feature is that it's extremely accessible because it has to be by law.

The U.S. Web Design System is mostly public domain, so you totally can use it. But it's not designed with you in mind; it's designed to help people who make website for the government.

(By the way, The U.S. Web Design System is open to contribution, which is pretty cool because it's a way you could make a significant impact on websites that are very important to people's lives.)

My mindset is that open source design systems are not meant be reused and spin up for yourself, but to learn from and apply to your own

— Mike Dick (@miked1ck) April 9, 2019

Here's another kicker: There is a spectrum of customizability to design systems, on purpose.

Even if you technically can use a public design system you've found and like, you might consider the customizability angle. There is a whole spectrum to this, but let's consider the extreme edges and middle:

  • Zero Customizability: We built this to strongly enforce consistency for ourselves.
  • Pre-Selected Variations: We've got accordions in three different colors.
  • BYO Theme: We'll give you a skeleton that loosely achieves the pattern and you apply the styles to your liking.

There are design systems at all points on this spectrum. Bootstrap might be in between the last two, where you get a fully styled theme, but customizability largely comes via setting Sass variables and that creates infinite variations.

Polaris, Shopify's design system, is open source, but definitely for Shopify stuff. They are intentionally not trying to do what Bootstrap does. It's far more about enforced consistency and adhering to a cohesive brand than it is slapping together and customizing a page.

Material Design is definitely Google's thing. In its early days, I feel like the messaging was that this is Google's cohesive design work. But these days, they definitely encourage other developers to use it too. If you do, your thing will look a lot like a Google thing. Maybe that's what you want, maybe it's not. Either way, you should know what you're getting into.

Google's take on customizability so far is a Sketch plugin. They have no incentive to allow for a level of customization to make things not look like Google, because that would be antithetical to the whole thing.

In case this isn't obvious (and I very much fear that it isn't), design systems aren't a commodity. We don't get to simply pick the one that has the nicest accordion and use it on the next project. We might not even be allowed to use it. It might be intentionally branded for a specific company. There are all kinds of factors to consider here.

My parting advice is actually to the makers of public design systems: clearly identify who this design system is for and what they are able to do with it.

I'd also like to note that everyone who I've brought this up to in the last few weeks has had different opinions about all this target audience messaging stuff in design systems. Of course, I'd love to read your comments about how you feel about it.

The post Who Are Design Systems For? appeared first on CSS-Tricks.

The Circle of a React Lifecycle

Css Tricks - Tue, 04/23/2019 - 5:44am

A React component goes through different phases as it lives in an application, though it might not be evident that anything is happening behind the scenes.

Those phases are:

  • mounting
  • updating
  • unmounting
  • error handling

There are methods in each of these phases that make it possible to perform specific actions on the component during that phase. For example, when fetching data from a network, you’d want to call the function that handles the API call in the componentDidMount() method, which is available during the mounting phase.

Knowing the different lifecycle methods is important in the development of React applications, because it allows us to trigger actions exactly when they’re needed without getting tangled up with others. We’re going to look at each lifecycle in this post, including the methods that are available to them and the types of scenarios we’d use them.

The Mounting Phase

Think of mounting as the initial phase of a component’s lifecycle. Before mounting occurs, a component has yet to exist — it’s merely a twinkle in the eyes of the DOM until mounting takes place and hooks the component up as part of the document.

There are plenty of methods we can leverage once a component is mounted: constructor() , render(), componentDidMount() and static getDerivedStateFromProps(). Each one is handy in it’s own right, so let’s look at them in that order.

constructor()

The constructor() method is expected when state is set directly on a component in order to bind methods together. Here is how it looks:

// Once the input component is mounting... constructor(props) { // ...set some props on it... super(props); // ...which, in this case is a blank username... this.state = { username: '' }; // ...and then bind with a method that handles a change to the input this.handleInputChange = this.handleInputChange.bind(this); }

It is important to know that the constructor is the first method that gets called as the component is created. The component hasn’t rendered yet (that’s coming) but the DOM is aware of it and we can hook into it before it renders. As a result, this isn’t the place where we’d call setState() or introduce any side effects because, well, the component is still in the phase of being constructed!

I wrote up a tutorial on refs a little while back, and once thing I noted is that it’s possible to set up ref in the constructor when making use of React.createRef(). That’s legit because refs is used to change values without props or having to re-render the component with updates values:

constructor(props) { super(props); this.state = { username: '' }; this.inputText = React.createRef(); } render()

The render() method is where the markup for the component comes into view on the front end. Users can see it and access it at this point. If you’ve ever created a React component, then you’re already familiar with it — even if you didn’t realize it — because it’s required to spit out the markup.

class App extends React.Component { // When mounting is in progress, please render the following! render() { return ( <div> <p>Hello World!</p> </div> ) } }

But that’s not all that render() is good for! It can also be used to render an array of components:

class App extends React.Component { render () { return [ <h2>JavaScript Tools</h2>, <Frontend />, <Backend /> ] } }

...and even fragments of a component:

class App extends React.Component { render() { return ( <React.Fragment> <p>Hello World!</p> </React.Fragment> ) } }

We can also use it to render components outside of the DOM hierarchy (a la React Portal):

// We're creating a portal that allows the component to travel around the DOM class Portal extends React.Component { // First, we're creating a div element constructor() { super(); this.el = document.createElement("div"); } // Once it mounts, let's append the component's children componentDidMount = () => { portalRoot.appendChild(this.el); }; // If the component is removed from the DOM, then we'll remove the children, too componentWillUnmount = () => { portalRoot.removeChild(this.el); }; // Ah, now we can render the component and its children where we want render() { const { children } = this.props; return ReactDOM.createPortal(children, this.el); } }

And, of course, render() can — ahem — render numbers and strings...

class App extends React.Component { render () { return "Hello World!" } }

...as well as null or Boolean values:

class App extends React.Component { render () { return null } } componentDidMount()

Does the componentDidMount() name give away what it means? This method gets called after the component is mounted (i.e. hooked to the DOM). In another tutorial I wrote up on fetching data in React, this is where you want to make a request to obtain data from an API.

We can have your fetch method:

fetchUsers() { fetch(`https://jsonplaceholder.typicode.com/users`) .then(response => response.json()) .then(data => this.setState({ users: data, isLoading: false, }) ) .catch(error => this.setState({ error, isLoading: false })); }

Then call the method in componentDidMount() hook:

componentDidMount() { this.fetchUsers(); }

We can also add event listeners:

componentDidMount() { el.addEventListener() }

Neat, right?

static getDerivedStateFromProps()

It’s kind of a long-winded name, but static getDerivedStateFromProps() isn’t as complicated as it sounds. It’s called before the render() method during the mounting phase, and before the update phase. It returns either an object to update the state of a component, or null when there’s nothing to update.

To understand how it works, let’s implement a counter component which will have a certain value for its counter state. This state will only update when the value of maxCount is higher. maxCount will be passed from the parent component.

Here’s the parent component:

class App extends React.Component { constructor(props) { super(props) this.textInput = React.createRef(); this.state = { value: 0 } } handleIncrement = e => { e.preventDefault(); this.setState({ value: this.state.value + 1 }) }; handleDecrement = e => { e.preventDefault(); this.setState({ value: this.state.value - 1 }) }; render() { return ( <React.Fragment> <section className="section"> <p>Max count: { this.state.value }</p> <button onClick={this.handleIncrement} class="button is-grey">+</button> <button onClick={this.handleDecrement} class="button is-dark">-</button> </section> <section className="section"> <Counter maxCount={this.state.value} /> </section> </React.Fragment> ) } }

We have a button used to increase the value of maxCount, which we pass to the Counter component.

class Counter extends React.Component { state={ counter: 5 } static getDerivedStateFromProps(nextProps, prevState) { if (prevState.counter < nextProps.maxCount) { return { counter: nextProps.maxCount }; } return null; } render() { return ( <div className="box"> <p>Count: {this.state.counter}</p> </div> ) } }

In the Counter component, we check to see if counter is less than maxCount. If it is, we set counter to the value of maxCount. Otherwise, we do nothing.

You can play around with the following Pen below to see how that works on the front end:

See the Pen
getDerivedStateFromProps
by Kingsley Silas Chijioke (@kinsomicrote)
on CodePen.

The Updating Phase

The updating phase occurs when a component when a component’s props or state changes. Like mounting, updating has its own set of available methods, which we’ll look at next. That said, it’s worth noting that both render() and getDerivedStateFromProps() also get triggered in this phase.

shouldComponentUpdate()

When the state or props of a component changes, we can make use of the shouldComponentUpdate() method to control whether the component should update or not. This method is called before rendering occurs and when state and props are being received. The default behavior is true. To re-render every time the state or props change, we’d do something like this:

shouldComponentUpdate(nextProps, nextState) { return this.state.value !== nextState.value; }

When false is returned, the component does not update and, instead, the render() method is called to display the component.

getSnapshotBeforeUpdate()

One thing we can do is capture the state of a component at a moment in time, and that’s what getSnapshotBeforeUpdate() is designed to do. It’s called after render() but before any new changes are committed to the DOM. The returned value gets passed as a third parameter to componentDidUpdate().

It takes the previous state and props as parameters:

getSnapshotBeforeUpdate(prevProps, prevState) { // ... }

Use cases for this method are kinda few and far between, at least in my experience. It is one of those lifecycle methods you may not find yourself reaching for very often.

componentDidUpdate()

Add componentDidUpdate() to the list of methods where the name sort of says it all. If the component updates, then we can hook into it at that time using this method and pass it previous props and state of the component.

componentDidUpdate(prevProps, prevState) { if (prevState.counter !== this.state.counter) { // ... } }

If you ever make use of getSnapshotBeforeUpdate(), you can also pass the returned value as a parameter to componentDidUpdate():

componentDidUpdate(prevProps, prevState, snapshot) { if (prevState.counter !== this.state.counter) { // .... } } The Unmounting Phase

We’re pretty much looking at the inverse of the mounting phase here. As you might expect, unmounting occurs when a component is wiped out of the DOM and no longer available.

We only have one method in here: componentWillUnmount()

This gets called before a component is unmounted and destroyed. This is where we would want to carry out any necessary clean up after the component takes a hike, like removing event listeners that may have been added in componentDidMount(), or clearing subscriptions.

// Remove event listener componentWillUnmount() { el.removeEventListener() } The Error Handling Phase

Things can go wrong in a component and that can leave us with errors. We’ve had error boundary around for a while to help with this. This error boundary component makes use of some methods to help us handle the errors we could encounter.

getDerivedStateFromError()

We use getDerivedStateFromError() to catch any errors thrown from a descendant component, which we then use to update the state of the component.

class ErrorBoundary extends React.Component { constructor(props) { super(props); this.state = { hasError: false }; } static getDerivedStateFromError(error) { return { hasError: true }; } render() { if (this.state.hasError) { return ( <h1>Oops, something went wrong :(</h1> ); } return this.props.children; } }

In this example, the ErrorBoundary component will display “Oops, something went wrong” when an error is thrown from a child component. We have a lot more info on this method in a wrap up on goodies that were released in React 16.6.0.

componentDidCatch()

While getDerivedStateFromError() is suited for updating the state of the component in cases where where side effects, like error logging, take place, we ought to make use of componentDidCatch() because it is called during the commit phase, when the DOM has been updated.

componentDidCatch(error, info) { // Log error to service }

Both getDerivedStateFromError() and componentDidCatch() can be used in the ErrorBoundary component:

class ErrorBoundary extends React.Component { constructor(props) { super(props); this.state = { hasError: false }; } static getDerivedStateFromError(error) { return { hasError: true }; } componentDidCatch(error, info) { // Log error to service } render() { if (this.state.hasError) { return ( <h1>Oops, something went wrong :(</h1> ); } return this.props.children; } } And that’s the lifecycle of a React component!

There’s something neat about knowing how a React component interacts with the DOM. It’s easy to think some “magic” happens and then something appears on a page. But the lifecycle of a React component shows that there’s order to the madness and it’s designed to give us a great deal of control to make things happen from the time the component hits the DOM to the time it goes away.

We covered a lot of ground in a relatively short amount of space, but hopefully this gives you a good idea of not only how React handles components, but what sort of capabilities we have at various stages of that handling. Feel free to leave any questions at all if anything we covered here is unclear and I’d be happy to help as best I can!

The post The Circle of a React Lifecycle appeared first on CSS-Tricks.

Netlify Functions for Sending Emails

Css Tricks - Tue, 04/23/2019 - 4:26am

Let's say you're rocking a JAMstack-style site (no server-side languages in use), but you want to do something rather dynamic like send an email. Not a problem! That's the whole point of JAMstack. It's not just static hosting. It's that plus doing anything else you wanna do through JavaScript and APIs.

Here's the setup: You need a service to help you send the email. Let's just pick Sparkpost out of a hat. There are a number of them, and I'll leave comparing their features and pricing to you, as we're doing something extremely basic and low-volume here. To send an email with Sparkpost, you hit their API with your API key, provide information about the email you want to send, and Sparkpost sends it.

So, you'll need to run a little server-side code to protect your API key during the API request. Where can you run that code? A Lambda is perfect for that (aka a serverless function or cloud function). There are lots of services to help you run these, but none are easier than Netlify, where you might be hosting your site anyway.

Get Sparkpost ready

I signed up for Sparkpost and made sure my account was all set up and verified. The dashboard there will give you an API key:

Toss that API Key into Netlify

Part of protecting our API key is making sure it's only used in server-side code, but also that we keep it out of our Git repository. Netlify has environment variables that expose it to functions as needed, so we'll plop it there:

Let's spin up Netlify Dev, as that'll make this easy to work with

Netlify Dev is a magical little tool that does stuff like run our static site generator for us. For the site I'm working on, I use Eleventy and Netlify Dev auto-detects and auto-runs it, which is super neat. But more importantly, for us, it gives us a local URL that runs our functions for testing.

Once it's all installed, running it should look like this:

In the terminal screenshot above, it shows the website itself being spun up at localhost:8080, but it also says:

? Lambda server is listening on 59629

That'll be very useful in a moment when we're writing and testing our new function — which, by the way, we can scaffold out if we'd like. For example:

netlify functions:create --name hello-world

From there, it will ask some questions and then make a function. Pretty useful to get started quickly. We'll cover writing that function in a moment, but first, let's use this...

Sparkpost has their own Node lib

Sparkpost has an API, of course, for sending these emails. We could look at those docs and learn how to hit their URL endpoints with the correct data.

But things get even easier with their Node.js bindings. Let's get this set up by creating all the folders and files we'll need:

/project ... your entire website or whatever ... /functions/ /send-email/ package.json send-email.js

All we need the package.json file for is to yank in the Sparkpost library, so npm install sparkpost --save-dev will do the trick there.

Then the send-email.js imports that lib and uses it:

const SparkPost = require('sparkpost'); const client = new SparkPost(process.env.SPARKPOST); exports.handler = function(event, context, callback) { client.transmissions .send({ content: { from: 'chris@css-tricks.com', subject: 'Hello, World!', html: "<html><body><p>My cool email.</p></body></html>" }, recipients: [{ address: 'chriscoyier@gmail.com' }] }); }

You'll want to look at their docs for error handling and whatnot. Again, we've just chosen Sparkpost out of a hat here. Any email sending service will have an API and helper code for popular languages.

Notice line 2! That's where we need the API key, and we don't need to hard-code it because Netlify Dev is so darn fancy that it will connect to Netlify and let us use the environment variable from there.

Test the function

When Netlify Dev is running, our Lamba functions have that special port they are running. We'll be able to have a URL like this to run the function:

http://localhost:34567/.netlify/functions/send-email

This function is set up to run when it's hit, so we could simply visit that in a browser to run it.

Testing

Maybe you'll POST to this URL. Maybe you'll send the body of the email. Maybe you'll send the recipient's email address. It would be nice to have a testing environment for all of this.

Well, we can console.log() stuff and see it in the terminal, so that's always handy. Plus we can write our functions to return whatever, and we could look at those responses in some kind of API testing tool, like Postman or Insomnia.

It works!

I'll leave it to you to get fancy with it ;)

The post Netlify Functions for Sending Emails appeared first on CSS-Tricks.

Could Grouping HTML Classes Make Them More Readable?

Css Tricks - Mon, 04/22/2019 - 9:45am

You can have multiple classes on an HTML element:

<div class="module p-2"></div>

Nothing incorrect or invalid there at all. It has two classes. In CSS, both of these will apply:

.module { } .p-2 { } const div = document.querySelector("div"); console.log(div.classList.contains("module")); // true console.log(div.classList.contains("p-3")); // false

But what about grouping them? All we have here is a space-separated string. Maybe that's fine. But maybe we can make things more clear!

Years ago, Harry Roberts talked about grouping them. He wrapped groups of classes in square brackets:

<div class="[ foo foo--bar ] [ baz baz--foo ]">

The example class names above are totally abstract just to demonstrate the grouping. Imagine they are like primary names and variations as one group, then utility classes as another group:

<header class="[ site-header site-header-large ] [ mb-10 p-15 ]">

Those square brackets? Meaningless. Those are there to visually represent the groups to us developers. Technically, they are also classes, so if some sadist wrote .[ {}, it would do stuff in your CSS. But that's so unlikely that, hopefully, the clarity from the groups outweighs it and is more helpful.

That example above groups the primary name and a variation in one group and some example utility classes in another group.

I'm not necessarily recommending that approach. They are simply groups of classes that you might have.

Here's the same style of grouping, with different groups:

<button class="[ link-button ] [ font-base text-xs color-primary ] [ js-trigger ]" type="button" hidden>

That example has a single primary name, utility classes with different naming styles, and a third group for JavaScript specific selectors.

Harry wound up shunning this approach a few years ago, saying that the look of it was just too weird for the variety of people and teams he worked with. It caused enough confusion that the benefits of grouped classes weren't worth it. He suggested line breaks instead:

<div class="media media--large testimonial testimonial--main">

That seems similarly clear to me. The line breaks in HTML are totally fine. Plus, the browser will have no trouble with that and JSX is generally written with lots of line breaks in HTML anyway because of how much extra stuff is plopped onto elements in there, like event handlers and props.

Perhaps we combine the ideas of line breaks as separators and identified groups... with emojis!

See the Pen
Grouping Classes
by Chris Coyier (@chriscoyier)
on CodePen.

Weird, but fun. Emojis are totally valid there. Like the square brackets, they could also do things if someone wrote a class name for them, but that's generally unlikely and something for a team to talk about.

Another thing I've seen used is data-* attributes for groups instead of classes, like...

<div class="primary-name" data-js="js-hook-1 js-hook-2" data-utilities="padding-large" >

You can still select and style based on attributes in both CSS and JavaScript, so it's functional, though slightly less convenient because of the awkward selectors like [data-js="js-hook-1"] and lack of convenient APIs like classList.

How about you? Do you have any other clever ideas for class name groups?

The post Could Grouping HTML Classes Make Them More Readable? appeared first on CSS-Tricks.

So, You Wanna Submit a Proposal to Speak at an Event

Css Tricks - Mon, 04/22/2019 - 4:38am

You’ve been scouring the web for upcoming events. You’ve subscribed to Developer Avocados and you’ve bookmarked conferences.css-tricks.com. And now you’ve found a call for proposals (CFP) that you can’t wait to enter. You quickly fill out the online form and your pinky races towards the Enter button...

Stop. Take a deep breath. And move slowly away from the keyboard.

As a conference organizer, I’ve gone through hundreds — if not thousands — of speaking proposals. While many are excellent, there are always a bunch that show a profound misunderstanding of the event, audience, and duties of a speaker. These are the ones that immediately get dumped onto the "No Thanks" list on my Trello board. And, as a regular speaker, I’ve learned more than a few things about getting proposals accepted.

While there’s no magic bullet for fast tracking your talk, there are a number of habits you can develop and questions you can ask yourself before hitting "submit" to improve your chances of getting invited to events. If you’re a fan of checklists, I’ve put one together to guide you through the process of submitting a proposal.

It’s even available on CodePen. &#x1f609;

See the Pen
The CFP Checklist
by Jason Rodriguez (@rodriguezcommaj)
on CodePen.

Start with some research

The first thing before submitting a proposal is to research the heck out of the event.

There are a ton of events out there, each with its own unique audience and vibe. Some are big, some are small; some have huge budgets and some are bootstrapped and brand new. Your first task as a potential speaker is to learn as much as you can about the event to make sure that you’re a good fit for it and the audience. There are a few ways to do this.

First, check out the website to get a feel for the event. See when and where it is, check out past years (if there are any), and read every last bit of copy on the site. A few things to keep an eye out for: an FAQ page, a CFP page, info about sponsorships or speaking opportunities, lists of past speakers, and a hashtag. The event hashtag is important, as that will allow you to check out hype and past attendee experiences on Twitter, as well to as get a sense of excitement about the upcoming event. If there isn’t a hashtag, or all of the comments about the event are terrible, then perhaps it’s time to move on to the next CFP.

Next, do a search on YouTube, Speaker Deck, SlideShare, and Notist for past talks and slide decks. These will give you a great idea of what to expect at the event and what kinds of talks go over well with the audience.

After you’ve completed a first pass of research, it’s time to answer some key questions:

  • When and where is the event?
  • Who’s organizing it?
  • Do they have a code of conduct?
  • Do they value diversity and inclusion?
  • Are they looking for specific topics or proposals?
  • Do they cover travel/hotel?
  • Do they pay speakers?
  • Most importantly: who is their audience?

You may not be able to find an answer to all of these, but try your hardest. Feel free to reach out to organizers — most are happy to answer questions for potential speakers, and the more you know, the better you’ll be able to determine whether or not you’re a good fit for their event.

Add focus your idea

After you’ve done your research, it’s time to focus in on your proposal idea. Chances are good that you’re hunting around for events with a talk idea already in mind, but even so, you should take a few steps to make it’s as compelling for organizers as possible.

The main question you want to answer when developing a talk idea is, "What will attendees get out of my session?" This is where knowing about the audience and event — all of that research — pays off.

Far too many would-be speakers submit proposals for the wrong reasons. Many think of events as marketing and sales opportunities for their business. Others are looking to make a name for themselves so they can start charging on the speakers circuit. But the best talks come from sharing personal experiences, challenges, and solutions to problems you’ve experienced in your own work.

By researching the audience, you can determine what’s likely to be important to them. You get a feel for their challenges and interests, and you can think more deeply about how your experiences and skills can best serve them. Try to forget about the actual organizers and making a pitch to them, and instead focus all of your energy on clearly communicating how attendees’ lives and work will be improved after they sit in on your session.

A great exercise is to list out the key things attendees would take away from your talk. Try to focus on 3-5 things that people can put to work when they get back home. Making them as actionable as possible is a fantastic idea. While some proposals are all about inspiration, wrapping practical advice into inspirational examples is an excellent way to make that inspiration stick in people’s minds.

Another suggestion is to run your idea by colleagues, friends, or your partner. Put together a two-minute summary, stand up in front of them, and give them the ol’ elevator pitch. Not only will this force you to add a clear focus to your idea, but it’ll let you know if you’re ready to get up on stage in front of strangers. If you can’t give a short talk in a few minutes now, then you should probably sit back down and prepare some more before answering that call for proposals.

Craft your proposal into something worth reading

Finally, it’s time to craft your proposal and get it ready to submit.

Most CFPs consist of an online form. They can range from a few questions to multiple pages of inputs, but you’ll be filling something out for organizers to review. Although some speakers are able to fly through the forms and quickly hit "Submit," I’d recommend prepping your CFPs outside of the form first.

Open up a text file or make a note in your app of choice on one side of your screen and the CFP form on the other. Go through each field in the form and write down your response in your notes. Putting together a rough draft outside of the form gives you the opportunity to think through your answers and edit them until they clearly reflect your focused idea and the value for attendees. What’s better is that you can take that note and share it with someone you trust and respect. Gather feedback from them and use it to further refine your proposal.

A lot of CFP ask for supporting materials. These can be videos showing that you are a clear communicator, links to your website or social media accounts showing your personal interests, or even slides from previous talks. Instead of fumbling around and potentially timing out the CFPs form (and having to start all over), collect all of those materials in your note or a folder on your computer. If you’re a seasoned speaker, make sure you curate your materials to show your best and most recent talks.

Submit and wait

OK. You’ve done the research. You’ve focused your idea. You’ve even drafted the answers to the CFP, pitched the idea to your partner in the kitchen, and collected feedback from a co-worker or two. It’s time to scratch that itch and submit your proposal.

Go back to the CFP form, open up your notes and resources, and start copying and pasting. Take your time to work through the form and triple-check that you’ve filled everything out. Attach any supporting materials (seriously, how many times have we all sent an email that says "See attached file" without actually attaching anything?) and take a deep breath. Scroll to the top and read through every response as many times as you need to before you feel comfortable submitting.

Now, press "Submit." Do a little celebration, take another deep breath, and move on with your life.

It can take a long time for organizers to process submissions and figure out an agenda. Try to be patient. It’s tempting to email organizers and ask about the status of your proposal, but resist the urge. Organizers are extraordinarily busy — with the conference and their full-time jobs — and should be left to review proposals instead of fielding emails from impatient potential speakers.

A good organizer will get back to you when they’re ready and let you know the status of your submission — good or bad. If they don’t, chances are the event wasn’t that great to begin with. The key thing is to try to forget about your submission as much as possible (while still keeping the event on your calendar, just in case) and focus on more important things. Not only will this ease your anxiety but you’ll be in for a wonderful surprise when your proposal is accepted.

Speaking at events can be incredibly rewarding. Sure, it’s massively time-consuming and, depending on your disposition, extremely stressful, but it’s an excellent way to build connections and help others in the industry. While you could start spamming every event with proposals, your chances of being invited to speak all hinge on the amount of preparation you put into your submission. Taking the time to make sure you’re a good fit for an event, that you understand the audience, and that you have a focus and are able to clearly communicate your idea will up the odds of you standing onstage, clicking through slides, and (hopefully) solving some problems for the folks that paid to be there.

I’m definitely not the first person to write about answering CFPs. There are a ton of good tips out there for crafting the perfect proposal. Here are a few of my favorites:

Finally, if you have any hesitation about not being "good enough" to speak at conferences, read this excellent post from Sara Wachter-Boettcher. Then start crafting that perfect proposal.

The post So, You Wanna Submit a Proposal to Speak at an Event appeared first on CSS-Tricks.

Inclusively Hidden

Css Tricks - Fri, 04/19/2019 - 9:31am

Scott O'Hara recently published "Inclusively Hidden," a nice walkthrough of the different ways to hide things on the web. Nothing is ever cut and dry when it comes to the web! What complicates this is that hidden begs the question: hidden for whom? Different answers to that have different solutions:

  • Hidden for everyone? display: none; or visibility: hidden; or the hidden attribute. (But watch out for that hidden attribute, says Monica Dinculescu.)
  • Hidden visually, but present for assistive tech? A .screen-reader-only class with a smattering of properties to do the job correctly.
  • Hidden for assistive tech, but not visually? The aria-hidden="true" attribute/value.

It's worth grokking all this because it's is a perfect example of why HTML and CSS is not some easy bolt-on skill for front-end web development. This is critical stuff that isn't done as correctly as it should be.

If you like video, I did one called "Hiding Things with CSS" that goes over a lot of this.

As I write this, I'm freshly back from Smashing Conf in San Francisco. Sara Soueidan had a wonderful talk that covered some "hiding things" situations that are even less intuitive than what we might be accustomed to seeing.

One thing she covered was the inert attribute and how it can be used to skip interactive elements from keyboard tabbing. It can even be used on a parent element, nullifying everything inside it. I understood that part, but not entirely why it's useful since it seems like you might as well use display: none; if an element is hidden and the elements inside aren't meant to be in focus. But I'm sure it's my lack of understanding, so I'm looking forward to Sara's video to come out so I can re-watch it. It had to do with maintaining a non-awkward tabbing order.

Another thing Sara covered is that some folks who use assistive technology also tend to explore touch screens with haptics, moving about the page with their fingers looking for interactive elements. If you, say, replace a native checkbox with a styled checkbox, it's possible to do that in a way thats mostly accessible by using a real checkbox that you hide and replace with a graphic, but Sara demoed how you can resize the checkbox over the top of the replacement and hide visually with opacity: 0; — that ensures someone can still find the element by touch. That doesn't seem to be the default way this kind of thing is taught or built, so it's great to see Sara calling it out. Yet another example of HTML and CSS being nuanced and tricky languages.

Direct Link to ArticlePermalink

The post Inclusively Hidden appeared first on CSS-Tricks.

Tabs: It’s Complicated™

Css Tricks - Fri, 04/19/2019 - 9:14am

I've said before one quick and powerful thing you can learn as a front-end developer just getting starting with JavaScript is changing classes.

const button = document.querySelector(".my-button"); const element = document.querySelector(".content"); button.addEventListener("click", function() { element.classList.toggle("sparkles"); });

We could use that skill to build some tabs, right? Right.

We got this.

Say we have this changing classes ability in our skillset now and we need to build a tabbed interface. If we just add a little more code that deals with click handlers, we could probably wire up some simple tabs, like this:

See the Pen
XQpqZV
by Chris Coyier (@chriscoyier)
on CodePen.

Totally functional tabs. I might pat myself on the back a little here. See how I used those anchor links to create jump links between the link and the tabbed section? That's mighty semantic, don't you think? The tabs are accessible with a keyboard, have focus styles, and can be activated with the Return key.

Did we win? Case closed? Perfect tabs?

Nothing is ever so easy, is it?

One issue here is that we didn't do anything special with keyboard handling, which tabbed interfaces may require. Heydon Pickering wrote about this:

Unlike a same-page link, a tab does not move the user to the associated section/panel of content. It just reveals the content visually. This is advantageous to sighted users (including sighted screen reader users) who wish to flit between different sections without having to wade back up the page each time they want to choose a new one.

This comes with an unfortunate side effect: If the user wishes to move to a section by keyboard and interact with its internal content, they have to step through any tabs to the right of the current tab, which are in focus order.

Turns out there is a whole checklist of other behavioral things tabs interfaces can and should be doing. In Heydon's explanation, the Tab key actually acts as a way to jump from the tab itself to the content related to that tab, actually moving the focus. Shift+Tab brings them back. Then the arrow keys are used to change tabs. All this requires more JavaScript and even some HTML to allow for the focus state... plus a sprinkle of aria-* attributes which I lack the expertise to explain you why they are important at all.

In the end, like this:

See the Pen
Tab Interface (PE)
by Heydon (@heydon)
on CodePen.

So the question becomes: are our class-changing skills actually a detriment to the web because they don't account for things like this? Is doing things with whatever basic tools we have a net loss for web accessibility? I dunno. Too big of a question for my little brain. It's interesting to consider, though.

Part of it comes down to muscle memory.

If we learn to code tabs like that first demo there, we'll tend to reach for that over and over so long as nobody bites our fingers off for doing it. I coded that demo in about three minutes because I've done it so many times. Creating those tabs is certainly part of my muscle memory.

There is plenty of talk about JavaScript frameworks being a scourge across the web because they seem to be ushering in an era of worst-in-class accessibility. But what if your muscle memory for building tabs was reaching for a pre-built tabs UI that brings along all the right functionality and left styling largely to you?

That's what Reach UI tabs are (which assumes we're working with React...).

I'm not telling you to go out and switch your projects to React so you can get some free tabs, but React is already massive. If good patterns like this become the defacto choice, then it's possible that the effect is a net gain on accessibility. Seems possible to me, anyway. It might just stop me from poorly hand-coding a tabbed interface for the 359th time.

The post Tabs: It’s Complicated™ appeared first on CSS-Tricks.

How to Get a Progressive Web App into the Google Play Store

Css Tricks - Fri, 04/19/2019 - 4:29am

PWA (Progressive Web Apps) have been with us for some time now. Yet, each time I try explaining it to clients, the same question pops up: "Will my users be able to install the app using app stores?" The answer has traditionally been no, but this changed with Chrome 72 which shipped a new feature called TWA (Trusted Web Activities).

Trusted Web Activities are a new way to integrate your web-app content such as your PWA with yourAndroid app using a protocol based on Custom Tabs.

In this article, I will use Netguru’s existing PWA (Wordguru) and explain step-by-step what needs to be done to make the application available and ready to be installed straight from the Google Play app store.

Some of the things we cover here may sound silly to any Android Developers out there, but this article is written from the perspective of a front-end developer, particularly one who has never used Android Studio or created an Android Application. Also, please do note that a lot of what we're covering here is still extremely experimental since it's limited to Chrome 72.

Step 1: Set up a Trusted Web Activity

Setting up a TWA doesn’t require you to write any Java code, but you will need to have Android Studio. If you’ve developed iOS or Mac software before, this is a lot like Xcode in that it provides a nice development environment designed to streamline Android development. So, grab that and meet me back here.

Create a new TWA project in Android Studio

Did you get Android Studio? Well, I can’t actually hear or see you, so I’ll assume you did. Go ahead and crack it open, then click on "Start a new Android Studio project." From there, let’s choose the "Add No Activity" option, which allows us to configure the project.

The configuration is fairly straightforward, but it’s always good to know what is what:

  • Name The name of the application (but I bet you knew that).
  • Package name: An identifier for Android applications on the Play Store. It must be unique, so I suggest using the URL of the PWA in reverse order (e.g. com.netguru.wordguru).
  • Save location: Where the project will exist locally.
  • Language: This allows us to select a specific code language, but there’s no need for that since our app is already, you know, written. We can leave this at Java, which is the default selection.
  • Minimum API level: This is the version of the Android API we’re working with and is required by the support library (which we’ll cover next). Let’s use API 19.

There are few checkboxes below these options. Those are irrelevant for us here, so leave them all unchecked, then move on to Finish.

Add TWA Support Library

A support library is required for TWAs. The good news is that we only need to modify two files to fill that requirement and the both live in the same project directory: Gradle Scripts. Both are named build.gradle, but we can distinguish which is which by looking at the description in the parenthesis.

There’s a Git package manager called JitPack that’s made specifically for Android apps. It’s pretty robust, but the bottom line is that it makes publishing our web app a breeze. It is a paid service, but I’d say it’s worth the cost if this is your first time getting something into the Google Play store.

Editor Note: This isn’t a sponsored plug for JitPack. It’s worth calling out because this post is assuming little-to-no familiarity with Android Apps or submitting apps to Google Play and it has less friction for managing an Android App repo that connects directly to the store. That said, it’s totally not a requirement.

Once you’re in JitPack, let’s connect our project to it. Open up that build.gradle (Project: Wordguru) file we just looked at and tell it to look at JitPack for the app repository:

allprojects { repositories { ... maven { url 'https://jitpack.io' } ... } }

OK, now let’s open up that other build.gradle file. This is where we can add any required dependencies for the project and we do indeed have one:

// build.gradle (Module: app) dependencies { ... implementation 'com.github.GoogleChrome:custom-tabs-client:a0f7418972' ... }

TWA library uses Java 8 features, so we’re going to need enable Java 8. To do that we need to add compileOptions to the same file:

// build.gradle (Module: app) android { ... compileOptions { sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 } ... }

There are also variables called manifestPlaceholders that we’ll cover in the next section. For now, let’s add the following to define where the app is hosted, the default URL and the app name:

// build.gradle (Module: app) android { ... defaultConfig { ... manifestPlaceholders = [ hostName: "wordguru.netguru.com", defaultUrl: "https://wordguru.netguru.com", launcherName: "Wordguru" ] ... } ... } Provide app details in the Android App Manifest

Every Android app has an Android App Manifest (AndroidManifest.xml) which provides essential details about the app, like the operating system it’s tied to, package information, device compatibility, and many other things that help Google Play display the app’s requirements.

The thing we’re really concerned with here is Activity (<activity>). This is what implements the user interface and is required for the "Activities" in "Trusted Web Activities."

Funny enough, we selected the "Add No Activity" option when setting up our project in Android Studio and that’s because our manifest is empty and contains only the application tag.

Let’s start by opening up the manfifest file. We’ll replace the existing package name with our own application ID and the label with the value from the manifestPlaceholders variables we defined in the previous section.

Then, we’re going to actually add the TWA activity by adding an <activity> tag inside the <application> tag.

<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.netguru.wordguru"> // highlight <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="${launcherName}" // highlight android:supportsRtl="true" android:theme="@style/AppTheme"> <activity android:name="android.support.customtabs.trusted.LauncherActivity" android:label="${launcherName}"> // highlight <meta-data android:name="android.support.customtabs.trusted.DEFAULT_URL" android:value="${defaultUrl}" /> // highlight <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> <intent-filter android:autoVerify="true"> <action android:name="android.intent.action.VIEW"/> <category android:name="android.intent.category.DEFAULT" /> <category android:name="android.intent.category.BROWSABLE"/> <data android:scheme="https" android:host="${hostName}"/> // highlight </intent-filter> </activity> </application> </manifest>

And that, my friends, is Step 1. Let’s move on to Step 2.

Step 2: Verify the relationship between the website and the app

TWAs require a connection between the Android application and the PWA. To do that, we use Digital Asset Links.

The connection must be set on both ends, where TWA is the application and PWA is the website.

To establish that connection we need to modify our manifestPlaceholders again. This time, we need to add an extra element called assetStatements that keeps the information about our PWA.

// build.gradle (Module: app) android { ... defaultConfig { ... manifestPlaceholders = [ ... assetStatements: '[{ "relation": ["delegate_permission/common.handle_all_urls"], ' + '"target": {"namespace": "web", "site": "https://wordguru.netguru.com"}}]' ... ] ... } ... }

Now, we need to add a new meta-data tag to our application tag. This will inform the Android application that we want to establish the connection with the application specified in the manifestPlaceholders.

<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="${packageId}"> <application> ... <meta-data android:name="asset_statements" android:value="${assetStatements}" /> ... </application> </manifest>

That’s it! we just established the application to website relationship. Now let’s jump into the conversion of website to application.

To establish the connection in the opposite direction, we need to create a .json file that will be available in the app’s /.well-known/assetlinks.json path. The file can be created using a generator that’s built into Android Studio. See, I told you Android Studio helps streamline Android development!

We need three values to generate the file:

  • Hosting site domain: This is our PWA URL (e.g. https://wordguru.netguru.com/).
  • App package name: This is our TWA package name (e.g. com.netguru.wordguru).
  • App package fingerprint (SHA256): This is a unique cryptographic hash that is generated based on Google Play Store keystore.

We already have first and second value. We can get the last one using Android Studio.

First we need to generate signed APK. In the Android Studio go to: Build ? Generate Signed Bundle or APK ? APK.

Next, use the existing keystore, if you already have one. If you need one, go to "Create new…" first.

Then let’s fill out the form. Be sure to remember the credentials as those are what the application will be signed with and they confirm your ownership of the application.

This will create a keystore file that is required to generate the app package fingerprint (SHA256). This file is extremely important as it is works as a proof that you are the owner of the application. If this file is lost, you will not be able to do any further updates to your application in the store.

Next up, let’s select type of bundle. In this case, we’re choosing "release" because it gives us a production bundle. We also need to check the signature versions.

This will generate our APK that will be used later to create a release in Google Play store. After creating our keystore, we can use it to generate required app package fingerprint (the SHA256).

Let’s head back to Android Studio, and go to Tools ? App Links Assistant. This will open a sidebar that shows the steps that are required to create a relationship between the application and website. We want to go to Step 3, "Declare Website Association" and fill in required data: Site domain and Application ID. Then, select the keystore file generated in the previous step.

After filling the form press "Generate Digital Asset Links file" which will generate our assetlinks.json file. If we open that up, it should look something like this:

[{ "relation": ["delegate_permission/common.handle_all_urls"], "target": { "namespace": "android_app", "package_name": "com.netguru.wordguru", "sha256_cert_fingerprints": ["8A:F4:....:29:28"] } }]

This is the file we need to make available in our app’s /.well-known/assetlinks.json path. I will not describe how to make it available on that path as it is too project-specific and outside the scope of this article.

We can test the relationship by clicking on the "Link and Verify" button. If all goes well, we get a confirmation with "Success!"

Yay! We’ve established a two-way relationship between our Android application and our PWA. It’s all downhill from here, so let’s drive it home.

Step 3: Get required assets

Google Play requires a few assets to make sure the app is presented nicely in the store. Specifically, here’s what we need:

  • App Icons: We need a variety of sizes, including 48x48, 72x72, 96x96, 144x144, 192x192… or we can use an adaptive icon.
  • High-res Icon: This is a 512x512 PNG image that is used throughout the store.
  • Feature Graphic: This is a 1024x500 JPG or 24-bit PNG (no alpha) banner that Google Play uses on the app details view.
  • Screenshots: Google Play will use these to show off different views of the app that users can check out prior to downloading it.

Having all those, we can proceed to the Google Play Store developers console and publish the application!

Step 4: Publish to Google Play!

Let’s go to the last step and finally push our app to the store.

Using the APK that we generated earlier (which is located in the AndroidStudioProjects directory), we need to go to the Google Play console to publish our application. I will not describe the process of publishing an application in the store as the wizard makes it pretty straightforward and we are provided step-by-step guidance throughout the process.

It may take few hours for the application to be reviewed and approved, but when it is, it will finally appear in the store.

If you can’t find the APK, you can create a new one by going to Build ? Generate signed bundle / APK ? Build APK, passing our existing keystore file and filling the alias and password that we used when we generated the keystore. After the APK is generated, a notice should appear and you can get to the file by clicking on the "Locate" link.

Congrats, your app is in Google Play!

That’s it! We just pushed our PWA to the Google Play store. The process is not as intuitive as we would like it to be, but still, with a bit of effort it is definitely doable, and believe me, it gives that great filling at the end when you see your app displayed in the wild.

It is worth pointing out that this feature is still very much early phase and I would consider it experimental for some time. I would not recommend going with a production release of your application for now because this only works with Chrome 72 and above — any version before that will be able to install the app, but the app itself will crash instantly which is not the best user experience.

Also, the official release of custom-tabs-client does not support TWA yet. If you were wondering why we used raw GitHub link instead of the official library release, well, that’s why.

The post How to Get a Progressive Web App into the Google Play Store appeared first on CSS-Tricks.

Faking env() to Use it Now

Css Tricks - Thu, 04/18/2019 - 7:21am

There is already an env() function in CSS, but it kinda came out of nowhere as an Apple thing for dealing with "The Notch" but it has made it's way to be a draft spec. The point will be for UAs or authors to declare variables that cannot be changed. Global const for CSS, sorta.

That spec doesn't seem to suggest how we'll actually set those env() values just yet. If you want them now, the easiest way to fake them would be using regular ol' CSS custom properties and simply not change them.

But if you want that env() syntax though, there is a PostCSS plugin for emulating it. The way the plugin handles them is through a JavaScript file that declares them.

postcssCustomProperties({ importFrom: 'path/to/file.js' /* module.exports = { environmentVariables: { '--branding-padding': '20px', '--branding-small': '600px' } } */ });

Having them start life as JavaScript is interesting, as it means we could perhaps have a single place to set variables that are accessible both to JavaScript and CSS.

That's what Harry Nicholls covers more in his article, "Why you should use CSS env()" like some gotchas when dealing with units and such. But if you really needed a single source for unchangeable variables in both CSS and JavaScript, then I'd say this is a good way to go — and could potentially be ripped out once support for env() formally arrives.

The post Faking env() to Use it Now appeared first on CSS-Tricks.

Creating Reusable Base Classes in TypeScript with a Real-Life Example

Css Tricks - Thu, 04/18/2019 - 5:14am

Hey CSS-Tricksters! Bryan Hughes was kind enough to take a concept from an existing post he published on converting to TypeScript and take it a few couple steps further in this post to elaborate on creating reusable base classes. While this post doesn’t require reading the other one, it’s certainly worth checking it out because it covers the difficult task of rewriting a codebase and writing unit tests to help the process.

Johnny-Five is an IoT and robotics library for Node.js. Johnny-Five makes it easy to interact with hardware by taking a similar approach that jQuery took to the web a decade ago: it normalizes the differences between various hardware platforms. Also like jQuery, Johnny-Five provides higher-level abstractions that make it easier to work with the platform.

Johnny-Five supports a wide array of platforms via IO Plugins, from the Arduino family, to the Tessel, to the Raspberry Pi, and many more. Each IO Plugin implements a standardized interface for interacting with lower-level hardware peripherals. Raspi IO, which I first created five years ago, is the IO plugin that implements support for the Raspberry Pi.

Any time there are multiple implementations that conform to one thing, there is a chance to share code. IO Plugins are no exception, however, we have not shared any code between IO Plugins to date. We recently decided, as a group, that we wanted to change this. The timing was fortuitous since I was planning on rewriting Raspi IO in TypeScript anyways, so I agreed to take on this task.

The goals of a base class

For those who many not be familiar with using class-based inheritance to enable code sharing, let’s do a quick walk-through of what I mean when I say “creating a base class to reuse code."

A base class provides structure and common code that other classes can extend. Let’s take a look at a simplified TypeScript example base class that we will extend later:

abstract class Automobile { private _speed: number = 0; private _direction: number = 0; public drive(speed: number): void { this._speed = speed; } public turn(direction: number): void { if (direction > 90 || direction < -90) { throw new Error(`Invalid direction "${direction}"`); } this._direction = direction; } public abstract getNumDoors(): number; }

Here, we have created a base class that we call Automobile. This provides some basic functionality shared between all types of automobiles, whether it’s a car, a pickup, etc. Notice how this class is marked as abstract, and how there is one abstract method called getNumDoors. This method is dependent on the specific type of automobile. By defining it as an abstract class, we are saying that we require another class to extend this class and implement this method. We can do so with this code:

class Sedan extends Automobile { public getNumDoors(): number { return 4; } } const myCar = new Sedan(); myCar.getNumDoors(); // prints 4 myCar.drive(35); // sets _speed to 35 myCar.turn(20); // sets _direction to 20

We’re extending the Automobile class to create a four-door sedan class. We can now call all methods on both classes, as if it were a single class.

For this project, we’ll create a base class called AbstractIO that any IO plugin author can then extend to implement a platform-specific IO Plugin.

Creating the Abstract IO base class

Abstract IO is the base class I created to implement the IO Plugin spec for use by all IO Plugin authors, and is available today on npm.

Each author has their own unique style, some preferring TypeScript and others preferring vanilla JavaScript. This means that, first and foremost, this base class must conform to the intersection of TypeScript best practices and JavaScript best practices. Finding the intersection of best practices isn’t always obvious though. To illustrate, let’s consider two parts of the IO Plugin spec: the MODES property and the digitalWrite method, both of which are required in IO Plugins.

The MODES property is an object, with each key having a human readable name for a given mode type, such as INPUT, and the value being the numerical constant associated with the mode type, such as 0. These numerical values show up in other places in the API, such as the pinMode method. In TypeScript, we would want to use an enum to represent these values, but JavaScript doesn’t support it. In JavaScript, the best practice is to define a series of constants and put them into an object “container."

How do we resolve this apparent split between best practices? Create one using the other! We start by defining an enum in TypeScript and define each mode with an explicit initializer for each value:

export enum Mode { INPUT = 0, OUTPUT = 1, ANALOG = 2, PWM = 3, SERVO = 4, STEPPER = 5, UNKNOWN = 99 }

Each value is carefully chosen to map explicitly to the MODES property as defined by the spec, which is implemented as part of the Abstract IO class with the following code:

public get MODES() { return { INPUT: Mode.INPUT, OUTPUT: Mode.OUTPUT, ANALOG: Mode.ANALOG, PWM: Mode.PWM, SERVO: Mode.SERVO, UNKNOWN: Mode.UNKNOWN } }

With this, we have nice enums when we’re in TypeScript-land and can ignore the numerical values entirely. When we’re in pure JavaScript-land, we still have the MODES property we can pass around in typical JavaScript fashion so we don’t have to use numerical values directly.

But what about methods in the base class that derived classes must override? In the TypeScript world, we would use an abstract class, as we did in the example above. Cool! But what about the JavaScript side? Abstract methods are compiled out and don’t even exist in the output JavaScript, so we have nothing to ensure methods are overridden there. Another contradiction!

Unfortunately, I couldn’t come up with a way to respect both languages, so I defaulted to using the JavaScript approach: create a method in the base class that throws an exception:

public digitalWrite(pin: string | number, value: number): void { throw new Error(`digitalWrite is not supported by ${this.name}`); }

It’s not ideal because the TypeScript compiler doesn’t warn us if we don’t override the abstract base method. However, it does work in TypeScript (we still get the exception at runtime), as well as being a best practice for JavaScript.

Lessons learned

While working through the best way to design for both TypeScript and vanilla JavaScript, I determined that the best way to solve discrepancies is:

  1. Use a common best practice shared by each language
  2. If that doesn’t work, try to use the TypeScript best practice “internally" and map it to a separate vanilla JavaScript best practice “externally," like we did for the MODES property.
  3. And if that approach doesn’t work, default to using the vanilla JavaScript best practice, like we did for the digitalWrite method, and ignore the TypeScript best practice.
  4. These steps worked well for creating Abstract IO, but these are simply what I discovered. If you have any better ideas I’d love to hear them in the comments!

    I discovered that abstract classes are not useful in vanilla JavaScript projects since JavaScript doesn’t have such a concept. This means that they are an anti-pattern here, even though abstract classes are a TypeScript best practice. TypeScript also doesn’t provide mechanisms to ensure type-safety when overriding methods, such as the override keyword in C#. The lesson here is that you should pretend that abstract classes don’t exist when targeting vanilla JavaScript users as well.

    I also learned that it’s really important to have a single source of truth for interfaces shared across modules. TypeScript uses duck typing as its core type system pattern, and is very useful inside any given TypeScript project. However, synchronizing types across separate modules using duck typing turned out to be more of a maintenance headache than exporting an interface from one module and importing it into another. I had to keep publishing little changes to modules until I got them aligned on their types, leading to excess version number churn.

    The final lesson I learned isn’t a new one: get feedback throughout the design process from library consumers. Knowing this going in, I set up two primary rounds of feedback. The first round was in person at the Johnny-Five collaborator’s summit where we brainstormed as a group. The second round was a pull request I opened against myself, despite being the only collaborator on Abstract IO with permission to merge pull requests. The pull request proved invaluable as we sifted through the details as a group. The code at the beginning of the PR bared little resemblance to the code when it was merged, which is good!

    Wrapping up

    Producing base classes destined to be consumed by both TypeScript and vanilla JavaScript users is a mostly straightforward process, but there are some gotchas. Since TypeScript is a superset of JavaScript, the two mostly share the same best practices. When differences in best practices do arise, a little creativity is required to find the best compromise.

    I managed to achieve my goals with Abstract IO, and implemented a base class that serves both TypeScript and vanilla JavaScript IO Plugin authors well. Turns out, it’s (mostly) possible to have your cake and eat it too!

    The post Creating Reusable Base Classes in TypeScript with a Real-Life Example appeared first on CSS-Tricks.

An Event Apart Boston is Coming. Save Now!

Css Tricks - Thu, 04/18/2019 - 4:37am

(This is a sponsored post.)

An Event Apart Boston is almost here! We're talking, like, less than a month away. If you've been holding off from registering, this might be your last chance because time and seating are both limited. Besides, we're talking about three days of pure knowledge-dropping by an impressive lineup of speakers on a wide range of topics. Seriously, just look at the full schedule and prepare to be get stoked for a great time.

But, if a couple of weeks until show time is a little too tight for your liking, that's where An Event Apart has you totally covered because there's another one taking place in Washington D.C. this summer. And three more throughout the rest of the year in Chicago, Denver and San Francisco.

The reason an Event Apart is so near-and-dear to the CSS-Tricks family is that it scratches a common itch that we see come up around here often: how can we possibly stay on top of our careers as front-enders when our industry is changing at lightning speed and when we're all-consumed trying to keep on top of our actual jobs? An Event Apart is our chance to take intention time away from the day-to-day and invest in our careers by learning from some of the best in the business, meeting folks who do what we do, and having those micro-interactions with others in the hallways that spark the interesting types of dialogues you just can't get from Twitter.

Think about it: 17 speakers over three days covering everything from design systems and Progressive Web Apps to variable fonts and CSS Grid Layout. There's so much to gain by attending. Just look at the awesome takeaways Chris got from An Event Apart Seattle in March.

And, to sweeten the pot, An Event Apart gave us a special discount code for CSS-Tricksters like yourself. Enter the AEACP at checkout to knock $100 off the price.

Hope to see you at one of the upcoming events!

Register Today

Direct Link to ArticlePermalink

The post An Event Apart Boston is Coming. Save Now! appeared first on CSS-Tricks.

How AI Can Improve The UX Of Websites and Landing Pages

Usability Geek - Wed, 04/17/2019 - 5:55am
Artificial Intelligence (AI) is no longer a vision for the future – it is already here and is having a significant impact on how businesses can improve their practices. One big way that AI is...
Categories: Web Standards

In the Shadow of Notre Dame

Typography - Wed, 04/17/2019 - 5:41am

The cathedral of Notre Dame has stood at the heart of France and of Paris for the best part of 1,000 years. It watched as Paris rose from a former outpost founded during the Roman Republic to become the biggest city of medieval Europe. And although European printing was born in Germany, it is in […]

The post In the Shadow of Notre Dame appeared first on I Love Typography.

Clever code

Css Tricks - Wed, 04/17/2019 - 4:00am

This week, Chris Ferdinandi examined a clever JavaScript snippet, one that's written creatively with new syntax features, but is perhaps less readable and performant. It's a quick read, but his callout of our industry's fixation on cleverness is worth... calling out:

...we’ve become obsessed as an industry with brevity and clever code, and it results in code that’s sometimes less performant, and typically harder to read and make sense of for most people.

He made a similar argument late last month when he wrote about code readability, noting that brevity might look cool but ultimately leads to all sorts of issues in a codebase:

Often, web developers are obsessed with brevity. There’s this thing were developers will try to write the same function in the fewest number of characters possible.

Personally, I think brevity is pointless. Readability is a lot more important.

I entirely agree with Chris on this point, however, I think there is one important distinction to make and that's the difference between code that's intended as a prototype and code that's intended for production. As Jeremy Keith argued a short while ago:

What’s interesting is that—when it comes to prototyping—our usual front-end priorities can and should go out the window. The priority now is speed. If that means sacrificing semantics or performance, then so be it. If I’m building a prototype and I find myself thinking “now, what’s the right class name for this component?”, then I know I’m in the wrong mindset. That question might be valid for production code, but it’s a waste of time for prototypes.

I agree with Chris that we should be writing code that is easy to read when we’re in production. I also think experimenting with code in this way is a good thing when it comes to prototypes. We shouldn’t ever shy away from playing with code and pushing things a little bit – so long as we’re not doing that in a giant web app with a a team of other developers working alongside us.

I’ve noticed that there are some folks that are doing genuinely ingenious things with Sass. I consistently sit back and think, "Wow, I’ve never seen anything like this before." But when it comes to a production web app that has to be understood by hundreds of people at the same time, I don’t believe that this is the reaction we want when someone looks at the code.

As a result, I’ve been trying to write Sass code that is actually so simple that it almost looks dumb. One easy way to make code a lot simpler is to reduce the amount of nesting:

.element { .heading { ... } }

This looks fine when there’s code inside — and it’s pretty easy to understand — but add a complex bit of design in the mix (say, using pseudo elements and media queries) and you suddenly have a rather complex set of rules in front of you. Creativity and cleverness can be harder to scan and identify one small part of the code that you’re looking for. Plus, in this example, we’ve unnecessarily made our .heading class a little bit more specific which might encourage us to override things in a hacky way elsewhere in the codebase.

We could write the following:

.element { ... } .element-heading { ... }

I know this looks foolishly simple but the relationship between these two classes is easier to see and easier to extend in the future. Bundling all that code into a single nested class can get out of hand real fast. Even if it happens to look a lot cooler.

(As an aside, Andy Bell's post on using the ampersand in Sass — and the resulting comments — is a great example of the clash between creativity and practicality.)

Anyway, the point I’m trying to make here is that CSS (and JavaScript for that matter) is a strange language because there are no definite rules you can make about it. It all really depends on the codebase and the project. But I think we can safely say that our code ought to be a lot more boring than our prototypes when it moves to production.

Continue to make prototypes that are wild and experimental or impossibly weird! Code quality be damned.

The post Clever code appeared first on CSS-Tricks.

The Power of Named Transitions in Vue

Css Tricks - Tue, 04/16/2019 - 4:05am

Vue offers several ways to control how an element or component visually appears when inserted into the DOM. Examples can be fading in, sliding in, or other visual effects. Almost all of this functionality is based around a single component: the transition component.

A simple example of this is with a single v-if based on a Boolean. When the Boolean is true, the element appears. When the Boolean is false, the element disappears. Normally, this element would just pop in and out of existence, but with the transition component you can control the visual effect.

<transition> <div v-if="isVisible">is this visible?</div> </transition>

Several articles have been written that cover the transition component quite well, like articles from Sarah Drasner, Nicolas Udy, and Hassan Djirdeh. Each article covers different aspects of Vue’s transition component in detail. This article will expand on the topic by focusing on one aspect of the transition component; the fact that they can be “named."

<transition name="fade"> <div v-if="isVisible">is this visible?</div> </transition>

The initial change this attribute offers is that the CSS classes injected onto the element during the transition sequence will be prefixed by the given name. Basically, it would be fade-enter instead of v-enter from the example above. This single attribute can go well beyond this simple option. It can be used to leverage certain features of Vue and CSS which allows for some interesting outcomes.

Another thing to consider is that the name attribute can be bound:

<transition v-bind:name="currentTransition"> <div v-if="isVisible">is this visible?</div> </transition>

In this example, the transition will be named the value currentTransition resolves to. This simple change provides another level of options and features to an app’s animations. With static and dynamic named transitions, a project can have a series of prebuilt transitions ready to apply throughout the entire app, components that can extend existing transitions applied to them, switch a transition being used before or after being applied, allowing users to choose transitions, and control how individual elements of a list transition into place based on the current state of that list.

This article is intended to explore these features and explain how to use them.

What happens when transitions are named?

By default, when a transition component is used, it applies specific classes in a specific sequence to the element. These classes can be leveraged in CSS. Without any CSS, these classes, in essence, do nothing for the element. Therefore, there is a need for CSS of this nature:

.v-enter, .v-leave-to { opacity: 0; } .v-enter-active, .v-leave-active { transition: 0.5s; }

This causes the element to fade in and out with a duration of half a second. A minor change to the transition provides for elegant visual feedback to the user. Still, there is an issue to consider. But first, what’s different with a named transition?

.fade-enter, .fade-leave-to { opacity: 0; } .fade-enter-active, .fade-leave-active { transition: 0.5s; }

Essentially the same CSS but with fade- prefixed instead of v-. This naming addresses the potential issue that can happen when using the default class names of the transition component. The v- prefix makes the classes global in effect, especially if the CSS is placed in the style block of the app’s root level. This would, in effect, make *all* transitions without a name attribute throughout the entire app use the same transition effect. For small apps this may suffice, but in larger, more complex apps, it may lead to undesirable visual effects, as not everything should fade in and out over half a second.

Naming transitions provides a level of control for developers throughout the project as to how different elements or components are inserted or removed visually. It is suggested that all transitions be named — even if there is just one — to establish the habit of doing so. Even if an app has only one transition effect, there may be a need to add a new one at a future point. Having already named existing transitions in the project eases the effort of adding a new one.

Building a collection of transition effects

Naming transitions provides for a simple yet very useful process. A common practice might be to create the transition classes as part of the component that is using them. If another common practice of scoping styles for a component is done, those classes will only be available to that particular component. If two different components have similar transitions in their style blocks, then we are just duplicating code.

So, let’s consider keeping CSS for transitions in the style block of the root of the app, typically the app.vue file. For most of my projects, I place them as the last section of the style block, making them easy to locate for adjustments and additions. Keeping the CSS in this location makes the transition effects available to every use of the transition component throughout the entire app. Here are examples from some of my projects.

.fade-enter, .fade-leave-to { opacity: 0; } .fade-enter-active, .fade-leave-active { transition: 0.5s; } .slide-enter { opacity: 0; transform: scale3d(2, 0.5, 1) translate3d(400px, 0, 0); } .slide-enter-to { transform: scale3d(1, 1, 1); } .slide-enter-active, .slide-leave-active { transition: 0.5s cubic-bezier(0.68, -0.55, 0.265, 1.55); } .slide-leave { transform: scale3d(1, 1, 1); } .slide-leave-to { opacity: 0; transform: scale3d(2, 0.5, 1) translate3d(-400px, 0, 0); } .rotate-enter { transform: perspective(500px) rotate3d(0, 1, 0, 90deg); } .rotate-enter-active, .rotate-leave-active { transition: 0.5s; } .rotate-leave-to { transform: perspective(500px) rotate3d(0, 1, 0, -90deg); }

There are multiple ways to store these transition classes depending on your preferences and the needs of the project. The first, as mentioned earlier, is to keep it all in the style block of the app.vue file. You can also keep a Sass partial of all the transitions in the project’s assets folder and import it into the app’s style block.

<style lang="scss"> @import "assets/_transitions.scss"; </style>

This method allows for adjustments and additions to the collection of transitions outside of the Vue files. Another benefit of this setup is that such a file can be easily transferred between projects if they share transition effects. If one project gets a new transition, then it’s easy enough to transfer the addition to another project without having to touch main project files.

If you’re using CSS instead of Sass, then you can include the file as a requirement of the project. You can accomplish this by keeping the file in the assets folder of the project and placing a require statement in the main.js file.

require("@/assets/transitions.css");

Another option is keep the transition styles in a static CSS file that can be stored elsewhere, either in the public folder of the project or just on the server itself. Since this is a regular CSS file, no building or deployment would be required — just include a link reference in the index.html file.

<link rel="stylesheet" type="text/css" href="/css/transitions.css">

This file could also potentially be stored in a CDN for all projects to share. Whenever the file is updated, the changes are immediately available everywhere it is referenced. If a new transition name is created, then existing projects can start using the new name as needed.

Now, let’s slow down a minute

While we’re building a collection of transitions to use throughout our project, let’s consider users out there who may not want abrupt animations, or who may want no animations at all. Some people could consider our animations over-the-top and unnecessary, but for some, they can actually cause problems. Some time ago, WebKit introduced the prefers-reduced-motion media query to assist with possible Vestibular Spectrum Disorder issues. Eric Bailey also posted a nice introduction to the media query as well.

In most cases, adding the media query as part of our collection of transitions is quite easy and should be considered. We can either reduce the amount of motion involved in the transition to reduce the negative effects or simply turn them off.

Here’s a simple example from one of my demos below:

.next-enter { opacity: 0; transform: scale3d(2, 0.5, 1) translate3d(400px, 0, 0); } .next-enter-to { transform: scale3d(1, 1, 1); } .next-enter-active, .next-leave-active { transition: 0.5s cubic-bezier(0.68, -0.55, 0.265, 1.55); } .next-leave { transform: scale3d(1, 1, 1); } .next-leave-to { opacity: 0; transform: scale3d(2, 0.5, 1) translate3d(-400px, 0, 0); } /* If animations are reduced at the OS level, use simpler transitions */ @media screen and (prefers-reduced-motion: reduce) { .next-enter { opacity: 0; transform: translate3d(100px, 0, 0); } .next-enter-active, .next-leave-active { transition: 0.5s; } .next-leave-to { opacity: 0; transform: translate3d(-100px, 0, 0); } }

In that example, I took what was a rather exaggerated transition and made it simpler. The animation is a slide that moves to the left with an elastic ease, then scales down and fades out as it moves away. If someone has the reduce motion preference set, then the animation becomes a much simpler transition with a shorter distance (which gives it a slower velocity) and keeps the fade. If we had wanted to turn them off, then we’d only need to reference the classes with the transition property and set their value to none.

To test this requires finding and selecting a checkbox on your respective OS. On Windows, you will find it in Control Panel > Ease of Access Center > Make the computer easier to see section; look for "Turn off all unnecessary animations (when possible)." On a Mac, look under System Preferences > Accessibility > Display; look for "Reduce motion." The latest iOS devices have a similar setting under Accessibility as well.

Let’s stay flexible with our transitions collection

With this collection of transitions, there is the potential snag of a lack of flexibility with the effects. For instance, what if one element needs a slightly slower fade time? Let’s say that everything else in the effect can stay the same, only the transition-duration needs to be different. There are ways to adjust for that without having to create a whole new transition name.

The easiest method is to use an inline style directly on the element within the transition component.

<transition name="fade"> <div style="transition-duration: 6s;" v-if="isVisible">this has a different duration</div> </transition>

Such a change can also be done through the various ways Vue offers handling styles and classes.

Let’s say you are using the component element with the is attribute for dynamic components such as this:

<transition name="fade" mode="out-in"> <component :is="currentComponent"></component> </transition>

Even with this dynamic component, we have options to adjust properties of the transition effect. Again, we can apply an inline style on the component element, which will be placed on the root element of the component. The root element also receives the transition classes, so we would directly override their properties.

<transition name="fade" mode="out-in"> <component :is="currentComponent" style="transition-duration: 6s;"></component> </transition>

Another option is to pass in props to our components. That way, the desired changes can be applied through the component’s code to its root element.

<transition name="fade" mode="out-in"> <component :is="currentComponent" duration="6s"></component> </transition> <template> <div :style="`transition-duration: ${duration}`">component one</div> </template> <script> export default { name: "component-one", props: { duration: String } }; </script>

We can also override the properties of the transition’s classes inside the component’s style block, especially if it is scoped.

<style scoped> .fade-enter-active, .fade-leave-active { transition-duration: 1s; } </style>

In this case, the component will have a fade duration of one second instead of the global duration of half-a-second. We can even take it a step further and have different durations for each side of the sequence.

<style scoped> .fade-enter-active { transition-duration: 1s; } .fade-leave-active { transition-duration: 2s; } </style>

Any of the global transition classes can be altered within the component when needed. Although this isn’t quite as flexible as changing the property outside of a class structure, it can still be quite useful in certain circumstances.

As you can see, even with our collection of prebuilt transitions, we still have options for flexibility.

Dynamic transitions

Even after all these interesting things we can do with Vue’s transition component, yet another interesting feature waits to be explored. The name attribute on the transition component can be dynamic in nature, meaning we can change the current transition in use at will.

This means that the transition can be changed to have different animation effects with different situations, based in code. For example, we could have a transition change because of the answer to a question, transitions decided from user interaction, and have a list use different transitions based on the current state of the list itself.

Let’s look into these three examples.

Example 1: Change transition based on an answer

In this example, we have a simple math question that must be answered. Two numbers are randomly selected and we are expected to provide the sum. Then the button is clicked to check the answer against the expected answer. A small notification appears above the equation that indicates whether the answer is true or false. If the answer is correct, the notification is given a transition that suggests a head nodding yes with an up and down animation. If your answer is incorrect, the notification goes side-to-side suggesting a head shaking no.

See the Pen
VueJS Dynamic Transitions: Change Transition Based on an Answer
by Travis Almand (@talmand)
on CodePen.

The logic behind this is not overly complicated, nor is the setup of the transition. Here’s the HTML:

<transition :name="currentTransition"> <div id="notification" :class="response.toString()" v-if="answerChecked">{{ response }}</div> </transition>

Rather simple in nature. We have a bound name on the transition and then a v-if on the notification div. We also apply a true or false class to decorate the notification based on the response.

Here’s the CSS for the transitions:

.positive-enter-active { animation: positive 1s; } @keyframes positive { 0% { transform: translate3d(0, 0, 0); } 25% { transform: translate3d(0, -20px, 0); } 50% { transform: translate3d(0, 20px, 0); } 75% { transform: translate3d(0, -20px, 0); } 100% { transform: translate3d(0, 0, 0); } } .negative-enter-active { animation: negative 1s; } @keyframes negative { 0% { transform: translate3d(0, 0, 0); } 25% { transform: translate3d(-20px, 0, 0); } 50% { transform: translate3d(20px, 0, 0); } 75% { transform: translate3d(-20px, 0, 0); } 100% { transform: translate3d(0, 0, 0); } }

You’ll see that I’m using CSS animations to accomplish the up-and-down and side-to-side effects.

Here’s some of the JavaScript:

methods: { randomProblem: function () { this.a = Math.floor(Math.random() * Math.floor(10)); this.b = Math.floor(Math.random() * Math.floor(10)); }, check: function () { this.response = this.a + this.b === parseInt(this.answer); this.answerChecked = true; this.currentTransition = this.response ? 'positive' : 'negative'; }, reset: function () { this.answer = null; this.answerChecked = false; this.randomProblem(); } }

There’s the randomProblem method that sets up our equation. The check method that decides on which transition effect to use based on comparing the provided answer with the correct answer. Then the simple reset method that just, well, resets everything.

This is just a simple example. Another possible example is having a notification that has two different effects based on whether the notification is important or not. If the message is not overly important, then we can have a subtle animation that doesn’t drive the user’s eyes away from the current task. If it is important, we could use an animation that is more direct in nature in an effort to force the eyes up to the notification.

Example 2: Change transition based on user interaction

Another thing we can build is a carousel of some sort. This could be presentation slides, an image gallery, or a series of instructions. The basic idea is that we have a need to present information to the user in a sequence. In this presentation, the user gets to decide when to proceed and whether to move forward or to go backward.

See the Pen
VueJS Dynamic Transitions: Change Transition Based on User Interaction
by Travis Almand (@talmand)
on CodePen.

This, again, is a rather simple setup. The example, more or less, is a slide presentation type of situation. The two buttons at the bottom shift between two components with a sliding transition. A real project would have more components or perhaps logic to change the contents of the components based on the current slide. This example shall stay simple to demonstrate the idea.

Here’s the HTML:

<transition :name="currentTransition" mode="out-in"> <component :is="slides[currentSlide]"></component> </transition>

You’ll see that we’re merely transitioning whenever the component is switched out by a bound is attribute on the component element.

Here’s the CSS:

.next-enter { opacity: 0; transform: scale3d(2, 0.5, 1) translate3d(400px, 0, 0); } .next-enter-to { transform: scale3d(1, 1, 1); } .next-enter-active, .next-leave-active { transition: 0.5s cubic-bezier(0.68, -0.55, 0.265, 1.55); } .next-leave { transform: scale3d(1, 1, 1); } .next-leave-to { opacity: 0; transform: scale3d(2, 0.5, 1) translate3d(-400px, 0, 0); } .prev-enter { opacity: 0; transform: scale3d(2, 0.5, 1) translate3d(-400px, 0, 0); } .prev-enter-to { transform: scale3d(1, 1, 1); } .prev-enter-active, .prev-leave-active { transition: 0.5s cubic-bezier(0.68, -0.55, 0.265, 1.55); } .prev-leave { transform: scale3d(1, 1, 1); } .prev-leave-to { opacity: 0; transform: scale3d(2, 0.5, 1) translate3d(400px, 0, 0); } /* If animations are reduced at the OS level, use simpler transitions */ @media screen and (prefers-reduced-motion: reduce) { .next-enter { opacity: 0; transform: translate3d(100px, 0, 0); } .next-enter-active, .next-leave-active { transition: 0.5s; } .next-leave-to { opacity: 0; transform: translate3d(-100px, 0, 0); } .prev-enter { opacity: 0; transform: translate3d(-100px, 0, 0); } .prev-enter-active, .prev-leave-active { transition: 0.5s; } .prev-leave-to { opacity: 0; transform: translate3d(100px, 0, 0); } }

Here we have two transitions, one for when the user clicks on the “next” button and the other is for the "prev" button. Each essentially slides the component in the appropriate direction with the transform property, but with a few extras to create a kind of squeezing effect for a cartoonish feel. We also make use of prefers-reduced-motion to change the animation to be a simpler fade with a small slide to the side in the appropriate direction.

Now, for the JavaScript:

methods: { changeSlide: function (dir) { this.currentSlide = dir === 'next' ? this.currentSlide + 1 : this.currentSlide - 1; this.currentTransition = dir; } }

Each button calls the changeSlide method on its click event and passes which direction it represents. Then we have some logic to keep track of what the current slide happens to be. A single line controls which transition to use. Since the “next” button passes “next” as the direction it corresponds to the “next” transition in the CSS. Same for the "prev" button. Each time the user clicks a button, the app automatically knows which transition to use. Thus, we have nice transition effects that provide context as to which direction the user is progressing through the sequence.

Example 3: Change transition based on list state

For our final example, we’ll see how to change transitions based on the current state of a list inside a transition-group component. The idea here is a list to be updated an item at a time with a different transition each time.

See the Pen
VueJS Dynamic Transitions: Change Transition Based on List State
by Travis Almand (@talmand)
on CodePen.

In this example, we are presented with a list of cities on the right and a blank list on the left. As cities are chosen on the right, they fill in the blanks on the left. The first city slides in from above while fading into view. The next cities before the last will slide in either from the right or the left, depending on the previous transition, and the last city slides in from below.

Here’s the HTML:

<transition-group :name="currentListTransition" tag="ul" class="list"> <li v-for="(item, index) in selectedItems" :key="item">{{ item }}</li> </transition-group>

As usual, a rather simple setup. Here are the transitions in CSS:

.top-enter-active, .top-leave-active { transition: 0.5s; } .top-enter, .top-leave-to { opacity: 0; transform: translate3d(0, -40px, 0); } .top-move { opacity: 0.5; transition: 0.5s; } .left-enter-active, .left-leave-active { transition: 0.5s; } .left-enter, .left-leave-to { opacity: 0; transform: translate3d(-40px, 0, 0); } .left-move { opacity: 0.5; transition: 0.5s; } .right-enter-active, .right-leave-active { transition: 0.5s; } .right-enter, .right-leave-to { opacity: 0; transform: translate3d(40px, 0, 0); } .right-move { opacity: 0.5; transition: 0.5s; } .bottom-enter-active, .bottom-leave-active { transition: 0.5s; } .bottom-enter, .bottom-leave-to { opacity: 0; transform: translate3d(0, 30px, 0); } .bottom-move { opacity: 0.5; transition: 0.5s; } /* If animations are reduced at the OS level, turn off transitions */ @media screen and (prefers-reduced-motion: reduce) { .top-enter-active, .top-leave-active { transition: none; } .top-move { transition: none; } .left-enter-active, .left-leave-active { transition: none; } .left-move { transition: none; } .right-enter-active, .right-leave-active { transition: none; } .right-move { transition: none; } .bottom-enter-active, .bottom-leave-active { transition: none; } .bottom-move { transition: none; } }

As you can see, a transition for each possible direction of the cities appearing the blank list.

Now, for our JavaScript:

methods: { chooseCity: function (index) { let selectedLength = this.selectedItems.length; let citiesLength = this.cities.length; let clt = this.currentListTransition; if (selectedLength === 0) { clt = 'top'; } else if (selectedLength > 0 && selectedLength < citiesLength - 1) { clt = clt === 'top' || clt === 'left' ? 'right' : 'left'; } else if (selectedLength === citiesLength - 1) { clt = 'bottom'; } this.currentListTransition = clt; this.selectedItems.push(this.cities[index]); document.querySelector(`.city:nth-child(${index + 1})`).classList.add('selected'); }, clearSelection: function () { this.currentListTransition = 'right'; this.selectedItems = []; document.querySelectorAll('.city.selected').forEach(element => { element.classList.remove('selected'); }); } }

The chooseCity method handles what happens as you choose each city. What we mostly care about is the series of if and if/else statements in the middle of the method. As cities are selected, the logic looks at the current length of the selectedItems array that the selected cities eventually get pushed into. If the length is zero, then that’s the first city, so the transition should have it come in from the top. If the length is between zero and the total number of our cities list, then the transition should be right or left. The new direction used is based on the direction of the previous transition direction. Then, finally, if we’re on the last city to be chosen, it’ll change to the bottom transition. Again we use prefers-reduced-motion, in this case to turn off the transitions altogether.

Another option to change transitions for a list is changing according to the type of items chosen; such as east coast versus west coast cities, each having different transitions. Consider changing the transition based on the current number of items added to the list; for instance, a different transition for every five items.

So long, and thanks for all the transitions

After all these examples and ideas, I hope that you will consider leveraging Vue’s transition component in your own projects. Exploring the possibilities of adding transitions and animations to your apps to provide context and interest for your users. In many cases, additions such as these are rather simple to implement, almost to the point of it being a shame not to add them. Vue offers an exciting and highly useful feature, the transition component, out of the box and I can only encourage its usage.

Cheers.

The post The Power of Named Transitions in Vue appeared first on CSS-Tricks.

WooCommerce in a Data-Driven World

Css Tricks - Tue, 04/16/2019 - 2:54am

(This is a sponsored post.)

WooCommerce recently made an entire overhaul of its highly visible dashboard screen in the WordPress admin available as a new plugin that can be downloaded free from the WordPress Plugin Directory. The new design is gorgeous, of course. I mean, anytime WooCommerce touches an admin screen, other plugin developers really pay attention because it influences they way many of them approach UI in WordPress.

But the real reason the new dashboard struck me is the sheer amount of data WooCommerce provides users. As someone who has worked on a fair share of WooCommerce (and non-WooCommerce) online stores, reporting is something that comes up quite frequently and it's nice to know WooCommerce not only bakes it right into their product, but designs it so well that it's easy to glean insights about sales, products and customers at a glance.

Here's a clean shot of the new dashboard from the blog post announcing it.

If you've had to integrate custom reporting into an online store a la Google Analytics or some other tooling, you'll know that it requires a fair amount of setup and know-how to make sure data is feeding into the right places, certain clicks or actions are getting tracked, and that the reports themselves are solid, including things like filtering by date and other variables. That's a lot of work considering we can get that and more, directly from the makers of the e-commerce platform.

As Woo mentions in its post, the dashboard changes contained in the feature plugin are merely a preview of what's to come and we have a lot of other fine features to look forward to, including new types of reports, activity feeds and more. There's a lot of power and flexibility to be gained if setting up an online store is in your cards, then the fact that WooCommerce and these features are completely open source and free of charge in the WordPress ecosystem practically make it a no-brainer.

Try WooCommerce

Direct Link to ArticlePermalink

The post WooCommerce in a Data-Driven World appeared first on CSS-Tricks.

You Are Creating For A Human: Here Is Some Advice

Usability Geek - Mon, 04/15/2019 - 12:15pm
You should know whom you are creating for. Your user is not an abstract substance. Think of a person. Explore your customer persona as you would like to explore the mind of your loved one. Discover...
Categories: Web Standards

A Website is a Car and Not a Book

Css Tricks - Mon, 04/15/2019 - 7:03am

I’ve been wondering for a good long while why it feels like web design and development isn’t respected as much as native app development, and why the front-end role in many organizations is seen as a nice-to-have rather than a vital part of the business. Why is it so hard to see that this gig we call "front-end development" is crucial for business and even the day-to-day lives of users?

Is it just me that feels this way?

We depend on front-end developers to help us file our taxes, buy our food and clothes, pay our bills, and entertain us. We find new music, we read stories and play games, and we fall in love... all on websites made up of nothing more than HTML, CSS, and JavaScript written by front-enders.

I’m not trying to be a jerk here, but you can see organizations everywhere that de-prioritize front-end development. There are slow websites! Ad-tech junk everywhere! Poor responsive interfaces! Divs used for buttons! Inaccessible forms! The problems on the web today are daunting and overwhelming to those who care about both good front-end development and the health of the web itself.

What's the cause? Well, I certainly don’t believe that it’s malice. Nobody wants to make slow websites or broken interfaces and nobody (I think) is intentionally trying to break the web. So, why do we all end up doing things that go against what we know to be best practices? What is it about the complexities of web design that is so hard to grasp?

Again, I’m not being mean here – this is an honest question.

I got coffee with my pal Lindsay Grizzard the other day and we were talking about this stuff, asking each other these and other really tough questions related to our work. We both see problems in this industry and it drives us both a little mad to some extent.

Anyway, I asked Lindsay that question: what is it about web design that makes it so difficult to understand? She posited that the issue is that most people believe web design is like designing a book. Heck, we still call these things web pages. But Lindsay argued that building a modern website is nothing like designing a book; it’s more like designing a car.

Lindsay and I looked at the cars parked on the street next to us: they have to be mass produced and they have to be tested. Each has to be built up of perfectly identical components that need to fit together in a very specific format. There are technical issues – limitations of physics, money, and time – that require confronting on a daily basis. You can’t point at one part of the car and have an opinion about aesthetics because that one component changes the relationships of the others. You have to understand that you’re looking at an immensely complicated system of moving parts.

I love that comparison though, even if it’s not particularly helpful to give others insight into what we do: a website is a car and not a book.

The post A Website is a Car and Not a Book appeared first on CSS-Tricks.

Simulating Mouse Movement

Css Tricks - Mon, 04/15/2019 - 4:11am

If you've ever had to display an interactive animation during a live talk or a class, then you may know that it's not always easy to interact with your slides and while talking.

This happened to me when I needed to show this particles demo to my students. I didn't want to have to stay next to my computer to move my mouse in order to show off the demo.

See the Pen
Particles (on move)
by Louis Hoebregts (@Mamboleoo)
on CodePen.

If you do not interact with the iframe, you will see nothing but a blank space. As soon as you start moving your mouse or your finger, you can see the animation.

For that reason, I created the same demo but I used some extra code to simulate someone interacting with the demo.

See the Pen
Particles (fake)
by Louis Hoebregts (@Mamboleoo)
on CodePen.

Simplex noise

The trick here is to use an algorithm that will generate "smooth" random positions. If we use a classic random function, the fake mouse will be at a purely random position on every frame. What we want is to have a position on every frame that is directly linked to the previous one. Thankfully, there is a technique that does exactly what we need: Simplex noise (or more commonly known as Perlin noise).

Let's take a look at this image where the height of each column is defined with random values on top, and values from Simplex noise algorithm below.

You can quickly notice that the bottom graph seems much smoother because every column height is connected to the previous one. Those graphs are only showing one dimension (the x-axis, from left to right) but with Simplex noise you can get values in multiples dimensions. In our case, we will need two dimensions for the X and Y coordinates of the fake mouse we're simulating.

If you are more interested to know how Simplex noise works, check out the video "I.5: Perlin Noise - The Nature of Code" by Daniel Shiffman

Get noise coordinates

The first thing we need to make our demo work is to implement a script that generates noise. In my case, I'm using this script by Seph.

Once the noise script is loaded, we can start using it on every frame to make our mouse move.

I will be using an image of a mouse for the demos that I put on position: fixed; with a class .mouse, but you could animate anything else for your own projects.

So, let's take a look at the code:

// We retrieve the image from the DOM const el = document.querySelector('.mouse'); // The render function is called on every frame function render (a) { // The a variable is the amount of milliseconds since we started our script // Get a noise value based on the elapsed time to get a new value on every frame // This noise algorithm is returning values between [-1, 1] so we need to map them to [0, 1] by adding one to the value and dividing it by 2 const noiseX = (noise.simplex2(0, a*0.0005) + 1) / 2; // We get another noise value for the y axis but because we don't want the same value than x, we need to use another value for the first parameter const noiseY = (noise.simplex2(1, a*0.0005) + 1) / 2; // Convert the noise values from [0, 1] to the size of the window const x = noiseX * window.innerWidth; const y = noiseY * window.innerHeight; // Apply the x & y coordinates on our element el.style.transform = `translate(${x}px, ${y}px)`; // Call the render function once the browser is ready to make it an infinite loop requestAnimationFrame(render); } // Ask the browser to call render to start our animation requestAnimationFrame(render);

Here is the result we get with the above script:

See the Pen
Virtual user 1
by Louis Hoebregts (@Mamboleoo)
on CodePen.

Allow interactivity

With the current code, we are not allowed to interact with our demo anymore. Let's add a bit more code to use our real mouse position when we interact with the demo and switch back to a fake mouse as soon as we stop.

const el = document.querySelector('.mouse'); let lastMove = 0; // When the mouse is being moved function onMouseMove (e) { // Get the x and y coordinates x = e.clientX; y = e.clientY; // Save the last move time lastMove = Date.now(); } // Update the mouse position based on x & y function updateMouse (x, y) { el.style.transform = `translate(${x}px, ${y}px)`; } function render (a) { // Check if last move was more than 500ms ago if (Date.now() - lastMove > 500) { // Generate a fake mouse position ... updateMouse(x, y); } } // Listen to mouse events window.addEventListener('mousemove', onMouseMove);

Now, if you move your mouse, the fake mouse will follow yours. If you stop moving for 500ms, the fake mouse will start moving again.

See the Pen
Virtual user 3
by Louis Hoebregts (@Mamboleoo)
on CodePen.

Customized movement

The speed of the mouse can be updated by changing the value of the third parameter. So far, we are setting this value by taking the elapsed time multiplied by 0.0005, which is equal to a/2000.

// Define a speed ratio const speed = a * 0.0005; // Use the speed const noiseX = (noise.simplex3(1, 0, speed) + 1) / 2;

We can also add a bit more randomness in the changes of direction by adding more noise from its position.

let random = 0; function render (a) { ... // Update the random value random += 0.1; // Compute a x random offset based on the window width const randX = noise.simplex3(1, 0, random) * window.innerWidth * 0.1; // Compute a y random offset based on the window height const randY = noise.simplex3(3, 0, random) * window.innerHeight * 0.1; // Define the x & y values based on (noise * screen) + randomness const x = noiseX * innerWidth + randX; const y = noiseY * innerHeight + randY; ... }

Play with the inputs to see how speed and randomly calculated values can influence the fake mouse movement.

See the Pen
Virtual user 4
by Louis Hoebregts (@Mamboleoo)
on CodePen.

More mice

Now that we have created one fake mouse, why not create 500 of them?

See the Pen
Virtual user 5
by Louis Hoebregts (@Mamboleoo)
on CodePen.

I now use this trick for almost all my demos. I think it's really cool to be able to display a project without using a video or being forced to keep moving the mouse randomly while trying to talk about the demo.

If you have any questions or remarks, please leave a comment below or ping me on Twitter.

The post Simulating Mouse Movement appeared first on CSS-Tricks.

Syndicate content
©2003 - Present Akamai Design & Development.