Archive

Archive for April, 2020

Advice for Writing a Technical Resume

April 27th, 2020 No comments

Marco Rogers asked a very good question on Twitter:

I talk to a lot of people new to tech from non-traditional backgrounds, e.g. bootcamps or self-taught. I’m looking for good information for those people on how to build out a strong resume when they don’t have work experience yet. Advice is fine, links to resources is better.

— Marco Rogers (@polotek) April 10, 2020

I’ve been on both sides of the interview table for many years now, both searching for jobs and as a hiring manager. My resume skills and most salient advice for writing one is likely from my experiences looking though thousands of applications.

When it comes to writing a resume, It’s helpful to think about the human aspect first and foremost. Imagining a hiring manager’s perspective will give you an edge because it helps speak to them directly. Remember, a coveted position or reputable company commonly sifts through anywhere between tens and thousands of applications. It takes a staff that is materially impacted in the time and energy it takes to review every candidate and evaluate those who make it in to the interview stage. Even attention to minor details will help your odds of standing out.

Here are my general suggestions to make the best possible resume.

Formatting is important

Spelling, grammar and formatting are all crucial to a well-written resume. Typos, errors, and poor use of things like bold and italic styles (especially when used together) are clear red flags, so pay extra attention to what you write and how it is written. These types of mistakes give the impressions that you either lack attention to detail or are unwilling to go the extra step. As trivial as this might seem, use your spell check and get a second set of eyes on your resume before submitting it.

A few formatting tips to keep in mind:

  • Use headings to separate sections
  • Use lists to help summarize highlights and things scannable
  • Use a good font and font size that makes the content legible
  • Use line spacing that lets content breath rather than packing it close together
  • Avoid using all caps, or combining bold, italic, and underlines on the same content.

I don’t have a strong opinion on charts that show off your skills or lists of hobbies. But I will say that I’ve noticed them more frequently on the applications of junior developers, so you might unintentionally communicate you have less experience by including it.

If you don’t have a lot of work history, it’s totally OK to throw in open source projects!

Or side projects! Or working on your own site! A few folks mentioned the same thing in the Twitter thread and it’s solid advice. A good hiring manager should know that senior-level candidates don’t grow on trees — they just want to see some work that shows you have promise.

This is problematic advice in some ways, as not everyone has time on the side to devote to projects. I wouldn’t so far as to say including those things is a hard requirement for a good resume. But if you’re otherwise lacking relevant work experience, including personal projects can show the kind of work you’re capable of doing as well as the kind of work that excites you. I’ve taken chances on folks with slim-to-no work experience but with a solid combination of a portfolio site, GitHub contributions, or even a few CodePen demos that show potential.

Call out your contributions to your work experience

Each time you list a work example, answer this: what did you accomplish? This is a good way to provide valuable information without or any unnecessary fluff. Everyone is going to tout their work experience. Adding the outcomes of your work will make you stand out.

Here’s an example that would catch my attention:

Due to my team’s work refactoring the product page, we were able to meet the demands of our customers, which resulted in a 25% growth in sales. We also took the opportunity to upgrade the codebase from React.createClass to React Hooks for all of our components, ensuring a more flexible and maintainable system.

This tells me you can work on a team to deliver goals. It also tells me that you understand technical debt and how to solve it. That’s the sort of person I want to hire.

If so far your experience is limited to a code bootcamp, it’s great to talk through that.

Every job applicant is coming from a different background and from varying degrees of experience. It’s safe to assume you are not the most experienced person in the pool.

And that’s OK!

For example, let’s say your development experience is limited to online or in-person coding bootcamps rather than commercial projects. What did you learn there? What were you excited by? What was your final project? Is there a link to that work? When I’m hiring someone who’s coming in early in their career, I’m mostly looking for curiosity and enthusiasm. I’m probably not alone there.

Don’t be too long… or too short

We mentioned earlier that hiring is a time-consuming job. It’s good to keep this in mind as you’re writing by making your resume as brief as possible — ideally on a single standard page. And, yes, two pages is OK if you really need it.

Keeping everything short is a balancing act when you’re also attempting to include as much useful information as possible. Treat that constraint as a challenge to focus on the most important details. It’s a good problem if you have more to say than what fits!

At best, padding a resume into multiple pages conveys you’re unable to communicate in a succinct manner. At worst, it shows a lack of respect for a hiring manager’s time.

Make sure there’s a way to reach you

I cannot tell you how many resumes that lack the following essentials: name, email, and phone number. Seriously, it happens even on resumes that are otherwise very impressive.

Your name and contact information are hard requirements. I don’t want to search around for your email if you’re applying. To be honest, I probably won’t search at all because I’m busy and there are many other candidates to choose from.

Preparation is your friend

Make sure your accompanying cover letter (yes, you should include one) communicates you’ve done at least a little research on the company, conveys you understand what they need in a candidate, and how you fit into that need.

I will personally adjust my the descriptions in my own resume so there is a direct connection between my skills and the position.

Your work and education details should be reverse-chronological

Your most recent work is more important than your oldest work. It’s a better reflection of what you’re capable of doing today and how fresh your skills are in a particular area. The same goes for your education: lead with your most recent experience.

The person reviewing your resume can decide to continue reading further if they’re compelled by the most recent information.

Wrapping up

If you want to stand out in the crowd, make sure your resume is one that represents you well. Ask someone to help you proof and use spellcheck, and make sure you’ve put your best foot forward.

And don’t be discouraged by rejections or unreturned messages. It’s less likely to be about you personally and more likely due to the number of people applying. So keep trying!

The post Advice for Writing a Technical Resume appeared first on CSS-Tricks.

Categories: Designing, Others Tags:

The Latest Research for Web Designers, April 2020

April 27th, 2020 No comments

In today’s roundup of the latest research for web designers, we’re going to look at a variety of topics, from 2020 holiday shopping predictions to missed opportunities in SEO.

Retail Experts Predict Huge Uptick in E-commerce Holiday Sales

Shelley E. Kohan wrote a piece for Forbes entitled, “Coronavirus Fears May Drive U.S. E-Commerce Sales Beyond 2020 Projections—And Change How People Shop In The Future”.

While all we have at this point are guesses about when the coronavirus crisis will end and what will happen to the global economy as a result, Kohan has a really interesting data-backed theory. It goes like this:

During the holiday season, there’s a noticeable increase in e-commerce sales. Because of the concentration of buying activity throughout the season, consumers become accustomed to this way of shopping, which is why e-commerce sales activity often remains high even as we move into non-holiday months.

Principal analyst of eMarketer Andrew Lipsman explains:

During the holiday, a time with more concentrated buying activity, consumers spend more online creating a step-change, meaning the consumer may not return to past behavior.

Because of the quarantine and self-isolation orders around the globe right now, consumers are buying far more online than they have before. And the longer they have to rely on this means of shopping, the more comfortable they’re going to become with it.

So, while predictions of holiday e-commerce sales might have been modest for 2020 prior to the coronavirus, that could easily change.

What Can Web Designers Do About This?

If Kohan’s and Lipsman’s theories are correct, e-commerce shopping is going to soar this fall/winter. So, it would be a good idea to start working with your clients now who plan on capitalizing on the holiday shopping season.

It wouldn’t be a bad idea either to start helping clients prepare for the end of the crisis. For businesses that have slowed down or stopped altogether, they might be becoming complacent, just waiting for demand to return. Instead, they should be working on a plan to hit the ground running the second things start to pick up — and you should be right there with them to ensure their site is ready for it. That could mean preparing their web hosting for a surge in traffic, redesigning the homepage for summer sales, or helping them digitize more of their business now that consumers have become accustomed to doing stuff online.

Experian Survey Reveals Data Breach Fears

A recent Experian survey shed some light on the state of cybersecurity, why businesses fear data breaches, and what they’re doing about it.

In 2019, data breaches were on the rise with 63% of organizations reporting the loss or theft of a thousand records or more.

And as security breaches become more prevalent, companies are losing faith in their ability to fight off an attack. Of those surveyed, only 23% believe their business is protected from email phishing attacks and 20% believe they’re protected from ransomware.

As for what they’re doing to protect their organizations, a lot of the focus is on securing their physical infrastructure:

  • 73% audit their physical security measures
  • 69% do background checks on employees and vendors
  • 57% do third-party cybersecurity assessments
  • 49% have cybersecurity insurance

What’s surprising is a lack of concern or attention paid to their websites and data captured there (at least in terms of this survey).

What Can Web Designers Do About This?

If you know that security is a primary concern for business clients, make it part of the early conversations you have with prospects. Lay out the facts about digital security. Then, make sure your proposal includes a plan for fortifying their website from security breaches.

Even if their focus is on the physical protection of company data, they’ll appreciate you bringing the risks of a digital breach to their attention. And if you’re looking for ways to stabilize your income, this would nicely open the doors to a new opportunity selling website support and maintenance.

HubSpot Research Reveals a Gap in Technical SEO

A recent survey from HubSpot research reveals how many companies are using SEO and what kinds of technical SEO, specifically, they’re using.

According to the report, 63.57% of organizations actively invest time in optimizing their web presences for search.

While it’s good to know that many businesses are taking SEO seriously, it’s unnerving to see how few of them have made technical SEO a priority.

According to the survey, companies employ the following technical SEO tactics:

  • 24% optimize for speed
  • 23.5% optimize for mobile
  • 23% localize their websites
  • 14% do keyword strategy
  • 11% create content clusters
  • 2% have a backlinking strategy

If search rankings are so important to companies, why aren’t they investing more time in these necessary optimization tactics? Is it a lack of education on the benefits of technical SEO or is it that their dedicated SEO doesn’t know how to implement them?

What Can Web Designers Do About This?

The first thing web designers need to focus on is the fact that less than two-thirds of companies are spending time on SEO. That alone poses an opportunity for designers to get in there and start educating prospects and clients on the benefits of SEO.

This will then enable you to introduce yourself as part of the solution. You might not be an SEO expert in terms of content, but you’re certainly an expert in terms of mobile responsiveness, performance, accessibility, and tagging.

If technical search optimization isn’t currently part of your web design checklist, it should be (at least for clients who understand and appreciate the value of technical SEO).

Wrap-Up

What’s so great about this research is that all of it points to greater opportunities for web designers. While the world might be feeling scared, isolated, and hopeless right now, there’s still work that needs to be done. And there’s a lot you as web designers can do to keep businesses afloat amidst all this uncertainty and ready to hit the ground running once we return to a normal pace of life again.

Featured image via Unsplash.

Source

Categories: Designing, Others Tags:

Getting Started With Nuxt

April 27th, 2020 No comments

Getting Started With Nuxt

Getting Started With Nuxt

Timi Omoyeni

2020-04-27T10:30:00+00:002020-04-27T12:05:08+00:00

Web developers build a lot of Single Page Applications using JavaScript frameworks (Angular, React, Vue). SPAs dynamically populate the contents of their pages on load which means by the time google crawls their site, the important content is yet to be injected into the site. Part of this problem can be solved by pre-rendering your application’s content. This is where server-side applications come in, and for Vuejs developers, we can build server-side applications using Nuxt.js.

We’re going to assume that you have not used it before, as such it will start from the ground-up — introducing you to Nuxt.js, its file structure and how routing works. While also touching how you can get it to work with Vuex.

At the end of this tutorial, you should be able to go on to build basic web applications in Nuxt.js, and if you have been wondering how to get started with Nuxt.js, this will do justice to that.

This article is targeted at those that are fairly familiar with Vue.js and it’s a concept, For those without knowledge of Vue.js, consider starting from the official Vuejs documentation and The Net Ninja’s Vuejs playlist.

What Is Nuxt.js?

According to their official page:

“Nuxt is a progressive framework based on Vue.js to create modern web applications. It is based on Vue.js official libraries (vue, vue-router and vuex) and powerful development tools (webpack, Babel and PostCSS). Nuxt’s goal is to make web development powerful and performant with great developer experience in mind.”

It allows you to create three types of applications, depending on the purpose it’s intended for:

  1. Static Generated pages (Pre-rendering)
    Static generated applications do not require API requests to fetch the contents of the pages, i.e. the contents are already included in the HTML file. An example of a static site is a portfolio website or a landing page for a product.

  2. Single Page Application
    Most JavaScript frameworks (React, Angular, Emberjs, Vue, etc) are single page application whose contents are dynamically populated with faster transitions. Most SPAs make use of the HTML5 history API or the location Hash for routing.

  3. Server Side Rendered Applications (SSR)
    Server-Side Rendering is a technique used to fetch and display client-side data on the server to send a fully rendered page to the client. This is a good approach to get good SEO for your application.

Creating Your First Nuxt.js Application

You can create a Nuxt.js application in two ways:

  1. Using the scaffolding tool create-nuxt-app.
  2. From scratch.

In case you just want to see the finished app that we would be building, here’s a link to the GitHub repo.

In this tutorial, we would be focused on using create-nuxt-app so let’s get started. If you have npx installed, open your terminal and run this command:

$ npx create-nuxt-app nuxt-tutorial-app

or

$ yarn create nuxt-app nuxt-tutorial-app

For the purpose of this tutorial, nuxt-tutorial-app is the name of the application but feel free to name yours differently.

This would be followed by a list of options that help in configuring your application with what you might need for development.

Here’s what my configuration looks like:

Nuxt conguration options. (Large preview)

For the purpose of this tutorial, we do not need axios, linting and Prettier configurations.

Once that is done, we’ll run the following command in our terminal:

$ cd nuxt-tutorial-app
$ npm run dev

Your app should now be running on http://localhost:3000 and this is what you should see:

Nuxt scaffolding default landing page. (Large preview)

At this point, your app is ready for development.

Understanding Nuxt Folder Structure

Scaffolding the application as we did creates different files and folders which we can start working with. For someone who hasn’t work with Nuxt before, this might throw you off balance. So we’ll be looking at the folders, getting to understand their importance.

  • Assets
    This folder is for un-compiled files such as images, font files, SASS, LESS or JavaScript files. Let us add create a styles folder and a main.css file and copy and paste the following in it.
a {
  text-decoration: none;
  color: inherit;
  cursor: pointer;
}
.header {
  width: 100%;
  max-width: 500px;
  margin-left: auto;
  margin-right: auto;
  height: 60px;
  top: 0;
  position: sticky;
  background-color: #fff;
  display: flex;
  justify-content: space-between;
  align-items: center;
}
.logo {
  width: 40%;
  max-width: 200px;
  height: 40px;
}
.logo .NuxtLogo {
  max-width: 30px;
  margin-left: 10px;
  max-height: 40px;
}
.nav {
  width: 60%;
  height: 40px;
  display: flex;
  justify-content: space-between;
  padding-right: 10px;
  max-width: 300px;
}
.nav__link {
  width: 80px;
  display: flex;
  align-items: center;
  border-radius: 4px;
  justify-content: center;
  height: 100%;
  border: 1px solid #00c58e;
  cursor: pointer;
}
.nav__link:active {
  background-color: #00c58e;
  border: 1px solid #00c58e;
  color: #fff;
  box-shadow: 5px 3px 5px 2px #3f41468c;
}
.home {
  padding-top: 30px;
}
.home__heading {
  text-align: center;
}
.directories {
  display: flex;
  box-sizing: border-box;
  padding: 10px;
  max-width: 1000px;
  margin: 0 auto;
  flex-wrap: wrap;
  justify-content: center;
}
@media (min-width: 768px) {
  .directories {
    justify-content: space-between;
  }
}
.directory__container {
  width: 100%;
  max-width: 220px;
  cursor: pointer;
  border-radius: 4px;
  border: 1px solid #00c58e;
  display: flex;
  height: 60px;
  margin: 10px 5px;
  margin-right: 0;
  justify-content: center;
  align-items: center;
}
.directory__name {
  text-align: center;
}
.directory {
  width: 100%;
  margin: 50px auto;
  max-width: 450px;
  border-radius: 4px;
  border: 1px solid #00c58e;
  box-sizing: border-box;
  padding: 10px 0;
}
.directory__info {
  padding-left: 10px;
  line-height: 22px;
  padding-right: 10px;
}

The styles above will be used across the application for what we’ll be building. As you can see we have styles for the navigation and other aspects which we’ll plug into the application as we progress.

  • Components
    This folder is one we’re familiar with from Vue.js, it contains your reusable components.

Now, let’s create our first component and name it navBar.vue, and add the following code to it. We want the navbar of the site to display the logo and link to the Home and About pages which we will create in future. This navbar will be visible across the application. It will also make use of some styles that we have added above.

<template>
  <header class="header">
    <div class="logo">
      <nuxt-link to="/">
        <Logo />
      </nuxt-link>
    </div>
    <nav class="nav">
      <div class="nav__link">
        <nuxt-link to="/">Home</nuxt-link>
      </div>
      <div class="nav__link">
        <nuxt-link to="/About">About</nuxt-link>
      </div>
    </nav>
  </header>
</template>
<script>
import Logo from "@/components/Logo";
export default {
  name: "nav-bar",
  components: {
    Logo
  }
};
</script>
<style>
</style>

The template section contains what will be visible to the user. We have a header element which contains our logo and nav links. For us to link to the pages, we make use of nuxt-link which provides navigation between component pages.

In the script section, we import the logo component using Nuxt alias @ and declared it in our component for use by adding it as a component. This makes it possible for us to render it in the template.

  • Layout
    Here, we’ll be storing our application layouts. This is particularly useful if your application’s design calls for two or more layouts, e.g. one for authenticated users and another for guests or admins. For the purpose of this tutorial, we’ll be sticking to the default layout.

Let us open our default.vue file and add our navBar component to the layout of our application.

<template>
  <div>
    <Nav />
    <nuxt />
  </div>
</template>
<script>
import Nav from "~/components/navBar.vue";
export default {
  components: {
    Nav
  }
};
</script>

In the template section, we’ve added our Nav component inside the layout container to always appear at the top after importing it into the file and declaring it in the script section.

The next thing after our Nav component is , which tells Nuxt where to render all its routes.

This Nav component is the one we created above. By adding it here, the Nav component will be used across the application.

  • Middleware
    This folder was created to house JavaScript files that are required to run before a page(s) is rendered. If you’ve ever used the Vuejs navigation guard, this folder was created for files like that.

  • Pages
    This is another folder that developers with Vuejs background would not be familiar with. It works in such a way that every *.vue file is created as a route in your application so it serves as both views and a router folder at the same time, we’ll talk more about this in the next section.

  • Plugins
    This is where you store files that you want to run before mounting the root Vue.js application. It is not a required folder so it can be deleted.

  • nuxt.config.js
    This file is used to configure your application, it is usually pre-populated based on the config when creating your app. An ideal nuxt.config.js file should look like this by default:

export default {
  mode: 'universal',
  /*
  ** Headers of the page
  */
  head: {
    title: process.env.npm_package_name || '',
    meta: [
      { charset: 'utf-8' },
      { name: 'viewport', content: 'width=device-width, initial-scale=1' },
      { hid: 'description', name: 'description', content: process.env.npm_package_description || '' }
    ],
    link: [
      { rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' }
    ]
  },
  /*
  ** Customize the progress-bar color
  */
  loading: { color: '#fff' },
  /*
  ** Global CSS
  */
  css: [
  ],
  /*
  ** Plugins to load before mounting the App
  */
  plugins: [
  ],
  /*
  ** Nuxt.js dev-modules
  */
  buildModules: [
  ],
  /*
  ** Nuxt.js modules
  */
  modules: [
  ],
  /*
  ** Build configuration
  */
  build: {
    /*
    ** You can extend webpack config here
    */
    extend (config, ctx) {
    }
  }
}

Each time a change is made to this file, your application will automatically restart to reflect the changes. Let’s go over what the properties used in the file mean.

  • Mode
    The type of application; either universal or spa. By selecting universal, you’re telling Nuxt that you want your app to be able to run on both the server-side and the client-side.
  • Head
    All the default meta tags properties and favicon link found inside the head tag in your app is found here. This is because Nuxt.js doesn’t have a default index.html file, unlike Vue.js.
  • loading
    All Nuxt applications come with a default loader component and the color can be customized here.
  • css
    You’re expected to enter the link to all your global CSS files so your application can take it into account when mounting the application. We’re going to add the link to our css file to this and restart our application.
 /*
   ** Global CSS
   */
  css: ["~/assets/styles/main.css"]
  • plugins
    This is where you connect all the plugins in your plugins folder to the application. It takes in an object with properties such as src that accepts the file path to the plugin and a mode that configures how your application treats such plugin; either as a server-side plugin or a client-side plugin. For example:
{ src: '~/plugins/universal-plugin.js' }, // for server and client plugins
{ src: '~/plugins/client-side.js', mode: 'client' }, // for client only plugins
{ src: '~/plugins/server-side.js', mode: 'server' }, // for server side only plugins

This is important to avoid error either on the server-side or client-side especially if your plugin requires something like localStorage that is not available on the server-side.

For more info about the nuxt.config.js file, check out the official doc.

Nuxt Pages And Routing System

The pages folder in your Nuxt application is used to configure your application’s routes, i.e. your route name is dependent on the name of each file in this folder, e.g. if you have an about.vue file inside your pages file, it means you now have an /about route in your app, but that’s not all. What happens if you want a dynamic route for your application? Or a nested route? How do you go about it? let’s find out.

Basic Routes

Basic routes can be classified as routes that do not require extra configuration for them to work. For example, a direct route /work or a /contact route. So if your pages folder looks like this:

pages/
--| me/
 -----| index.vue
 -----| about.vue
--| work.vue
--| contact.vue
--| index.vue

Nuxt would automatically generate a router config that looks like this:

router: {
  routes: [
    {
      name: 'index',
      path: '/',
      component: 'pages/index.vue'
    },
    {
      name: 'work',
      path: '/work',
      component: 'pages/work'
    },
    {
      name: 'contact',
      path: '/contact',
      component: 'pages/contact'
    },
    {
      name: 'me',
      path: '/me',
      component: 'pages/me/index.vue'
    },
    {
      name: 'me-about',
      path: '/me/about',
      component: 'pages/me/about.vue'
    }
  ]
}

These paths can then be used to access the components tied to them. You can see that the path does not contain pages. And Nuxt handles the components named index.vue as it should without an additional config for that.

Nested Routes

To create a nested route, create a folder called dashboard inside the pages folder. This folder should contain all the files you want to nest in it. For example, user.vue and settings.vue. Then at the root of pages folder, create a file called dashboard.vue.

pages/
 --| me/
 -----| index.vue
 -----| about.vue
 --| dashboard/
 -----| user.vue
 -----| settings.vue
 --| dashboard.vue
 --| work.vue
 --| contact.vue
 --| index.vue

This would automatically generate a router with routes that look like this:

router: {
  routes: [
    {
      name: 'index',
      path: '/',
      component: 'pages/index.vue'
    },
    {
      name: 'work',
      path: '/work',
      component: 'pages/work'
    },
    {
      name: 'contact',
      path: '/contact',
      component: 'pages/contact'
    },
    
    {
      name: 'me',
      path: '/me',
      component: 'pages/me/index.vue'
    },
    {
      name: 'me-about',
      path: '/me/about',
      component: 'pages/me/about.vue'
    },
    {
      name: 'dashboard',
      path: '/dashboard',
      component: 'pages/dashboard.vue',
      children: [
        {
          name: 'dashboard-user',
          path: '/dashboard/user',
          component: 'pages/dashboard/user.vue'
        },
        {
          name: 'dashboard-settings',
          path: '/dashboard/settings',
          component: 'pages/dashboard/settings.vue'
        }
      ]
    }
  ]
}

Notice that the route name always follows a regular pattern:

name of the folder + '-' + name of the file
 

With this, you can be sure that each route will have a unique name.

Dynamic Routes

Dynamic routes are routes that are defined by a variable, this variable can either be a name, number or an id gotten from client data on the app. This comes in handy when working with an API, where the id will likely be the id of the item coming from the database.

In Nuxt, dynamic routes are defined by appending an _ to a file name or folder name in the pages folder. For instance, if you want a dynamic route whose variable name is id, all you need is to name your file _id.vue and Nuxt automatically creates a dynamic route for you. For example:

pages/
--| me/
-----| index.vue
-----| about.vue
-----| _routeName
-------| index.vue
-------| info.vue
--| dashboard/
-----| user.vue
-----| settings.vue
--| dashboard.vue
--| work.vue
--| _id.vue
--| contact.vue
--| index.vue

This would automatically create a router file with the following routes,

   {
      name: 'work',
      path: '/work',
      component: 'pages/work'
    },
    {
      name: 'contact',
      path: '/contact',
      component: 'pages/contact'
    },
    {
      name: 'id',
      path: '/:id',
      component: 'pages/_id.vue'
    }
    {
      name: 'me',
      path: '/me',
      component: 'pages/me/index.vue'
    },
    {
      name: 'me-about',
      path: '/me/about',
      component: 'pages/me/about.vue'
    },
    {
      name: 'me-routeName',
      path: '/me/:routeName',
      component: 'pages/me/_routeName/index.vue'
    },
    {
      name: 'me-routeName-info',
      path: '/me/:routeName/info',
      component: 'pages/me/route.vue'
    },
    {
      name: 'dashboard',
      path: '/dashboard',
      component: 'pages/dashboard.vue',
      children: [
        {
          name: 'dashboard-user',
          path: '/dashboard/user',
          component: 'pages/dashboard/user.vue'
        },
        {
          name: 'dashboard-settings',
          path: '/dashboard/settings',
          component: 'pages/dashboard/settings.vue'
        }
      ]
    }
  ]
}

Although some of the Vue.js router tags work in Nuxt and can be used interchangeably, it is recommended that we use Nuxt router components. Here are some of the differences between the Nuxt Router tags and Vue.js Router tags.

VueJs NuxtJS
router-link nuxt-link
router-view (for nested routes) nuxt-child
router-view(default) nuxt

Difference between vue.js router and nuxt.js router

At this point, Here’s what your app should look like this, with the navigation shown at the top.

The Landing page. (Large preview)

Now that we understand how Nuxt pages and Routes work, let’s add our first page and route about.vue. This page would list some directories in the application with a link to a new page that shows more information about such directory.

Let us add the following code to it:

<template>
  <section class="home">
    <h1 class="home__heading">About Nuxtjs Directory Structure</h1>
    <div class="directories">
      <div class="directory__container" v-for="directory in directories" :key="directory.id">
        <p class="directory__name">
          <nuxt-link
            :to="{ name: 'id', params: { id: directory.id, dir: directory } }"
          >{{ directory.name }}</nuxt-link>
        </p>
      </div>
    </div>
  </section>
</template>
<script>
export default {
  name: "about-nuxt",
  data() {
    return {
      directories: [
        {
          id: 0,
          name: "The Assets Directory",
          info:
            "By default, Nuxt uses vue-loader, file-loader and url-loader webpack loaders for strong assets serving. You can also use the static directory for static assets. This folder is for un-compiled files such as images, font files, SASS, LESS or JavaScript files"
        },
        {
          id: 1,
          name: "The Components Directory",
          info:
            "The components directory contains your Vue.js Components. You can't use asyncData in these components."
        },
        {
          id: 2,
          name: "The Layouts Directory",
          info:
            "The layouts directory includes your application layouts. Layouts are used to change the look and feel of your page (for example by including a sidebar). Layouts are a great help when you want to change the look and feel of your Nuxt.js app. Whether you want to include a sidebar or having distinct layouts for mobile and desktop"
        },
        {
          id: 3,
          name: "The Middleware Directory",
          info:
            "The middleware directory contains your Application Middleware. Middleware lets you define custom functions that can be run before rendering either a page or a group of pages (layouts)."
        },
        {
          id: 4,
          name: "The Pages Directory",
          info:
            "The pages directory contains your Application Views and Routes. The framework reads all the .vue files inside this directory and creates the application router. Every Page component is a Vue component but Nuxt.js adds special attributes and functions to make the development of your universal application as easy as possible"
        },
        {
          id: 5,
          name: "The Plugins Directory",
          info:
            "The plugins directory contains your Javascript plugins that you want to run before instantiating the root Vue.js Application. This is the place to register components globally and to inject functions or constants. Nuxt.js allows you to define JavaScript plugins to be run before instantiating the root Vue.js Application. This is especially helpful when using your own libraries or external modules."
        },
        {
          id: 6,
          name: "The Static Directory",
          info:
            "The static directory is directly mapped to the server root (/static/robots.txt is accessible under http://localhost:3000/robots.txt) and contains files that likely won't be changed (e.g. the favicon). If you don't want to use Webpack assets from the assets directory, you can create and use the static directory (in your project root folder)."
        },
        {
          id: 7,
          name: "The Store Directory",
          info:
            "The store directory contains your Vuex Store files. The Vuex Store comes with Nuxt.js out of the box but is disabled by default. Creating an index.js file in this directory enables the store. Using a store to manage the state is important for every big application. That's why Nuxt.js implements Vuex in its core."
        }
      ]
    };
  }
};
</script>
<style>
</style>

Starting from the script section, we created an array which we store in the directories variable. Each array contains an object with id, name, and info. This is the data we’ll show to the user when this page is opened. We want to show it to the user such that the names are clickable.

We do that in the template section, using v-for to loop through the array. This makes it possible to get each item in the array, which we can access using directory. In the loop, we use nuxt-link to handle the linking of each time. Using nuxt-link, we pass the details (id, name and info) of each directory item via nuxt router. We do this because we want to be able to display this on the show page when the user clicks on an item.

If you navigate to the /about route using your browser, you should see something like this:

About page. (Large preview)

Now, let’s create a new file and name it _id.vue. This would automatically create a dynamic route that takes the id param from the link display a little information about any directory clicked on from the About page.

Let us add this to our file:

<template>
  <section class="directory">
    <h1 class="directory__name">{{ directory.name }}</h1>
    <p class="directory__info">{{ directory.info }}</p>
  </section>
</template>
<script>
export default {
  name: "directory-info",
  data() {
    return {
      directory: this.$route.params.dir
    };
  }
};
</script>
<style>
</style>

What we have done is to create a page that fetches data from the route param dir using the this.$route.params. This gets us the name and info of the clicked directory, which we then display to the user.

So if you click on any directory link (e.g. store directory), you should see this.

What the ID page looks like. (Large preview)

But there’s a problem, if you refresh this page, your directory info gets lost and you get an error. This would be fixed using our Vuex Store so let’s dive into it.

Using Vuex Store In Nuxt

Vuex can be accessed in Nuxt using two modes:

  1. Classic mode (deprecated).
  2. Modules mode.

Modules mode

Nuxt automatically creates a Store folder upon the creation of your app. In Modules mode, Nuxt would treat every file inside this folder as a module but index.js is required for Vuex store to be activated in your app. So let’s create an index.js file in our store folder and set it up for use. Let us add the following to our file.

index.js

export const state = () => ({
  
})

export const getters = {

}

export const mutations = {
  
}

export const actions = {
  
}

All we have done is to set up the store for our file with all we might need; the state for storing data, getters for performing extra manipulation to our state, mutations for modifying our state and actions for committing mutations.

Nuxt also allows users to separate each core concept into different files which means we can have store.js, getters.js, mutation.js and action.js and this is good as it makes for easy maintainability. Now, we fix the problem of directory disappearing on refresh, we’ll use the store, but first, we need to install and set up Vuex persist for our store.

Install Vuex persist from npm using either command below, depending on your preference.

$ npm install --save vuex-persist

or

$ yarn add vuex-persist

After installing, we’re going to create a vuex-persist.js file in our plugins folder and add the following:

import VuexPersistence from 'vuex-persist'

export default ({
  store
}) => {
  window.onNuxtReady(() => {
    new VuexPersistence({
      storage: window.localStorage
    }).plugin(store);
  });
}

Here, we import our plugin from node-modules and configure it to save your store in localStorage. This plugin allows you to choose other storage options such as sessionStorage too so feel free to explore their documentation for more info.

Remember to add it to your nuxt.config.js file.

/*
   ** Plugins to load before mounting the App
   */
  plugins: [{
    src: '~/plugins/vuex-persist',
    mode: 'client'
  }],

Here, we added the file path to our plugin and told Nuxt to only run this plugin on the client side of this application.

Now, we can set our store up to accept and store directory info. Update your store to handle directory info like this:

export const state = () => ({
  directory: ''
})
export const getters = {
}
export const mutations = {
  saveInfo(state, payload) {
    state.directory = payload.directory
  }
}
export const actions = {
}

What we’ve done is to add a directory state to our store and a mutation function saveInfo that modifies the value of the directory state we added to our store in anticipation of the data we’d be passing it soon.

Next, in your about.vue file, update it to look like this.

<template>
  <section class="home">
    <h1 class="home__heading">About Nuxtjs Directory Structure</h1>
    <div class="directories">
      <div
        class="directory__container"
        v-for="directory in directories"
        :key="directory.id"
        @click.prevent="storeDirectoryInfo(directory)"
      >
        <p class="directory__name">
          <nuxt-link
            :to="{ name: 'id', params: { id: directory.id, dir: directory } }"
          >{{ directory.name }}</nuxt-link>
        </p>
      </div>
    </div>
  </section>
</template>
<script>
export default {
  name: "about-nuxt",
  data() {
    return {
      directories: [
        //remains the same
      ]
    };
  },
  methods: {
    storeDirectoryInfo(dir) {
      this.$store.commit("saveInfo", {
        directory: dir
      });
    }
  }
};
</script>
<style>
</style>

Now, we’ve added a click event to every directory container that passes the directory info as an argument to the storeDirectoryInfo. In this function, we commit the directory object to our store.

Finally, we would go back to our _id.vue file and replace the directory variable with our data from the store like this:

<template>
  <section class="directory" v-if="directory">
    <h1 class="directory__name">{{ directory.name }}</h1>
    <p class="directory__info">{{ directory.info }}</p>
  </section>
</template>
<script>
import { mapState } from "vuex";
export default {
  name: "directory-info",
  computed: {
    ...mapState(["directory"])
  }
};
</script>
<style></style>

Here, we refactor our code to use directory object directly from our store by first importing mapState from Vuex.

import { mapState } from 'vuex';

Instead of first checking if this.$route.params.dir is undefined before accessing the data from our store, we decide to use our store by reading the data that’s in the store.

<script>
import { mapState } from "vuex";
export default {
  name: "directory-info",
  computed: {
    ...mapState(["directory"])
  }
};
</script>

Then we update our template to make sure it doesn’t render while directory is undefined.

<template>
  <section class="directory" v-if="directory">
    <h1 class="directory__name">{{ directory.name }}</h1>
    <p class="directory__info">{{ directory.info }}</p>
  </section>
</template>

On doing this, no matter how many times we refresh our app, our directory object is safe in our store and can be easily accessed using the …mapState(['stateVariable']) method.

Deploying To Heroku

Now that our nuxt-tutorial-app app is complete, what’s next? Deploying our shiny new app to production.

We’ll be deploying our Nuxt.js app to Heroku using Github for easy deployment so if you’ve not set up a repository for your app, now would be a time to do so. The next thing would be to open Heroku and create a new app, choose a name and connect it to GitHub and the repo created above. Next, go to your settings, you should see something like this.

Heroku App settings page. (Large preview)

Now, add the following config variables.

NPM_CONFIG_PRODUCTION=false
HOST=0.0.0.0
NODE_ENV=production

The next thing we have to do is to create a Procfile in the root folder of our app (same level as nuxt.config.js) and enter this command:

web: nuxt start

This will run the nuxt start command and tell Heroku to direct external HTTP traffic to it.

After adding the Procfile to your app, commit and push your changes to your repo. If you have automatic deploys enabled for your app, your app should be live and accessible from its URL. If you can see your app live, congratulations! ? you have successfully built and deployed your first Nuxt.js application.

Conclusion

Now that we know how to create a basic Nuxt application and deploy to Heroku, what’s next? Here are some resources that cover things like using Axios in Nuxt and implementing authentication in your app.

  1. Using the axios module.
  2. Implementing Authentication in Nuxt.
  3. Nuxt.js official documentation.
  4. nuxt-tutorial-app Github repo.
(ks, ra, yk, il)
Categories: Others Tags:

The Cost of Javascript Frameworks

April 26th, 2020 No comments

I expect this post from Tim Kadlec to be quoted in every performance conference talk for the next few years. There is a lot of data here, so please check it out for yourself, but the short story is that JavaScript-framework-powered sites are definitely heavier and more resource-intensive than non-JavaScript-framework-powered sites. Angular is the beefiest and React is hardest on the CPU. But as Tim says:

… it says very little about the performance of the core frameworks in play and much more about the approach to development these frameworks may encourage

Another big caveat is that there isn’t data here on-site usage after first-load, which is a huge aspect of “single-page app” approaches.

Still, while you can be performant with frameworks (although even that top 10% isn’t super encouraging), the frameworks aren’t doing much to help what has turned into a bad situation. It mimics exactly what we talked about recently with accessibility. It’s not the frameworks “fault” exactly, but they are also the best positioned to stop the bleeding.

Direct Link to ArticlePermalink

The post The Cost of Javascript Frameworks appeared first on CSS-Tricks.

Categories: Designing, Others Tags:

Popular Design News of the Week: April 20, 2020 – April 26, 2020

April 26th, 2020 No comments

Every week users submit a lot of interesting stuff on our sister site Webdesigner News, highlighting great content from around the web that can be of interest to web designers.

The best way to keep track of all the great stories and news being posted is simply to check out the Webdesigner News site, however, in case you missed some here’s a quick and useful compilation of the most popular designer news that we curated from the past week.

Note that this is only a very small selection of the links that were posted, so don’t miss out and subscribe to our newsletter and follow the site daily for all the news.

14 CSS Lists

This Website will Self-destruct

6 Excellent Ideas to Make Passive Income for Designers

How to Create a Compelling Landing Page

Making Things Better

65 UX Methods and When to Use Them

Animation in Design System E-Book

Pattern.css

The Decline of Usability

Affinity Designer Vs Illustrator: Pros & Cons Compared

Persuasive Design: How to Nudge Users in the Right Direction

Interfaces in Games

22 Things You Can do to Improve your Google Website Ranking even When Sales are Down

9 E-Commerce Website Design Tips and Best Practices in 2020

Bootstrap Vs. Material-UI

Tips to Nailing Big Typography Designs

How to Design your Thoughts for Better Creativity

5 Biggest UI/UX and Product Design Myths Debunked

18 Modern Fonts to Use in 2020

Designing for Conversions: 7 UX Best Practices for ECommerce in 2020

UX Design Portfolio Advice from Hiring Managers

7 Worthy Ideas to Make Good Use of Rejected Designs

Ways to Contribute While in Quarantine

Remote Work Report

Brainstorming from a Distance: How Distributed Teams Collaborate

Want more? No problem! Keep track of top design news from around the web with Webdesigner News.

Source

Categories: Designing, Others Tags:

@property

April 25th, 2020 No comments

The @property is totally new to me, but I see it’s headed to Chrome, so I suppose it’s good to know about!

There is a draft spec and an “intent to ship” document. The code from that document shows:

@property --my-property {
  syntax: "<color>";
  initial-value: green;
  inherits: false;
}

That it’s the CSS exact-equivalent to a CSS.registerProperty(), the JavaScript syntax for declaring CSS custom properties, also a new thing (under the Houdini umbrella, it seems).

It looks like you declare these not within a selector block, but outside (like a @media query), and once you have, you haven’t actually created a new custom property yet, you’ve just registered the fact that you probably will later. When you actually go to create/use the custom property, you create it within a selector block like you already do now.

The “commonly cited use-case” is pretty darn cool. Right now, this isn’t possible in CSS:

.el {
  background: linear-gradient(white, black);
  /* this transition won't work */
  transition: 1s;
}
.el:hover {
  background: linear-gradient(red, black);
}

You might think the white in that gradient will fade to red with that transition, but no, that’s not transition-able in that way. If we needed this in the past, we’d resort to trickery like fading in a pseudo-element with the new gradient colors or transitioning the background-position of a wider-than-the-element gradient to fake it.

Sounds like now we can…

@property --gradient-start {
  syntax: "<color>";
  initial-value: white;
  inherits: false;
}

.el {
  --gradient-start: white;
  background: linear-gradient(var(--gradient-start), black);
  transition: --gradient-starty 1s;
}

.el:hover {
  --gradient-start: red;
}

Presumably, that works now because we’ve told CSS that this custom property is a so it can be treated/animated like a color in away that wasn’t possible before.

Reminds me of how when we use the attr() function to pull like data-size="22px" off an element, we can’t actually use the 22px, it’s just a string. But that maybe-someday we’ll get attr(data-size px);

I have no idea when @property will actually be available, but looks like Chrome will ship first and there are positive signals from Safari and Firefox. ?

The post @property appeared first on CSS-Tricks.

Categories: Designing, Others Tags:

How to Make a CSS-Only Carousel

April 24th, 2020 No comments

We mentioned a way to make a CSS-only carousel in a recent issue of the newsletter and I thought that a more detailed write up would be interesting and capture some of my thoughts on making one.

So, here’s what we’re making today:

There’s no JavaScript here, whatsoever! No jQuery plugins. No trickiness. Just a couple of new-ish CSS properties that I’ve been experimenting with as well as some basic HTML.

OK to start, we need to focus on the markup. The design includes a left navigation made up of images and a large image gallery on the right that lets us scroll through each image individually. We’ll also need a wrapper to help us organize the layout:

<div class="wrapper">
  <nav class="lil-nav"></nav>
  <div class="gallery"></div>
</div>

Next, we can add images! For this little example, I checked out our list of sites with high quality images that you can use for free and went with Unsplash.

After saving images with the CodePen asset manager, I started adding the URLs to the nav element:

<nav class="lil-nav">
  <a href="#image-1">
    <img class="lil-nav__img" src="..." alt="Yosemite" />
  </a>
  <a href="#image-2">
    <img class="lil-nav__img" src="..." alt="Basketball hoop" />
  </a>
  <!-- more images go here --> 
</nav>

See that the href to each of these links is pointing to an ID? That’s because if we look at the demo again, we want to be able to click an image and then we want to it to hop to the larger version of that image in the gallery to the right.

So, now we can start to add these images to the large gallery, too…

<div class="gallery">
  <img class="gallery__img" id="image-1" src="..." alt="Yosemite" />
  <img class="gallery__img" id="image-2" src="..." alt="Basketball hoop" />
  <!-- more images go here --> 
</div>

Nifty. Next is the fun part: styling this bad boy. We can use a grid layout the parent .wrapper and set some smart defaults for the img element:

img {
  display: block;
  max-width: 100%;
}

.wrapper {
  display: grid;
  grid-template-columns: 1fr 5fr;
  grid-gap: 20px;
}
CodePen Embed Fallback

So far, we have our layout sorted and our links set up. Next, let’s any any overflow that might spill outside our wrapper and make sure that the nav and the gallery are scrollable:

.wrapper {
  display: grid;
  grid-template-columns: 1fr 5fr;
  grid-gap: 10px;
  overflow: hidden;
  height: 100vh; 
}

.gallery {
  overflow: scroll;
}

.lil-nav {
  overflow-y: scroll;
  overflow-x: hidden;
}
CodePen Embed Fallback

We can scroll through each image in the gallery now, but if this was a production website we’d probably want to make sure that folks can scroll passed this carousel a bit more easily. Trent Walton wrote about this very problem several years ago and I think it’s always worth keeping in mind.

Next up, let’s focus on the carousel snap of each image in the gallery. To do that we’ll need to use the scroll-snap-type and scroll-snap-align property like this:

.gallery {
  overflow: scroll;
  scroll-snap-type: x mandatory;
}

.gallery__img {
  scroll-snap-align: start;
  margin-bottom: 10px;
}

Now try scrolling through the gallery on the right-hand side again:

CodePen Embed Fallback

If you want to learn more about these properties I’d highly recommend this piece about practical CSS scroll snapping which digs into the nitty-gritty of these properties.

We have a pretty dang usable carousel! From here, all we have to do is tidy up the design because the gallery image isn’t the full height of the screen. To do that we can use object-fit and give each image a min-height with the vh unit, just like this:

.gallery__img {
  scroll-snap-align: start;
  margin-bottom: 10px;
  min-height: 100vh;
  object-fit: cover;
}

Now the big gallery images will always be the full size of the screen and will scale to take up the width and height. Let’s move on and tackle the style of the little navigation images:

.lil-nav {
  overflow-y: scroll;
  overflow-x: hidden;
}

.lil-nav a {
  height: 200px;
  display: flex;
  margin-bottom: 10px;
}

.lil-nav__img {
  object-fit: cover;
}
CodePen Embed Fallback

At first, I made this little nav act like a carousel too, but it felt really weird. I’m just keeping the default scroll behavior for now. In that demo above, though, try clicking an image. Notice how it jumps to that image in the carousel immediately? It would be nice if we could animate that transition a bit — and we can!

.gallery {
  overflow: scroll;
  scroll-snap-type: x mandatory;
  scroll-behavior: smooth;
}

That scroll-behavior CSS property is super handy for this and so now the whole thing will animate if you click one of the nav items:

CodePen Embed Fallback

Nifty, eh? One more tiny thing we could do here is throw a filter on the nav items to make them black and white and then animate them on hover:

.lil-nav__img {
  object-fit: cover;
  filter: saturate(0);
  transition: 0.3s ease all;
}

.lil-nav__img:hover {
  transform: scale(1.05);
  filter: saturate(1);
}

I’m sure there’s a lot more we could do here but I think this works quite nicely!

CodePen Embed Fallback

We could even throw a tiny bit of JavaScript into the mix to show which image is active, but I reckon that folks know that just from looking at the gallery.

That’s it! We now have a carousel that’s pretty dang good for progressive enhancement and it means we don’t have to load a library of JavaScript or write a bunch more code than we really need to.

Making the carousel responsive…

Let’s go one step further though and make this chap responsive. What we want to do is reverse the order of our grid by moving all of our current styles into a media query that is only activated at larger screens.

You might want to open up this demo in a new tab and decrease/increase the size of the browser to see the changes take place:

CodePen Embed Fallback

If you load this demo on a mobile device you should see how the layout switches between the two modes. This is done by using a single media query on the .wrapper element. Note that we’re using Sass:

$large: 1200px;

.wrapper {
  overflow: hidden;
  height: 100vh;
  display: grid;
  grid-template-rows: 2fr 1fr;
  grid-gap: 10px;

  @media screen and (min-width: $large) {
    grid-template-columns: 1fr 5fr;
    grid-template-rows: auto;
  }
}

Let’s add one on the navigation, too. But this time, we need to tell the navigation to start on the second row so it moves to the bottom of the screen:

.lil-nav {
  overflow-x: scroll;
  overflow-y: hidden;
  display: flex;
  grid-row-start: 2;

  @media screen and (min-width: $large) {
    overflow-y: scroll;
    overflow-x: hidden;
    display: block;
    grid-row-start: auto;
  }
}

With the gallery we need to switch around the scroll-type for larger screens and reverse the overflow property as well:

.gallery {
  overflow-x: scroll;
  overflow-y: hidden;
  scroll-snap-type: x mandatory;
  scroll-behavior: smooth;
  display: flex;

  @media screen and (min-width: $large) {
    display: block;
    overflow-y: scroll;
    overflow-x: hidden;
    scroll-snap-type: y mandatory;
  }
}

That’s the bulk of the changes we’ve had to make and I quite like it! If we wanted to make this production-ready, we would think about accessibility (e.g. we probably don’t want screen readers to read out all the images in both the nav and gallery). Then there’s performance — we might consider lazy-loading so the images are only rendered when they’re needed.

Either way, this is a good start !

The post How to Make a CSS-Only Carousel appeared first on CSS-Tricks.

Categories: Designing, Others Tags:

“The title ‘Front-End Developer’ is obsolete.”

April 24th, 2020 No comments

That title is from the opening tweet of a thread from Benjamin De Cock. I wouldn’t go that far, myself. What I like about the term is that ‘Front-End’ literally means the browser, and while the job has been changing quite a lot — and is perhaps fracturing before our eyes — the fact that the job is about doing browser work is still true. We’re browser people. This was a point I tried to make in my “Ooooops I guess we’re full-stack developers now” talk.

I really like Benjamin’s sentiment though. There is a scourge of implementations of things on the web that are both heavier and worse because they re-implement something that the browser offers better and “for free.” Think sliders: scrolling behavior, snap points, fixed/sticky positioning, form controls, animation, etc.

Our industry seems to have acknowledged that backend and frontend developers require very different skills (even though they often use the exact same language), and yet it’s struggling to see there’s too much bundled into the term “front-end developer”.

That’s the tricky part. That’s at the heart of The Great Divide. There’s an awful lot of front-end developers where their job solely focuses on JavaScript. You could call them “JavaScript Engineers” or “JavaScript Developers,” and that feels OK. However, I’m not sure what you call someone who’s a great front-end developer, not particularly focused on JavaScript, but is on other aspects of the front end.

The modern frontend developer is most often than not a “Jack of all trades” mastering JS (or even just a framework) and barely tolerating HTML/CSS as a necessary evil. That’s understandable. I strongly think it’s a different specialization, and it’s too much for a single person.

Yep, it’s OK! The divide isn’t a bad thing; it’s just a thing. Front-end teams need JavaScript specialists and CSS specialists and accessibility specialists and performance specialists and animation specialists and internationalization specialists and, and, and, and. They don’t have to all be separate people. People can be good at multiple things. It’s just exceptionally rare that people are good at everything, even when scoped only to front-end skills.

The post “The title ‘Front-End Developer’ is obsolete.” appeared first on CSS-Tricks.

Categories: Designing, Others Tags:

Chrome + System Fonts Snafu

April 24th, 2020 No comments

There was just a bug late last year where system fonts (at least on Mac, I don’t know what the story was on other platforms) in Chrome appeared too thin and tracked-in at small sizes and too thick and tracked-out at larger sizes. That one was fixed, thankfully. But while it was a problem, it was the reason I gave up on system fonts for now and switched something else. A performance loss but aesthetic gain.

Now there is a new much worse bug, where the system font can’t be bolded. It’s not great, as a ton of sites roll with the system font stack as it has two major benefits: 1) it can help your site look like the operating system 2) it has great performance as the site doesn’t need to download/display and custom fonts.

Jon Henshaw wrote it up:

… the bug caught the attention of Adam Argyle, maker of VisBug and Chrome CSS Developer Advocate at Google. Argyle created a Chromium bug report, but the Chromium development team ultimately decided it wasn’t a blocker for releasing version 81. That resulted in sites like Coywolf not being able to use bold text for fonts that are larger than 16px (e.g., every heading).

The bug won’t be fixed in version 82 because the Chromium team announced that they’re skipping it, and will be releasing version 83 in mid-May instead. Argyle assured everyone on the original GitHub bug report that it would be fixed in version 83.

Above is Jon’s site. Andy Bell’s site got hit by it too.

So we’re looking at 4 weeks or so. Adam proposed a temporary fix of going Helvetica for now:

body {
  font-family: -apple-system, Helvetica;
}

I guess with -apple-system in there, older versions of Chrome/macOS still might be able to benefit from system fonts? Not sure.

That brings up a source of confusion for me. When I first heard of using system font stacks, there was -apple-system and BlinkMacSystemFont and you were supposed to use them in that order in the font stack. Then came along -system-ui, and that seemed to work well all by itself and that was nice as it was obviously less Mac-specific. But there is also system-ui (no starting dash), and that seems to do the same thing and I’m not sure which is correct. Now it looks like the plan is ui-sans-serif and friends (like ui-serif and ui-monospace). I like the idea, but I’d love to hear clarity from browser vendors on what the recommended use is. Are we in a spot like this?

/* Just a guess... */
body {
  font-family: 
    ui-sans-serif, 
    system-ui, 
    -system-ui, 
    -apple-system,
    BlinkMacSystemFont,
    Roboto, Helvetica, Arial, 
    sans-serif, 
    "Apple Color Emoji";
}

Another observation from me… as I was trying to replicate this on Chrome 81, at first I was like “weird, works for me”, because I was trying out the bolding on default 16px text. I noticed that it was when the font was 20px or bigger the problem kicked in:

Bramus has an alternative fix idea: use Inter.

The post Chrome + System Fonts Snafu appeared first on CSS-Tricks.

Categories: Designing, Others Tags:

SVG, Favicons, and All the Fun Things We Can Do With Them

April 24th, 2020 No comments
Mockup of four SVG favicon treatments. The first treatment is a pink star with a tab title of, “SVG Favicon.” The second treatment is a hot pink star with a tab title of, “Light Level SVG Favicon.” The third treatment is a light pink star with a tab title of, “Inverted Colors SVG Favicon.” The fourth treatment is a black pink star with a tab title of, “High Contrast Mode SVG Favicon.” The tabs are screen captures from Microsoft Edge, with the browser chrome updating to match each specialized mode.

Favicons are the little icons you see in your browser tab. They help you understand which site is which when you’re scanning through your browser’s bookmarks and open tabs. They’re a neat part of internet history that are capable of performing some cool tricks.

One very new trick is the ability to use SVG as a favicon. It’s something that most modern browsers support, with more support on the way.

Here’s the code for how to add favicons to your site:

<link rel="icon" type="image/svg+xml" href="/favicon.svg">
<link rel="alternate icon" href="/favicon.ico">
<link rel="mask-icon" href="/safari-pinned-tab.svg" color="#ff8a01">

If a browser doesn’t support a SVG favicon, it will ignore the first link element declaration and continue on to the second. This ensures that all browsers that support favicons can enjoy the experience.

You may also notice the alternate attribute value for our rel declaration in the second line. This programmatically communicates to the browser that the favicon with a file format that uses .ico is specifically used as an alternate presentation.

Following the favicons is a line of code that loads another SVG image, one called safari-pinned-tab.svg. This is to support Safari’s pinned tab functionality, which existed before other browsers had SVG favicon support. There’s additional files you can add here to enhance your site for different apps and services, but more on that in a bit.

Here’s more detail on the current level of SVG favicon support:

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

Desktop

Chrome Firefox IE Edge Safari
80 41 No 80 TP

Mobile / Tablet

Android Chrome Android Firefox Android iOS Safari
80 No No 13.4

Why SVG?

You may be questioning why this is needed. The .ico file format has been around forever and can support images up to 256×256 pixels in size. Here are three answers for you.

Ease of authoring

It’s a pain to make .ico files. The file is a proprietary format used by Microsoft, meaning you’ll need specialized tools to make them. SVG is an open standard, meaning you can use them without any further tooling or platform lock-in.

Future-proofing

Retina? 5k? 6k? When we use a resolution-agnostic SVG file for a favicon, we guarantee that our favicons look crisp on future devices, regardless of how large their displays get.

Performance

SVGs are usually very small files, especially when compared to their raster image counterparts — even more-so if you optimize them beforehand. By only using a 16×16 pixel favicon as a fallback for browsers that don’t support SVG, we provide a combination that enjoys a high degree of support with a smaller file size to boot.

This might seem a bit extreme, but when it comes to web performance, every byte counts!

Tricks

Another cool thing about SVG is we can embed CSS directly in it. This means we can do fun things like dynamically adjust them with JavaScript, provided the SVG is declared inline and not embedded using an img element.

<svg  version="1.1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
  <style>
    path { fill: #272019; }
  </style>
  <!-- etc. -->
</svg>

Since SVG favicons are embedded using the link element, they can’t really be modified using JavaScript. We can, however, use things like emoji and media queries.

Emoji

Lea Verou had a genius idea about using emoji inside of SVG’s text element to make a quick favicon with a transparent background that holds up at small sizes.

Now that all modern browsers support SVG favicons, here’s how to turn any emoji into a favicon.svg:

<svg xmlns="https://t.co/TJalgdayix” viewBox=”0 0 100 100″>
?

Useful for quick apps when you can’t be bothered to design a favicon! pic.twitter.com/S2F8IQXaZU

— Lea Verou (@LeaVerou) March 22, 2020

In response, Chris Coyier whipped up a neat little demo that lets you play around with the concept.

Dark Mode support

Both Thomas Steiner and Mathias Bynens independently stumbled across the idea that you can use the prefers-color-scheme media query to provide support for dark mode. This work is built off of Jake Archibald’s exploration of SVG and media queries.

<svg width="128" height="128" xmlns="http://www.w3.org/2000/svg">
  <style>
    path { fill: #000000; }
    @media (prefers-color-scheme: dark) {
      path { fill: #ffffff; }
    }
  </style>
  <path d="M111.904 52.937a1.95 1.95 0 00-1.555-1.314l-30.835-4.502-13.786-28.136c-.653-1.313-2.803-1.313-3.456 0L48.486 47.121l-30.835 4.502a1.95 1.95 0 00-1.555 1.314 1.952 1.952 0 00.48 1.99l22.33 21.894-5.28 30.918c-.115.715.173 1.45.768 1.894a1.904 1.904 0 002.016.135L64 95.178l27.59 14.59c.269.155.576.232.883.232a1.98 1.98 0 001.133-.367 1.974 1.974 0 00.768-1.894l-5.28-30.918 22.33-21.893c.518-.522.71-1.276.48-1.99z" fill-rule="nonzero"/>
</svg>

For supporting browsers, this code means our star-shaped SVG favicon will change its fill color from black to white when dark mode is activated. Pretty neat!

Other media queries

Dark mode support got me thinking: if SVGs can support prefers-color-scheme, what other things can we do with them? While the support for Level 5 Media Queries may not be there yet, here’s some ideas to consider:

A mockup of how these media query-based adjustments could work.

Keep it crisp

Another important aspect of good favicon design is making sure they look good in the small browser tab area. The secret to this is making the paths of the vector image line up to the pixel grid, the guide a computer uses to turn SVG math into the bitmap we see on a screen.

Here’s a simplified example using a square shape:

A crisp orange square on a white background. There is also a faint grid of gray horizontal and vertical lines that represent the pixel grid. Screenshot from Figma.

When the vector points of the square align to the pixel grid of the artboard, the antialiasing effect a computer uses to smooth out the shapes isn’t needed. When the vector points aren’t aligned, we get a “smearing” effect:

A blurred orange square on a white background. There is also a faint grid of gray horizontal and vertical lines that represent the pixel grid. Screenshot from Figma.

A vector point’s position can be adjusted on the pixel grid by using a vector editing program such as Figma, Sketch, Inkscape, or Illustrator. These programs export SVGs as well. To adjust a vector point’s location, select each node with a precision selection tool and drag it into position.

Some more complicated icons may need to be simplified, in order to look good at such a small size. If you’re looking for a good primer on this, Jeremy Frank wrote a really good two-part article over at Vidget.

Go the extra mile

In addition to favicons, there are a bunch of different (and unfortunately proprietary) ways to use icons to enhance its experience. These include things like the aforementioned pinned tab icon for Safari¹, chat app unfurls, a pinned Windows start menu tile, social media previews, and homescreen launchers.

If you’re looking for a great place to get started with these kinds of enhancements, I really like realfavicongenerator.net.

Icon output from realfavicongenerator.net arranged in a grid using CSS-Trick's logo. There are two rows of five icons: android-chrome-192x192.png, android-chrome-384x384.png, apple-touch-icon.png, favicon-16x16.png, favicon-32x32.png, mstile-150x150.png, safari-pinned-tab.svg, favicon.ico, browserconfig.xml, and site.webmanifest.
It’s a lot, but it guarantees robust support.

A funny thing about the history of the favicon: Internet Explorer was the first browser to support them and they were snuck in at the 11th hour by a developer named Bharat Shyam:

As the story goes, late one night, Shyam was working on his new favicon feature. He called over junior project manager Ray Sun to take a look.

Shyam commented, “This is good, right? Check it in?”, requesting permission to check the code into the Internet Explorer codebase so it could be released in the next version. Sun didn’t think too much of it, the feature was cool and would clearly give IE an edge. So he told Shyam to go ahead and add it. And just like that, the favicon made its way into Internet Explorer 5, which would go on to become one of the largest browser releases the web has ever seen.

The next day, Sun was reprimanded by his manager for letting the feature get by so quickly. As it turns out, Shyam had specifically waited until later in the day, knowing that a less experienced Program Manager would give him a pass. But by then, the code had been merged in. Incidentally, you’d be surprised just how many relatively major browser features have snuck their way into releases like this.

From How We Got the Favicon by Jay Hoffmann

I’m happy to see the platform throw a little love at favicons. They’ve long been one of my favorite little design details, and I’m excited that they’re becoming more reactive to user’s needs. If you have a moment, why not sneak a SVG favicon into your project the same way Bharat Shyam did way back in 1999.


¹ I haven’t been able to determine if Safari is going to implement SVG favicon support, but I hope they do. Has anyone heard anything?

The post SVG, Favicons, and All the Fun Things We Can Do With Them appeared first on CSS-Tricks.

Categories: Designing, Others Tags: