Archive

Archive for November, 2019

It’s my job, and yours.

November 21st, 2019 No comments

The role of ethics in our modern web space has been on my mind for the past few years and I suspect it will occupy my thoughts increasingly as I move forward. With each encounter of a questionable feature or setting on a website, I can’t help but think of all of the people involved and the discussions that may (or may not) have taken place.

Marketing has always straddled the line between promoting a product to an open and willing target audience and outright manipulating those who don’t need it (have you watched toy commercials with a young child lately?). For better or worse, persuasion in marketing has proven to be effective. Fortunately, it is fairly easy to spot an advertisement, even when disguised as sponsored content or product placement. This is what sets marketing apart from some of the more hidden aspects that are built into the apps and sites we use every day.

Many of the discussions surrounding design ethics are focused on privacy, data collection, and analysis by mega-companies and social networks. While there are many unsolved issues in this space, I hope we don’t limit our thoughts and conversations to these global apps. In fact, the smaller the product or company for which you are working, chances are the bigger impact you will have. With that in mind, let’s explore some ways we can be more mindful when creating our next product.

Research and Communication

Fundamental to the design and development of anything we publish is research and communication. Asking yourself or your team a series of questions may help facilitate important conversations and decisions. These may include:

  • Why are we creating this?
  • Who is most affected by this?
  • What outcomes should we consider?
  • Could we do better? How?
  • Could this cause harm?

While unintended consequences are unavoidable by nature, thinking through these questions upfront could help avoid negative impacts later.

Consider Your Team

A team of people with diverse backgrounds and life experiences can contribute to building a more thoughtful product. When creating something for a wide variety of people, it is best to include a wide variety of people throughout that build process. If your team is small (I was a team of 1 for many years), then try to do usability testing and research with people who don’t necessarily have your same background, interests, and career.

Consider Your Role

Ethics in design isn’t only about the things you create, but it is also carried out in the conversations you have. Informing your boss or client that the feature they requested isn’t ideal can be undesirable, but it is your responsibility to tell them why and what, if anything, could be done to make it better. It is almost always easier to complete a list of requests rather than explore options and present a case for why and how something else should be considered. You were hired for your expertise.

What’s Your Legacy?

While not everyone has the luxury of having their dream job or working on an ideal project, it is important for me to be able to look back at the end of the day and be proud of the work I have done. Is your work helping others? Are you creating something that makes this world a better place? If so, I’d love to hear more about it.

So, when asked what about building websites has you interested this year? the role of ethics in the design and development of the things we use every day weighs heavy on my thoughts.

Also, variable fonts.


If you are interested in learning more about Ethic in Design, here are some resources that I recommend:

The post It’s my job, and yours. appeared first on CSS-Tricks.

Categories: Designing, Others Tags:

The future is bright, because the future is static

November 20th, 2019 No comments

I’ve been doing this web thing for money for 10 years this year and although I haven’t been around as long as some folks, I feel like I’ve seen a few cycles come and go now, so let’s say that hot new things are often cynically viewed, initially. This milestone of mine has also got me in a retrospective mood, too, and the question “What about building websites has you interested this year?“ has only encouraged that.

When I first came into the industry, I was an out-and-out designer, delivering static comps to developers until after one-too-many poor builds of my work: I decided to get into code myself. Naturally I focused purely on the front-end—specifically HTML and CSS. Yes, I got a bit into JavaScript too (once Flash became fully irrelevant), but markup and styles have always been my favorite things about web technology. I’ve never really been into back-end development, either. Sure, I can do it, but it’s certainly not my strong suit and usually this weakens my offering a touch—especially as a freelance web designer. Well, it did weaken me, until now.

JAMstack: an awful name, but awfully empowering.

I love JAMstack because it empowers people like me, who aren’t very strong with back-end stuff, and the aspect of JAMstack that I like the most—and which I think is the best part—is static site generators (SSGs). I’m talking specifically about SSGs like Eleventy and less-so Gatsby here, for reference.

The biggest reason that I like SSGs like Eleventy is that I can have a completely flexible, component-driven codebase that at build-time, compiles down to nothing but lovely, static HTML. You still get the power of JavaScript too, but instead of forcing it down the pipe, you run it at compile-time. This has enabled me to do some pretty darn complex stuff. Eleventy does all of this at lightning speed, too.

Mix Eleventy with Netlify and in some cases, Heroku, and suddenly you have a powerful development setup which results in a fast, performant website that auto-deploys. It’s perfect setup for me.

This stuff excites me so much that I made an Eleventy starter kit this year called Hylia. I did this for two reasons:

  1. I wanted to test the viability of a content-managed static-site that uses source controlled content. I chose Netlify CMS to do this
  2. I wanted to empower people without tech skills to publish a performant, accessible blog of their own, so they didn’t have to rely on centralised systems

The platform went down really well and I think part of the reason for its success is that even though it’s (optionally) content managed, powered by design tokens and fully componentized, it performs really well because all you get is HTML and CSS with a bit of progressively enhanced JavaScript.

This is the magic of SSGs, because they give us developer experience, but much more importantly, because the output is static and lightweight (unless you prevent that with lots of code), it creates a really solid basis for a good user experience, too! This isn’t just the case for small projects like Hylia, too, because SSGs can even power huge projects like the Duet Design System, for example.

Looking back at the empowerment that SSGs enable, I’ll just list some things that they have enabled me, a web designer, to do this year:

  • Self-publish a book
  • Create rapid, interactive prototypes for clients which has completely transformed the decision making process
  • Build actual, full websites for clients
  • Completely transform my design process to use HTML and CSS as a deliverables, rather than static comps
  • Build and document an incredibly comprehensive, multi-platform design system (WIP)
  • Re-platform my CSS newsletter (WIP)

These are huge things that have had a massive, positive impact on me and next year, SSGs are only going to feature more in my work as I transition into providing educational material, too.

Wrapping up

The future is bright with the JAMstack and SSGs—especially when what is delivered to the end-user is fast, progressively enhanced websites. I honestly think that they are creating a momentum wave towards a bigger focus in performance, too.

If we chuck in some serverless technology: suddenly, designers and front-end developers really are all powerful and this really excites me because suddenly, we give lots of people power to have great ideas that might not have been able to before.

The post The future is bright, because the future is static appeared first on CSS-Tricks.

Categories: Designing, Others Tags:

The Typed Object Model

November 20th, 2019 No comments

I help write technical documentation and one feature I’ve been writing about this year that has really stood out is the Typed Object Model (or Typed OM). If you haven’t come across it yet you would be forgiven as it’s pretty new. It falls under the CSS Houdini suite of API’s and on the surface seems the least exciting. However, it underpins all of them and will eventually change how we view CSS as a language.

It allows for typing of values in CSS. Remember the base syntax of CSS:

selector {
  property: value;
}

That value can be a lot of things, colors, units, images, words. Which to CSS makes sense, but to us, when we access it and try to change it via any means, it comes as a string.

Typed OM allows that to be returned as a type instead. So if we were to access, say 10px in JavaScript, instead of '10px' being returned, we get the number 10 and the unit 'px'. Which is a whole heap easier to work with.

You may have seen some of Ana Tudor’s amazing demos. In her example ‘Hollow’, she registers custom properties in JavaScript to use in her CSS. She’s using the Properties & Values API and thus can determine the types of these properties. This wouldn’t be possible if Typed OM wasn’t around.

How about an example

On the face of it, it seems a little bit more work than the way we’re used to accessing and setting styles at the moment, but there are a lot of benefits. If we want to, say, get the width of an element we would do something like this:

const elementWidth = getComputedStyle(myElement).width;
// returns '300px'

Not only are we accessing a string here, but getComputedStyle forces a re-layout. We may not be aware of what units are being used, and so accessing the numerical part of the string becomes tricky, and if we are running this in our code a number of times it could harm performance.

If we want to use Typed OM and return a typed value we would have to access the properties and values via computedStyleMap() and it’s get() method:

const elementWidth = myElement.computedStyleMap().get('width');
// returns CSSUnitValue {value: 300, type: 'px'}

Now we can access the value and the unit separately, and the value here is returned as an integer.

elementWidth.value // 300
elementWidth.unit // 'px'

We also haven’t forced a re-layout, which is nothing short of a win. Bet you’re now wondering and yes, not only can you access the CSS value as a type, but you can create unit values pretty easily as well, via the global CSS object:

let newWidth = CSS.px(320);
// returns CSSUnitValue {value: 320, type: 'px'}

That’s a small example and one that’s easy to show, as the units part of the specification has been fleshed out somewhat considerably to some other value types. But regardless it allows for a lot less string matching and flexibility.

Another set of values which is well specced are transform values: translate, rotate, scale, etc. This is great because if we wanted to change one of these values on an element without Typed OM, it can be tricky, especially if we’ve set more than one.

.myElement {
  transform: rotate(10deg) scale(1.2);
}

Let’s say we wanted to increase the rotation. If we access this property with getComputedStyle() a matrix is returned.

const transform = getComputedStyle(myElement).transform;
// returns matrix(0.984808, 0.173648, -0.173648, 0.984808, 0, 0)

With the transforms we have on the element, we can’t possibly pull out one value from the matrix. I’m not going to go all vectors, scalar values, and dot product here, but suffice to say, you can’t pull out one value once the matrix has been formed. There are definitely going to be numerous mappings.

If you have just a transform or scale, this is possible by string matching where the value is in the matrix. But that’s information for another day.

We could use custom properties to set the value of these transforms and update those:

.myElement {
  --rotate: 10deg;
  transform: rotate(var(--rotate)) scale(1.2);
}
myElement.style.setProperty('--rotate', '15deg');

However, we need to know the name of the custom property and we are still passing in a string.

Enter Typed OM. Let’s take a look at what’s returned from the computedStyleMap:

myElement.computedStyleMap().get('transform');
/* returns
CSSTransformValue {
  0: CSSRotate {...}
  1: CSSScale {...}
} */

Each transform value has its own type. There’s CSSRotate and CSSScale for the above code. As well as all the others like skew and translate. So instead of dealing with matrix, or still working with strings, we can create these types and apply a CSSTransformValue with them.

const newTransform = new CSSTransformValue([
  new CSSRotate(CSS.deg(15)),
  new CSSScale(CSS.number(1.2), CSS.number(1.2))
])
myElement.attributeStyleMap.set('transform', newTransform);

Notice how we’re creating the transform types with the class method and the new keyword, rather than the factory method used with the numerical values.

We have a lot more control over each individual value, something much needed when we declare multiple values in CSS.

I put together a Pen with all this example code here.

It’s the foundations

As we begin to get more familiar with other API’s within the Houdini suite, the benefits of all of this will become even more obvious. When we declare a new custom property with the Properties and Values API, we set a type and get automatic error handling, for instance. These value types are also passed into the worklets of the Paint API and Layout API, so we can use the power there too.

There are more types I haven’t mentioned, more types to come and really a lot more to write about. If it hasn’t been already, Typed OM is being implemented in all major browsers at this time. It certainly piqued my interest this year, so look out for it as 2020 comes around!

The post The Typed Object Model appeared first on CSS-Tricks.

Categories: Designing, Others Tags:

Techniques for a Newspaper Layout with CSS Grid and Border Lines Between Elements

November 20th, 2019 No comments

I recently had to craft a newspaper-like design that featured multiple row and column spans with divider lines in between them. Take a look at the mockup graphic here and see if it makes you sweat at all. If you’re like me, you have been around a while and know just how difficult this would have been with old layout techniques.

Newspaper design with line dividers between cells

The project came with a few requirements:

  • Show the outlines of the grid
  • Columns can be wider, or longer than others
  • Divider lines must be shown between the various blocks

CSS Grid: Teaching an old layout new tricks

Newspaper layouts can cause headaches because everyday CSS is one-dimensional, meaning that elements flow on either a horizontal or vertical axis. Even modern flexbox layout is still uni-directional.

For a layout like this, we would almost want the properties that good ol’ HTML tables once provided: things like row and column spans to stretch cells in all directions. We would also want the benefits of modern day CSS, with all the responsiveness and flexible boxes that can grow to fill available space.

CSS grid combines the best of tables with the best of flexible boxes. In fact, grid’s even better because it provides the grid-gap property for creating gutters between cells while taking available space into account. Powerful as this may be, how can we create divider-lines exactly in the middle of those gutters?

Let’s look at three techniques to make that happen.

What we’ll create

First, we will build a simplified version of the newspaper design that’ll help illustrate the crux of the three different techniques that we’re going to cover. A deceptively easy design, one would say.

Column and row spans in a CSS grid layout

Technique 1: The faux column

This solution creates “faux” columns that allow us to draw vertical lines, and then place a grid on top. Horizontal dividers are painted if needed. The “faux” columns are created by using pseudo selectors in the grid container.

<div class="frontpage">
  <div class="fp-cell fp-cell--1">
    <div class="fp-item">1</div>
  </div>
  <div class="fp-cell fp-cell--2">
    <div class="fp-item">2</div>
  </div>
  <div class="fp-cell fp-cell--3 fp-cell--border-top">
    <div class="fp-item">3</div>
  </div>
  <div class="fp-cell fp-cell--4 fp-cell--border-top">
    <div class="fp-item">4</div>
  </div>
</div>

See the Pen
Newspaper-design, ‘faux-column’ technique
by Marco Troost (@marco-troost)
on CodePen.

Setting up the lines between the columns

Let’s create a three-column container using display: grid and pseudo-selectors (:before and :after) to create two columns that fill 100% of the container’s height.

.frontpage {
  position: relative;
  display: grid;
  /* Three columns */
  grid-template-columns: 1fr 1fr 1fr;
  grid-column-gap: 32px;
  border: 1px solid transparent;
  border-top: 1px solid #DADCE0;
  border-bottom: 1px solid #DADCE0;
  overflow: hidden;
}

/* Two faux columns */
.frontpage:before,
.frontpage:after {
  position: absolute;
  top: 0;
  height: 100%;
  content: '';
  width: calc(33.3% - 4px);
}

.frontpage:before {
  left: 0;
  border-right: 1px solid #DADCE0;
}

.frontpage:after {
  right: 0;
  border-left: 1px solid #DADCE0;
}

Note: 33% of the container doesn’t take the gutter width into account, so you’ll have to compensate accordingly.

This is calculated as:

33% minus (gutter-width divided by (amount of gutters times amount of gutters)) divided by amount of gutters)

Or, with actual numbers:

33% - (32 / (2* 2)) / 2 = 4

We could use one pseudo-selector instead:

.frontpage {
  position: relative;
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  grid-column-gap: 32px;
  border: 1px solid transparent;
  border-top: 1px solid #DADCE0;
  border-bottom: 1px solid #DADCE0;
  overflow: hidden;
}

.frontpage:before {
  box-sizing: border-box;
  position: absolute;
  top: 0;
  height: 100%;
  content: '';
  left: calc(33.3% - 5.3px);
  width: calc(33.3% + 10.7px);
  border-left: 1px solid #DADCE0;
  border-right: 1px solid #DADCE0;
}

See the Pen
Newsgrid-layout ‘faux-columns’ (using only :before)
by Marco Troost (@marco-troost)
on CodePen.

Note: A different calculation is needed when using only one pseudo-selector: One for positioning, and one for width.

The width is calculated as:

33% plus (amount of gutters times gutter-width) / (amount of gutters times amount of columns)

Again, with actual numbers:

33% + (2 * 32) / (2 * 3) = 10.7

The position is calculated as:

33% minus (amount of gutters times gutter-width) / (amount of gutters times amount of columns) divided by 2)

Making the grid

The design consists of four blocks of content. We’re going to place them in the container and give them a modifier class for future reference while making sure their z-index is higher than the pseudo-selectors of the grid.

<div class="frontpage">
  <div class="fp-cell fp-cell--1"></div>
  <div class="fp-cell fp-cell--2"></div>
  <div class="fp-cell fp-cell--3"></div>
  <div class="fp-cell fp-cell--4"></div>
</div>

Now let’s set the background color for the cells (.fp-cell) to white. This way, the vertical lines won’t show through. We can also set the vertical padding for the cell to 16px in order to match half of the gutter.

The first and second content blocks should get their own unique spans as shown in the design. The first block spans all the way down and the second block spans the second and third columns.

.fp-cell {
  position: relative;
  z-index: 2;
  padding: 16px 0;
  background-color: #fff;
}

/* Span all the way down! */
.fp-cell--1 {
  grid-row: 1 / span 2;
}

/* Span the second and third columns */
.fp-cell--2 {
  grid-column: 2 / span 2;
}

Vertical line dividers

If you look at the design, only the last two cells need a horizontal border. We can give ’em a sweet modifier class.

<div class="frontpage">
  <div class="fp-cell fp-cell--1"></div>
  <div class="fp-cell fp-cell--2"></div>
  <div class="fp-cell fp-cell--3 fp-cell--border-top"></div>
  <div class="fp-cell fp-cell--4 fp-cell--border-top"></div>
</div>
.fp-cell--border-top:before {
  content: '';
  position: absolute;
  top: 0;
  left: -16px;
  right: -16px;
  border-top: 1px solid #DADCE0;
}

The negative margins are half of the gutter width.

Technique #2: Using background-color

Another way to create the dividers is to utilize the grid-gap property. This solution doesn’t necessarily create a “real” distance between cells, but rather leaves some blank space where the background-color of the grid can shine through. The gutter width is delegated to padding within the grid cells.

<div class="container">
  <div class="frontpage">
    <div class="fp-cell fp-cell--1">
      <div class="fp-item">1</div>
    </div>
    <div class="fp-cell fp-cell--2">
      <div class="fp-item">2</div>
    </div>
    <div class="fp-cell fp-cell--3">
      <div class="fp-item">3</div>
    </div>
    <div class="fp-cell fp-cell--4">
      <div class="fp-item">4</div>
    </div>
  </div>
</div>
.container {
  overflow-x: hidden;
  border-top: 1px solid #DADCE0;
  border-bottom: 1px solid #DADCE0;
}

.frontpage {
  position: relative;
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  grid-gap: 1px;
  margin: 0 -16px;
  background-color: #DADCE0;
}

.fp-cell {
  background-color: #fff;
  padding: 16px;
}

.fp-cell--1 {
  grid-row: 1 / span 2;
}

.fp-cell--2 {
  grid-column: 2 / span 2;
}

.fp-cell--3 {
  grid-column: 2;
}

.fp-item {
  background-color: #efefef;
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 200px;
  height: 100%;
}

See the Pen
Newspaper-design, background-color technique
by Marco Troost (@marco-troost)
on CodePen.

Since all cells have an extra 16px of horizontal padding, the grid needs to be offset by just as much. A wrapper container will take care of the overflow.

<div class="container">
  <div class="frontpage">
  <!-- ... -->
  </div>
</div>
.container {
  border-top: 1px solid #DADCE0;
  border-bottom: 1px solid #DADCE0;
  overflow-x: hidden;
}

.frontpage {
  position: relative;
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  grid-gap: 1px;
  background-color: #DADCE0;
  margin: 0 -16px;
}

Technique #3: Creating a cell border

This solution appends a right and bottom border to each cell. Like the last example, the grid-gap is mimicked by adding padding to the cell content. That means it also needs to be wrapped in an extra container.

<div class="container">
  <div class="frontpage">
    <div class="fp-cell fp-cell--1">
      <div class="fp-item">1</div>
    </div>
    <div class="fp-cell fp-cell--2">
      <div class="fp-item">2</div>
    </div>
    <div class="fp-cell fp-cell--3">
        <div class="fp-item">3</div>
    </div>
    <div class="fp-cell fp-cell--4">
      <div class="fp-item">4</div>
    </div>
  </div>
</div>
.container {
  border-top: 1px solid #DADCE0;
  overflow-x: hidden;
}

.frontpage {
  margin: 0 -17px 0 -16px;
  position: relative;
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
}

.fp-cell {
  padding: 16px;
  background-color: #fff;
  border-right: 1px solid #DADCE0;
  border-bottom: 1px solid #DADCE0;
}

.fp-cell--1 {
  grid-row: 1 / span 2;
}

.fp-cell--2 {
  grid-column: 2 / span 2;
}

.fp-cell--3 {
  grid-column: 2;
}

.fp-item {
  background-color: #efefef;
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 200px;
  height: 100%;
}

See the Pen
Newspaper-design, ‘cell-border’-technique
by Marco Troost (@marco-troost)
on CodePen.

As mentioned, each cell is given a border on the right and on the bottom. The main trick here is the use of the (asymmetrical) negative margin on the grid. This is needed to compensate for the cell’s right border.

.frontpage {
  margin: 0 -17px 0 -16px;
  position: relative;
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
}

Conclusion

Occam’s razor stipulates that the simplest solution wins. In our case, that’s technique number two. But then again, the other solutions have plenty of merit and they could prove useful if, for example, access to the DOM is not possible.

All of these techniques will work. Choosing the right one depends on your use case. The first technique uses the actual grid-gap property to create the gaps, but the others are perhaps easier to understand at a glance… and perhaps easier to maintain as well.

The post Techniques for a Newspaper Layout with CSS Grid and Border Lines Between Elements appeared first on CSS-Tricks.

Categories: Designing, Others Tags:

Variations on Theme: Reinventing Type on the Web

November 20th, 2019 No comments
Image of Tristan and Tillie explaining variable fonts

If anyone knows anything about me, it’s usually one of two things: that I have two outrageously fluffy dogs, or that I like fonts and typography. Like, really really like them. So while I am super excited about how well Tristan is doing with his hydrotherapy —we’re walking 50% further than he was able just a couple months ago, without having to take breaks in the middle—I’m even more riled up about variable fonts.

I know, you’re probably all really shocked.

I’ve been pretty single-minded about them since their introduction three years ago, and think they are going to be a massively Big Thing. But it just hasn’t gotten to that tipping point—yet. But a few things are coming together that make me think this just might be the year. Let me step back a bit and explain.

See the Pen
Variable font, outlined
by Jason Pamental (@jpamental)
on CodePen.

Plex Sans Variable, with outlines showing the range of weights and widths possible with a single file

The future is variable

Variable fonts are an evolution of the OpenType font specification that allows a single file to contain all of the variations of width, weight, slant, italics, and virtually any other permutation of a typeface the type designer want’s to expose—all in a single file. That one file is highly efficient, so it’s far smaller than all of the individual files. For the web, that means we can in many cases save considerable data download, reduce the number of HTTP requests, and in general vastly increase the design flexibility at our disposal. A pretty big change from those plain ‘ol static web fonts we’ve been using for the past 10 years. There’s loads of good stuff out there about them (I’ve written a few here, here, here, and here), but you can also browse the tag right here on CSS Tricks.

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

Desktop

Chrome Opera Firefox IE Edge Safari
66 53 62 No 17 11

Mobile / Tablet

iOS Safari Opera Mobile Opera Mini Android Android Chrome Android Firefox
11.0-11.2 No No 76 78 68
Variable fonts are viewable by 87% of devices on the web according to caniuse.com.

Now that browser support is pretty complete (for the most part everything but IE11 and a couple of Android browsers like Baidu and UC), availability of variable fonts is improving (check out v-fonts.com), and Google is launching support for them via their new API—it feels like this might finally be the breakout year for them.

What excites me the most about that is what we’ll see people create. I’m sure at first it will be lots of “rip and replace”, similar to what we saw on the Nielson/Norman group site with their inclusion of Source Sans Variable on their site last year, or what Google has been testing with Oswald Variable on sites 148 million times a day for the past several months. Basically just using that instead of a few static instances to reap the benefits of faster page loads and less code.

Which is great, but only just a beginning.

What I’m looking forward to seeing is people embracing the full range of what these fonts can do. Going form ultra-light to super-heavy, super-condensed to extra-wide. Whatever the fonts support is there for us to explore. I’m hoping to see designers dive in and explore the power of great typography. Type that speaks more and varied volumes to help guide us around our sites and apps. Type set in motion that can lead us from here to there.

See the Pen
Layout variations, part deux
by Jason Pamental (@jpamental)
on CodePen.

This is one of the explorations I did for my newsletter and talks, playing with notions of legibility and the tension between reading fast and slow.

Will some of it be awful?

Probably. But so were a lot of early responsive websites. And lots of sites with static web fonts when they first launched. Or Flash-based sites. All of these have been evolutions of what we can design and make on the web. It’s up to us to do it well instead of poorly. I’m excited to learn together.

After all, if type is the voice of our words—with variable fonts—that voice has become a chorus.

The post Variations on Theme: Reinventing Type on the Web appeared first on CSS-Tricks.

Categories: Designing, Others Tags:

Build your own React

November 20th, 2019 No comments

Wowza! Rodrigo Pombo’s article about how to build React from scratch is fantastic, not only because it’s well written, but because of the outstanding interaction design: each line in the code examples ge highlighted and explored in further detail as you scroll down the page.

This makes it super easy to walk through each process step by step:

How neat is that? This definitely feels like a new way we should consider showing technical information I reckon as it’s just so much easier to read the code.

Oh, and the part about building your own React? Andy Bell advocates something similar when it comes to state management:

Libraries like Redux, MobX and Vuex make managing cross-component state almost trivial. This is great for an application’s resilience and it works really well with a state-first, reactive framework such as React or Vue.

How do these libraries work though? What would it take to write one ourselves? Turns out, it’s pretty straightforward and there’s an opportunity to learn some really common patterns and also learn about some useful modern APIs that are available to us.

Seems like Rodrigo’s pattern is a nice way to make that sort of learning possible.

Direct Link to ArticlePermalink

The post Build your own React appeared first on CSS-Tricks.

Categories: Designing, Others Tags:

Is Your Email List Checker the Best You Can Get? Here’s How to Find Out

November 20th, 2019 No comments

Are you using an email list checker to maintain your email hygiene? Way to go! If you want your email marketing to succeed, pruning your database periodically is an essential practice. But is the service you chose doing a great job?

What if you could get even better results? Let’s see how you can tell whether your email list checker is the very best you could have picked.

What is an email list checker?

Just in case you’ve never used one and you’re not familiar with the term: an email list checker scans your list of contacts and removes invalid, outdated and other types of risky email addresses. We’re going to explain them in detail below and see why it’s important to get rid of them.

Now, let’s see what a great email checker should be able to do. There are many email validation services on the market, and this will help you choose the best.

1. An email list checker should remove invalid email addresses

First, how do invalid emails end up on your list? There are several ways that can happen:

  • You don’t use the double opt-in to ask new subscribers to confirm their subscription via email.
  • Also, there is probably no reCAPTCHA on your signup form to automatically establish the difference between humans and bots.
  • Most likely, you’re not using an email verification API to check emails in real time.
  • Lastly, some email addresses may have been valid and active when they were added to your list, but were deactivated in the meantime.

A reliable email list checker should be able to spot these addresses right away and weed them out. Otherwise, they bounce and affect your sender reputation and deliverability.

2. Can you get rid of spam traps?

In a nutshell: identifying them is difficult, but yes, some email verification services can detect them and isolate them from your list.

Spam traps prevent email fraud, so they’re a necessary tool against the huge amount of Spam that’s being sent. Internet Service Providers (ISPs) and blacklist providers place spam traps in key places on the Internet to attract Spam senders and block them. Their impact on your email marketing can be devastating.

So, search for an email list checker that uses more complex algorithms to detect spam traps. Eliminating even half of them from your list will make a difference.

3. Say goodbye to those who mark you as Spam

You’re a legitimate sender who follows email marketing practices. However, some people mark you as Spam. Why does that happen? Here are a few reasons:

  • You haven’t emailed your list in a long time and certain people forgot they subscribed. They may have no idea who you are, so they hit the Spam button. Email addresses that belong to these frequent complainers are known as abuse emails.
  • Does your subject line include any spammy-looking words? Apart from this triggering Spam filters, it can also prompt your subscribers to use the dreaded button.
  • Some people are not on board with your emailing frequency. Maybe you email them too often, so they label you as Spam and unsubscribe.

The good news is that, if you choose the right email list checker, it can detect users who have a habit of marking emails as Spam and remove them from your list.

Furthermore, an email validation API checks emails in real time and can identify these users and prevent them from getting on your list.

4. Why keep temporary email addresses in your database?

Let’s say you wrote a great ebook and put it up on your website, gated behind a registration form. Content offers are an efficient list building tool, but they can also attract people who don’t want a long-term relationship with your business.

So, they use a temporary (or disposable) email address to register, get the freebie, and leave. While you may be glad you just added another contact to your list, that contact turns out to be a dead end.

The email address self-destructs (sometimes, within minutes) and bounces. A high bounce rate will cause you trouble with your Email Service Provider (ESP) and trigger the MailChimp Omnivore warning, for instance.

That’s why it’s important to allow an email list checker to remove disposable emails and protect your sender reputation.

5. Catch-all emails are risky. Can an email list checker detect them?

It absolutely should. Nonetheless, take a closer look at your email validation results: sometimes, email checkers will just mark catch-all emails as “risky” and advise you to remove them.

But are all catch-all emails bad? Not exactly.

Catch-all emails are set up to accept all email sent to a particular domain, even if the recipient doesn’t exist. Many organizations use them to ensure they’re not missing any email and stay on top of their communication. But because of their very nature, catch-all emails tend to be flooded with email and some of them will bounce.

Which ones? That’s a great question that no email list checker can answer. As we explained above, some services can’t even detect them and only label them as “risky.” Other can spot them, but are not able to tell you whether they’re valid or not.

The best solution to validate these emails is to score them. Look for a trustworthy email scoring system and run your catch-alls through it to get a better idea of their validity.

What else should my email checker do?

Now that we covered some of the crucial features an email list checker should offer, let’s move on to other aspects. They’re equally important to help you get the best possible results.

Does your service offer an API?

As we’ve mentioned before, an API checks email addresses in real time and ensures there will be no risky signups in your list. The API is a little piece of code that you install on your forms. Once it’s there, it runs quietly in the background and keeps your list clean.

How does your email list checker protect your data?

Is your service GDPR compliant? What kinds of mechanisms does it use to keep your email lists safe during the validation process? Also, for how long does it store that data? These are all questions you have to ask when picking a list scrubbing service. The more layers of defense against breaches and cyberattacks, the safer your information is.

Can I get 24/7 customer support? Yes, you can

Not all email checkers offer 24/7 customer support, but some do, and you don’t have to pay anything extra for this perk. Being able to reach out to an expert when you stumble is a useful service to have.

Let’s wrap up

Competition is strong in the email verification landscape. But that’s a good thing: it forces services to refine their algorithms, innovate, and become increasingly accurate.

What’s hard, though, is picking the very best service at the most reasonable price. So, we hope this article has shed some light on the topic and will help you find the email list checker you were looking for.

Getting access to the benefits we mentioned above is possible and doesn’t cost a fortune, so why settle for anything less?

Categories: Others Tags:

Is Your Email List Checker the Best You Can Get? Here’s How to Find Out

November 20th, 2019 No comments

Are you using an email list checker to maintain your email hygiene? Way to go! If you want your email marketing to succeed, pruning your database periodically is an essential practice. But is the service you chose doing a great job?

What if you could get even better results? Let’s see how you can tell whether your email list checker is the very best you could have picked.

What is an email list checker?

Just in case you’ve never used one and you’re not familiar with the term: an email list checker scans your list of contacts and removes invalid, outdated and other types of risky email addresses. We’re going to explain them in detail below and see why it’s important to get rid of them.

Now, let’s see what a great email checker should be able to do. There are many email validation services on the market, and this will help you choose the best.

1. An email list checker should remove invalid email addresses

First, how do invalid emails end up on your list? There are several ways that can happen:

  • You don’t use the double opt-in to ask new subscribers to confirm their subscription via email.
  • Also, there is probably no reCAPTCHA on your signup form to automatically establish the difference between humans and bots.
  • Most likely, you’re not using an email verification API to check emails in real time.
  • Lastly, some email addresses may have been valid and active when they were added to your list, but were deactivated in the meantime.

A reliable email list checker should be able to spot these addresses right away and weed them out. Otherwise, they bounce and affect your sender reputation and deliverability.

2. Can you get rid of spam traps?

In a nutshell: identifying them is difficult, but yes, some email verification services can detect them and isolate them from your list.

Spam traps prevent email fraud, so they’re a necessary tool against the huge amount of Spam that’s being sent. Internet Service Providers (ISPs) and blacklist providers place spam traps in key places on the Internet to attract Spam senders and block them. Their impact on your email marketing can be devastating.

So, search for an email list checker that uses more complex algorithms to detect spam traps. Eliminating even half of them from your list will make a difference.

3. Say goodbye to those who mark you as Spam

You’re a legitimate sender who follows email marketing practices. However, some people mark you as Spam. Why does that happen? Here are a few reasons:

  • You haven’t emailed your list in a long time and certain people forgot they subscribed. They may have no idea who you are, so they hit the Spam button. Email addresses that belong to these frequent complainers are known as abuse emails.
  • Does your subject line include any spammy-looking words? Apart from this triggering Spam filters, it can also prompt your subscribers to use the dreaded button.
  • Some people are not on board with your emailing frequency. Maybe you email them too often, so they label you as Spam and unsubscribe.

The good news is that, if you choose the right email list checker, it can detect users who have a habit of marking emails as Spam and remove them from your list.

Furthermore, an email validation API checks emails in real time and can identify these users and prevent them from getting on your list.

4. Why keep temporary email addresses in your database?

Let’s say you wrote a great ebook and put it up on your website, gated behind a registration form. Content offers are an efficient list building tool, but they can also attract people who don’t want a long-term relationship with your business.

So, they use a temporary (or disposable) email address to register, get the freebie, and leave. While you may be glad you just added another contact to your list, that contact turns out to be a dead end.

The email address self-destructs (sometimes, within minutes) and bounces. A high bounce rate will cause you trouble with your Email Service Provider (ESP) and trigger the MailChimp Omnivore warning, for instance.

That’s why it’s important to allow an email list checker to remove disposable emails and protect your sender reputation.

5. Catch-all emails are risky. Can an email list checker detect them?

It absolutely should. Nonetheless, take a closer look at your email validation results: sometimes, email checkers will just mark catch-all emails as “risky” and advise you to remove them.

But are all catch-all emails bad? Not exactly.

Catch-all emails are set up to accept all email sent to a particular domain, even if the recipient doesn’t exist. Many organizations use them to ensure they’re not missing any email and stay on top of their communication. But because of their very nature, catch-all emails tend to be flooded with email and some of them will bounce.

Which ones? That’s a great question that no email list checker can answer. As we explained above, some services can’t even detect them and only label them as “risky.” Other can spot them, but are not able to tell you whether they’re valid or not.

The best solution to validate these emails is to score them. Look for a trustworthy email scoring system and run your catch-alls through it to get a better idea of their validity.

What else should my email checker do?

Now that we covered some of the crucial features an email list checker should offer, let’s move on to other aspects. They’re equally important to help you get the best possible results.

Does your service offer an API?

As we’ve mentioned before, an API checks email addresses in real time and ensures there will be no risky signups in your list. The API is a little piece of code that you install on your forms. Once it’s there, it runs quietly in the background and keeps your list clean.

How does your email list checker protect your data?

Is your service GDPR compliant? What kinds of mechanisms does it use to keep your email lists safe during the validation process? Also, for how long does it store that data? These are all questions you have to ask when picking a list scrubbing service. The more layers of defense against breaches and cyberattacks, the safer your information is.

Can I get 24/7 customer support? Yes, you can

Not all email checkers offer 24/7 customer support, but some do, and you don’t have to pay anything extra for this perk. Being able to reach out to an expert when you stumble is a useful service to have.

Let’s wrap up

Competition is strong in the email verification landscape. But that’s a good thing: it forces services to refine their algorithms, innovate, and become increasingly accurate.

What’s hard, though, is picking the very best service at the most reasonable price. So, we hope this article has shed some light on the topic and will help you find the email list checker you were looking for.

Getting access to the benefits we mentioned above is possible and doesn’t cost a fortune, so why settle for anything less?

Categories: Others Tags:

Performing iOS Animations On Views With UIKit And UIView

November 20th, 2019 No comments

Performing iOS Animations On Views With UIKit And UIView

Performing iOS Animations On Views With UIKit And UIView

Saravanan V

2019-11-20T11:00:00+00:002019-11-20T18:35:42+00:00

I have been an iOS developer for over a decade now and have rarely seen articles that consolidate all possible ways to perform animations in iOS. This article aims to be a primer on iOS animations with the intent of exhaustively covering the different ways of doing the same.

Given the extensiveness of the topic, we would cover each part succinctly at a fairly high level. The goal is to educate the reader with a set of choices to add animations to his/ her iOS app.

Before we start off with topics related to iOS, let us take a brief look at animation speed.

Animating At 60FPS

Generally in videos, each frame is represented by an image and the frame rate determines the number of images flipped in the sequence. This is termed as ‘frames per second’ or FPS.

FPS determines the number of still images flipped within a second, which literally means that the more the number of images/ frames, more details/ information are displayed in the video. This holds true for animations as well.

FPS is typically used to determine the quality of animations. There is a popular opinion that any good animation should run at 60fps or higher — anything less than 60fps would feel a bit off.

Do you want to see the difference between 30FPS and 60FPS? Check this!

Did you notice the difference? Human eyes can definitely feel the jitter at lower fps. Hence, it is always a good practice to make sure that any animation you create, adheres to the ground rule of running at 60FPS or higher. This makes it feel more realistic and alive.

Having looked at FPS, let’s now delve into the different core iOS frameworks that provide us a way to perform animations.

Core Frameworks

In this section, we will touch upon the frameworks in the iOS SDK which can be used for creating view animations. We will do a quick walk through each of them, explaining their feature set with a relevant example.

UIKit/ UIView Animations

UIView is the base class for any view that displays content in iOS apps.

UIKit, the framework that gives us UIView, already provides us some basic animation functions which make it convenient for developers to achieve more by doing less.

The API, UIView.animate, is the easiest way to animate views since any view’s properties can be easily animated by providing the property values in the block-based syntax.

In UIKit animations, it is recommended to modify only the animatable properties of UIVIew else there will be repercussions where the animations might cause the view to end up in an unexpected state.

animation(withDuration: animations: completion)

This method takes in the animation duration, a set of view’s animatable property changes that need to be animated. The completion block gives a callback when the view is done with performing the animation.

Almost any kind of animation like moving, scaling, rotating, fading, etc. on a view can be achieved with this single API.

Now, consider that you want to animate a button size change or you want a particular view to zoom into the screen. This is how we can do it using the UIView.animate API:

let newButtonWidth: CGFloat = 60

UIView.animate(withDuration: 2.0) { //1
    self.button.frame = CGRect(x: 0, y: 0, width: newButtonWidth, height: newButtonWidth) //2
    self.button.center = self.view.center //3
}

Here’s what we are doing here:

  1. We call the UIView.animate method with a duration value passed to it that represents how long the animation, described inside the block, should run.
  2. We set the new frame of the button that should represent the final state of the animation.
  3. We set the button center with its superview’s center so that it remains at the center of the screen.

The above block of animation code should trigger the animation of the button’s frame changing from current frame:

Width = 0, Height = 0

To the final frame:

Width = Height = newButtonWidth

And here’s what the animation would look like:

animateWithDuration:delay:usingSpringWithDamping:initialSpringVelocity:options:animations:completion

This method is like an extension of the animate method where you can do everything that you can perform in the prior API with some physics behaviors added to the view animations.

For example, if you want to achieve spring damping effects in the animation that we have done above, then this is how the code would look like:

let newButtonWidth: CGFloat = 60
UIView.animate(withDuration: 1.0, //1
    delay: 0.0, //2
    usingSpringWithDamping: 0.3, //3
    initialSpringVelocity: 1, //4
    options: UIView.AnimationOptions.curveEaseInOut, //5
    animations: ({ //6
        self.button.frame = CGRect(x: 0, y: 0, width: newButtonWidth, height: newButtonWidth)
        self.button.center = self.view.center
}), completion: nil)

Here’s the set of parameters we use:

  1. duration
    Represents the duration of the animation determining how long the block of code should run.
  2. delay
    Represents the initial delay that we want to have before the start of the animation.
  3. SpringWithDamping
    Represents the value of the springy effect that we want the view to behave. The value must be between 0 to 1. The lower the value, the higher the spring oscillation.
  4. velocity
    Represents the speed at which the animation should start.
  5. options
    Type of animation curve that you want to apply to your view animation.
  6. Finally, the block of code where we set the frame of the button that needs to be animated. It is the same as the previous animation.

And here’s what the animation would look like with the above animation configuration:

UIViewPropertyAnimator

For a bit more control over animations, UIViewPropertyAnimator comes handy where it provides us a way to pause and resume animations. You can have custom timing and have your animation to be interactive and interruptible. This is very much helpful when performing animations that are also interactable with user actions.

The classic ‘Slide to Unlock’ gesture and the player view dismiss/ expand animation (in the Music app) are examples of interactive and interruptible animations. You can start moving a view with your finger, then release it and the view will go back to its original position. Alternatively, you can catch the view during the animation and continue dragging it with your finger.

Following is a simple example of how we could achieve the animation using UIViewPropertyAnimator:

let newButtonWidth: CGFloat = 60
let animator = UIViewPropertyAnimator(duration:0.3, curve: .linear) { //1
    self.button.frame = CGRect(x: 0, y: 0, width: newButtonWidth, height: newButtonWidth)
    self.button.center = self.view.center
}
animator.startAnimation() //2

Here’s what we are doing:

  1. We call the UIViewProperty API by passing the duration and the animation curve.
  2. Unlike both the above UIView.animate API’s, the animation won’t start unless you specify it by yourself i.e. you’re in full control of the complete animation process/ flow.

Now, let’s say that you want even more control over the animations. For example, you want to design and control each and every frame in the animation. There’s another API for that, animateKeyframes. But before we delve into it, let’s quickly look at what a frame is, in an animation.

What Is A frame?

A collection of the view’s frame changes/ transitions, from the start state to the final state, is defined as animation and each position of the view during the animation is called as a frame.

animateKeyframes

This API provides a way to design the animation in such a way that you can define multiple animations with different timings and transitions. Post this, the API simply integrates all the animations into one seamless experience.

Let’s say that we want to move our button on the screen in a random fashion. Let’s see how we can use the keyframe animation API to do so.

UIView.animateKeyframes(withDuration: 5, //1
  delay: 0, //2
  options: .calculationModeLinear, //3
  animations: { //4
    UIView.addKeyframe( //5
      withRelativeStartTime: 0.25, //6
      relativeDuration: 0.25) { //7
        self.button.center = CGPoint(x: self.view.bounds.midX, y: self.view.bounds.maxY) //8
    }

    UIView.addKeyframe(withRelativeStartTime: 0.5, relativeDuration: 0.25) {
        self.button.center = CGPoint(x: self.view.bounds.width, y: start.y)
    }

    UIView.addKeyframe(withRelativeStartTime: 0.75, relativeDuration: 0.25) {
        self.button.center = start
    }
})

Here’s the breakdown:

  1. duration
    Call the API by passing in the duration of the animation.
  2. delay
    Initial delay duration of the animation.
  3. options
    The type of animation curve that you want to apply to your view animation.
  4. animations
    Block that takes all keyframe animations designed by the developer/ user.
  5. addKeyFrame
    Call the API to design each and every animation. In our case, we have defined each move of the button. We can have as many such animations as we need, added to the block.
  6. relativeStartTime
    Defines the start time of the animation in the collection of the animation block.
  7. relativeDuration
    Defines the overall duration of this specific animation.
  8. center
    In our case, we simply change the center property of the button to move the button around the screen.

And this is how the final animations looks like:

CoreAnimation

Any UIKit based animation is internally translated into core animations. Thus, the Core Animation framework acts as a backing layer or backbone for any UIKit animation. Hence, all UIKit animation APIs are nothing but encapsulated layers of the core animation APIs in an easily consumable or convenient fashion.

UIKit animation APIs don’t provide much control over animations that have been performed over a view since they are used mostly for animatable properties of the view. Hence in such cases, where you intend to have control over every frame of the animation, it is better to use the underlying core animation APIs directly. Alternatively, both the UIView animations and core animations can be used in conjunction as well.

UIView + Core Animation

Let’s see how we can recreate the same button change animation along with specifying the timing curve using the UIView and Core Animation APIs.

We can use CATransaction‘s timing functions, which lets you specify and control the animation curve.

Let’s look at an example of a button size change animation with its corner radius utilizing the CATransaction‘s timing function and a combination of UIView animations:

let oldValue = button.frame.width/2
let newButtonWidth: CGFloat = 60

/* Do Animations */
CATransaction.begin() //1
CATransaction.setAnimationDuration(2.0) //2
CATransaction.setAnimationTimingFunction(CAMediaTimingFunction(name: CAMediaTimingFunctionName.easeInEaseOut)) //3

// View animations //4
UIView.animate(withDuration: 1.0) {
    self.button.frame = CGRect(x: 0, y: 0, width: newButtonWidth, height: newButtonWidth)
    self.button.center = self.view.center
}

// Layer animations
let cornerAnimation = CABasicAnimation(keyPath: #keyPath(CALayer.cornerRadius)) //5
cornerAnimation.fromValue = oldValue //6
cornerAnimation.toValue = newButtonWidth/2 //7

button.layer.cornerRadius = newButtonWidth/2 //8
button.layer.add(cornerAnimation, forKey: #keyPath(CALayer.cornerRadius)) //9

CATransaction.commit() //10

Here’s the breakdown:

  1. begin
    Represents the start of the animation code block.
  2. duration
    Overall animation duration.
  3. curve
    Represents the timing curve that needs to be applied to the animation.
  4. UIView.animate
    Our first animation to change the frame of the button.
  5. CABasicAnimation
    We create the CABasicAnimation object by referring the cornerRadius of the button as the keypath since that’s what we want to animate. Similarly, if you want to have granular level control over the keyframe animations, then you can use the CAKeyframeAnimation class.
  6. fromValue
    Represents the starting value of the animation, i.e. the initial cornerRadius value of the button from where the animation must start off.
  7. toValue
    Represents the final value of the animation, i.e. the final cornerRadius value of the button where the animation must end.
  8. cornerRadius
    We must set the cornerRadius property of the button with the final value of the animation else the button’s cornerRadius value will get auto-reverted to its initial value after the animation completes.
  9. addAnimation
    We attach the animation object that contains the configuration of the entire animation process to the layer by representing the Keypath for which the animation needs to be performed.
  10. commit
    Represents the end of the animation code block and starts off the animation.

This is how the final animation would look like:

This blog is a great read to help create more advanced animations as it neatly walks you through most of the Core Animation framework APIs with instructions guiding you through every step of the way.

UIKitDynamics

UIKit Dynamics is the physics engine for UIKit which enables you to add any physics behaviors like collision, gravity, push, snap, etc, to the UIKit controls.

UIKitDynamicAnimator

This is the admin class of the UIKit Dynamics framework that regulates all animations triggered by any given UI control.

UIKitDynamicBehavior

It enables you to add any physics behavior to an animator which then enables it to perform on the view attached to it.

Different kinds of behaviors for UIKitDynamics include:

  • UIAttachmentBehavior
  • UICollisionBehavior
  • UIFieldBehavior
  • UIGravityBehavior
  • UIPushBehavior
  • UISnapBehavior

The architecture of UIKitDynamics looks something like this. Note that Items 1 to 5 can be replaced with a single view.

Let us apply some physics behavior to our button. We will see how to apply gravity to the button so that it gives us a feeling of dealing with a real object.

var dynamicAnimator   : UIDynamicAnimator!
var gravityBehavior   : UIGravityBehavior!

dynamicAnimator = UIDynamicAnimator(referenceView: self.view) //1

gravityBehavior = UIGravityBehavior(items: [button]) //2
dynamicAnimator.addBehavior(gravityBehavior) //3

Here’s the breakdown:

  1. UIKitDynamicAnimator
    We have created a UIKitDynamicAnimator object which acts as an orchestrator for performing animations. We have also passed the superview of our button as the reference view.
  2. UIGravityBehavior
    We have created a UIGravityBehavior object and pass our button into the array elements on which this behavior is injected.
  3. addBehavior
    We have added the gravity object to the animator.

    This should create an animation as shown below:

    Notice how the button falls off from the center (its original position) of the screen to the bottom and beyond.

    We should tell the animator to consider the bottom of the screen to be the ground. This is where UICollisionBehavior comes into picture.

    var dynamicAnimator   : UIDynamicAnimator!
    var gravityBehavior   : UIGravityBehavior!
    var collisionBehavior : UICollisionBehavior!
    
    dynamicAnimator = UIDynamicAnimator(referenceView: self.view) //1
    
    gravityBehavior = UIGravityBehavior(items: [button]) //2
    dynamicAnimator.addBehavior(gravityBehavior) //3
    
    collisionBehavior = UICollisionBehavior(items: [button]) //4
    collisionBehavior.translatesReferenceBoundsIntoBoundary = true //5
    dynamicAnimator.addBehavior(collisionBehavior) //6
  4. UICollisionBehavior
    We have created a UICollisionBehavior object and passed along the button so that the behavior is added to the element.
  5. translatesReferenceBoundsIntoBoundary
    Enabling this property tells the animator to take the reference views boundary as the end, which is the bottom of the screen in our case.
  6. addBehavior
    We have added collision behavior to the animator here.

    Now, our button should hit the ground and stand still as shown below:

    That’s pretty neat, isn’t it?

    Now, let us try adding a bouncing effect so that our object feels more real. To do that, we will use the UIDynamicItemBehavior class.

    var dynamicAnimator   : UIDynamicAnimator!
    var gravityBehavior   : UIGravityBehavior!
    var collisionBehavior : UICollisionBehavior!
    var bouncingBehavior  : UIDynamicItemBehavior!
    
    dynamicAnimator = UIDynamicAnimator(referenceView: self.view) //1
    
    gravityBehavior = UIGravityBehavior(items: [button]) //2
    dynamicAnimator.addBehavior(gravityBehavior) //3
    
    collisionBehavior = UICollisionBehavior(items: [button]) //4
    collisionBehavior.translatesReferenceBoundsIntoBoundary = true //5
    dynamicAnimator.addBehavior(collisionBehavior) //6
    
    //Adding the bounce effect
    bouncingBehavior = UIDynamicItemBehavior(items: [button]) //7
    bouncingBehavior.elasticity = 0.75 //8
    dynamicAnimator.addBehavior(bouncingBehavior) //9
  7. UIDynamicItemBehavior
    We have created a UIDynamicItemBehavior object and pass along the button so that the behavior is added to the element.
  8. elasticity
    Value must be between 0-1, it represents the elasticity i.e. the number of times the object must bounce on and off the ground when it is hit. This is where the magic happens — by tweaking this property, you can differentiate between different kinds of objects like balls, bottles, hard-objects and so on.
  9. addBehavior
    We have added collision behavior to the animator here.

Now, our button should bounce when it hits the ground as shown below:

This repo is quite helpful and shows all UIKitDynamics behaviors in action. It also provides source code to play around with each behavior. That, in my opinion, should serve as an extensive list of ways to perform iOS animations on views!

In the next section, we will take a brief look into the tools that will aid us in measuring the performance of animations. I would also recommend you to look at ways to optimize your Xcode build since it will save a huge amount of your development time.

Performance Tuning

In this section, we will look at ways to measure and tune the performance of iOS animations. As an iOS developer, you might have already used Xcode Instruments like Memory Leaks and Allocations for measuring the performance of the overall app. Similarly, there are instruments that can be used to measure the performance of animations.

Core Animation Instrument

Try the Core Animation instrument and you should be able to see the FPS that your app screen delivers. This is a great way to measure the performance/ speed of any animation rendered in your iOS app.

Drawing

FPS is vastly lowered in the app that displays heavy content like images with effects like shadows. In such cases, instead of assigning the Image directly to the UIImageView‘s image property, try to draw the image separately in a context using Core Graphics APIs. This overly reduces the image display time by performing the image decompression logic asynchronously when done in a separate thread instead of the main thread.

Rasterization

Rasterization is a process used to cache complex layer information so that these views aren’t redrawn whenever they’re rendered. Redrawing of views is the major cause of the reduction in FPS and hence, it is best to apply rasterization on views that are going to be reused several times.

Wrapping Up

To conclude, I have also summed up a list of useful resources for iOS animations. You may find this very handy when working on iOS animations. Additionally, you may also find this set of design tools helpful as a (design) step before delving into animations.

I hope I have been able to cover as many topics as possible surrounding iOS animations. If there is anything I may have missed out in this article, please let me know in the comments section below and I would be glad to make the addition!

Smashing Editorial(dm, yk, il)
Categories: Others Tags:

7 Fantastic eCommerce Product Videos and The Lessons They Taught Us

November 20th, 2019 No comments

Due to availability and ease of use, eCommerce companies have all but taken most markets by storm, becoming the preferred purchase alternative for customers.

And it comes as no surprise, really. In today’s online world, there are few boundaries for when and where people decide to shop online.

More importantly, this also means that the way people interact with digital content – especially how they make their purchase decisions – has also changed.

Customers now rely on digital content to gauge the viability of a purchase, which has led companies to step up their digital marketing game. Customers can’t interact with the product up front, so they rely on engaging product videos – like product spotlights, whiteboard animations, and influencer unboxings – to decide.

Today, we’ll figure out what makes great product videos, well, great! And go over some examples to learn valuable insights you can apply to your own content.

Why Use Product Videos?

Put simply, videos let you bring your customers closer to what you are selling. To showcase its features and benefits, and give customers a clear sense of how it would improve their lives – even if their only experience with the product is through a screen.

Moreover, the right product video can help you explain what you are offering in quick, visually attractive, and engaging ways. Something particularly useful to industries selling complex or highly technical products, such as software solutions or healthcare products.

Elements of a Great Product Video

Every type of video marketing piece has its own set of characteristics that make it work. When it comes to product videos, these are the key elements to account for:

  • Simplicity: Keep it simple and clear, no matter how complex the product is. The secret of a successful product video is to develop a well-written script and combine it with meaningful visuals to convey its value and benefits clearly.
  • Length: Timeframes vary slightly depending on what you are showcasing; however, viewers’ attention span drops dramatically after the two-minute mark. Compelling product videos tend to stay between the 1 and 3 minute’ mark. When covering absolutely everything requires more time, a video series is usually the best way to go.
  • Context: Without context, your video will lack punch, and customers will be less likely to purchase it. Create a narrative around your product or service; show exactly how it’d make their lives better. In short, deliver an experience with your piece.

Valuable Lessons from Fantastic Videos

With the why and how out of the way, it’s time to jump into those video examples and see what we can learn from those who’ve already done a great job.

Pencil

Without any spoken or written words, this video manages to convey the product’s usage and benefits in less than 2 minutes!

Pencil is a stylus for touch-screen devices, developed for designers and illustrators. With a cheerful melody, the video focuses on showing hands using the tool in a variety of situations.

The message is clear: It looks like a regular pencil, but it’s better – You can draw, write, erase, and blend with “your hands.” To give it a realistic and engaging effect, the camera moves along with the pencil’s movements, reinforcing the whole theme. Cool, right?

Pure Argan Milk

Well-executed, storytelling can help you form a connection between your customers and your product right away. And this video, introducing the Pure Argan Milk treatment, perfectly illustrates just that.

Whether you are selling software or a moisturizer, it’s crucial to help users resonate with what you are offering in your video. Emotion is the best way to go about it, and that emotion is usually powered by storytelling.

To accomplish that in this piece, they deliver a personal and emotional story while explaining what the product is and how the treatment works. Altogether, it helps build trust in the product’s capabilities, and that reflects it in the perceived reliability of the brand!

Blume

Here’s another example of fantastic storytelling powering a product video, but using an explainer video animation this time around.

Animation can be a great alternative to create engaging and attractive pieces to deliver longer – or more abstract/complex – messages across, bringing them to life without risking losing your audience’s interest midway. Blume’s video revolves around one concept: showcase the value of uniqueness.

To do so, this video weaves a lovely, heartfelt family story that doubles as the company’s background, and lists all the benefits of their product while at it. It reinforces a personal tone through beautiful animations and an empathetic narrator that helps viewers feel comfortable right from the start.

Figma

When you are planning a video, there are plenty of approaches you can take. Figma’s videos focus on addressing a problem right away and bringing up the solution.

Figma is a collaborative design platform, and they used animation to reveal how messy the design process can be.

With simple and dynamic visuals – combined with a cool narrator, and an upbeat tune – this video showcases every single benefit of using their platform, and how much more simple the process can get. It’s short, fun, clear, and straight to the point.

Night Cable by Native Union

Here’s another straight-up approach – Showing a problem and how to solve it. The cool thing about Night Cable’s video is that they do it in less than 45 seconds!

Native Union addressed a very basic, but incredibly common and unsolved issue: we all need to charge our devices, but cables tend to be way too short, poor quality, and uncomfortable.

Through simplicity and familiar settings – at home, in bed, or having a relaxing day in sweatpants – the video displays how helpful their product actually is. In the end, the message is both subtle and persuasive: You don’t just need the product, you’ll also want it!

Breville Precision Brewer

This is a classic “how-to” video that displays the product in action.

Thirty-three seconds, no voice-over, and yet it delivers a clear message by showing how to easily brew an “over the ice” coffee using their classy and elegant machine.

Even though home appliances can be hard to explain because they usually involve too many features, in this case, they managed to keep it super simple, clear, and informative, in record time!

Sonos

Sonos’ video is a great way to show how live-action elements can be enhanced with the right type of animation by their side.

The product itself is a cool set of wireless speakers and home sound systems — nothing really innovative by today’s standards.

However, by using linear and elegant black and white visuals, this video combines animation and the actual products in different situations and rooms. It walks viewers through many of the product’s functions and addresses common questions while at it. The result is an elegant piece that conveys the brand’s tone.

What We Learned

High-quality product videos can help eCommerce businesses bring their potential customers and their products closer than any other medium could. By using beautiful and compelling pieces, they can convey all the relevant information their customers would need to take action.

Done right, they can lead to increased conversions and help build brand loyalty in one fell swoop. The operative piece there being “done right.

There are plenty of approaches you can take with your product videos, so they require a lot of know-how and planning to get them just the way you need them. That said, by following the design ideas and examples we went over today, you have a much better sense of the elements you’ll need to cover!

Time to take these ideas as inspiration, and start developing your own awesome piece for your eCommerce company. Good luck!

Categories: Others Tags: