Archive

Archive for May, 2019

Does Your Web Design Business Need a Rebrand?

May 16th, 2019 No comments

How long ago did you start your design business or side gig? Three months? Three years? And how long has it been since you evaluated your business since then?

As a web designer, your job is to think critically and creatively for your clients, which is why you ask them probing questions like:

  • How old is your business?
  • What’s its mission?
  • Who’s your target audience?
  • What’s the personality of your brand?
  • Where do you see your business in five years?

The better you understand the business, the more easily you can design a website and shape a brand identity around it for them. But I’m willing to bet you haven’t spent much time doing the same for your own business.

I know the last thing you want to do is to take time away from revenue-generating work to evaluate your business and potentially rebrand it. However, what if a rebrand could bring you better work, better quality of clients, and better pay?

There’s a reason why you put so much care into designing a website that perfectly aligns with a company’s mission and personality. You should do the same for your own.

4 Questions to Ask Yourself About Your Business

Lots of companies undergo rebrands. In some cases, it’s because they want to clean up a tarnished image as was the case in Uber’s rebrand. In other cases, they decide to strengthen their branding with visuals that are more uniquely their own, like MailChimp did.

For you? Well, it might be more practical and simple than that.

Consider the following scenarios. Some may sound familiar while others don’t. However, if you do find any connection to the questions and situations I’m about to pose, then it may be time for your business to undergo a rebrand:

1. Did You Start Without a Niche?

Web designers work in a very congested and competitive space, especially as a younger generation of designers raised on computers and apps enter the workforce. That’s why you may find that working without a specialty doesn’t work so well for you.

For starters, a jack-of-all-trades doesn’t look all that different from other web designers that also claim to do it all. Secondly, it’s very hard for you to work efficiently if you’re taking on a coaching website today, a SaaS website next week, and a monstrous ecommerce site a month from now.

There’s something to be said for the kind of efficiency and quality output that comes from having a more narrow focus.

If your business name or website convey this “I’ll work with anyone!” mentality, it might be time for a change.

2. Did You Pick the Wrong Niche?

Let’s say that you did start your business targeting a specific niche or geographic area. If you’re finding success in this space hard to come by, it may be because you picked the wrong niche.

For example:

I have a client whose design agency was originally supposed to target companies in a specific segment of the medical industry. However, a month ago, he told me he wanted to shift the focus to a specific segment of the tech space instead.

He was right to make the switch. While he may have been passionate about the medical niche, the quality of client would’ve been bad for business. So, he carved out a new niche that he knew he’d be comfortable designing websites for and with clients he’d be able to build great relationships with.

If you’re kicking yourself for picking a niche that doesn’t feel right or isn’t profitable, it’s never too late to change.

3. Does Your Business Need to Look Bigger?

When many of us start out, we’re a one-man (or woman) show. It’s great in many respects since we get total control over the business and all decisions related to it. However, there may come a time when the kind of clients you want to work with expect you to have a team of professionals behind you.

Now, whether or not you actually hire anyone to help you build websites, write copy, or manage projects is up to you. However, if you’re selling a premium web design service to clients, your branding and messaging should convey that.

The rebrand could be a simple name change, to be honest. So, rather than market your business using your own name, you’d give it a formal agency name. Or you could switch from branding yourself as a local design company to a global one.

If you feel that giving your business the appearance of size would help you get more clients and, more importantly, ones willing to pay premium prices, a rebrand will help.

4. Have You Changed Your Services?

It’s not just a switch from basic to premium services that may necessitate a change in your branding and marketing. Switching the types of services offered could do it, too.

I have another client who came to me with a similar problem. Her story goes like this:

She launched her company back in the 1970s as a software solution provider for printers. As you can imagine, that type of business has needed to evolve greatly over the years. However, what hasn’t changed much is the name of the company or the design of their branding and messaging. Because of this, it’s been difficult to sell web design and maintenance services to clients.

To reduce confusion, they’re moving to a shortened version of the company name, changing the logo to match, and are now about to undergo a full redesign and rewrite of their website. It’s the only logical solution if they want to reach a modern audience with modern needs.

If you’ve made a major switch in the kinds of services you provide and you feel as though your branding no longer represents what you do very well, then it’s time to change that.

Does Your Web Design Business Need a Rebrand?

What’s nice about this exercise is that it gives you an excuse to stop and think about what your business currently is, who it serves, and where you want to go with it. That’s not always something you think to prioritize as a web designer since you’re so busy doing it for everyone else.

However, this is a great exercise to do once a year to make sure your business is on track to do what you want it to do. And, if not, to adjust your branding and design so that you can get on the right track before it’s too late.

Featured image via Unsplash.

Add Realistic Chalk and Sketch Lettering Effects with Sketch’it – only $5!

Source

Categories: Designing, Others Tags:

How to use grids in graphic design

May 15th, 2019 No comments
grids in graphic design

Do you want to know the best way to set up any graphic design? How about one of the most useful concepts of all graphic design? In short, do you want to understand how to use graphic grids?

In this article, I want to discuss the topic of graphic grids in detail, through rules, useful examples and design resources that you can download and save on your computer. I will tell you how much of the grids are necessary for the construction of any graphic design, the aesthetic-usability effect and how to build a grid in a harmonious way.

Come on, let’s start that there is so much to talk about!

What are the graphic grids?

A grid, or cage, is essentially a subdivision of the workspace through vertical and horizontal lines aimed at organizing the spaces and defining the elements that will make up a project. Let’s think more specifically, and try to understand why the division and organization of a workspace in graphic design are so fundamental.

The composition of the grids is the basis of graphic design

Whether you work with the press or with the web, on the design of a logo or on the construction of a font, on packaging design or layout, understanding how to compose grids is something you need to consider essential among your skills as a designer. A grid is like an invisible glue that holds the project together and gives it coherence. For many designers, though, grids are an almost unknown thing, especially among the many self-teachers who, of course, were not taught about the theoretical aspect of design and therefore about grid theories.

grids in graphic design

The fact that a good organization of the project is so often overlooked is one of the reasons why around the streets and on the web we often see projects with bad balances or alignments. This article was born just to try to fill this “hole” in the training of many creatives. Without a starting grid, a project is born already messy.

Always start with a grid

Whatever your project, once thought and sketched (because making sketches is very important), you have to start realizing the final project starting from a grid.

grids in graphic design

Why? Well, try considering each of your projects as if it were a building. A building without its supporting structure collapses or at least is very unstable when that structure is poorly designed. In addition to being fundamental to creating a supporting structure for your layout, the cages are also extremely important for creating harmony between shapes and relationships. For example, the balance between the white spaces and the text or imagery in the middle of a web page. In fact, a good composition can lead to much more usable projects, as stated in the Aesthetic-Usability Effect theory.

The aesthetic-usability effect

There is a theory about design called the Aesthetic-Usability Effect. Essentially this theory states that when something is designed to be beautiful, consequently and naturally, then it will be something that will also be easily usable. It is a very important concept in all design: from graphics to interface design. A well-designed grid makes your design not only more beautiful but also more usable!

grids in graphic design

So how do you design something beautiful and easily useable? Ok, you have to start from a grid, but what kind of grid? Based on which principles and which theories? We’ll discuss this a little further below.

How to build a functional grid

I told you how a harmonious composition plays a crucial role in determining the success of a project. To construct a harmonious design project it is therefore necessary to construct a graphic grid that is also harmonic. Yes, but how do you construct a harmonious graphic grid?

One of the most effective ways to do this is to use mathematics (nothing complicated) and specific mathematical relationships to construct the structure of the grid itself. Here’s how it’s done:

Follow the paper format

grids in graphic design

The first method is to exploit the dimensional relationships of the support on which you are working. For example, if you are working on an international sheet of paper, such as the A4, it will have a ratio between the two sides of 1: 1.414 and you can then use this mathematical relationship to create the divisions given within the sheet itself.

Creating divisions in a stable relationship with each other inside the sheet will create an important visual harmony.

How to create a grid on A4 paper

Once you have built a grid, you absolutely must not limit your creativity. A grid serves to channel creativity towards your goal. Alas, grid construction is not a science with a set of rules to learn by heart. Many of the most effective grids in graphic design were born from experiments with mathematical relationships, with texts, photographs, and elements of the page or website. Sometimes even from random experiments!

grids in graphic design

You, as a graphic designer, do not have to invent new grids or new methods to build graphic elements, you can simply rely on mathematical conventions, such as those I mentioned in this article. You can even take visual inspiration from highly published magazines and from other websites. The important thing is this: the grids are a great help if they become the most difficult and expensive part of your job, maybe you are doing something wrong. Grids should decrease and not increase the time spent on your project.

Resources

Before concluding, I think it may be useful to have some useful resources for building grids. Let’s start with books, or rather with a book in particular because knowledge is power, isn’t it?

One of the most useful resources in graphic design is the book (in English and German) of one of the masters of Swiss design in the mid-1900s, Josef Muller-Brockmann entitled “Grid Systems in Graphic Design”. This really is a MUST for every graphic designer professional. A historical and precious piece for your library. The price is directly proportional to the quality, really.

Even if you get the smallest chance to read it, it’s very worth it. You could even try getting it at a library. Here are some easy online tools that will also help in your grid creating adventures:

Gridulator – create simple grids that can be quickly saved in .png

Grid Designer – very useful for web designers to design columns and export with .css files

Searching on Google for keywords such as “grid building tool” or “grid builder” can find an infinite number of free tools that do more or less the same simple things.

Conclusion

That’s it for today. I hope I have convinced you of the importance of building a good and balanced grid in all your graphics and design projects. I also hope that this has helped you find a few new resources for designing and creating the perfect grid.

This is just an introductory article on the grids in graphic design. In short, this is just the tip of the iceberg. There are many design theories and strategies out there that will help you perfect your grid related design technique, so always be on the lookout!

Read More at How to use grids in graphic design

Categories: Designing, Others Tags:

A Deep Dive into Native Lazy-Loading for Images and Frames

May 15th, 2019 No comments
Eager cat loaded lazily (but still immediately because it's above the fold)

Today’s websites are packed with heavy media assets like images and videos. Images make up around 50% of an average website’s traffic. Many of them, however, are never shown to a user because they’re placed way below the fold.

What’s this thing about images being lazy, you ask? Lazy-loading is something that’s been covered quite a bit here on CSS-Tricks, including a thorough guide with documentation for different approaches using JavaScript. In short, we’re talking about a mechanism that defers the network traffic necessary to load content when it’s needed — or rather when trigger the load when the content enters the viewport.

The benefit? A smaller initial page that loads faster and saves network requests for items that may not be needed if the user never gets there.

If you read through other lazy-loading guides on this or other sites, you’ll see that we’ve had to resort to different tactics to make lazy-loading work. Well, that’s about to change when lazy-loading will be available natively in HTML as a new loading attribute… at least in Chrome which will hopefully lead to wider adoption. Chrome has already merged the code for native lazy-loading and is expected to ship it in Chrome 75, which is slated to release June 4, 2019.

The pre-native approach

Until now, developers like ourselves have had to use JavaScript (whether it’s a library or something written from scratch) in order to achieve lazy-loading. Most libraries work like this:

  • The initial, server-side HTML response includes an img element without the src attribute so the browser does not load any data. Instead, the image’s URL is set as another attribute in the element’s data set, e.?g. data-src.
<img data-src="https://tiny.pictures/example1.jpg" alt="...">
  • Then, a lazy-loading library is loaded and executed.
  • <script src="LazyLoadingLibrary.js"></script>
    <script>LazyLoadingLibrary.run()</script>
  • That keeps track of the user’s scrolling behavior and tells the browser to load the image when it is about to be scrolled into view. It does that by copying the data-src attribute’s value to the previously empty src attribute.
  • <img src="https://tiny.pictures/example1.jpg" data-src="https://tiny.pictures/example1.jpg" alt="...">

    This has worked for a pretty long time now and gets the job done. But it’s not ideal for good reasons.

    The obvious problem with this approach is the length of the critical path for displaying the website. It consists of three steps, which have to be carried out in sequence (after each other):

    1. Load the initial HTML response
    2. Load the lazy-loading library
    3. Load the image file

    If this technique is used for images above the fold the website will flicker during loading because it is first painted without the image (after step 1 or 2, depending on if the script uses defer or async) and then — after having been loaded — include the image. It will also be perceived as loading slowly.

    In addition, the lazy-loading library itself puts an extra weight on the website’s bandwidth and CPU requirements. And let’s not forget that a JavaScript approach won’t work for people who have JavaScript disabled (although we shouldn’t really care about them in 2019, should we?).

    Oh, and what about sites that rely on RSS to distribute content, like CSS-Tricks? The initial image-less render means there are no images in the RSS version of content as well.

    And so on.

    Native lazy-loading to the rescue!

    Lazy cat loaded lazily

    As we noted at the start, Chromium and Google Chrome will ship a native lazy-loading mechanism in the form of a new loading attribute, starting in Chrome 75. We’ll go over the attribute and its values in just a bit, but let’s first get it working in our browsers so we can check it out together.

    Enable native lazy-loading

    Until Chrome 75 is officially released, we have Chrome Canary and can enable lazy-loading manually by switching two flags.

    1. Open chrome://flags in Chromium or Chrome Canary.
    2. Search for lazy.
    3. Enable both the “Enable lazy image loading” and the “Enable lazy frame loading” flag.
    4. Restart the browser with the button in the lower right corner of the screen.
    Native lazy-loading flags in Google Chrome

    You can check if the feature is properly enabled by opening your JavaScript console (F12). You should see the following warning:

    [Intervention] Images loaded lazily and replaced with placeholders. Load events are deferred.”

    All set? Now we get to dig into the loading attribute.

    The loading attribute

    Both the img and the iframe elements will accept the loading attribute. It’s important to note that its values will not be taken as a strict order by the browser but rather as a hint to help the browser make its own decision whether or not to load the image or frame lazily.

    The attribute can have three values which are explained below. Next to the images, you’ll find tables listing your individual resource loading timings for this page load. Range response refers to a kind of partial pre-flight request made to determine the image’s dimensions (see How it works) for details). If this column is filled, the browser made a successful range request.

    Please note the startTime column, which states the time image loading was deferred after the DOM had been parsed. You might have to perform a hard reload (CTRL + Shift + R) to re-trigger range requests.

    The auto (or unset) value

    <img src="auto-cat.jpg" loading="auto" alt="...">
    <img src="auto-cat.jpg" alt="...">
    <iframe src="https://css-tricks.com/" loading="auto"></iframe>
    <iframe src="https://css-tricks.com/"></iframe>
    Auto cat loaded automatically
    Auto cat loaded automatically

    Setting the loading attribute to auto (or simply leaving the value blank, as in loading="") lets the browser decide whether or not to lazy-load an image. It takes many things into consideration to make that decision, like the platform, whether Data Saver mode is enabled, network conditions, image size, image vs. iframe, the CSS display property, among others. (See How it works) for info about why all this is important.)

    The eager value

    <img src="auto-cat.jpg" loading="eager" alt="...">
    <iframe src="https://css-tricks.com/" loading="eager"></iframe>
    Eager cat loaded eagerly
    Eager cat loaded eagerly

    The eager value provides a hint to the browser that an image should be loaded immediately. If loading was already deferred (e.?g. because it had been set to lazy and was then changed to eager by JavaScript), the browser should start loading the image immediately.

    The lazy value

    <img src="auto-cat.jpg" loading="lazy" alt="...">
    <iframe src="https://css-tricks.com/" loading="lazy"></iframe>
    Lazy cat loaded lazily
    Lazy cat loaded lazily

    The lazy value provides a hints to the browser that an image should be lazy-loaded. It’s up to the browser to interpret what exactly this means, but the explainer document states that it should start loading when the user scrolls “near” the image such that it is probably loaded once it actually comes into view.

    How the loading attribute works

    In contrast to JavaScript lazy-loading libraries, native lazy-loading uses a kind of pre-flight request to get the first 2048?bytes of the image file. Using these, the browser tries to determine the image’s dimensions in order to insert an invisible placeholder for the full image and prevent content from jumping during loading.

    The image’s load event is fired as soon as the full image is loaded, be it after the first request (for images smaller than 2?KB) or after the second one. Please note that the load event may never be fired for certain images because the second request is never made.

    In the future, browsers might make twice as many image requests as there would be under the current proposal. First the range request, then the full request. Make sure your servers support the HTTP Range: 0-2047 header and respond with status code 206 (Partial Content) to prevent them from delivering the full image twice.

    Due to the higher number of subsequent requests made by the same user, web server support for the HTTP/2 protocol will become more important.

    Let’s talk about deferred content. Chrome’s rendering engine Blink uses heuristics to determine which content should be deferred and for how long to defer it. You can find a comprehensive list of requirements in Scott Little’s design documentation. This is a short breakdown of what will be deferred:

    • Images and frames on all platforms which have loading="lazy" set
    • Images on Chrome for Android with Data Saver enabled and that satisfy all of the following:
      • loading="auto" or unset
      • no width and height attributes smaller than 10px
      • not created programmatically in JavaScript
    • Frames which satisfy all of the following:
      • loading="auto" or unset
      • is from a third-party (different domain or protocol than the embedding page)
      • larger than 4 pixels in height and width (to prevent deferring tiny tracking frames)
      • not marked as display: none or visibility: hidden (again, to prevent deferring tracking frames)
      • not positioned off-screen using negative x or y coordinates

    Responsive images with srcset

    Native lazy-loading also works with responsive img elements using the srcset attribute. This attribute offers a list of image file candidates to the browser. Based on the user’s screen size, display pixel ratio, network conditions, etc., the browser will choose the optimal image candidate for the occasion. Image optimization CDNs like tiny.pictures are able to provide all image candidates in real-time without any back end development necessary.

    <img src="https://demo.tiny.pictures/native-lazy-loading/lazy-cat.jpg" srcset="https://demo.tiny.pictures/native-lazy-loading/lazy-cat.jpg?width=400 400w, https://demo.tiny.pictures/native-lazy-loading/lazy-cat.jpg?width=800 800w" loading="lazy" alt="...">

    Browser support

    At the time of this writing, no browser supports native-loading by default. However, Chrome will enable the feature, as we’ve covered, starting in Chrome 75. No other browser vendor has announced support so far. (Edge being a kind of exception because it will soon make the switch to Chromium.)

    You can detect the feature with a few lines of JavaScript:

    if ("loading" in HTMLImageElement.prototype) {
      // Support.
    } else {
      // No support. You might want to dynamically import a lazy-loading library here (see below).
    }

    See the Pen
    Native lazy-loading browser support
    by Erk Struwe (@erkstruwe)
    on CodePen.

    Automatic fallback to JavaScript solution with low-quality image placeholder

    One very cool feature of most JavaScript-based lazy-loading libraries is the low-quality image placeholder (LQIP). Basically, it leverages the idea that browsers load (or perhaps I should say used to load) the src of an img element immediately, even if it gets later replaced by another URL. This way, it’s possible to load a tiny file size, low-quality image file on page load and later replace it with a full-sized version.

    We can now use this to mimic the native lazy-loading’s 2 KB range requests in browsers that do not support this feature in order to achieve the same result, namely a placeholder with the actual image dimensions and a tiny file size.

    See the Pen
    Native lazy-loading with JavaScript library fallback and low-quality image placeholder
    by Erk Struwe (@erkstruwe)
    on CodePen.

    Conclusion

    I’m really excited about this feature. And frankly, I’m still wondering why it hasn’t got much more attention until now, given the fact that its release is imminent and the impact on global internet traffic will be remarkable, even if only small parts of the heuristics are changed.

    Think about it: After a gradual roll-out for the different Chrome platforms and with auto being the default setting, the world’s most popular browser will soon lazy-load below-the-fold images and frames by default. Not only will the traffic amount of many badly-written websites drop significantly, but web servers will be hammered with tiny requests for image dimension detection.

    And then there’s tracking: Assuming many unsuspecting tracking pixels and frames will be prevented from being loaded, the analytics and affiliate industry will have to act. We can only hope they don’t panic and add loading="eager" to every single image, rendering this great feature useless for their users. They should rather change their code to be recognized as tracking pixels by the heuristics described above.

    Web developers, analytics and operations managers should check their website’s behavior with this feature and their servers’ support for Range requests and HTTP/2 immediately.

    Image optimization CDNs could help out in case there are any issues to be expected or if you’d like to take image delivery optimization to the max (including automatic WebP support, low-quality image placeholders, and much more). Read more about tiny.pictures!

    References

    The post A Deep Dive into Native Lazy-Loading for Images and Frames appeared first on CSS-Tricks.

    Categories: Designing, Others Tags:

    A Better Approach for Using Purgecss with Tailwind

    May 15th, 2019 No comments

    Greg Kohn looks at how to use Purgecss — a tool that helps remove unused styles — and Tailwind — a utility-based CSS framework — and why we might want to pair these tools together:

    Tailwind, by intention, is aiming to equip you with an arsenal of utility classes by generating more than you need. There are some best practices which will help keep this overall build size down, like limiting your colors and breakpoints or turning off the modules by default before adding them as necessary. Still, you’ll inevitably generate classes that go unused. And honestly, approaching your configuration with an unrelenting miserly attitude will slow you down and make development less fun. By leaning on Purgecss, there’s no worry that the CSS your users download will only include classes that are ultimately needed.

    I’ve never used Tailwind or Purgecss, but I reckon the latter could be particularly useful if you have a giant old codebase and you don’t have the resources to refactor things just yet. I guess my only concern with introducing a tool like that is it could encourage folks to not refactor large and problematic areas in their styles – taking the safest route with this tool instead.

    For more info about Tailwind, though, Ben Tinsley wrote a great post a while back about how to get started and Nick Basile showed us how to style a form with Tailwind.

    Direct Link to ArticlePermalink

    The post A Better Approach for Using Purgecss with Tailwind appeared first on CSS-Tricks.

    Categories: Designing, Others Tags:

    ’SVG Web Page Components For IoT And Makers (Part 2)’

    May 15th, 2019 No comments
    A collection of animated panels for one type of panel (or component) showing thermometers.

    ‘SVG Web Page Components For IoT And Makers (Part 2)’

    ‘SVG Web Page Components For IoT And Makers (Part 2)’

    Richard Leddy

    2019-05-15T13:30:16+02:002019-05-15T12:06:22+00:00

    So, we already have ways of dynamically loading a menu of SVG icons made to react by loading panels if we so desire, but the icons were not actual components. We were able to use a simple trick of bringing in the SVG for each icon and passing it into the Vue application. It was simple enough to generate a list of icons, and each icon reacted in a similar way except for small data differences. The data difference made it possible to bind the name of a panel to each icon in such a way that the handler for the icon’s button click could pass it on.

    When a panel is loaded in the form of Vue component, everything about the panel and its components has to be loaded, templates, JavaScript, and more. So, the job of just managing loading the panel is bigger than what we have encountered so far in this discussion.

    Let’s look at Vue’s way of providing a hook for async loading. The following snippet is from the Vue guide.

    Vue.component('async-example', function (resolve, reject) {
      setTimeout(function () {
        // Pass the component definition to the resolve callback
        resolve({
          template: '<div>I am async!</div>'
        })
      }, 1000)
    })
    

    The guide tells us that the setTimeout function is an example of how to use the synchronicity with Vue components. Notice that where before there had been an object as the second parameter to Vue.component, there is now a function, which is referred to as a factory function. Within the resolve callback is a component definition, that would have been the second parameter to Vue.component before.

    So, I had to stare at this example a while before it made sense to me. Here is another example, which suits me better:

    Vue.component('async-example', function (resolve, reject) {
      // Vue will call this function and promise itself to handle
      // it when it gets back with data.
      
      // this function can then call a promising object loader
      // here the 'loader' function is some abstract function.
      // Most likely the application will use 'fetch'
      // but it could be something else.
      loader('/my/resource/on/server.json').
        then(function (JSON_data) {
             var object = transformJSONToJSObject(JSON_data);
              resolve(object)
        }).catch( (error) => { handle it } );
    

    It seems like the right thing to do to make a more general function to go around this form.

    function componentLoader(c_name,resource_url) {
      Vue.component(c_name, function (resolve, reject) {
        loader(resource_url).
          then(function (JSON_data) {
               var object = transformJSONToJSObject(JSON_data);
                resolve(object)
          }).catch( (error) => { handle it } );
    }
    

    So, in general, to load a component, we would just need a line like the following:

    componentLoader('ThermoPanel','./JSON/thermo-panel.json');
    

    So now, just what is the JSON that is being loaded? It can include everything about the component. In this case, as a panel component, it can include thermometers, machine switches, sliders, gauges, and more. While it seemed nicer to keep the components parts on the web page, it may actually work better to use the subcomponent field that is in the longer example for ‘thermo-panel’ that we made before and also for the other similarly constructed panels. The JSON will contain a complete panel structure.

    However, if the reader will notice the inclusion of the function call to transformJSONToJSObject, he will understand that JSON might be coded in some way to make transport easier and to make it easier for a server to handle the definition. After all, the definition will include complete SVG templates, function definitions, and other JavaScript expressions. Also, the JSON object may contain more than just the panel definition because some information may simply aid in bookkeeping or validation. So, one can expect that there will be some treatment of the object upon receipt.

    As for the encoding, the data coming in from the server may be encoded in a number of ways. Perhaps it will be simply URL encoded. Or more securely, it might be enciphered. For this discussion, we can just use URL encoding.

    Some of the tools that are available for creating Vue applications no doubt take care of the JSON transformation. But, this discussion has so far avoided the use of command line tools. This omission is not that bad as we have also used Vue with the minimum of resources, using only one script tag for the referring to the CDN. However, I certainly do recommend looking into the command line tools especially for organizing projects.

    When the JSON arrives at the page, given the component is completely assembled with subcomponents, no more work has to be done to fetch the parts. We can make the assumption that all components will come in fully defined for the rest of this discussion. But, assembling complete component hierarchies will require command line tools at some point.

    The SVG editing process will also require some work. The SVG editing processes allow a designer to draw a panel and all the components on it. But, each subcomponent has to be identified, called out in a group, or given a place holder. Any approach to using the drawing requires some treatment of the SVG so that Vue component tags can replace the groups or graphic elements. In this way, any artist rendering can become a template. And, the drawn subcomponents will have to be disassembled into templates for Vue subcomponents.

    This sort of parsimony is contrary to the workflow of most of the JavaScript frameworks. The frameworks are about assembling pages. But, editing or drawing, results in something already assembled by an artist. In practice, the result of editing does not provide a text file that corresponds directly to a framework component definition.

    More about the editing process may be considered in some other discussion. There is a lot to it. But, for now, we have the tools we need in order to load hierarchal components and make them come alive.

    The Lazy Application

    For our IoT panel construction, we already have a selection bar that responds to searches. And, we have a way of loading components when we need them. We just need to connect up these parts. And, at last, we have to make sure that the panels appear and that they start working when they do.

    The lazy loading of panels done by the async code above provides a sketch of an idea. But, thankfully, some people have experimented to find ways of making sure that all kinds of components can be loaded. There is one codepen entry that shows how to update Vue apps with new components of varying types. That is the mechanism that is needed for updating a designated part of the page with different types of panel.

    With the ability to add in different kinds of panels and with a simple mechanism to load their definitions, we can, at last, have our panel searching page.

    Here is the HTML that we need in our page so that the Vue app can place components in dynamically:

    <template v-for="(panel, index) in panelList">
      <component :is="panel" :key="panel.name"></component>
    </template>
    

    The component tag is a Vue meta tag. See the reference for dynamic components. The properties, special attributes, used for the component tag in this case are is and key. The is attribute exists for dynamic components. And, the key ensures that the new children will have different identities from each other and helps Vue to decide what to draw.

    “Children of the same common parent must have unique keys. Duplicate keys will cause rendering errors.”

    The template tag will loop through components that are provided in the panelList data field of the application.

    So, starting with the application level Vue definition for the icon app, we can make changes to include the panelList in the data elements. (Let’s now call it the panelApp).

    var panelApp = new Vue({
            el: '#PanelApp',
            data: {
            iconList: [  // Where is the data? Still on the server.
            ],
            panelList: [
            ],
            queryToken : "Thermo Batches"  // picked a name for demo
            },
            methods : {
              goGetPanel: function (pname) {
                //
                  var url = panelURL(pname);  // this is custom to the site.
                  fetch(url).then((response) => {  // this is now browser native
                    response.text().then((text) => {
                          var newData = decodeURIComponent(text); 
                           eval(pHat);  // widgdef = object def, must be assignment
                           pHat = widgdef;
                         var pnameHat = pname + pcount++;
                         pHat.name = pnameHat; // this is needed for the key
                         this.panelList.push(pHat);  // now it's there.
                      }).catch( error => { /* handle it */ });
              }
            }
        });
    

    Besides adding in the panel, goGetPanel is now in a form required for getting a component definition from a database or other store. The server side must be careful about delivering JavaScript code in the correct format. As for what the object looks like coming from the server, we have already seen it. It is the kind of object used as a parameter to Vue.component.

    Here is the complete body of the Vue app that provides a menu as a search result and a place to put panels fetched from the server when the user clicks an icon.

    <div id="PanelApp">  <!-- Recognize the name from the Vue doc -->
      <div>
      <h2 itemprop="name">Request MCU Groups</h2>
      <p itemprop="description">These are groups satistfying this query: {{queryToken}}.</p>
      <button onclick="GetIcons(11)">Find All</button>
      <button onclick="GetIcons(5)">Find 5 Point</button>
      <button onclick="GetIcons(6)">Find 6 Point</button>
      </div>
    
      <!-- Here is a Vue loop for generating a lit -->
      <div class="entryart" style="padding:4px">
      <button v-for="iconEntry in iconList" @click="goGetPanel(iconEntry.name)" >
        <div v-html="iconEntry.icon">
        </div>
      </button>
      </div>
      
      <div class="entryart" style="padding:4px" >
        <template v-for="(panel, index) in panelList">
          <component :is="panel" :key="panel.name" :ref="panel.name" ></component>
        </template>
      </div>
      
    </div>
    

    In the last div, the component tag now has a ref parameter bound to the panel name. The ref parameter allows Vue app to identify which component to update with data and keeps components separate. The ref parameters also allow our application access to the new dynamically loaded components.

    In one test version of the panel app, I have the following interval handler:

    setInterval(() => {
      var refall = panelApp.$refs;   // all named children that panels
      for ( var pname in refall ) {  // in an object
        var pdata = refall[pname][0];  // off Vue translation, but it's there.
        pdata.temp1 = Math.round(Math.random()*100);  // make thermos jump around.
        pdata.temp2 = Math.round(Math.random()*100);
      }
    },2000)
    

    The code provides a little animation, changing thermometers randomly. Each panel has two thermometers, and the app allows the user to keep adding panels. (In the final version, some panels must be thrown away.) The refs are being accessed using panelApp.$refs, a field that Vue creates given the refs information in the component tag.

    So, this is what the randomly jumping thermometers look like in one snapshot:

    A collection of animated panels for one type of panel (or component) showing thermometers.

    A collection of animated panels for one type of panel (or component). (Large preview)

    Connecting The Panel To The IoT Device

    So, the last piece of code is a setInterval test updating thermometers with random values every two seconds. But, what we want to do is read in real data from real machines. In order to do that, we will need some form of communication.

    There are a variety of ways. But, let’s use MQTT which is a pub/sub message system. Our SPWA can subscribe to messages from devices at any time. When it gets those messages the SPWA can direct each message to the appropriate data handler for the panel mapped to the device identified in the message.

    So, basically what we need to do is replace the setInterval with a response handler. And, that will be for one panel. We probably want to map panels to handlers as they are loaded. And, it is up to the web server to see that the correct mapping is delivered.

    Once the web server and the SPWA have the page ready for operation, the web server no longer needs to take care of messaging between the page and the device. the MQTT protocol specifies a routing server to handle pub/sub. A number of MQTT servers have been made. Some of them are open source. One very popular one is Mosquito, and there are a few developed on top of Node.js.

    The process for the page is simple. The SPWA subscribes to a topic. One good version of a topic is an identifier for an MCU such as a MAC address or a serial number. Or, the SPWA could subscribe to all temperature readings. But, then the page would have to do the work of filtering the messages from all devices. Publication in MQTT is essentially a broadcast or multicast.

    Let’s take a look at how the SPWA will interface with MQTT.

    Initializing MQTT On The SPWA

    There are several client libraries to choose from. One, for instance, is a MQTT.js. Another is eclipse paho. There are more of course. Let’s use Eclipse Paho since it has a CDN stored version. We just need to add the following line to our page:

    <script src="https://cdnjs.cloudflare.com/ajax/libs/paho-mqtt/1.0.1/mqttws31.min.js" type="text/javascript"></script>
    

    The MQTT client has to connect to a server before it can send and receive messages. So, lines setting up the connection also need to be included in the JavaScript. We can add in a function MQTTinitialize which sets up the client and the responses for connection management and message receipt.

    var messagesReady = false;
    var mqttClient = null;
    
    function MQTTinitialize() {
      mqttClient = new Paho.MQTT.Client(MQTTHostname, Number(MQTTPort), "clientId");
      mqttClient.onMessageArrived = onMessageArrived;
      // connect the client
      mqttClient.connect({
               onSuccess: () => {
                 messagesReady = true;
               }
            });
      // set callback handlers
      mqttClient.onConnectionLost = (response) => {
        //
        messagesReady = false;
        //
        if (response.errorCode !== 0) {
          console.log("onConnectionLost:"+response.errorMessage);
        }
        setTimeout(() => {
                MQTTinitialize()
               },1000); // try again in a second
      };
    }
    
    
    Setting up Subscription

    With the connection ready, the client can subscribe to message channels, send messages on them, etc. Just a few routines can do most of the work necessary to connect panels with the MQTT pathways.

    For the panel SPWA, the moment of subscription can be used to establish the association between the panel and the topic, the MCU identifier.

    function panelSubcription(topic,panel) {
        gTopicToPanel[topic] = panel;
        gPanelToTopic[panel] = topic;
        mqttClient.subscribe(topic);
    }
    

    Given that an MCU is publishing on its topic, the SPWA will receive a message. Here, the Paho message is unpacked. And, then the message is passed on into the application mechanics.

    function onMessageArrived(pmessage) {
      //
      var topic = pmessage.destinationName;
      var message = pmessage.payloadString;
      //
      var panel = gTopicToPanel[topic];
      deliverToPanel(panel,message);
    }
    

    So, now all we need to do is create deliverToPanel which should be somewhat like the interval handler that we had before. However, the panel is clearly identified, and only the keyed data sent in the particular message may be updated.

    function deliverToPanel(panel,message) {
      var refall = panelApp.$refs;   // all named children that panels
      var pdata = refall[panel][0];  // off Vue translation, but it's there.
      var MCU_updates = JSON.parse(message);
      for ( var ky in MCU_updates ) {
        pdata[ky] = MCU_updates[ky]
      }
    }
    

    This deliverToPanel function is abstract enough to allow any panel definition with any number of data points for animation.

    Sending Messages

    To complete the application loop between the MCU and the SPWA, we define a function to send a message.

    function sendPanelMessage(panel,message) {
        var topic = gPanelToTopic[panel];
        var pmessage = new Paho.MQTT.Message(message);
        pmessage.destinationName = topic;
        mqttClient.send(pmessage);
    }
    

    The sendPanelMessage function does no more than sending the message out on the same topic pathway that the SPWA subscribes to.

    As we plan to make the icon buttons responsible for bringing in some number of panels for a single cluster of MCU’s, there will be more than one panel to take care of. But, we keep in mind that each panel corresponds to a single MCU, so we have a one-one mapping, for which we may use two JavaScript maps for the map and the inverse.

    So, when do we send messages? Usually, the panel application will send a message when it wants to change the state of the MCU.

    Keeping The View (Vue) State In Sync With Devices

    One of the great things about Vue is that it is very easy to keep the data model synchronized with the activity of the user, who may edit fields, click on buttons, use sliders, etc. One can be sure that button and field changes will be reflected immediately in the components’ data fields.

    But, we want changes to fire off messages to the MCU as soon as the changes occur. So, we seek to make use of the interface events that Vue may govern. We seek to respond to such an event, but only after the Vue data model is ready with the current value.

    I created another kind of panel, this one with a fairly artistic looking button (perhaps inspired by Jackson Pollock). And, I went about turning it into something whose click reports the state back to the panel that contains it. That was not so simple a process.

    One thing that threw me off is that I had forgotten some of the oddities in managing SVG. I first tried to change the style string so that the display field of the CSS style would either be “None” or “something”. But, the browser never rewrote the styles string. But, as that was cumbersome, I tried changing the CSS class. That also had no effect. But, there the visibility attribute, which most of us recall from old HTML (version 1.0 perhaps), but that is very up to date in SVG. And, that works well. All, I had to do was to get the button click event to propagate.

    Vue has designed properties to propagate in one direction, parent to child. So, to change data in the application, or in the panel, you have to send a change event to the parent. Then, you can change the data. The change of the data element controlling the button causes Vue to update the property affecting the visibility of the SVG element we have chosen to indicate state.
    Here is an example:

    More than one type of panel and more than one animation instance per type.

    Finally, a collection of different types of panels each with instances assigned to separate MCU’s. (Large preview)

    Each instance of the squiggly button panel is independent. So, some are ON and some are OFF.

    This snippet of SVG contains the odd-looking yellow indicator:

    <path
         :visibility="stateView"
         style="opacity:0.98000004;fill:#faea4a;fill-opacity:1;stroke:#eecd5c;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
           id="sunthing"
           d="m -36.544616,12.266886 c 19.953088,17.062165 5.07961,-19.8251069 5.317463,8.531597 0.237853,28.356704 13.440044,-8.847959 -3.230451,10.779678 -16.670496,19.627638 14.254699,-2.017715 -11.652451,3.586456 -25.90715,5.60417 10.847826,19.889979 -8.095928,-1.546575 -18.943754,-21.436555 -1.177383,14.210702 -4.176821,-12.416207 -2.999438,-26.6269084 -17.110198,8.030902 2.14399,-8.927709 19.254188,-16.9586105 -19.075538,-8.0837048 9.448721,-5.4384245 28.52426,2.6452804 -9.707612,-11.6309807 10.245477,5.4311845 z"
           transform="translate(78.340803,6.1372042)" />
    

    The visibility is populated by stateView, a computed variable that maps the state boolean to a string for SVG.

    Here is the panel component definition template:

    <script type="text/x-template" id="mcu-control-panel-template">
      <div>
        <control-switch :state="bstate" v-on:changed="saveChanges" ></control-switch>
        <gauge :level="fluidLevel" ></gauge>
      </div>
    </script>
    

    And, this is the JavaScript definition of the Vue panel with its children as subcomponents:

    var widgdef = {
      data: function () {
        var currentPanel = {  // at the top level, values controlling children
          bstate : true,
          fluidLevel : Math.round(Math.random()*100)
        }
        //
        return currentPanel
      },
      template: '#mcu-control-panel-template',
      methods: {
        saveChanges: function() {  // in real life, there is more specificity
          this.bstate = !this.bstate
          relayToMCU(this.name,"button",this.bstate) // to be defined
        }
      },
      components: {
        'control-switch' : {  // the odd looking button
          props: ['state'],
          template: '#control-switch-template',  // for demo it is in the page. 
          computed: {
            // you saw this in the SVG above.
            stateView : function() {
              return ( this.state ) ?  "visible" : "hidden"
            }
          },
          methods : {
            // the button handler is in the SVG template at the top.
            stateChange : function () {  // can send
              this.$emit('changed');  // tell the parent. See on the template instance
            }
          }
        },
        'gauge' : { // some other nice bit of SVG
          props: ['level'],
          template: '#gauge-template'
        }
      }
    }
    

    So, now the mechanism for a single button embedded in a panel has been laid out. And, there has to be a hook for telling the MCU that something has taken place. It must be called immediately after the data state of the panel component has been updated. Let’s define it here:

    function relayToMCU(panel,switchName,bstate) {
      var message = switchName + ':' + bstate  // a on element parameter string.
      sendPanelMessage(panel,message)
    }
    

    There is the state change on it’s way to hardware in just two lines of code.

    But, this is a fairly simple case. Any switch can be viewed as a function call to a piece of hardware out in the world. So, the string might contain the switch name and several other data elements. So, the component method that registers change will have to have some custom handling in it in order that it might gather together all the pieces of data set on the panel and send them along in one command string. Even the command string is a little simple. If the MCU is quite small, the command string might have to be translated into a code. If the MCU has a great deal of capability, the command string might actually be a JSON structure or perhaps all the data that the panel hosts.

    In this discussion, the buttons on the icon panel contain the name of the panel to fetch. That may also be fairly simplified as well. It seems to make sense that that parameter can stand for any panel that might be stored in an enterprises databases. But, perhaps it is some formula. Perhaps, information about the panel should be wrapped around the panel definition that we receive from the server. In any case, the basics can be easily expanded upon once certain headaches are out of the way, like making the SVG respond to clicks properly.

    Conclusion

    This discussion has laid out some basic steps and decisions that lead to the realization of a Single Page Web App (SPWA) that can interface with IoT devices. We now know how to get panels from a web server and turn them into MCU interface.

    There is much more to this discussion with quite a few other discussions that may follow. Starting with Vue is one thing to think about. But, then there is the whole MCU story, which we have only briefly touched upon.

    In particular, by selecting MQTT as a communication substrate, we assume that IoT devices on the other end can somehow be ruled by MQTT. But, that may not always be the case. Sometimes gateways are needed if MQTT is to gain access to a device with serial links or Bluetooth. Or, perhaps all one ever needs from on the web page is WebSockets. Nevertheless, we used MQTT as an example to show how Vue could both receive and send data while keeping its data state in sync with devices.

    Once again we only have part of the story. This time it is for synchronization because the page should be able to deal with alerts and bother the user if something critical is happening. Sometimes messages can get lost. So, we have to have a mechanism for acknowledgments.

    Finally, it is my opinion that Vue makes updating data upon receipt quite elegant. But, sending the state changes is not so straight forward. It does not seem to make the job much simpler than can be done with vanilla JavaScript. But, there is a way and it makes sense.

    Perhaps a clean library can be built to make a universal set of components for all panels. The elements for making such libraries and having them stored in a database have been briefly mentioned. Tools that go beyond just making SVG pictures may have to be developed. In any case, there are likely many things that can be done for the next steps.

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

    Reputation Management 101

    May 15th, 2019 No comments

    I really don’t need to explain how important your reputation is, do I?

    Short version: if people think you suck, either as a person or as a designer, they won’t hire you. It’s not a difficult concept, all things considered.

    Figuring out what other people think of us is much harder. Controlling what they think about you is next to impossible, as any attempt to “change your image” will probably backfire, unless you’re a consummate actor. And then… then there’s one big, honking problem: the idea of “sucking as a person or as a designer” will vary from person to person.

    No matter how wonderful you are, somebody will…misjudge you…That’s life

    Everybody wants something different out of life. Some people will think you’re an arrogant know-it-all if you talk too loudly or confidently, and others will think you’re weak and indecisive if you’re quiet. Some will expect their website to be loaded with as many shiny things as possible; others will dismiss you if they get even a metaphorical whiff of JavaScript.

    If you’re looking to this article to help you control how others perceive you, don’t bother. No matter how wonderful you are, somebody will misinterpret you, misjudge you, or just not pay enough attention. That’s life.

    On the other hand, what you can do is build a reputation that appeals to the clients you want. You know, the fairly reasonable ones. These tips can help you to minimize the number of negative interactions you have with clients in general. The more positive interactions you have, the better your reputation, the more clients you actually like will come knocking at your door.

    Get A Set of Principles, And Stick To Them

    This seems like a no-brainer, but people often start out with good intentions, but ill-defined principles. I did. It has led to a situation or two where a client asked me to implement a sort of “grey pattern”, or do something a little sketchy, but ultimately not “bad”. This would inevitably end with them asking me to do something I just wouldn’t do, and my relationship with those clients never ended well.

    refuse to make the same mistake twice

    Unfortunately, it takes some trial and error to find out just how far you’ll go, and what you’re willing to do for a client. The best thing you can do is learn quickly, and refuse to make the same mistake twice. As you develop your set of principles into something codified and clear, you’ll learn how to avoid clients who would put you in awkward positions.

    Be As Direct As You Can

    Be honest, while being as tactful as you can. You don’t have to blurt out your life history to anyone who will listen, like I do, but you should be direct in your communications. Never, ever depend on subtext to do your talking for you. More often than not, people will misunderstand you.

    They might misunderstand you anyway. People will sometimes try to “read between the lines”, even if there’s nothing there to read. There is nothing you can do about this, but as long as you’ve been honest, then it’s not your fault.

    Bonus tip: keep a record of your communications, so you can refer back to it to resolve disputes and (if things go very wrong) lawsuits.

    Be Careful About The Promises You Make

    Both in your advertising and in your direct communications, be wary of making commitments you can’t live up to. This is difficult, especially when you’re freelancing, or struggling as a business. It’s tempting to say “yes” to everything when you’re just getting started, but don’t.

    You might take on too much at once, or worse, you might agree to build something you do not yet have the skill to build. God knows I have. Asking, “How hard can it be?” is an invitation for the universe to beat you over the head with some harsh truths.

    A broken promise might be the single worst thing you can do to your reputation

    Sometimes you don’t know what you can do until you try, but it’s probably best to try on your own time, not when there are paying clients waiting. A broken promise might be the single worst thing you can do to your reputation, so be very, very careful about what you commit to.

    Oh, and always give yourself some wiggle room with your deadlines. You might think you can pack two projects up close together in your calendar, but that so often ends in disaster; besides, you need time to unwind, and let your brain rest.

    Own Up To Your Mistakes the Moment You Discover Them

    And for God’s sake, do your best to remedy them. Offer a discount or partial refund if you have to, but only as a last resort. A show of willingness will often be enough to smooth things over, and even when it’s not, it makes a great start.

    Advertise With Discretion

    The way you advertise yourself is a big part of your reputation, especially at the beginning. Want to make a good impression? Don’t use pop-up modals. Don’t blast people’s eyeballs with unwanted interruptions of any kind. And for goodness’ sake, don’t try to make people feel bad for not wanting your newsletter.

    If you’re going to upsell, time your upselling properly. Ideally, you will do it in person, and do it right after your client has said something like, “That’s amazing! We love what you’ve done.” That’s the time to ask if there’s more you can do for them. Not before.

    Advertise confidently, not insistently.

    There’s A Lot You Just Can’t Control

    Get used to it. All you can really do is this: do your best work, and treat people kindly and compassionately. That won’t always be enough, and some people will still misjudge you. Some will try to take advantage of you. Ditch those people fast, and keep looking.

    A good reputation is a long-term project. In time, good clients will see your honesty and hard work. Those qualities are precious enough that they’ll want to protect you, and yes, they’ll want to pay you.

    Yay!

    Featured image via Unsplash.

    Add Realistic Chalk and Sketch Lettering Effects with Sketch’it – only $5!

    Source

    Categories: Designing, Others Tags:

    8 Customer Retention Strategies (Bonus Tip Included)

    May 15th, 2019 No comments

    No matter how big you become, you can never claim that your customer loyalty is a going concern forever.

    Either consumer expectations will change, or the competition will start providing something better in the market. And frankly speaking, you cannot control any of the above in a free market.

    Customers are value maximizers. It means that customers will come to you when you are proposing higher perceived value than the competition. Customer’s Perceived Value (CPV) is the difference between the benefits of product/service received by the customers and the costs incurred by them to get those benefits. And these costs do not include only the monetary part. Non-monetary costs like buyer’s time, effort and psychological toll are also considered while calculating CPV. As long as you provide high CPV to your customers, they will stick to your business.

    There are three ways to maximize CPV. One, you increase the benefits provided by your product with the latest features and advanced methods which will increase your costs. Second, you decrease the monetary costs associated with your product that will affect the gross margins. And third, decrease customers’ non-monetary costs. And the reduction of these non-monetary costs will not only retain your old customers but will also help in attracting the new ones.

    In this article, we will discuss 8 customer retention strategies which can reduce these non-monetary costs for your customers:

    1- Get Close

    How close are you to your customers? Getting close here means that your business should be easily approachable. If a customer has to wait for hours before getting in touch with your customer care executive. Or your business does not reply to his emails for days. Then you are definitely not close to your customer. And proceedings on these lines will soon make you invisible in their eyes, and hence they will move to a competitor who listens to them.

    With the entry of social media and new review systems, it has become more challenging for businesses to respond immediately to the feedback coming in from various channels. But if a business puts an honest effort in improving conversations with customers, then huge ROI can be expected in terms of customer loyalty.

    2- Frequency Programs

    An old, obvious but most successful strategy of customer retention. Reward your loyal customers. Simple, right? No.

    Designing frequency programs is also a complex process. You have to maximize the impact on loyalty and minimize the load on your pockets. But if you are creative enough in managing them, then FPs can be a great way of improving customer retention.

    FPs are appreciated because they create cross-selling opportunities for your business too. For example, if you are owning a PVR and you start offering popcorns (a high margin product) on a discount for every 3rd movie watched by your frequent customer, then he will be tempted to watch at least 3 movies to buy those popcorns at a cheap rate.

    3- Premium Club Memberships

    Every business has some high revenue generating customers. These customers are very important for businesses like banks, law firms, airlines, and consultants, etc. These people do not shy away from spending on high-end products of your business. Then why not create a special club for such customers. This will be a major psychological boost for them.

    These club members get access to some special benefits and discounts on their purchase. For example, if there is a customer who is a frequent flyer and always books business class tickets and luxury hotels on your travel website. You can make him part of your premium club and offer him a small taxi ride from the airport to his hotel for free.

    Such strategic initiatives are not only economical but also give a psychological pump to the customer.

    4- Create Tie-ups

    This strategy is useful for both B2B and B2C businesses. It is very important to have loyal customers in B2B businesses as the order size is measured in millions and billions of dollars. Businesses (clients) can be made loyal if you make them dependent on you. This dependency can be created with the help of institutional tie-ups.

    For example, if you are a commercial vehicle seller. It is important for your customers to get their newly bought vehicles insured. Hence, it becomes obvious for you to have a tie-up with an insurance company. This will save both time and energy of your customers. Thus, resulting in a spike in customer retention.

    5- Brand Communities

    Whether it’s “HOG” of Harley Davidson or the “Citizens” of Manchester City FC, your brand name can work wonders for your loyalty. A brand community cannot be built overnight. For that, you need some proud customers who are ready to show their love for your company without hesitation. They can also reduce your marketing cost so much as they are your advocates.

    A community is the result of the differentiation of your product and marketing capabilities. A brand community once built, will push your customers to stay within that elite group which resonates with their likes and gives them a sense of affiliation.

    6- Personalization

    Customizing your product/services for different customers also generates a sense of belonging in them. Who doesn’t like to feel special?

    Therefore, it is your responsibility to treat each customer like they are your priority. But to create personalized services, you need some proper data management. You should know what your frequent customers like about your business and what makes them come more often. This is very useful in hospitality businesses and food-related ventures.

    7- Benchmark Competition

    Although this is necessary for all parts of the business, it plays a critical role in driving your customer loyalty. Never underestimate your competition. Always keep an eye on their latest offerings. Check if their strategy is working and act fast on it. After all, they are trying to take away your market share.

    8- Win-Back Strategy

    No matter what you do and how much you do, it is an undeniable truth that some customers will leave at the end of the day. But that does not mean that they cannot come back. It will be easier for your business to re-attract the old customers as compared to new ones because you know who they are. You have their contact details and buying history.

    Plus, they are a great source of honest feedback. Contact them for an exit interview. Ask them what they did not like about you. If you can make some changes to get them on board again, do it.

    Bonus Tip: CRM

    Throughout the article, in implementation of all the 8 strategies, did you have a thought that your customer and sales data plays an important role here?

    Of course, it does. First of all, you won’t get to know about your frequent customers if you don’t have any statistics of your sales. You cannot build FPs, club memberships, and brand communities for them. You cannot personalize your service if you don’t have their purchasing history. You cannot win back your ex-customers if you can’t retrieve their names and contacts in a click. CRM can solve all these problems for you.
    CRM software records and analyze your sales data. These analytics can tell you about your frequent and premium customers. It also provides you with insights about your strong and weak areas which will help you in improving your sales cycle. Hence, implement a CRM in your company to know your customers better so that you can serve them better.

    Categories: Others Tags:

    What is a Font? The Complete Guide for Typography Designers

    May 14th, 2019 No comments
    what is a font

    What is a font? And how are fonts used? How can you create quality typographic projects, using the best characters? This article aims to be the answer to these and many other questions that many young designers ask themselves every day.

    Today, with this guide, I want to try to create a complete introductory resource for all the main topics of the font world. In short, it is a super guide for designers to use fonts!

    OK, let’s go!

    What is a font? And what is a typeface? And a glyph?

    Before figuring out how to use fonts, it’s good to know what a font is, the difference between a typeface, a glyph, and so on. Because yes, typeface and fonts don’t mean exactly the same thing. The characters are, in graphics, typography, and publishing, like bricks in architecture, atoms in physics or numbers in mathematics. In short, they are the basis of graphics matter.

    what is a font

    A set of characters studied coherently and according to the same formal principles, forms a typeface, whose file is called a font. But let’s clarify these aspects better.

    Fonts, typefaces, and glyphs

    These characters are letters, punctuation marks or symbols. So, for example, the letter “A” is a character. This character can be composed of several glyphs, such as A, ä, ? or â, which will, therefore, be glyphs of the same character and of the same typeface. The set of all the characters and glyphs of the Latin alphabet designed according to the same visual coherence and meaning, takes the name, again, of a typeface.

    And it is here that misunderstandings arise in many different languages. English is clearer: the character (understood as a letter) is a character, the glyph is a glyph and the coherent set of all this, the typeface, is a typeface.

    what is a font

    The font, however, is the file

    Font is another thing: font is the medium that allows you to apply a font. That is: while Garamond is a character (typeface), the garamond_semibold.otf file is a font (better: one of the fonts that make up the Garamond font family). To explain it we can make the comparison with music: if a typeface (character) is a song, the font is the .mp3 file that allows us to listen to it. It is, therefore, wrong to say “Listen to this chorus via this mp3!”, While it is much more correct to say “Listen to this song!”

    We often use the word “font” instead of character, it is a common mistake of the digital age: to confuse the software (medium) with its purpose (end). It’s a bit like saying “but this is Photoshop” looking at a montage.

    And it is a mistake that I myself made for years and in which I still make from time to time. So learn from my mistakes!

    Why do you say “font”?

    Many think that font is a term of English origin but in reality, its origin is French. It is, in fact, the English transposition of the term “source”, of medieval French. This word, which pronounced itself “font” (in French the end is truncated and not pronounced) originally meant “fused”. The Latin root of the word is the same as the Italian verb “folder”. The word font was then imported into England where it spread to all English-speaking countries and from there to the whole world over the last century.

    What are the font variants and types of typefaces?

    Let’s look at the terms that serve to identify the various files that make up a family of fonts and the types of main typefaces:

    The variants of a font (weights, italics, etc.)

    As mentioned, a font is a file and each file corresponds to a typeface in which all the glyphs that have been designed so that it works together, as a single body, and inserted. Generally, font files are grouped into font families, where there are variations of the original typeface.

    what is a font

    Types of typographic characters

    The typefaces are not all the same, indeed, they are very different! In graphic schools or universities, fonts are often said to be divided into two categories, the serif and the sans serif. These are two French terms that mean “with thanks” and “without thanks”. In reality there are several others, even within these two macro-categories.

    Serif and Sans Serif

    what is a font

    The substantial difference between these two categories of fonts is the use of the “graces”, or those small extensions at the ends of the rods, which derive from manual calligraphic writing.

    How does a font work?

    As I said before, a character, or a single letter in all its variants, is composed of various different glyphs. Glyphs, in turn, are composed of many different structural elements, which take different names:

    How to use fonts

    In a complete guide on typography in graphics, one cannot talk about how to use these fonts. How many times have you started searching for the font best suited to your project by scrolling the font drop-down for hours, searching through the hundreds of characters you downloaded or purchased?

    To put it simply, the font should always compliment the context. Of course, there are many ways it can do that, so it’s not exactly a science. What it is, however, is a skill that can be adapted and fine-tuned with some practice.

    How to use fonts: combine multiple fonts with each other

    Choosing a font is a complicated process and requires careful analysis of your project. But knowing how to match fonts can be even more difficult. In reality, there are so many things to talk about in this wonderful and fascinating world. Because the type is really one of the most mysterious and profound aspects of graphic design.

    what is a font

    There are lots of courses you can take in order to get this right. My advice would be to at least research and study as much as you can. Again, this is one of those things that can only be perfected through practice.

    The conclusion

    I hope you’ve learned something new today. Although this article aimed to cover a lot, there is still a lot to know.

    Fonts have been around for quite a while, and won’t be going away ever. They are an essential part of graphic design, and design as a whole. My advice would be to get as comfortable with them as possible and to practice using a wide variety of them, combine them, and maybe even experimenting with your own.

    Read More at What is a Font? The Complete Guide for Typography Designers

    Categories: Designing, Others Tags:

    Integrating Third-Party Animation Libraries to a Project

    May 14th, 2019 No comments
    A screenshot of a Netscape browser window.

    Creating CSS-based animations and transitions can be a challenge. They can be complex and time-consuming. Need to move forward with a project with little time to tweak the perfect transition? Consider a third-party CSS animation library with ready-to-go animations waiting to be used. Yet, you might be thinking: What are they? What do they offer? How do I use them?

    Well, let’s find out.

    A (sort of) brief history of :hover

    Once there was a time that the concept of a hover state was a trivial example of what is offered today. In fact, the idea of having a reaction to the cursor passing on top of an element was more-or-less nonexistent. Different ways to provide this feature were proposed and implemented. This small feature, in a way, opened the door to the idea of CSS being capable of animations for elements on the page. Over time, the increasing complexity possible with these features have led to CSS animation libraries.

    Macromedia’s Dreamweaver was introduced in December 1997 and offered what was a simple feature, an image swap on hover. This feature was implemented with a JavaScript function that would be embedded in the HTML by the editor. This function was named MM_swapImage() and has become a bit of web design folklore. It was an easy script to use, even outside of Dreamweaver, and it’s popularity has resulted in it still being in use even today. In my initial research for this article, I found a question pertaining to this function from 2018 on Adobe’s Dreamweaver (Adobe acquired Macromedia in 2005) help forum.

    The JavaScript function would swap an image with another image through changing the src attribute based on mouseover and mouseout events. When implemented, it looked something like this:

    <a href="#" onMouseOut="MM_swapImgRestore()" onMouseOver="MM_swapImage('ImageName','','newImage.jpg',1)">
      <img src="originalImage.jpg" name="ImageName" width="100" height="100" border="0">
    </a>

    By today’s standards, it would be fairly easy to accomplish this with JavaScript and many of us could practically do this in our sleep. But consider that JavaScript was still this new scripting language at the time (created in 1995) and sometimes looked and behaved differently from browser to browser. Creating cross-browser JavaScript was not always an easy task and not everyone creating web pages even wrote JavaScript. (Though that has certainly changed.) Dreamweaver offered this functionality through a menu in the editor and the web designer didn’t even need to write the JavaScript. It was based around a set of “behaviors” that could be selected from a list of different options. These options could be filtered by a set of targeted browsers; 3.0 browsers, 4.0 browsers, IE 3.0, IE 4.0, Netscape 3.0, Netscape 4.0. Ah, the good old days.

    Choosing Behaviors based on browser versions, circa 1997.
    A screenshot from the Dreamweaver application that shows the options panel for toggling an element's behavior in HTML.
    The Swap Image Behaviors panel in Macromedia Dreamweaver 1.2a

    About a year after Dreamweaver was first released, the CSS2 specification from W3C mentioned :hover in a working draft dated January 1998. It was specifically mentioned in terms of anchor links, but the language suggests it could have possibly been applied to other elements. For most purposes it would seem this pseudo selector would be the beginning of an easy alternative to MM_swapImage(), since background-image was in the same draft. Although browser support was an issue as it took years before enough browsers properly supported CSS2 to make it a viable option for many web designers. There was finally a W3C recommendation of CSS2.1, this could be considered to be the basis of “modern” CSS as we know it, which was published in June 2011.

    In the middle of all this, jQuery came along in 2006. Thankfully, jQuery went a long way in simplifying JavaScript among the different browsers. One thing of interest for our story, the first version of jQuery offered the animate() method. With this method, you could animate CSS properties on any element at any time; not just on hover. By its sheer popularity, this method exposed the need for a more robust CSS solution baked into the browser — a solution that wouldn’t require a JavaScript library that was not always very performant due to browser limitations.

    The :hover pseudo-class only offered a hard swap from one state to another with no support for a smooth transition. Nor could it animate changes in elements outside of something as basic as hovering over an element. jQuery’s animate() method offered those features. It paved the way and there was no going back. As things go in the dynamic world of web development, a working draft for solving this was well underway before the recommendation of CSS2.1 was published. The first working draft for CSS Transitions Module Level 3 was first published by the W3C in March 2009. The first working draft for CSS Animations Module Level 3 was published at roughly the same time. Both of these CSS modules are still in a working draft status as of October 2018, but of course, we are already making heavy use of them

    So, what first started as a JavaScript function provided by a third-party, just for a simple hover state, has led to transitions and animations in CSS that allow for elaborate and complex animations — complexity that many developers wouldn’t necessarily wish to consider as they need to move quickly on new projects. We have gone full circle; today many third-party CSS animation libraries have been created to offset this complexity.

    Three different types of third-party animation libraries

    We are in this new world capable of powerful, exciting, and complex animations in our web pages and apps. Several different ideas have come to the forefront on how to approach these new tasks. It’s not that one approach is better than any other; indeed, there is a good bit of overlap in each. The difference is more about how we implement and write code for them. Some are full-blown JavaScript-only libraries while others are CSS-only collections.

    JavaScript libraries

    Libraries that operate solely through JavaScript often offer capabilities beyond what common CSS animations provide. Usually, there is overlap as the libraries may actually use CSS features as part of their engine, but that would be abstracted away in favor of the API. Examples of such libraries are Greensock and Anime.js. You can see the extent of what they offer by looking at the demos they provide (Greensock has a nice collection over on CodePen). They’re mostly intended for highly complex animations, but can be useful for more basic animations as well.

    JavaScript and CSS libraries

    There are third-party libraries that primarily include CSS classes but provide some JavaScript for easy use of the classes in your projects. One library, Micron.js, provides both a JavaScript API and data attributes that can be used on elements. This type of library allows for easy use of pre-built animations that you can just select from. Another library, Motion UI, is intended to be used with a JavaScript framework. Although, it also works on a similar notion of a mixture of a JavaScript API, pre-built classes, and data attributes. These types of libraries provide pre-built animations and an easy way to wire them up.

    CSS libraries

    The third kind of library is CSS-only. Typically, this is just a CSS file that you load via a link tag in your HTML. You then apply and remove specific CSS classes to make use of the provided animations. Two examples of this type of library are Animate.css and Animista. That said, there are even major differences between these two particular libraries. Animate.css is a total CSS package while Animista provides a slick interface to choose the animations you want with provided code. These libraries are often easy to implement but you have to write code to make use of them. These are the type of libraries this article will focus on.

    Three different types of CSS animations

    Yes, there’s a pattern; the rule of threes is everywhere, after all.

    In most cases, there are three types of animations to consider when making use of third-party libraries. Each type suits a different purpose and has different ways to make use of them.

    Hover animations

    An illustration of a black button on the left and an orange button with a mouse cursor over it as a hover effect.

    These animations are intended to be involved in some sort of hover state. They’re often used with buttons, but another possibility is using them to highlight sections the cursor happens to be on. They can also be used for focus states.

    Attention animations

    An illustration of a webpage with gray boxes and a red alert at the top of the screen to show an instance of an element that seeks attention.

    These animations are intended to be used on elements that are normally outside of the visual center of the person viewing the page. An animation is applied to a section of the display that needs attention. Such animations could be subtle in nature for things that need eventual attention but not dire in nature. They could also be highly distracting for when immediate attention is required.

    Transition animations

    An illustration of concentric circles stacked vertically going from gray to black in ascending order.

    These animations are often intended to have an element replace another in the view, but can be used for one element as well. These will usually include an animation for “leaving” the view and mirror animation for “entering” the view. Think of fading out and fading in. This is commonly needed in single page apps as one section of data would transition to another set of data, for example.

    So, let’s go over examples of each of these type of animations and how one might use them.

    Let’s hover it up!

    Some libraries may already be set for hover effects, while some have hover states as their main purpose. One such library is Hover.css, which is a drop-in solution that provides a nice range of hover effects applied via class names. Sometimes, though, we want to make use of an animation in a library that doesn’t directly support the :hover pseudo-class because that might conflict with global styles.

    For this example, I shall use the tada animation that Animate.css provides. It’s intended more as an attention seeker, but it will nicely suffice for this example. If you were to look through the CSS of the library, you’ll find that there’s no :hover pseudo-class to be found. So, we’ll have to make it work in that manner on our own.

    The tada class by itself is simply this:

    .tada {
      animation-name: tada;
    }

    A low-lift approach to make this react to a hover state is to make our own local copy of the class, but extend it just a bit. Normally, Animate.css is a drop-in solution, so we won’t necessarily have the option to edit the original CSS file; although you could have your own local copy of the file if you wish. Therefore, we only create the code we require to be different and let the library handle the rest.

    .tada-hover:hover {
      animation-name: tada;
    }

    We probably shouldn’t override the original class name in case we actually want to use it elsewhere. So, instead, we make a variation that we can place the :hover pseudo-class on the selector. Now we just use the library’s required animated class along with our custom tada-hover class to an element and it will play that animation on hover.

    If you wouldn’t want to create a custom class in this way, but prefer a JavaScript solution instead, there’s a relatively easy way to handle that. Oddly enough, it’s a similar method to the MM_imageSwap() method from Dreamweaver we discussed earlier.

    // Let's select elements with ID #js_example
    var js_example = document.querySelector('#js_example');
    
    // When elements with ID #js_example are hovered...
    js_example.addEventListener('mouseover', function () {
      // ...let's add two classes to the element: animated and tada...
      this.classList.add('animated', 'tada');
    });
    // ...then remove those classes when the mouse is not on the element.
    js_example.addEventListener('mouseout', function () {
      this.classList.remove('animated', 'tada');
    });

    There are actually multiple ways to handle this, depending on the context. Here, we create some event listeners to wait for the mouse-over and mouse-out events. These listeners then apply and remove the library’s animated and tada classes as needed. As you can see, extending a third-party library just a bit to suit our needs can be accomplished in relatively easy fashion.

    Can I please have your attention?

    Another type of animation that third-party libraries can assist with are attention seekers. These animations are useful for when you wish to draw attention to an element or section of the page. Some examples of this could be notifications or unfilled required form inputs. These animations can be subtle or direct. Subtle for when something needs eventual attention but does not need to be resolved immediately. Direct for when something needs resolution now.

    Some libraries have such animations as part of the whole package, while some are built specifically for this purpose. Both Animate.css and Animista have attention seeking animations, but they are not the main purpose for those libraries. An example of a library built for this purpose would be CSShake. Which library to use depends on the needs of the project and how much time you wish to invest in implementing them. For example, CSShake is ready to go with little trouble on your part — simply apply classes as needed. Although, if you were already using a library such as Animate.css, then you’re likely not going to want to introduce a second library (for performance, reliance on dependencies, and such).

    So, a library such as Animate.css can be used but needs a little more setup. The library’s GitHub page has examples of how to go about doing this. Depending on the needs of a project, implementing these animations as attention seekers is rather straightforward.

    For a subtle type of animation, we could have one that just repeats a set number of times and stops. This usually involves adding the library’s classes, applying an animation iteration property to CSS, and waiting for the animation end event to clear the library’s classes.

    Here’s a simple example that follows the same pattern we looked at earlier for hover states:

    var pulse = document.querySelector('#pulse');
    
    function playPulse () {
      pulse.classList.add('animated', 'pulse');
    }
    
    pulse.addEventListener('animationend', function () {
      pulse.classList.remove('animated', 'pulse');
    });
    
    playPulse();

    The library classes are applied when the playPulse function is called. There’s an event listener for the animationend event that will remove the library’s classes. Normally, this would only play once, but you might want to repeat multiple times before stopping. Animate.css doesn’t provide a class for this, but it’s easy enough to apply a CSS property for our element to handle this.

    #pulse {
      animation-iteration-count: 3; /* Stop after three times */
    }

    This way, the animation will play three times before stopping. If we needed to stop the animation sooner, we can manually remove the library classes outside of the animationend function. The library’s documentation actually provides an example of a reusable function for applying the classes that removes them after the animation; very similar to the above code. It would even be rather easy to extend it to apply the iteration count to the element.

    For a more direct approach, let’s say an infinite animation that won’t stop until after some sort of user interaction takes place. Let’s pretend that clicking the element is what starts the animation and clicking again stops it. Keep in mind that however you wish to start and stop the animation is up to you.

    var bounce = document.querySelector('#bounce');
    
    bounce.addEventListener('click', function () {
      if (!bounce.classList.contains('animated')) {
        bounce.classList.add('animated', 'bounce', 'infinite');
      } else {
        bounce.classList.remove('animated', 'bounce', 'infinite');
      }
    });

    Simple enough. Clicking the element tests if the library’s “animated” class has been applied. If it has not, we apply the library classes so it starts the animation. If it has the classes, we remove them to stop the animation. Notice that infinite class on the end of the classList. Thankfully, Animate.css provides this for us out-of-the-box. If your library of choice doesn’t offer such a class, then this is what you need in your CSS:

    #bounce {
      animation-iteration-count: infinite;
    }

    Here’s a demo showing how this code behaves:

    See the Pen
    3rd Party Animation Libraries: Attention Seekers
    by Travis Almand (@talmand)
    on CodePen.

    Moving stuff out of the way

    When researching for this article, I found that transitions (not to be confused with CSS transitions) are easily the most common type of animations in the third-party libraries. These are simple animations that are built to allow an element to enter or leave the page. A very common pattern seen in modern Single Page Applications is to have one element leave the page while another replaces it by entering the page. Think of the first element fading out and the second fading in. This could be replacing old data with new data, moving to the next panel in a sequence, or moving from one page to another with a router. Both Sarah Drasner and Georgy Marchuk have excellent examples of these types of transitions.

    For the most part, animation libraries will not provide the means to remove and add elements during the transition animations. The libraries that provide additional JavaScript may actually have this functionality, but since most do not, we’ll discuss how to handle this functionality now.

    Inserting a single element

    For this example, we’ll again use Animate.css as our library. In this case, I’ll be using the fadeInDown animation.

    Now, please keep in mind there are many ways to handle inserting an element into the DOM and I don’t wish to cover them here. I’ll just be showing how to leverage an animation to make the insertion nicer and more natural than the element simply popping into view. For Animate.css (and likely many other libraries), inserting an element with the animation is quite easy.

    let insertElement = document.createElement('div');
    insertElement.innerText = 'this div is inserted';
    insertElement.classList.add('animated', 'fadeInDown');
    
    insertElement.addEventListener('animationend', function () {
      this.classList.remove('animated', 'fadeInDown');
    });
    
    document.body.append(insertElement);

    However you decide to create the element doesn’t much matter; you just need to be sure the needed classes are already applied before inserting the element. Then it’ll nicely animate into place. I also included an event listener for the animationend event that removes the classes. As usual, there are several ways to go about doing this and this is likely the most direct way to handle it. The reason for removing the classes is to make it easier to reverse the process if we wish. We wouldn’t want the entering animation competing with a leaving animation.

    Removing a single element

    Removing a single element is sort of similar to inserting an element. The element already exists, so we just apply the desired animation classes. Then at the animationend event we remove the element from the DOM. In this example, we’ll use the fadeOutDown animation from Animate.css because it works nicely with the fadeInDown animation.

    let removeElement = document.querySelector('#removeElement');
    
    removeElement.addEventListener('animationend', function () {
      this.remove();
    });
    
    removeElement.classList.add('animated', 'fadeOutDown');

    As you can see, we target the element, add the classes, and remove the element at the end of the animation.

    An issue with all this is that with inserting and removing elements this way will cause the other elements on the page to jump around to adjust. You’ll have to account for that in some way, most likely with CSS and the layout of the page to keep a constant space for the elements.

    Get out of my way, I’m coming through!

    Now we are going to swap two elements, one leaving while another enters. There are several ways of handling this, but I’ll provide an example that’s essentially combining the previous two examples.

    See the Pen
    3rd Party Animation Libraries: Transitioning Two Elements
    by Travis Almand (@talmand)
    on CodePen.

    I’ll go over the JavaScript in parts to explain how it works. First, we cache a reference to a button and the container for the two elements. Then, we create two boxes that’ll be swapped inside the container.

    let button = document.querySelector('button');
    let container = document.querySelector('.container');
    let box1 = document.createElement('div');
    let box2 = document.createElement('div');

    I have a generic function for removing the animation classes for each animationEnd event.

    let removeClasses = function () {
      box1.classList.remove('animated', 'fadeOutRight', 'fadeInLeft');
      box2.classList.remove('animated', 'fadeOutRight', 'fadeInLeft');
    }

    The next function is the bulk of the swapping functionality. First, we determine the current box being displayed. Based on that, we can deduce the leaving and entering elements. The leaving element gets the event listener that called the switchElements function removed first so we don’t find ourselves in an animation loop. Then, we remove the leaving element from the container since its animation has finished. Next, we add the animation classes to the entering element and append it to the container so it’ll animate into place.

    let switchElements = function () {
      let currentElement = document.querySelector('.container .box');
      let leaveElement = currentElement.classList.contains('box1') ? box1 : box2;
      let enterElement = leaveElement === box1 ? box2 : box1;
      
      leaveElement.removeEventListener('animationend', switchElements);
      leaveElement.remove();
      enterElement.classList.add('animated', 'fadeInLeft');
      container.append(enterElement);
    }

    We need to do some general setup for the two boxes. Plus, we append the first box to the container.

    box1.classList.add('box', 'box1');
    box1.addEventListener('animationend', removeClasses);
    box2.classList.add('box', 'box2');
    box2.addEventListener('animationend', removeClasses);
    
    container.appendChild(box1);

    Finally, we have a click event listener for our button that does the toggling. How these sequences of events are started is technically up to you. For this example, I decided on a simple button click. I figure out which box is currently being displayed, which will be leaving, to apply the appropriate classes to make it animate out. Then I apply an event listener for the animationEnd event that calls the switchElements function shown above that handles the actual swap.

    button.addEventListener('click', function () {
      let currentElement = document.querySelector('.container .box');
      
      if (currentElement.classList.contains('box1')) {
        box1.classList.add('animated', 'fadeOutRight');
        box1.addEventListener('animationend', switchElements);
      } else {
        box2.classList.add('animated', 'fadeOutRight');
        box2.addEventListener('animationend', switchElements);
      }
    }

    One obvious issue with this example is that it is extremely hard-coded for this one situation. Although, it can be easily extended and adjusted for different situations. So, the example is useful in terms of understanding one way of handling such a task. Thankfully, some animation libraries, like MotionUI, provide some JavaScript to help with element transitions. Another thing to consider is that some JavaScript frameworks, such as VueJS have functionality to assist with animating element transitions.

    I have also created another example that provides a more flexible system. It consists of a container that stores references to leave and enter animations with data attributes. The container holds two elements that will switch places on command. The way this example is built is that the animations are easily changed in the data attributes via JavaScript. I also have two containers in the demo; one using Animate.css and the other using Animista for animations. It’s a large example, so I won’t examine code here; but it is heavily commented, so take a look if it is of interest.

    See the Pen
    3rd Party Animation Libraries: Custom Transition Example
    by Travis Almand (@talmand)
    on CodePen.

    Take a moment to consider…

    Does everyone actually want to see all these animations? 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 as a follow-up with considerations for best practices. Definitely read these.

    So, does your animation library of choice support the prefers-reduced-motion? If the documentation doesn’t say that it does, then you may have to assume it does not. Although, it is rather easy to check the code of the library to see if there is anything for the media query. For instance, Animate.css has it in the _base.scss partial file.

    @media (print), (prefers-reduced-motion) {
      .animated {
        animation: unset !important;
        transition: none !important;
      }
    }

    This bit of code also provides an excellent example of how to do this for yourself if the library doesn’t support it. If the library has a common class it uses — like Animate.css uses “animated” — then you can just target that class. If it does not support such a class then you’ll have to target the actual animation class or create your own custom class for that purpose.

    .scale-up-center {
      animation: scale-up-center 0.4s cubic-bezier(0.390, 0.575, 0.565, 1.000) both;
    }
    
    @keyframes scale-up-center {
      0% { transform: scale(0.5); }
      100% { transform: scale(1); }
    }
    
    @media (print), (prefers-reduced-motion) {
      .scale-up-center {
        animation: unset !important;
        transition: none !important;
      }
    }

    As you can see, I just used the example as provided by Animate.css and targeted the animation class from Animista. Keep in mind that you’ll have to repeat this for every animation class you choose to use from the library. Although, in Eric’s follow-up piece, he suggests treating all animations as progressive enhancement and that could be one way to both reduce code and make a more accessible user experience.

    Let a framework do the heavy lifting for you

    In many ways, the various frameworks such as React and Vue can make using third-party CSS animation easier than with vanilla JavaScript, mainly because you don’t have to wire up the class swaps or animationend events manually. You can leverage the functionality the frameworks already provide. The beauty of using frameworks is that they also provide several different ways of handling these animations depending on the needs of the project. The examples below is only a small example of options.

    Hover effects

    For hover effects, I would suggest setting them up with CSS (as I suggested above) as the better way to go. If you really need a JavaScript solution in a framework, such as Vue, it would be something like this:

    <button @mouseover="over($event, 'tada')" @mouseleave="leave($event, 'tada')">
      tada
    </button>
    methods: {
      over: function(e, type) {
        e.target.classList.add('animated', type);
      },
      leave: function (e, type) {
        e.target.classList.remove('animated', type);
      }
    }

    Not really that much different than the vanilla JavaScript solution above. Also, as before, there are many ways of handling this.

    Attention seekers

    Setting up the attention seekers is actually even easier. In this case, we’re just applying the classes we require, again, using Vue as an example:

    <div :class="{animated: isPulse, pulse: isPulse}">pulse</div>
    
    <div :class="[{animated: isBounce, bounce: isBounce}, 'infinite']">bounce</div>

    In the pulse example, whenever the boolean isPulse is true, the two classes are applied. In the bounce example, whenever the boolean isBounce is true the animated and bounce classes are applied. The infinite class is applied regardless so we can have our never-ending bounce until the isBounce boolean goes back to false.

    Transitions

    Thankfully, Vue’s transition component provides an easy way to use third-party animation classes with custom transition classes. Other libraries, such as React, could offer similar features or add-ons. To make use of the animation classes in Vue, we just implement them in the transition component.

    <transition
      enter-active-class="animated fadeInDown"
      leave-active-class="animated fadeOutDown"
      mode="out-in"
    >
      <div v-if="toggle" key="if">if example</div>
      <div v-else key="else">else example</div>
    </transition>

    Using Animate.css, we merely apply the necessary classes. For enter-active, we apply the required animated class along with fadeInDown. For leave-active, we apply the required animated class along with fadeOutDown. During the transition sequence, these classes are inserted at the appropriate times. Vue handles the inserting and removing of the classes for us.

    For a more complex example of using third-party animation libraries in a JavaScript framework, explore this project:

    See the Pen
    KLKdJy
    by Travis Almand (@talmand)
    on CodePen.

    Join the party!

    This is a small taste of the possibilities that await your project as there are many, many third-party CSS animation libraries out there to explore. Some are thorough, eccentric, specific, obnoxious, or just straight-forward. There are libraries for complex JavaScript animations such as Greensock or Anime.js. There are even libraries that will target the characters in an element.

    Hopefully all this will inspire you to play with these libraries on the way to creating your own CSS animations.

    The post Integrating Third-Party Animation Libraries to a Project appeared first on CSS-Tricks.

    Categories: Designing, Others Tags:

    Google Fonts is Adding font-display

    May 14th, 2019 No comments

    Google announced at I/O that their font service will now support the font-display property which resolves a number of web performance issues. If you’re hearing cries of joy, that’s probably Chris as he punches the air in celebration. He’s wanted this feature for some time and suggests that all @font-face blocks ought to consider using the property.

    Zach Leatherman has the lowdown:

    This is big news—it means developers now have more control over Google Fonts web font loading behavior. We can enforce instant rendering of fallback text (when using font-display: swap) rather than relying on the browser default behavior of invisible text for up to 3 seconds while the web font request is in-flight.

    It’s also a bit of trailblazing, too. To my knowledge, this is the first web font host that’s shipping support for this very important font-display feature.

    Yes, a big deal indeed! You may recall that font-display instructs the browser how (and kinda when) to load fonts. That makes it a possible weapon to fight fight FOUT and FOIT issues. Chris has mentioned how he likes the optional value for that exact reason.

    @font-face {
      font-family: "Open Sans Regular";
      src: url("...");
      font-display: optional;
    }

    Oh and this is a good time to remind everyone of Monica Dinculescu’s font-display demo where she explores all the various font-display values and how they work in practice. It’s super nifty and worth checking out.

    Direct Link to ArticlePermalink

    The post Google Fonts is Adding font-display appeared first on CSS-Tricks.

    Categories: Designing, Others Tags: