Archive

Archive for May, 2020

Notion-Powered Websites

May 14th, 2020 No comments

I’m a big fan of Notion, as you likely know from previous coverage and recent video. It’s always interesting to see what other people do with Notion, and even how Notion uses Notion.

I’d say most usage of Notion is private and internal, but any page on Notion can be totally public with the flip of a switch. We do that with some stuff like our post ideas page and here’s a simple camping checklist I made for myself.

That’s pretty rad. You could use that for lots of business-things you might otherwise literally build a website to do. Maybe a public product roadmap, a job posting, a press release an announcement…

But it’s not quite a website. You don’t get a custom domain name. You don’t have any analytics on it. You’re limited by the exact feature set of Notion.

People have been trying to extract the data out of Notion and essentially use it as a CMS for a while now…

But all those ways are, ya know, a decent amount of effort.

Stephen Ou recently showed me a pretty cool idea he has called Fruition. It’s entirely free, and also a bit of effort to set up, but once you’re done, you have your own domain name that hosts a Notion page and gives you some control over it (like putting in fonts and scripts and such).

It’s very clever in that it uses Cloudflare Workers to do all the heavy lifting.

This is probably the easiest-to-manage website ever. Just open Notion, change stuff, done.

Stephen admits Fruition is somewhat complex to set up. If you’re looking for something easier and perhaps more flexible, check out Super.

Actual neumorphism in the wild!

I would note that none of these things are official Notion products or affiliates of it in any way. Honestly, they all make me a little nervous in that they could break if Notion ever decides they don’t care for the product to be used this way. I also feel like Notion has been saying an API is something they’d like to offer for a while. That will be the real answer to all this and there will be a proliferation of third-party products once we have it.

The post Notion-Powered Websites appeared first on CSS-Tricks.

Categories: Designing, Others Tags:

How to Make a Simple CMS With Cloudflare, GitHub Actions and Metalsmith

May 14th, 2020 No comments

Let’s build ourselves a CMS. But rather than build out a UI, we’re going to get that UI for free in the form of GitHub itself! We’ll be leveraging GitHub as the way to manage the content for our static site generator (it could be any static site generator). Here’s the gist of it: GitHub is going to be the place to manage, version control, and store files, and also be the place we’ll do our content editing. When edits occur, a series of automations will test, verify, and ultimately deploy our content to Cloudflare.

You can find the completed code for the project is available on GitHub. I power my own website, jonpauluritis.com, this exact way.

What does the full stack look like?

Here’s the tech stack we’ll be working with in this article:

  • Any Markdown Editor (Optional. e.g Typora.io)
  • A Static Site Generator (e.g. Metalsmith)
  • Github w/ Github Actions (CICD and Deployment)
  • Cloudflare Workers

Why should you care about about this setup? This setup is potentially the leanest, fastest, cheapest (~$5/month), and easiest way to manage a website (or Jamstack site). It’s awesome both from a technical side and from a user experience perspective. This setup is so awesome I literally went out and bought stock in Microsoft and Cloudflare.

But before we start…

I’m not going to walk you through setting up accounts on these services, I’m sure you can do that yourself. Here are the accounts you need to setup:

I would also recommend Typora for an amazing Markdown writing experience, but Markdown editors are a very personal thing, so use which editor feels right for you.

Project structure

To give you a sense of where we’re headed, here’s the structure of the completed project:

├── build.js
├── .github/workflows
│   ├── deploy.yml
│   └── nodejs.js
├── layouts
│   ├── about.hbs
│   ├── article.hbs
│   ├── index.hbs
│   └── partials
│       └── navigation.hbs
├── package-lock.json
├── package.json
├── public
├── src
│   ├── about.md
│   ├── articles
│   │   ├── post1.md
│   │   └── post2.md
│   └── index.md
├── workers-site
└── wrangler.toml

Step 1: Command line stuff

In a terminal, change directory to wherever you keep these sorts of projects and type this:

$ mkdir cms && cd cms && npm init -y

That will create a new directory, move into it, and initialize the use of npm.

The next thing we want to do is stand on the shoulders of giants. We’ll be using a number of npm packages that help us do things, the meat of which is using the static site generator Metalsmith:

$ npm install --save-dev metalsmith metalsmith-markdown metalsmith-layouts metalsmith-collections metalsmith-permalinks handlebars jstransformer-handlebars

Along with Metalsmith, there are a couple of other useful bits and bobs. Why Metalsmith? Let’s talk about that.

Step 2: Metalsmith

I’ve been trying out static site generators for 2-3 years now, and I still haven’t found “the one.” All of the big names — like Eleventy, Gatsby, Hugo, Jekyll, Hexo, and Vuepress — are totally badass but I can’t get past Metalsmith’s simplicity and extensibility.

As an example, this will code will actually build you a site:

// EXAMPLE... NOT WHAT WE ARE USING FOR THIS TUTORIAL
Metalsmith(__dirname)         
  .source('src')       
  .destination('dest')     
  .use(markdown())             
  .use(layouts())           
  .build((err) => if (err) throw err);

Pretty cool right?

For sake of brevity, type this into the terminal and we’ll scaffold out some structure and files to start with.

First, make the directories:

$ mkdir -p src/articles &&  mkdir -p layouts/partials 

Then, create the build file:

$ touch build.js

Next, we’ll create some layout files:

$ touch layouts/index.hbs && touch layouts/about.hbs && touch layouts/article.hbs && touch layouts/partials/navigation.hbt

And, finally, we’ll set up our content resources:

$ touch src/index.md && touch src/about.md && touch src/articles/post1.md && touch src/articles/post1.md touch src/articles/post2.md

The project folder should look something like this:

├── build.js
├── layouts
│   ├── about.hbs
│   ├── article.hbs
│   ├── index.hbs
│   └── partials
│       └── navigation.hbs
├── package-lock.json
├── package.json
└── src
    ├── about.md
    ├── articles
    │   ├── post1.md
    │   └── post2.md
    └── index.md

Step 3: Let’s add some code

To save space (and time), you can use the commands below to create the content for our fictional website. Feel free to hop into “articles” and create your own blog posts. The key is that the posts need some meta data (also called “Front Matter”) to be able to generate properly. The files you would want to edit are index.md, post1.md and post2.md.

The meta data should look something like this:

---
title: 'Post1'
layout: article.hbs 
---
## Post content here....

Or, if you’re lazy like me, use these terminal commands to add mock content from GitHub Gists to your site:

$ curl https://gist.githubusercontent.com/jppope/35dd682f962e311241d2f502e3d8fa25/raw/ec9991fb2d5d2c2095ea9d9161f33290e7d9bb9e/index.md > src/index.md
$ curl https://gist.githubusercontent.com/jppope/2f6b3a602a3654b334c4d8df047db846/raw/88d90cec62be6ad0b3ee113ad0e1179dfbbb132b/about.md > src/about.md
$ curl https://gist.githubusercontent.com/jppope/98a31761a9e086604897e115548829c4/raw/6fc1a538e62c237f5de01a926865568926f545e1/post1.md > src/articles/post1.md
$ curl https://gist.githubusercontent.com/jppope/b686802621853a94a8a7695eb2bc4c84/raw/9dc07085d56953a718aeca40a3f71319d14410e7/post2.md > src/articles/post2.md

Next, we’ll be creating our layouts and partial layouts (“partials”). We’re going to use Handlebars.js for our templating language in this tutorial, but you can use whatever templating language floats your boat. Metalsmith can work with pretty much all of them, and I don’t have any strong opinions about templating languages.

Build the index layout

<!DOCTYPE html>
<html lang="en">
  <head>
    <style>
      /* Keeping it simple for the tutorial */
      body {
        font-family: 'Avenir', Helvetica, Arial, sans-serif;
        -webkit-font-smoothing: antialiased;
        -moz-osx-font-smoothing: grayscale;
        text-align: center;
        color: #2c3e50;
        margin-top: 60px;
      }
      .navigation {
        display: flex;
        justify-content: center;
        margin: 2rem 1rem;
      }
      .button {
        margin: 1rem;
        border: solid 1px #ccc;
        border-radius: 4px;        
        padding: 0.5rem 1rem;
        text-decoration: none;
      }
    </style>
  </head>
  <body>
    {{>navigation }}
    <div>
       {{#each articles }}
        <a href="{{path}}"><h3>{{ title }}</h3></a>
        <p>{{ description }}</p>
       {{/each }}
    </div>
  </body>
</html>

A couple of notes:

  • Our “navigation” hasn’t been defined yet, but will ultimately replace the area where {{>navigation }} resides.
  • {{#each }} will iterate through the “collection” of articles that metalsmith will generate during its build process.
  • Metalsmith has lots of plugins you can use for things like stylesheets, tags, etc., but that’s not what this tutorial is about, so we’ll leave that for you to explore.

Build the About page

Add the following to your about.hbs page:

<!DOCTYPE html>
<html lang="en">
  <head>
    <style>
      /* Keeping it simple for the tutorial */
      body {
        font-family: 'Avenir', Helvetica, Arial, sans-serif;
        -webkit-font-smoothing: antialiased;
        -moz-osx-font-smoothing: grayscale;
        text-align: center;
        color: #2c3e50;
        margin-top: 60px;
      }
      .navigation {
        display: flex;
        justify-content: center;
        margin: 2rem 1rem;
      }
      .button {
        margin: 1rem;
        border: solid 1px #ccc;
        border-radius: 4px;        
        padding: 0.5rem 1rem;
        text-decoration: none;
      }    
    </style>
  </head>
  <body>
    {{>navigation }}
    <div>
      {{{contents}}}
    </div>
  </body>
</html>

Build the Articles layout

<!DOCTYPE html>
<html lang="en">
  <head>
    <style>
      /* Keeping it simple for the tutorial */
      body {
        font-family: 'Avenir', Helvetica, Arial, sans-serif;
        -webkit-font-smoothing: antialiased;
        -moz-osx-font-smoothing: grayscale;
        text-align: center;
        color: #2c3e50;
        margin-top: 60px;
      }
      .navigation {
        display: flex;
        justify-content: center;
        margin: 2rem 1rem;
      }
      .button {
        margin: 1rem;
        border: solid 1px #ccc;
        border-radius: 4px;        
        padding: 0.5rem 1rem;
        text-decoration: none;
      }
    </style>
  </head>
  <body>
    {{>navigation }}
    <div>
      {{{contents}}}
    </div>
  </body>
</html>

You may have noticed that this is the exact same layout as the About page. It is. I just wanted to cover how to add additional pages so you’d know how to do that. If you want this one to be different, go for it.

Add navigation

Add the following to the layouts/partials/navigation.hbs file

<div class="navigation">
  <div>
    <a class="button" href="/">Home</a>
    <a class="button" href="/about">About</a>
  </div>
</div>

Sure there’s not much to it… but this really isn’t supposed to be a Metalsmith/SSG tutorial. ¯_(?)_/¯

Step 4: The Build file

The heart and soul of Metalsmith is the build file. For sake of thoroughness, I’m going to go through it line-by-line.

We start by importing the dependencies

Quick note: Metalsmith was created in 2014, and the predominant module system at the time was common.js , so I’m going to stick with require statements as opposed to ES modules. It’s also worth noting that most of the other tutorials are using require statements as well, so skipping a build step with Babel will just make life a little less complex here.

// What we use to glue everything together
const Metalsmith = require('metalsmith');


// compile from markdown (you can use targets as well)
const markdown = require('metalsmith-markdown');


// compiles layouts
const layouts = require('metalsmith-layouts');


// used to build collections of articles
const collections = require('metalsmith-collections');


// permalinks to clean up routes
const permalinks = require('metalsmith-permalinks');


// templating
const handlebars = require('handlebars');


// register the navigation
const fs = require('fs');
handlebars.registerPartial('navigation', fs.readFileSync(__dirname + '/layouts/partials/navigation.hbt').toString());


// NOTE: Uncomment if you want a server for development
// const serve = require('metalsmith-serve');
// const watch = require('metalsmith-watch');

Next, we’ll be including Metalsmith and telling it where to find its compile targets:

// Metalsmith
Metalsmith(__dirname)            
  // where your markdown files are
  .source('src')      
  // where you want the compliled files to be rendered
  .destination('public')

So far, so good. After we have the source and target set, we’re going to set up the markdown rendering, the layouts rendering, and let Metalsmith know to use “Collections.” These are a way to group files together. An easy example would be something like “blog posts” but it could really be anything, say recipes, whiskey reviews, or whatever. In the above example, we’re calling the collection “articles.”

 // previous code would go here


  // collections create groups of similar content
  .use(collections({ 
    articles: {
      pattern: 'articles/*.md',
    },
  }))
  // compile from markdown
  .use(markdown())
  // nicer looking links
  .use(permalinks({
    pattern: ':collection/:title'
  }))
  // build layouts using handlebars templates
  // also tell metalsmith where to find the raw input
  .use(layouts({
    engine: 'handlebars',
    directory: './layouts',
    default: 'article.html',
    pattern: ["*/*/*html", "*/*html", "*html"],
    partials: {
      navigation: 'partials/navigation',
    }
  }))


// NOTE: Uncomment if you want a server for development
// .use(serve({
//   port: 8081,
//   verbose: true
// }))
// .use(watch({
//   paths: {
//     "${source}/**/*": true,
//     "layouts/**/*": "**/*",
//   }
// }))

Next, we’re adding the markdown plugin, so we can use markdown for content to compile to HTML.

From there, we’re using the layouts plugin to wrap our raw content in the layout we define in the layouts folder. You can read more about the nuts and bolts of this on the official plugin site but the result is that we can use {{{contents}}} in a template and it will just work.

The last addition to our tiny little build script will be the build method:

// Everything else would be above this
.build(function(err) {
  if (err) {
    console.error(err)
  }
  else {
    console.log('build completed!');
  }
});

Putting everything together, we should get a build script that looks like this:

const Metalsmith = require('metalsmith');
const markdown = require('metalsmith-markdown');
const layouts = require('metalsmith-layouts');
const collections = require('metalsmith-collections');
const permalinks = require('metalsmith-permalinks');
const handlebars = require('handlebars');
const fs = require('fs');


// Navigation
handlebars.registerPartial('navigation', fs.readFileSync(__dirname + '/layouts/partials/navigation.hbt').toString());


Metalsmith(__dirname)
  .source('src')
  .destination('public')
  .use(collections({
    articles: {
      pattern: 'articles/*.md',
    },
  }))
  .use(markdown())
  .use(permalinks({
    pattern: ':collection/:title'
  }))
  .use(layouts({
    engine: 'handlebars',
    directory: './layouts',
    default: 'article.html',
    pattern: ["*/*/*html", "*/*html", "*html"],
    partials: {
      navigation: 'partials/navigation',
    }
  }))
  .build(function (err) {
    if (err) {
      console.error(err)
    }
    else {
      console.log('build completed!');
    }
  });

I’m a sucker for simple and clean and, in my humble opinion, it doesn’t get any simpler or cleaner than a Metalsmith build. We just need to make one quick update to the package.json file and we’ll be able to give this a run:

 "name": "buffaloTraceRoute",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "build": "node build.js",
    "test": "echo "No Tests Yet!" "
  },
  "keywords": [],
  "author": "Your Name",
  "license": "ISC",
  "devDependencies": {
    // these should be the current versions
    // also... comments aren't allowed in JSON
  }
}

If you want to see your handy work, you can uncomment the parts of the build file that will let you serve your project and do things like run npm run build. Just make sure you remove this code before deploying.

Working with Cloudflare

Next, we’re going to work with Cloudflare to get access to their Cloudflare Workers. This is where the $5/month cost comes into play.

Now, you might be asking: “OK, but why Cloudflare? What about using something free like GutHub Pages or Netlify?” It’s a good question. There are lots of ways to deploy a static site, so why choose one method over another?

Well, Cloudflare has a few things going for it…

Speed and performance

One of the biggest reasons to switch to a static site generator is to improve your website performance. Using Cloudflare Workers Site can improve your performance even more.

Here’s a graph that shows Cloudflare compared to two competing alternatives:

Courtesy of Cloudflare

The simple reason why Cloudflare is the fastest: a site is deployed to 190+ data centers around the world. This reduces latency since users will be served the assets from a location that’s physically closer to them.

Simplicity

Admittedly, the initial configuration of Cloudflare Workers may be a little tricky if you don’t know how to setup environmental variables. But after you setup the basic configurations for your computer, deploying to Cloudflare is as simple as wrangler publish from the site directory. This tutorial is focused on the CI/CD aspect of deploying to Cloudflare which is a little more involved, but it’s still incredibly simple compared to most other deployment processes.

(It’s worth mentioning GitHub Pages, Netlify are also killing it in this area. The developer experience of all three companies is amazing.)

More bang for the buck

While Github Pages and Netlify both have free tiers, your usage is (soft) limited to 100GB of bandwidth a month. Don’t get me wrong, that’s a super generous limit. But after that you’re out of luck. GitHub Pages doesn’t offer anything more than that and Netlify jumps up to $45/month, making Cloudflare’s $5/month price tag very reasonable.

Service Free Tier Bandwidth Paid Tier Price Paid Tier Requests / Bandwidth
GitHub Pages 100GB N/A N/A
Netlify 100GB $45 ~150K / 400 GB
Cloudflare Workers Sites none $5 10MM / unlimited
Calculations assume a 3MB average website. Cloudflare has additional limits on CPU use. GitHub Pages should not be used for sites that have credit card transactions.

Sure, there’s no free tier for Cloudflare, but $5 for 10 million requests is a steal. I would also be remise if I didn’t mention that GitHub Pages has had a few outages over the last year. That’s totally fine in my book a demo site, but it would be bad news for a business.

Cloudflare offers a ton of additional features for that worth briefly mentioning: free SSL certificates, free (and easy) DNS routing, a custom Workers Sites domain name for your projects (which is great for staging), unlimited environments (e.g. staging), and registering a domain name at cost (as opposed to the markup pricing imposed by other registrars).

Deploying to Cloudflare

Cloudflare provides some great tutorials for how to use their Cloudflare Workers product. We’ll cover the highlights here.

First, make sure the Cloudflare CLI, Wrangler, is installed:

$ npm i @cloudflare/wrangler -g

Next, we’re going to add Cloudflare Sites to the project, like this:

wrangler init --site cms 

Assuming I didn’t mess up and forget about a step, here’s what we should have in the terminal at this point:

⬇️ Installing cargo-generate...
🔧   Creating project called `workers-site`...
✨   Done! New project created /Users/<User>/Code/cms/workers-site
✨  Succesfully scaffolded workers site
✨  Succesfully created a `wrangler.toml`

There should also be a generated folder in the project root called /workers-site as well as a config file called wrangler.toml — this is where the magic resides.

name = "cms"
type = "webpack"
account_id = ""
workers_dev = true
route = ""
zone_id = ""


[site]
bucket = ""
entry-point = "workers-site"

You might have already guessed what comes next… we need to add some info to the config file! The first key/value pair we’re going to update is the bucket property.

bucket = "./public"

Next, we need to get the Account ID and Zone ID (i.e. the route for your domain name). You can find them in your Cloudflare account all the way at the bottom of the dashboard for your domain:

Stop! Before going any further, don’t forget to click the “Get your API token” button to grab the last config piece that we’ll need. Save it on a notepad or somewhere handy because we’ll need it for the next section.

Phew! Alright, the next task is to add the Account ID and Zone ID we just grabbed to the .toml file:

name = "buffalo-traceroute"
type = "webpack"
account_id = "d7313702f333457f84f3c648e9d652ff" # Fake... use your account_id
workers_dev = true
# route = "example.com/*" 
# zone_id = "805b078ca1294617aead2a1d2a1830b9" # Fake... use your zone_id


[site]
bucket = "./public"
entry-point = "workers-site"
(Again, those IDs are fake.)

Again, those IDs are fake. You may be asked to set up credentials on your computer. If that’s the case, run wrangler config in the terminal.

GitHub Actions

The last piece of the puzzle is to configure GitHub to do automatic deployments for us. Having done previous forays into CI/CD setups, I was ready for the worst on this one but, amazingly, GitHub Actions is very simple for this sort of setup.

So how does this work?

First, let’s make sure that out GitHub account has GitHub Actions activated. It’s technically in beta right now, but I haven’t run into any issues with that so far.

Next, we need to create a repository in GitHub and upload our code to it. Start by going to GitHub and creating a repository.

This tutorial isn’t meant to cover the finer points of Git and/or GitHub, but there’s a great introduction. Or, copy and paste the following commands while in the root directory of the project:

# run commands one after the other
$ git init
$ touch .gitignore && echo 'node_modules' > .gitignore
$ git add .
$ git commit -m 'first commit'
$ git remote add origin https://github.com/{username}/{repo name}
$ git push -u origin master

That should add the project to GitHub. I say that with a little hesitance but this is where everything tends to blow up for me. For example, put too many commands into the terminal and suddenly GitHub has an outage, or the terminal unable to location the path for Python. Tread carefully!

Assuming we’re past that part, our next task is to activate Github Actions and create a directory called .github/workflows in the root of the project directory. (GitHub can also do this automatically by adding the “node” workflow when activating actions. At the time of writing, adding a GitHub Actions Workflow is part of GitHub’s user interface.)

Once we have the directory in the project root, we can add the final two files. Each file is going to handle a different workflow:

  1. A workflow to check that updates can be merged (i.e. the “CI” in CI/CD)
  2. A workflow to deploy changes once they have been merged into master (i.e. the “CD” in CI/CD)
# integration.yml
name: Integration


on:
  pull_request:
    branches: [ master ]


jobs:
  build:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        node-version: [10.x, 12.x]
    steps:
    - uses: actions/checkout@v2
    - name: Use Node.js ${{ matrix.node-version }}
      uses: actions/setup-node@v1
      with:
        node-version: ${{ matrix.node-version }}
    - run: npm ci
    - run: npm run build --if-present
    - run: npm test
      env:
        CI: true

This is a straightforward workflow. So straightforward, in fact, that I copied it straight from the official GitHub Actions docs and barely modified it. Let’s go through what is actually happening in there:

  1. on: Run this workflow only when a pull request is created for the master branch
  2. jobs: Run the below steps for two-node environments (e.g. Node 10, and Node 12 — Node 12 is currently the recommended version). This will build, if a build script is defined. It will also run tests if a test script is defined.

The second file is our deployment script and is a little more involved.

# deploy.yml
name: Deploy


on:
  push:
    branches:
      - master


jobs:
  deploy:
    runs-on: ubuntu-latest
    name: Deploy
    strategy:
      matrix:
        node-version: [10.x]


    steps:
      - uses: actions/checkout@v2
      - name: Use Node.js ${{ matrix.node-version }}
        uses: actions/setup-node@v1
        with:
          node-version: ${{ matrix.node-version }}
      - run: npm install
      - uses: actions/checkout@master
      - name: Build site
        run: "npm run build"
      - name: Publish
        uses: cloudflare/wrangler-action@1.1.0
        with:
          apiToken: ${{ secrets.CF_API_TOKEN }}

Important! Remember that Cloudflare API token I mentioned way earlier? Now is the time to use it. Go to the project settings and add a secret. Name the secret CF_API_TOKEN and add the API token.

Let’s go through whats going on in this script:

  1. on: Run the steps when code is merged into the master branch
  2. steps: Use Nodejs to install all dependencies, use Nodejs to build the site, then use Cloudflare Wrangler to publish the site

Here’s a quick recap of what the project should look like before running a build (sans node_modules):

├── build.js
├── dist
│   └── worker.js
├── layouts
│   ├── about.hbs
│   ├── article.hbs
│   ├── index.hbs
│   └── partials
│       └── navigation.hbs
├── package-lock.json
├── package.json
├── public
├── src
│   ├── about.md
│   ├── articles
│   │   ├── post1.md
│   │   └── post2.md
│   └── index.md
├── workers-site
│   ├── index.js
│   ├── package-lock.json
│   ├── package.json
│   └── worker
│       └── script.js
└── wrangler.toml

A GitHub-based CMS

Okay, so I made it this far… I was promised a CMS? Where is the database and my GUI that I log into and stuff?

Don’t worry, you are at the finish line! GitHub is your CMS now and here’s how it works:

  1. Write a markdown file (with front matter).
  2. Open up GitHub and go to the project repository.
  3. Click into the “Articles” directory, and upload the new article. GitHub will ask whether a new branch should be created along with a pull request. The answer is yes.
  4. After the integration is verified, the pull request can be merged, which triggers deployment.
  5. Sit back, relax and wait 10 seconds… the content is being deployed to 164 data centers worldwide.

Congrats! You now have a minimal Git-based CMS that basically anyone can use.

Troubleshooting notes

  • Metalsmith layouts can sometimes be kinda tricky. Try adding this debug line before the build step to have it kick out something useful: DEBUG=metalsmith-layouts npm run build
  • Occasionally, Github actions needed me to add node_modules to the commit so it could deploy… this was strange to me (and not a recommended practice) but fixed the deployment.
  • Please let me know if you run into any trouble and we can add it to this list!

The post How to Make a Simple CMS With Cloudflare, GitHub Actions and Metalsmith appeared first on CSS-Tricks.

Categories: Designing, Others Tags:

Online Together

May 14th, 2020 No comments

(This is a sponsored post.)

An Event Apart: Online Together is a single-day online conference with an intense focus on digital design, UX, content, code, and more, giving you deep insights into where we are now and where things are going next.

AEA! With a brand new online version of their conference! That’s awesome. AEA is a best-in-class web conference, so if you’re looking for a conference to help get your mind going on big-picture web design and development stuff again and connect with some like-minded industry people, this is your opportunity.

Direct Link to ArticlePermalink

The post Online Together appeared first on CSS-Tricks.

Categories: Designing, Others Tags:

Smashing Meets! Free Online Meetups On May 18th And 19th 2020

May 14th, 2020 No comments
Smashing Meets: May 18th - 19th

Smashing Meets! Free Online Meetups On May 18th And 19th 2020

Smashing Meets! Free Online Meetups On May 18th And 19th 2020

Rachel Andrew

2020-05-14T13:00:00+00:002020-05-15T23:37:48+00:00

We’re having a meetup! Join us for Smashing Meets — two free online meetups with speakers, activities, and plenty of chances to make new friends. Just like a real meetup, though you’ll need to bring your own pizza.

What Will Happen At Smashing Meets?

  • 3×30-mins interactive talks from experts, followed by a short Q&A.
  • Interactive activities in breakout rooms, with friendly communities around the world and collaborative design and coding challenges.
  • A fun quiz show where you can win some smashing prizes!

Smashing Meets: May 18th - 19th

Two Days, Different Timezones

To help make this a truly global meetup, we have two meets to sign up for:

We hope one of those will work for you, or come along to both! We will be happy to see you. More details on the speakers for each event below.

Smashing Meets: Day 1 (Monday, May 18th)

MAY 18 Stage (Always open) Sessions Sessions
13:00 Doors open
13:10 Introduction by MC
13:25 Talk 1 with Yiying Lu: Creativity In Cross-Cultural Innovation Meet Designers & Coffee Toronto Design Challenge (by Mark Boulton and Vitaly Friedman)
13:55 Close & Introduction by MC
14:00 Talk 2 with Phil Hawksworth: Building With Jamstack — Keeping UIs And APIs Aligned Q&A Yiying Meet Woman of Design & Tech
14:30 Close & Introduction (by MC)
14:35 Talk 3 with Mark Boulton: Accessible Typography Emoji Challenge (by Yiying) Q&A Phil
15:05 Close & intro Quiz by MC
15:10 Super Smash Purrrty! by Charis and Peter Q&A Mark
15:40 Close close by MC
  • Building With JAMstack: Keeping UIs And APIs Aligned by Phil Hawksworth
    In his talk, Phil will shed light on some of the techniques you can use when working with serverless functions, proxies and Jamstack tools to help you build projects with confidence.
  • Accessible Typography by Mark Boulton
    Mark will be sharing his personal advice on how to use that particular typeface you want to use in the most accessible way. A practical talk that covers a bit of type design as well as the details of typesetting.
  • Creativity In Cross-Cultural Innovation by Yiying Lu
    Yiying will tell us how we can create more business and cultural value by integrating creativity in our product, messaging, and delivery. By the end of this talk, you’ll be sure to have learned how to start creating design that bridges the gap between Art and Tech, Business and Culture, East and West.

Smashing Meets: Day 2 (Tuesday, May 19th)

MAY 19 Stage (Always open) Sessions Sessions
14:00 Doors open
14:10 Introduction by MC
14:25 Talk 1 with Mandy Michael: Fun With Browser And Sensor APIS Meet Talk.CSS Singapore Design Challenge (by Mark Boulton and Vitaly Friedman)
14:55 Close & Introduction by MC
15:00 Talk 2 with Rachel Andrew: Hello, Subgrid! Q&A Mandy Meet Web Weekend Kathmandu
15:30 Close & Introduction (by MC)
15:35 Talk 3 with Mark Boulton: Accessible Typography CodePen challenge (by HuiJing) Q&A Rachel
16:05 Close & intro Quiz by MC
16:10 Super Smash Purrrty! by Charis and Peter Q&A Mark
16:40 Close close by MC
  • Fun With Browser And Sensor APIs by Mandy Michael
    Whether it’s a practical implementation of the Light Sensor API or abducting a cat with a combination of sensors, Mandy will be looking — some simple code demos by exploring possibilities, tools and resources that are needed to create engaging and creative effects, visualizations and experiences.
  • Hello, Subgrid by Rachel Andrew
    In this talk, Rachel will introduce Subgrid alongside use cases, example code, and some thoughts on where we might see Grid heading in the future.
  • Accessible Typography by Mark Boulton
    Mark will be sharing his personal advice on how to use that particular typeface you want to use in the most accessible way. A practical talk that covers a bit of type design as well as the details of typesetting.

There are only a few days left to register, so sign up for the Meet (or Meets) of your choice here. It’s free, and we look forward to seeing you there.

(jn, il)
Categories: Others Tags:

Styling Components In React

May 14th, 2020 No comments
Code Output.

Styling Components In React

Styling Components In React

Shedrack Akintayo

2020-05-14T10:00:00+00:002020-05-15T23:37:48+00:00

Styling React components over the years has improved and become much easier with various techniques and strategies. In this tutorial, we’re going to learn how to style React components using four major styling strategies — with examples on how to use them. In the process, I will explain the cons and pros of these styling strategies, and by the end of this tutorial, you’ll know all about styling React components and how they work along with the various methods that can be used for styling these components.

Note: A basic understanding of ReactJS and CSS would be good to have for this tutorial.

What Does ‘Styling’ In React Applications Even Mean?

The reason you’ll style your React application is no different from that which you have in mind when styling other websites or web applications you have been working on. Styling in React applications describes how React components or elements are displayed on screen or any other media.

The whole essence of building frontend UIs with React is how flexible it is to build these UIs especially as components and also style them to give us a great look and experience. It is important to know that whatever styling strategy you may decide to use is still CSS — you are writing CSS like you’ve always done. The difference is that the strategies (which we’ll be looking at) help make the process easy because of the uniqueness of React.

Major Styling Strategies In React

There are various strategies to follow when planning to style React components, these strategies have also increased and evolved over the years. In this tutorial, we would be talking about the most popular and modern styling strategies, and how to use them to style our React components. These styling strategies include:

  1. CSS and SCSS Stylesheets
    This involves using separate stylesheets like our conventional way of styling our HTML websites either with CSS or a CSS preprocessor called SASS.
  2. CSS Modules
    A CSS Module is a CSS file in which all class names and animation names are scoped locally by default.
  3. styled-components
    styled-components is a library for React and React Native that allows you to use component-level styles in your application that are written with a mixture of JavaScript and CSS using a technique called CSS-in-JS.
  4. JSS
    JSS is an authoring tool for CSS which allows you to use JavaScript to describe styles in a declarative, conflict-free and reusable way. It can compile in the browser, server-side or at build time in Node.

In the next section of this tutorial, we are going to be talking about each of these strategies of styling with examples of their syntax.

1. CSS And SASS Stylesheets

CSS or SCSS Stylesheets is a styling strategy that involves the use of external CSS or SASS stylesheets that can be imported into your React components depending on where you need the styling to be applied.

For example, we have a SASS file of styles called Box.scss we need to use in a component called Box.js, below is the code for our SASS file.

// Box.scss
.Box {
  margin: 40px;
  border: 5px black;
}

.Box_content {
  font-size: 16px;
  text-align: center;
}

In other to make use of this styling inside our Box component all we need to do is import the SASS file directly into our Box.js component like so:

import React from 'react';
import './Box.css';

const Box = () => (
  <div className="Box">
    <p className="Box_content"> Styling React Components </p>
  </div>
);

export default Box;

After creating the styles and importing it into Box.js file, we can then set the className attribute to the match what we have in the stylesheet.

While using this strategy, you could also leverage on existing frameworks like; Bulma, Bootstrap, etc. These frameworks provide you with existing classes and components you could plug into your React application without styling every aspect of your application.

Benefits of using CSS and SASS Stylesheets

  1. It is much more popular than the rest of the styling strategies, so there is a ton of helpful resources when you run into a bug.
  2. Caching & Performance
    Standard CSS files are easy for the browser to optimize for, caching the files locally for repeat visits, and ultimately giving performance wins.
  3. Un-opinionated and Universal
    CSS and SASS is universal and has no opinion on how you render your UI making it a great choice for teams that have legacy CSS and are migrating over to a new framework or rebuilding their website or product.
  4. Quickly Iterate A New Design
    You can very easily rip out the entire stylesheet and create a new one to refresh the look and feel of your app without digging through potentially hundreds of components.
  5. CSS Frameworks
    CSS frameworks come in handy if you are a new developer, or you want to quickly work on a prototype without diving deep into writing your own full-blown stylesheets. CSS frameworks will provide you with building blocks to get your idea off the ground. Some of these frameworks include, Bootstrap, Bulma, Semantic UI, Materialize.

Shortcomings of using CSS and SASS Stylesheets

  1. Readability
    If not properly structured, a CSS or SASS stylesheet can become long and difficult to navigate through as the application becomes complex.
  2. Legacy CSS Can Live On For Years
    Most times these really large stylesheets can become so complex and long that cleaning up old, outdated or even unused styles can be a pain.

Note: “Sass has two syntaxes. The most commonly used syntax is known as “SCSS” (for “Sassy CSS”) and is a superset of CSS syntax. This means that every valid CSS stylesheet is valid SCSS as well. SCSS files use the extension .scss.
The second, older syntax is known as the indented syntax (or just “.sass”). Inspired by Haml’s terseness, it’s intended for people who prefer conciseness over similarity to CSS. Instead of brackets and semicolons, it uses the indentation of lines to specify blocks. Files in the indented syntax use the extension .sass.”

CSS Modules

A CSS Module is a CSS file in which all class names and animation names are scoped locally by default. When using CSS Modules, each React component is provided with its own CSS file, that is scoped to that file and component alone.

The beauty of CSS modules happens at build time when the local class names which can be super simple without conflict are mapped directly to the automatically-generated ones and are exported as a JS object literal to use within React.

We can make use of CSS Modules in our React applications by importing the file directly into the component file.

For example, the code below is an example of how to use a CSS module in a React Component.

//Box.css
 :local(.container) {
   margin: 40px;
   border: 5px dashed pink;
 }
 :local(.content) {
   font-size: 15px;
   text-align: center;
 }

:local(.className) is used when you use create-react-app boilerplate because of webpack configurations.

When using webpack, you can add the loader and also include the module to your webpack.config.js in other to make CSS modules work with Webpack.

test: /.css$/,
loader: 'style!css-loader?modules&importLoaders=1&localIdentName=[name]__[local]___[hash:base64:5]' 
}

In other to make use of this CSS Module inside our Box component we need to import the module file directly into our Box.js component and use the className instead of style prop to access the style like so:

import React from 'react';
import styles from './Box.css';

const Box = () => (
  <div className={styles.container}>
    <p className={styles.content}> Styling React Components </p>
  </div>
);

export default Box;

styles here is an object that contains the styles we created in Box.css. This object will contain the classes; container and content that maps to their respective styles. To make use of them, we assign the element’s className to the appropriate class we have in Box.css.

Benefits Of Using CSS Modules

  1. Modular and reusable CSS,
  2. No more styling conflicts,
  3. Explicit dependencies,
  4. Local scope,
  5. Clear dependencies,
  6. No Code duplication in case of SSR,
  7. No Additional costs in JS payload,
  8. Variables, Sharing variables in CSS and exposing it to JavaScript.

Shortcomings of using CSS Modules

  1. Extra build tools (e.g. webpack).
  2. Mixing CSS Modules and global CSS classes is cumbersome.
  3. When a Reference is made to an undefined CSS Module, it resolves to undefined without a warning.
  4. Using the styles object whenever constructing a className is compulsory.
  5. Only allows usage of camelCase CSS class names.

styled-components

styled-components is a library for React and React Native that allows you to use component-level styles in your application that are written with a mixture of JavaScript and CSS.

It was created with the same method of operation of CSS Modules, a way to write CSS that’s scoped to a single component, and not accessible to any other element in the page or even component.

styled-components allows React developers to write plain CSS in React components without having to worry about clashing of class names.

For example, if we need to implement styling in our Box.js file using styled components, we would first need to carry out the following steps:

  • First, we need to install styled-components library by running npm install styled-components --save.
  • We then need to import the styled component library into our component by writing import styled from 'styled-components';.
  • Now we can create a variable by selecting a particular HTML element where we store our style keys.
  • Then we use the name of our variable we created as a wrapper around our JSX elements.

The code below is an implementation of all the steps we mentioned above.

import React from 'react';
import styled from 'styled-components';

const Box = styled.div`
  margin: 40px;
  border: 5px black;
`;

const Content = styled.p`
  font-size: 16px;
  text-align: center;
`;

const Box = () => (
  <Box>
    <Content> Styling React Components </Content>
  </Box>
);

export default Box;

In the code above, we import the styled object from styled-components, which makes use of tagged template literals to style your component. We then create a variable that would hold our styling and also act as a wrapper around content, that’s why we have the and tags, in this variables, we assign it to the styled object plus the HTML element we want to style then followed by the accompanying styles for the HTML element. To use the variables we created for styling all we need to do is wrap our JSX or content in between them as tags.

Benefits Of Using styled-components

  1. Consistency
    styled-components make it easy for you to publish a React component to NPM. These components can be customised through props and/or extending via styled(Component) and no clashing with CSS selectors.
  2. Sass Syntax Out-Of-The-Box
    You can get SASS trademark syntax out of the box without having to install or setup SASS or any extra build tool.
  3. Dynamic Styling
    You can make use of props to dynamically change the styles in any way that feels natural to anyone comfortable with React.
  4. Theming
    Using React’s Context API, styled-components offers a ThemeContext that can you can pass a theme object directly to, making it very accessible in any of your components, and by default can be interpolated into your styled definitions.

Shortcomings Of Using styled-components

  1. Learning Curve
    Frontend developers that are already comfortable with writing traditional CSS will have to learn a different way of styling that is different from how traditional CSS is written.
  2. Integration with Legacy CSS can be painful.
    If you’re making use of a UI library like Material UI or even traditional CSS, integrating styled-components together with them can be confusing to locate and debug styles.
  3. Performance
    styled-components converts all of the style definitions in your React component into plain CSS at build time and the inject everything into the tags in the head of your index.html file. This affects performance in the sense that it is not only increasing the size of our HTML file which can have an impact on the load time, but there is also no way to chunk the output CSS either.

JSS

JSS is an authoring tool for CSS which allows you to use JavaScript to describe styles in a declarative, conflict-free and reusable way. It can compile in the browser, server-side or at build time in Node. JSS is a new styling strategy that hasn’t been adapted so much. It is framework agnostic and consists of multiple packages: the core, plugins, framework integrations and others.

JSS has third party API adapters that can be used to write JSS like styles but differently, these third party API adapters include:

  • Styled-JSS
    This is a styled-component API adapter.
  • Glamor-JSS
    Glamor flavored CSS with JSS under the hood.
  • Aphrodite-JSS
    Aphrodite like API.

React-JSS

React-JSS makes use of JSS with React using the new Hooks API. JSS and the default preset are already built into the library. According to the official React-JSS docs, the following are the benefits of using React-JSS instead of the core JSS library in your React components.

  • Dynamic Theming
    This allows context-based theme propagation and runtime updates.
  • Critical CSS Extraction
    The only CSS from rendered components gets extracted.
  • Lazy Evaluation
    Style Sheets are created when a component mounts and removed when it’s unmounted.
  • The static part of a Style Sheet will be shared between all elements.
  • Function values and rules are updated automatically with any data you pass to useStyles(data). You can pass props, state or anything from context for example.

The code below is an example of how React-JSS is used.

import React from 'react'
import {render} from 'react-dom'
import injectSheet, { ThemeProvider } from 'react-jss'
const styles = (theme) => ({
  wrapper: {
    padding: 40,
    background: theme.background,
    textAlign: 'center'
  },
  title: {
    font: {
      size: 40,
      weight: 900,
    },
    color: props => props.color
  },
  link: {
    color: theme.color,
    '&:hover': {
      opacity: 0.5
    }
  }
})
const Comp = ({ classes }) => (
  <div className={classes.wrapper}>
    <h1 className={classes.title}>Hello React-JSS!</h1>
    <a
      className={classes.link}
      href="http://cssinjs.org/react-jss"
      traget="_blank"
    >
      See docs
    </a>
  </div>
)
const StyledComp = injectSheet(styles)(Comp)
const theme = {
  background: '#aaa',
  color: '#24292e'
}
const App = () => (
  <ThemeProvider theme={theme}>
    <StyledComp color="red"/>
  </ThemeProvider>
)
render(<App />, document.getElementById("root"))

In the code above, which somewhat similar to using styled components, we import injectSheet and ThemeProvider from the react-jss library. The ThemeProvider is a High-Order component in React, which passes the theme object down the React tree by the use of context. It will contain the root theme of the component. While injectSheet is used for injecting the stylesheet we have created in this case styles into the main component.

const Comp = ({ classes }) => (
  <div className={classes.wrapper}>
    <h1 className={classes.title}>Hello React-JSS!</h1>
    <a
      className={classes.link}
      href="http://cssinjs.org/react-jss"
      traget="_blank"
    >
      See docs
    </a>
  </div>
)

The code above is the main React component that has not been injected with the styles object we have created, it contains the main code for our React component and it is going to be styled when we inject it with the styles object that we have created.

const StyledComp = injectSheet(styles)(Comp)

The line of code above is injecting the styles we have created into the component we created it for using the injectSheet() function.

const theme = {
  background: '#aaa',
  color: '#24292e'
}

The code above holds the theme object that would be passed to the HOC via context and it acts as the root theme of our component.

const App = () => (
  <ThemeProvider theme={theme}>
    <StyledComp color="red"/>
  </ThemeProvider>
)

In this portion of the code, what we are doing here is using the HOC, we are rendering our component that we have injected the styled sheet we created into .

At the end of rendering, this is what will be displayed on your bro.

Code Output.

Code Output. (Large preview)

Benefits Of JSS

  1. Local Scoping
    JSS supports local scoping, taking it to the next level by automating scoping, which leads to a high level of predictability.
  2. Encapsulation
    Encapsulation facilitates maintenance and eliminates errors, as you can modify all component-related code and style in the same place, without having to worry about unexpectedly changing other parts of the application.
  3. Reusability
    Components are reusable, so you only have to write them once, then you can run them everywhere while maintaining their styling too.
  4. Dynamic Styling
    You can make use of props to dynamically change the styles in any way that feels natural to anyone comfortable with React.

Shortcomings Of JSS

  1. Learning Curve
    Learning JSS can be very tricky especially frontend developers that are already used to writing traditional CSS.
  2. Extra Layer of Complexity
    Putting a CSS-in-JS library into use adds an extra layer to your React application, which can sometimes be unnecessary.
  3. Code Readability
    Custom or Automatically generated selectors can be very difficult to read especially when using your browser devtools to debug.

Conclusion

Each of these has its advantages and disadvantages, and it all depends on your personal/company preference and the complexity of your application. Also, whatever styling strategy you may decide to use, it is still basically CSS. You can write CSS like you’ve always done, but React and other libraries offer solutions that can also help with styling.

I hope you enjoyed working through this tutorial. You could always read more on Styling React Components from the references below. If you have any questions, leave a comment below and I’ll be happy to reply to each and every single one.

Resources

(ks, ra, yk, il)
Categories: Others Tags:

5 Reasons Why the Digital Platform Is an Entrepreneurs’ Best Bet to Staying Productive During COVID-19

May 14th, 2020 No comments

As the coronavirus outbreak continues to affect thousands of people and businesses in the world, there is no telling what will happen to the economy if the crisis continues. Due to this, many entrepreneurs are concerned of the negative impact it can have on their business.

With the government’s decree to close down non-essential businesses, more and more companies are seeing a decline in their sales.

With the future looking rather dismal, many are questioning what they can do to stay productive and profitable. Since it’s prohibited to come in close contact with another person as long as the “stay at home” order is in place, businesses can only do so much when it comes to marketing their services during this time. Because of this, more and more are turning to digital marketing in order to survive.

According to Forbes, digital marketing is an important factor that can help businesses get through the tough times the coronavirus has brought.

Though it was just a concept in the past, the idea of taking your marketing into the digital world has become a necessity for many companies, especially in light of what’s happening the world over.

Here are 10 additional reasons why you too should consider going digital:

1. It’s a Great Alternative to Print Media

It’s a well-known fact that until the threat of the pandemic ends, everyone is discouraged to go outside unless it’s necessary. With that in mind, it’s clear any marketing strategy that involves walking around to advertise your business or meet with investors is strictly prohibited.

Digital marketing, on the other hand, can provide you with a worthwhile alternative. The internet has become a very useful tool for business owners today because of the simple fact that it brings people together, no matter the distance.

In fact, compared to print media, digital marketing allows you to advertise your business within the four walls of your home. This means you can stay home without being concerned about contracting the disease and still be able to market your business to your target audience.

2. Cancelled Events and Business Conferences

Business-to-business companies often rely on trade shows and conferences to widen their customer base. Through these shows, they can let their audience know about their products and maybe even introduce a new one onto the market.

But with the implementation of the “stay at home” order, organizers are now being forced to cancel the events in order to ensure the safety of the participants and visitors.

Because of this, a good number of businesses are facing the loss of what could have been long-term relationships with customers and suppliers. However, despite the canceled events, business owners still have the opportunity to sell their products or services via digital marketing.

With the time spent at home, they can focus more on how to improve their reach, and compel their audience to avail of their product or services.

3. Social Media Use is Increasing during Lockdowns

Even with the strict “stay at home” rules, an entrepreneur should still remind their clients that they’re still active and ready to serve them. They can do this through their social media platforms.

Since folks have been advised to stay at home for their safety, more and more people are turning to social media to keep themselves entertained. According to the survey conducted by Statista, 43.1 percent of social media users have said that they would use Instagram during the entire duration of the “stay at home” order.

Armed with that information, business owners can change their marketing approach and use their efforts to build their digital presence. Not only will this make it be easier for them to reach their target audience, but it will also assure their clients that the business is still very much viable and active.

4. People Are More Likely to Buy Online During the Outbreak

With the strict social distancing rules implemented to avoid the spread of the virus, people are turning to e-commerce in order to avoid catching the disease. Since people still can’t access brick and mortar establishments freely, they’re more likely to order their necessities online.

For eCommerce companies, it’s important you set-up a communication system that still allows you to stay connected with your clients. As the disease continues to spread, it’s even more important to avoid human interaction.

Through active chat platforms, however, eCommerce businesses can still address their customer’s inquiries and needs around their products and services.

5. It Helps Entrepreneurs Stay Connected with Their Employees

With non-essential offices and businesses closed and employees advised to work from home during the pandemic, the digital platform has never proven to be more useful than it is now.

The improvement in technology has made it easier than ever before for people to communicate with each other. More importantly, during the home quarantine period, it’s one tool that can help businesses stay productive.

Even with people being advised to work from home, business owners can still stay in touch with their employees using online chat platforms. Apps like Zoom, Skype, Slack, and other productivity software are now being utilized by remote workers everywhere. Through these WFH tools, workers can still give their employers and supervisors updates regarding their tasks and responsibilities.

The Bottom Line

Just because you’re advised to work from home doesn’t mean you can’t get things done. As an entrepreneur, there’s nothing you want more than to see your business succeed. If you own a business, it’s important you are able to find ways to stay productive. It’s the only way you can keep your operation above water during the tough times.

Being at home can be challenging for many entrepreneurs but it does have its perks. For one, you can focus your efforts on improving your digital marketing strategies.

On top of that, it can also be an excellent opportunity to learn something new. Even during this challenging time, it’s important you look and see the bright side. For your business, it means getting a hold of the process of online marketing, and continue to establish your brand.


Photo by Carl Heyerdahl on Unsplash

Categories: Others Tags:

How Different Generations Interact With Your Business – [Infographic]

May 14th, 2020 No comments

Web design has always been a staple of effective digital communication. In a 2019 survey, 48% of people said a website’s design is their number one factor in determining the credibility of a business. And since good design highlights great content, the question is: what kind of content should we be emphasizing?

Online reviews are a particularly powerful source of content for any business, which is why we’ve delved into them here.

When customers review your business online, that content becomes a social proof for other potential customers considering your products. Good reviews can give you a massive leg up in terms of sales, but it’s important to remember that different age groups engage with reviews differently. We’ve created a visual guide to how different generations – from tech-savvy Gen Zers all the way up to traditional Boomers – interact with online reviews:

Infographic – WebsiteBuilderExpert

Categories: Others Tags:

Equal Width Columns in CSS Grid are Kinda Weird

May 13th, 2020 No comments

Everything is flexible these days. If you write grid-template-columns: 200px 200px 200px;, sure, you’d have equal-width columns, but that’s a rare day. What you usually mean is three columns of equal fluid width.

We’ve got fractional units for that, like grid-template-columns: 1fr 1fr fr;. That’s usually fine, but they aren’t very sturdy like pixels. A large bit of media (or something like a

, or long bit of text like a URL) can cause those columns to stretch and that's almost never what you want. I've called that a grid blowout. The big idea is that the minimum width of a 1fr column is auto, not 0. In other words,. those widened columns are just being as narrow as they know how to be!

To fix that, we can do like:

.el {
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr) minmax(0, 1fr);
}

..or we could shorten it:

.el {
  grid-template-columns: repeat(3, minmax(0, 1fr));
}

It's a little awkward, but OK. You only gotta learn it once. You might not even ever run into this if you're always setting max-width on your media and handling line breaks.

If you want to make your columns sturdy again without the minmax dance, you could use percentages rather than pixels and stay flexible. But what percentage do you use? 33.33%? That's fine as long as you don't have any gap — otherwise, the gap will add to the width and overflow the container. You could fake gaps by putting padding inside the columns, but that's a little janky and uneven.

This whole thing comes from a great tweet from Wes Bos:

? A visual guide to getting equal width columns in CSS Grid pic.twitter.com/PY4yYokY18

— Wes Bos (@wesbos) May 1, 2020

I know a ton of people run into this — based on the number of emails I get about the grid blowout article — so it's worth kinda internalizing why all this is the way it is. It probably should be easier but I don't have any particular suggestions on how it could be.

The post Equal Width Columns in CSS Grid are Kinda Weird appeared first on CSS-Tricks.

Categories: Designing, Others Tags:

Pseudo-elements in the Web Animations API

May 13th, 2020 No comments

To use the Web Animations API (e.g. el.animate()) you need a reference to a DOM element to target. So, how do you use it on pseudo-elements, which don’t really offer a direct reference? Dan Wilson covers a (newish?) part of the API itself:

const logo = document.getElementById('logo');

logo.animate({ opacity: [0, 1] }, {
  duration: 100,
  pseudoElement: '::after'
});

I noticed in Dan’s article that ::marker is supported. I was just playing with that recently while doing our List Style Recipes page. I figured I’d give it a spin by testing the WAAPI and @keyframes on both a ::marker and and ::after element:

CodePen Embed Fallback

At first, I confused myself because it seemed like the WAAPI wasn’t working on ::after, but Dan reminded me that when using a transform, the element can’t be display: inline. Instead, I made it inline-block and it worked fine. However, I did uncover that @keyframes don’t seem to work on ::marker elements in Firefox — hopefully they’ll fix that (and we get Chrome and Safari support for ::marker ASAP).

Direct Link to ArticlePermalink

The post Pseudo-elements in the Web Animations API appeared first on CSS-Tricks.

Categories: Designing, Others Tags:

7 Ways to Improve Productivity in the Workplace

May 13th, 2020 No comments

Most small businesses can’t afford to throw money at productivity problems. Besides, this doesn’t actually work. The best way to improve productivity is to develop and implement small, consistent improvements which make your employees and processes more efficient.

Improved productivity almost always results in increased profits for a business, especially if you don’t have to spend much to achieve it. It also improves morale and wellbeing amongst your workforce. If your employees feel empowered to be productive without being overworked, they will feel positive about their jobs and experience less stress. This is how you attract and retain great talent.

Workplace productivity is affected by a variety of factors. If your business is just starting to focus on productivity, you might want to start with the following strategies.

1. Reduce distractions

Many employers say that remote working, especially in the wake of an enormously stressful event like COVID-19, could result in a net loss in productivity. However, working in an office also comes with its own set of distractions. A typical office worker is interrupted every 11 minutes and takes an average of 25 minutes to refocus following an interruption.

Smartphones and social media are two of the biggest distractions. The average American looks at their phone more than 50 times a day. All of these interruptions, and the recovery periods needed to regain focus, add up to an enormous amount of wasted time. Consider requiring phones to be switched to silent or “do not disturb” mode during the workday, or asking employees to use them only for short periods.

Source: Giphy

Background noise is also hugely distracting. This is one reason why open plan offices contribute to reduced productivity. In addition, if you have people in customer-facing roles, they will have a hard time communicating with their customers in a noisy environment. Relocate your employees to a quieter area, require them to use earphones instead of phone speakers, or ask that off-topic chat be kept to a minimum outside of the break-room.

2. Equip your employees with the tools they need

You may have hired the best people around, but they won’t be able to do their jobs well if they don’t have the resources they need. There is nothing more frustrating than struggling to do your job on equipment which is outdated, under-powered, or just not up to the task.

This is particularly important when it comes to IT equipment. Substandard tech can mean hours of productive work lost to malfunctioning computers, lost files, and slow systems.

To enable your employees to do their jobs well, give them the best equipment you can afford. You’ll recover the larger initial investment in the form of higher productivity and quicker completion of deliverables.

3. Make improvements to your office

Issues with workplace conditions contribute to lowered productivity. A leaky ceiling, for example, is more than just an eyesore. It’s also a source of noise which, if left unfixed, can result in injuries.

Temperature is also important. Your employees should not be left shivering in the winter or sweating in the summer.

If your office is next to a busy street, consider installing sound-absorbing materials. This will help keep the noise at a manageable level and reduce noise-related distractions.

Adding office wall murals can also boost productivity. A chalkboard or whiteboard wall gives your employees a space for writing their thoughts, while an inspiring mantra will remind them why their work matters.

An unsafe or uncomfortable working environment could cost your organization thousands of dollars in workplace injury claims and lost productivity. It also exhibits a lack of concern for employee wellbeing, which reduces morale.

4. Reduce the need to send emails

Everyone hates sending an email and then having to follow up with the recipient to ask if they’ve received the message. Chasing up an email on the phone, by sending another email, through an instant messaging platform eats up valuable time. Using a tool made for email tracking that can automatically send reminder emails, is a big time saver.

If you want to reduce your organization’s dependence on emails, try switching to collaboration tools such as Google Suite, Office 365, or Slack. These don’t just make transferring files faster; they also let multiple people work on documents simultaneously, reducing back-and-forth and ending up with different versions of the same file.

5. Set realistic, achievable goals

Many managers struggle to monitor how their employees are performing. Part of this problem is not knowing how to set appropriate goals.

Source: Think Marketing Magazine

Adopting a framework such as SMART (which states that goals should be Specific, Measurable, Attainable, Realistic and Time-sensitive) or OKR (Objectives and Key Results) will help you and your employees agree on a common goal. This helps with productivity and accountability as everyone is aware of their goals.

Using the OKR framework is as simple as gathering your team in front of a whiteboard to share concise goals. Objectives should be short, memorable, and inspiring. Key results are specific and generally quantifiable, such as “reduce customer returns to just 5%” or “increase referral rate to 15%”.

Both objectives and key results tell you what you and your team want to achieve, not how you will achieve them. They give you something to aim for, and a framework around which to develop your policies.

6. Don’t hesitate to delegate

If you’re used to doing a task, delegating it might seem counter-intuitive. Surely it would be quicker to just do it yourself rather than teach someone else how? However, delegation serves two key purposes:

  • It lessens your workload in the long term. If you’re always trying to multitask, it might be because you’re doing tasks that another person could do just as well. Delegating these will free you up to do the more important things more effectively.
  • It improves employee morale. Trust is one of the most important currencies you can use in the workplace. Delegating tasks to another employee, especially one of your direct reports, is a sign that you trust them enough to do the job well. This makes people feel good and makes them want to do a great job!

The sooner you start delegating, the sooner you can see your organization’s productivity levels rise. Delegating is also a way to identify potential leaders within your team. If your delegation experiment doesn’t work at first, try offering further training or assigning tasks to someone else until you find the right person for the job.

7. Instill a culture of efficiency

Take a long, hard look at the way your business is operating. Never be afraid of the possibility that you might have to change the way you and your team work.

First, identify the activities that take the longest. Break these down into smaller pieces to see what’s slowing them down. Next, work with your employees to brainstorm other ways of doing things, such as removing unnecessary steps that don’t add any value.

This is also a good time to ask staff members to come up with lists of priorities. Most likely, there will be employees who will claim that all of their projects are urgent. There are three possibilities for this:

  • The current method of assigning tasks is not working.
  • Your team and/or clients need to recalibrate what constitutes “urgent”.
  • Your team might be compensating for flaws elsewhere in the organization.

Asking each of your team members to list their tasks and deadlines will ensure that priority jobs are done first and finished on time. In the meantime, while your team takes care of the tasks assigned to them, you can work with clients and other stakeholders to deal with the other issues listed above, if necessary.

Boosting your productivity is an ongoing process

Focusing on productivity should not stop when you have met your short-term goals. You must commit to continuously improving your processes and learning new skills if you want your business to stay ahead of the curve.

While many organizations implement productivity improvement measures from the top-down, involving employees in every phase of these initiatives is a better approach. This way they are more invested, can raise any concerns and will be better able to identify what is working – and what isn’t.

Improving workplace productivity also doesn’t happen overnight. Be patient! It takes time for a culture of continuous improvement to catch on. But once everyone has embraced this attitude, you’ll be seeing productivity levels rise consistently, and stay high.

Categories: Others Tags: