Recreating the CodePen Gutenberg Embed Block for Sanity.io

Chris recently put out a neat CodePen Embed Block for the Gutenberg editor in WordPress. It allows you to embed a Pen just by dropping in its URL. From there, you get access to control the size, theme, and the default tabs that render on initial load. Super neat!

Having a live preview of the embedded Pen while writing is so handy!

But it got me thinking: How difficult would it be to recreate it with Sanity Studio’s Portable Text editor? (Spoiler: Not that difficult). Since I already knew how to do it, it took me under seven minutes from start to finish. This tutorial takes you through how to get up and running with a studio, and how to add the schemas and the custom preview component for a CodePen embed.

That felt so cool that I want to teach you how to do it as well. Let’s dive right into it.

Getting Sanity Studio up and running locally

First, you’ll need to install Sanity Studio locally on your machine. In this tutorial we will be using the blog studio that you can initiate from the command line, but you can also check out the different starters on sanity.io/create. You should be able to tag along with one of those too.

This tutorial assumes that you have a bit of knowledge of JavaScript. It will use a bit of React, but only a small part. You should have installed node and npm if you haven’t already.

Oh, and you’ll want the Sanity CLI, which you can snag with the command line:

npm install --global @sanity/cli

Once the installation is done, you can initiate a new Sanity Studio with a new project by running the command sanity init. It will let you log in with your Google or GitHub account (or make a new account with an email/password). Give your project a name and follow the instructions. When given the options for a project template, choose the blog one:

? Select project template Movie project (schema + sample data) E-commerce (schema + sample data)
❯ Blog (schema) Clean project with no predefined schemas

After completing the steps, change directory (cd) into the new project folder and open it in your favorite code editor. To start the developer server that will also hot reload your studio when you make changes, run sanity start. To stop this server, you press ctrl + C in most command line tools.

Adding the schemas for a CodePen embed

Schemas define which document types that are available in the Studio, and which input fields they have. These schemas are defined in JavaScript objects that you import into the schemas.js file, where they are exported as a function that the Studio translates into its UI. There’s a lot you can do with these schemas, but in this tutorial, we will keep it reasonably simple.

Start with adding a new file inside /yourproject/schemas called codepen.js. Then type in this code:

export default { name: "codepen", type: "object", title: "CodePen Embed", fields: [ { name: "url", type: "url", title: "CodePen URL" } ]
};

Then you can go to /yourproject/schemas/schema.js and add the following two lines of code to it:

import createSchema from "part:@sanity/base/schema-creator";
import schemaTypes from "all:part:@sanity/base/schema-type"; import blockContent from "./blockContent";
import category from "./category";
import post from "./post";
import author from "./author";
import codepen from "/codepen.js"; // <= first import the object export default createSchema({ name: "default", types: schemaTypes.concat([ post, author, category, blockContent, codepen // <= add it to the schema types array ])
});

So what did we just do? Well, we have now made this CodePen object available as a type in other schemas in the Studio. In other words, you can now add type: 'codepen' to get those fields anywhere else in the schema code where you add fields. Adding this type to the rich text field is also our next step. Hang on!

Adding the CodePen field to the rich text editor

Before diving into the code bit, let us take a step back and look at what is going on in terms of the data formats we operate with, and how WordPress and Sanity differ slightly.

While Gutenberg stores rich text as JSON in its runtime (which is great!), what developers end up dealing with is mostly this content as HTML and JSON objects inside of HTML comments.

Sanity stores and distributes rich text content as Portable Text, which developers then serializes in their frontends. That means that you get fine-grained control over how rich text content is rendered by letting you use custom components for your favorite framework, either it’s ReactVueSvelte, or .NETPHP, or even Markdown.

In other words, you store your content as structured data in Sanity’s backend, and then decide how you want to use the data inside your frontend components. But enough exposition, let’s get back to the code!

Open /schemas/blockContent.js and notice that it’s of the type array. Yes, rich text is an array of different types, where one of them has to be of the block type (in which text paragraphs are stored). So the simplest way of making rich text is the following schema definition:

export default { name: "body", type: "array", title: "Body", of: [ { type: "block" } ]
};

Now, blockContent.js has a bunch of more stuff. You can see styles, lists, marks, and so on. All defining which properties should be available for the author. In the top array, there are two types block and image. We are going to add the third one, codepen:

export default { title: "Block Content", name: "blockContent", type: "array", of: [ { type: "block" // ... }, { type: "image", options: { hotspot: true } }, { type: "codepen" } ]
};

Save the file, and that’s it! If you now run sanity start in your command line (assuming you haven’t already), and open the Studio on https://localhost:3333, you should be able to find your new field in the rich text editor under the “post” type:

Sanity Studio with a CodePen button in the Rich Text editor.

If you try out the new button, you’ll get a modal with the URL field that you defined in the previous section. Feel free to add the URL from a cool CodePen that you have found. We will use this one from the legendary Sara Drasner; it’s pretty cool.

CodePen Embed Fallback

Just showing the URL value in the editor isn’t especially inspiring, though. So let’s go ahead and add the actual CodePen embed so we can interact with it directly in the editor!

Adding the CodePen embed as a preview

Open /yourproject/schemas/codepen.js again. Now we are going to make a small React component for our preview. Start by importing React in the top, and the boilerplate for the React component that we will turn into the embed:

import React from "react"; const CodePenPreview = ({ value }) => { return <pre>{JSON.stringify(value, null, 2)}</pre>;
}; export default { name: "codepen", type: "object", title: "CodePen Embed", fields: [ { name: "url", type: "url", title: "CodePen URL" } ]
};

The JSON.stringify stuff is a temporary little way of outputting the incoming data in a readable manner. You could also use console.log(value), but who has time to open the developer console?

Now you must tell Sanity how to use this component for the preview. As well as which of the fields in the object it should select for the value in the preview component.

import React from "react"; const CodePenPreview = ({ value }) => { return <pre>{JSON.stringify(value, null, 2)}</pre>;
}; export default { name: "codepen", type: "object", title: "CodePen Embed", preview: { select: { url: "url" }, component: CodePenPreview }, fields: [ { name: "url", type: "url", title: "CodePen URL" } ]
};

The editor should look something like this after you saved your changes:

Cool! Now we want to take the url value and somehow integrate it with a CodePen embed. The easiest way to go about this is to fit the markup for CodePen’s iFrame embed, and fit into our preview component in React.

The original iFrame element will look like this:

<iframe height="265" style="width: 100%;" scrolling="no" title="React Animated Page Transitions" src="https://codepen.io/sdras/embed/gWWQgb?height=265&theme-id=dark&default-tab=js,result" frameborder="no" allowtransparency="true" allowfullscreen="true"> See the Pen <a href='https://codepen.io/sdras/pen/gWWQgb'>React Animated Page Transitions</a> by Sarah Drasner (<a href='https://codepen.io/sdras'>@sdras</a>) on <a href='https://codepen.io'>CodePen</a>.
</iframe>

If we paste this snippet into our preview component, it will almost work. In order to make it JSX-compatible you’ll have to some few changes to some of the HTML-attributes. Make sure that you change:

  • style="width: 100%;" to style={{width: "100%"}}
  • frameborder="no" to frameBorder="no"
  • allow-transparency="true" to allowTransparency
  • allow-fullscreen="true" to allowFullScreen

You can remove the content (links, etc.) inside of the iframe, because it isn’t particularly useful inside the studio. What we should end up with is something like this:

import React from "react";
import Codepen from "react-codepen-embed"; const CodePenPreview = ({ value }) => { return ( <iframe height="265" style={{ width: '100%' }} scrolling="no" title="React Animated Page Transitions" src="https://codepen.io/sdras/embed/gWWQgb?height=370&theme-id=dark&default-tab=js,result" frameBorder="no" allowTransparency allowFullScreen />);
}; // ...

When saved, we should be able to see the CodePen embed inside the rich text editor:

Notice that the iFrame has an embed URL with some parameters for how it should be displayed. Of course, we could’ve asked someone to dive into CodePen to obtain this URL, but it’s probably better for to use the regular one. We’ll take the effort to reassemble into what we need:

The last part is to take the URL from the field, and get the hash and user out of it.

We split the URL string on forward slashes into an array. Then we use array destructuring to assign the different array elements to a variable. Since we only need the user and the hash we leave the other positions empty. This method isn’t bulletproof, as it assumed a specific format for the URL, but it works for this example. Then we reassemble the embedUrl by using template literals.

import React from "react"; const CodePenPreview = ({ value }) => { const { url } = value; const splitURL = url.split("/"); // [ 'https:', '', 'codepen.io', 'sdras', 'pen', 'gWWQgb' ] const [, , , user, , hash] = splitURL; const embedUrl = `https://codepen.io/${user}/embed/${hash}?height=370&theme-id=dark&default-tab=result`; return ( <iframe height="370" style={{ width: '100%' }} scrolling="no" title="CodePen Embed" src={embedUrl} frameBorder="no" allowTransparency allowFullScreen /> );
};
// ...

Save the changes and voilá; we’re pretty much done with the custom CodePen block!

Taking it further

Now, you probably noticed that Chris had put more settings into his custom block. Nothing is stopping us from doing the same! If we look up the documentation for the React CodePen embed component that we installed, we’ll find a table of properties that it can take. We can add these as fields in the schema definition. For example, if we wanted to add the themeId, we could do it as follows:

import React from "react";
import Codepen from "react-codepen-embed"; const CodePenPreview = ({ value }) => { const { url, themeId = "dark" } = value; // <= add themeId here, default it to "dark" const splitURL = url.split("/"); // [ 'https:', '', 'codepen.io', 'sdras', 'pen', 'gWWQgb' ] const [, , , user, , hash] = splitURL; const embedUrl = `https://codepen.io/${user}/embed/${hash}?height=370&theme-id=${themeId}&default-tab=result`; // <= add themeId here return ( <iframe height="370" style={{ width: '100%' }} scrolling="no" title="CodePen Embed" src={embedUrl} frameBorder="no" allowTransparency allowFullScreen /> );
}; export default { name: "codepen", type: "object", title: "CodePen Embed", preview: { select: { url: "url", themeId: "themeId" // <= add themeId here }, component: CodePenPreview }, fields: [ { name: "url", type: "url", title: "CodePen URL" }, // Add the new field below { name: "themeId", type: "string", title: "Theme ID", description: 'You can use "light" and "dark" also.' } ]
};

Conclusion

We just looked at how schemas for Sanity Studio work, and learned how to make previews for custom components to boot! Hopefully, you now know enough to make pretty much any custom component with a preview using these same principles. If you do, I would love to know about it either on Twitter or in the comments.

The post Recreating the CodePen Gutenberg Embed Block for Sanity.io appeared first on CSS-Tricks.

Setting Up Tailwind CSS In A React Project

Setting Up Tailwind CSS In A React Project

Setting Up Tailwind CSS In A React Project

Blessing Krofegha

2020-02-24T11:00:00+00:00 2020-02-25T01:38:05+00:00

In the dispensation of CSS libraries and frameworks, a ton of awesome libraries have been built to simplify the work of a developer in the quest to create intuitive interfaces. However, quite a lot of them (Bootstrap, Foundation) impose design decisions that are difficult to undo; they come with predefined components, therefore, eliminating the need for dynamic customization. This is the reason why Tailwind CSS is considered to be a good choice for building 21st-century web interfaces.

With Tailwind CSS, you get to create the components that suit what you want or what you are working on. These components can be created by harnessing the power of the utility-first prowess of Tailwind CSS. If you are tired of making use of Bootstrap and its likes, you’ll find Tailwind CSS a good fit for working on beautiful interfaces as you implement the designs you need using the utility classes it provides.

In this tutorial, you will learn what Tailwind CSS is and how to work with it. In the end, you’ll have built a profile card that uses Tailwind CSS utility classes. After that, you can go on to build a portfolio website that showcases your skills and other things you have worked on.

Note: While we won’t be writing CSS in this tutorial, a good knowledge of CSS will come in handy as you work through what we will be covering.

Styling In Modern Web Apps

There are different ways of organizing styling in modern applications which often have complex interfaces and design patterns. Let’s walk through BEM, preprocessors, CSS-in-JS and even design systems to find out what works best for you. Learn more →

What Is Tailwind CSS?

Tailwind CSS is a utilitybased low-level CSS framework intended to ease building web applications with speed and less focus to writing custom CSS, without leaving the comfort zone of your HTML code, yet achieve awesome interfaces.

For example, you could style a button with just a few classes (instead of always having to declare a single big class separately from your HTML and writing a bunch of properties to make something):

<button class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded ml-4 mt-4"> Button
</button>

Other CSS frameworks (such as Bootstrap, Foundation, Bulma, and so on) present you with diverse predefined components (such as modals, buttons, alerts, cards). But with Tailwind CSS, you get to make your own, or you’re forced to make your own depending on your project model. Another way to put it, you actually own the components, and you get to harness your customization power on any component of your choice. This means that there is no more need to fight against the framework, and trying to figure out which classes need to be overridden in order to get results you initially aimed for.

Why Use Tailwind CSS?

Maybe you’re not quite ready to betray other frameworks yet, or you haven’t been convinced to embrace the goodies that come with Tailwind CSS. Allow me to give you a few reasons why you may want to consider Tailwind CSS.

No Naming Conventions

One of the most stressful parts of writing custom CSS is having to name classes. At every point, you’re pondering which class should be generic or specific. How do you organize them and ensure they’re cascaded? Tailwind CSS solves those problems seamlessly by providing utility-based classes that can be used all the time.

However, cases may arise where you need to name some classes. Sometimes this tends to happen when you need to extract certain components and use them later in your design (with the help of the @apply directives).

Cache Benefits

When writing custom CSS (or using any other traditional CSS framework), you always have to make changes to your CSS files when making changes in your designs. With Tailwind CSS, you need not worry a bit about that since you’re using the same classes over and over again within the markup. This means that you do not have to bust your CSS cache everytime in order to make small changes to your design.

When Not To Use Tailwind CSS

Are you saying I should always use Tailwind CSS for every project? Of course not! There are a few use cases where you may not want to use Tailwind CSS.

If You’re Working On A Small Projects

When you need to get started with a mini-project that has a very short deadline (especially something a few users would be using or only yourself), then Tailwind CSS is not the best option. In those cases, I’d recommend using Bootstrap, Foundation or any other framework instead. That’s because they come with predefined ready-to-use components (themes to get started with). With Tailwind CSS, you have to creatively create your own.

If You’re A CSS Beginner

Before diving into Tailwind CSS for any project, its advisable to know CSS. Beginners that desire to use Tailwind CSS for web-based projects should first master CSS to a certain degree. It provides utility classes that are linked to the underlying CSS, therefore, only those with a solid knowledge of CSS can easily build with it.

If You Dislike Adding A Lot Of Classes To Your Elements

When writing Tailwind CSS, you always have to write lots of classes, which makes your codebase (HTML) look busy and sometimes difficult to read. If you prefer keeping your code neat, you may want to consider writing custom CSS or use any other CSS framework (such as Bootstrap).

With these reasons, it’s about time to move over to the business of the day: let’s set up Tailwind CSS in a React project together!

Getting Started

To set up our project, we’ll scaffold a new React app using create-react-app. If you have already done this, skip this process, otherwise, run the command below:

npx create-react-app react-tailwindcss && cd react-tailwindcss

Next, we install a few development dependencies. You can use any of the options that work for you.

Using npm

npm install tailwindcss postcss-cli autoprefixer -D

Using Yarn

yarn add tailwindcss postcss-cli autoprefixer -D

We need to initialize Tailwind CSS by creating the default configurations. Type the command below in your terminal:

npx tailwind init tailwind.js --full

This command creates a tailwind.js in your project’s base directory; the file contains the configuration, such as our colors, themes, media queries, and so on. It’s a useful file that helps with predefined sets of properties which will aid the need to re-brand certain conventions or properties if the need arises.

How To Configure PostCSS?

The PostCSS documentation states that:

“PostCSS is a tool for transforming styles with JS plugins. These plugins can lint your CSS, support variables and mixins, transpile future CSS syntax, inline images, and more.”

Why Autoprefixer?

It’s necessary to install Autoprefixer alongside Tailwind CSS because Autoprefixer usually tracks caniuse.com to see which CSS properties need to be prefixed. Hence, Tailwind CSS does not provide any vendor prefixing. If you’re curious as a cat in regards to PostCSS navigate to their documentation.

Create a PostCSS configuration file in your base directory manually or using the command:

touch postcss.config.js

Add the following lines of code to your PostCSS file:

const tailwindcss = require('tailwindcss');
module.exports = { plugins: [ tailwindcss('./tailwind.js'), require('autoprefixer') ],
};

Because PostCSS is necessary to lint our CSS, hence this configuration.

Code Steps

  • We fetched the Tailwind CSS package and placed it in a variable.
  • We wrapped tailwind.js (our default base configuration) in our tailwindcss variable.
  • We fetched the autoprefixer package.

How To Inject Tailwind’s Components, Utilities And Base Styles To Your App

Inside your src folder create a folder, name it assets, this is where all your styles would be stored. In that folder, create a tailwind.css file and main.css file respectively. The tailwind.css file will be used by us to import Tailwind CSS styles, and for custom configurations and rules. The main.css will hold the styles that are generated as a result of what we have in the tailwind.css file.

Next, we need to import the base styles and configurations. We will do that in one of the CSS files we created above. Add the following to your tailwind.css file.

@tailwind base; @tailwind components; @tailwind utilities;

Note that we used the @tailwind directive to inject Tailwind’s base, components, and utilities styles into our CSS:

  • @tailwind base
    This injects Tailwind’s base styles, which is a combination of Normalize.css and some additional base styles.

    Note: If you’d like to get the complete references of all the styles applied by Preflight, see this stylesheet.

  • @tailwind components
    This injects any component (reusable styles like cards and form elements, etc.) classes registered by plugins based in our config file.
  • @tailwind utilities
    This injects all of Tailwind’s utility classes(including the default and your own utilities) they are generated based on our config file.

Tailwind CSS will swap these directives out at build time with all of its generated CSS. If you’re using postcss-import, use this instead:

@import "tailwindcss/base"; @import "tailwindcss/components"; @import "tailwindcss/utilities";

How To Configure Your App To Build Your CSS

Next, we need to configure our project to build our CSS styles each time we run either the npm start or yarn start command.

Open your package.json file and use the snippet below in place of the script part of your package.json file:

"scripts": { "start": "npm run watch:css && react-scripts start", "build": "npm run build:css && react-scripts build", "test": "react-scripts test", "eject": "react-scripts eject", "build:css": "postcss src/assets/tailwind.css -o src/assets/main.css", "watch:css": "postcss src/assets/tailwind.css -o src/assets/main.css" },

Importing Our CSS

We need to import our CSS file appropriately to ensure that it’s properly watched and built when we run yarn start or npm start.

Open your index.js file and make the following changes:

  1. Import our main.css file and delete import './index.css';.
    import './assets/main.css'
    

    Your *index.js* should look like this after the changes:

    import React from "react";
    import ReactDOM from "react-dom";
    import './assets/main.css';
    import App from "./App";
    ReactDOM.render(<App />, document.getElementById("root"));
    
  2. Head over to App.js and delete import logo from './logo.svg'; leaving only import React from 'react';. Also delete everything inside the App component. (Don’t worry if our App.js looks barren now — we’ll add some code as we proceed in this post.)

Let’s Build A Profile Card Project

Now that our setup works well, and everything looks good, let’s build a Profile Card. However, I’d like to show you what the state of our app before we begin.

React app
React app (Large preview)

To start your app, type this command npm start or yarn start.

Command Prompt - Starting our app
Command Prompt – Starting our app (Large preview)

You’d observe that our Tailwind CSS is building the necessary files needed in main.css.

Let’s get started in our project.
Here’s what our code (App.js) looks like without implementing Tailwind CSS classes.

import React from 'react';
function App() { return ( <div className=""> <img className="" src={require('./profile.jpg')} alt="Display" /> <div className=""> <div className=""> Blessing Krofegha </div> <p className=""> When i’m not coding i switch to netflix with biscuits and cold tea as my companion. <span></span>😜 </p> </div> <div className=""> <span className="">#Software Engineer</span> <span className="">#Writter</span> <span className="">#Public Speaker</span> </div> </div> );
}
export default App;

The outcome of the above code snippet is thus the following:

Our Project without Tailwind CSS
Our Project without Tailwind CSS (Large preview)

As you can see, all of the text has been aligned to the left by default. The image is pretty big because there is no styling. The App component has four main divs to which we’ll be adding classes to. This will then, of course, change the styling of the elements.

First div

import React from 'react';
function App() { return ( <div className="max-w-sm rounded overflow-hidden shadow-lg"> <img className="w-full" src={require('./profile.jpg')} alt="Display" /> <div className=""> <div className=""> Blessing Krofegha </div> <p className=""> When I’m not coding, I switch to Netflix with biscuits and cold tea as my companion. <span></span>😜 </p> </div> <div className=""> <span className="">#Software Engineer</span> <span className="">#Writter</span> <span className="">#Public Speaker</span> </div> </div> );
}
export default App;

Code Steps

We gave the div max-width with max-w-sm for small screens and have added border-radius using the rounded class. To prevent scrolling bars from showing up, we used overflow-hidden.

On the first div, we garnished our background with a shadow effect using box-shadow with the shadow-lg class. Using this means that we’d be having a box-shadow(shadow effect) of 0px from the top, 10px from the right, 15px from the bottom, and -3px from the left (with a faint black on the left axis).

On the right axis, we’ve got 0px from the top, 4px from right, 6px from the bottom and -2px from the bottom (with a lighter shade of black rgba(0,0,0, 0.05)).

Do you mean a simple class name such as max-w-sm rounded overflow-hidden shadow-lg is responsible for all of this awesomeness? Yes! That’s the awesomeness of Tailwind CSS!

Next, we gave img a width of 100% with w-full and an src attribute and, of course, an alt attribute.

Here’s how our new Profile card should look like:

The outcome of our first div
The outcome of our first div (Large preview)

Second div

Add this class px-6 py-4 to our second div:

import React from 'react';
function App() { return ( <div className="max-w-sm rounded overflow-hidden shadow-lg"> <img className="w-full" src={require('./profile.jpg')} alt="Display" /> <div className="px-6 py-4"> <div className=""> Blessing Krofegha </div> <p className=""> When i’m not coding i switch to netflix with biscuits and cold tea as my companion. <span></span>😜 </p> </div> <div className=""> <span className="">#Software Engineer</span> <span className="">#Writter</span> <span className="">#Public Speaker</span> </div> </div> );
}
export default App;

Code Steps

In our second div, we gave it a padding-right/left of 1rem representing px-6 in the x-axis and padding-top/bottom of 1.5rem which is py-4 in the y-axis.

The outcome of our second div
The outcome of our second div (Large preview)

Third div

Add the class font-bold text-purple-500 text-xl mb-2 to our second div:

import React from 'react';
function App() { return ( <div className="max-w-sm rounded overflow-hidden shadow-lg"> <img className="w-full" src={require('./profile.jpg')} alt="Display" /> <div className="px-6 py-4"> <div className="font-bold text-purple-500 text-xl mb-2"> Blessing Krofegha </div> <p className="text-gray-700 text-base"> When i’m not coding i switch to netflix with biscuits and cold tea as my companion. <span></span>😜 </p> </div> <div className=""> <span className="">#Software Engineer</span> <span className="">#Writter</span> <span className="">#Public Speaker</span> </div> </div> );
}
export default App;

Code Steps

We set the font-weight to a value of 700 with font-bold class. Next, we gave our div a light purple color using text-purple-500 and made our font-size extra small by using text-xl. We gave our div a margin-bottom of 0.5rem by using mb-2. We also added a paragraph and made its color a darker shade of gray using text-gray-700.

We added a light text color to our paragraph with text-gray-700 and a font size of 1em using text-base. Therefore, text-base is equal font-size: 1rem and text-gray-700 is equal color: #4a5568;

Let’s see what changes were made with our 3rd div:

The outcome from our third div
The outcome from our third div (Large preview)

Fourth div

import React from 'react';
function App() { return ( <div className="max-w-sm rounded overflow-hidden shadow-lg"> <img className="w-full" src={require('./profile.jpg')} alt="Display" /> <div className="px-6 py-4"> <div className="font-bold text-purple-500 text-xl mb-2"> Blessing Krofegha </div> <p className="text-gray-700 text-base"> When i’m not coding i switch to netflix with biscuits and cold tea as my companion. <span></span>😜 </p> </div> <div className="px-6 py-4"> <span className="inline-block bg-gray-200 rounded-full px-3 py-1 text-sm font-semibold text-gray-700 mr-2">#Software Engineer</span> <span className="inline-block bg-gray-200 rounded-full px-3 py-1 text-sm font-semibold text-gray-700 mr-2">#Writter</span> <span className="inline-block bg-gray-200 rounded-full px-3 py-1 text-sm font-semibold text-gray-700 mt-2 ml-20">#Public Speaker</span> </div> </div> );
}
export default App;

Code Steps

Like the previous div mentioned above, we added a padding-right/left of 1rem representing px-6 in the x-axis and padding-top/bottom of 1.5rem respectively representing py-4 in the y-axis.

Lastly, we added a few classes to our spans which include inline-block. What this does is sets the display of the span which means the element is treated like other inline elements but allows the use of block properties.

We added a background-color of gray using bg-gray-200 and created a border-radius of 9999px using the rounded-full class; px3 adds padding to the x-axis while py-1 adds padding in the y-axis. text-sm is added to make the font-size of the text small and text-gray-700 was used to add a dark shade of gray color to the text. We went on to add margin-right to the span element.

If you’ve been carefully following along, then you should have something similar:

Final outcome of our Profile Card
The final outcome of our Profile Card (Large preview)

Note: You can replace the image with an image of your choice (preferably yours) and also personalize the content any way you wish.

Conclusion

I hope you enjoyed this tutorial. Of course, you can take always take it a bit further by making this a little profile application that says much more about you beyond the little information we have above. For example, you could go on to share a list of skillsets that you have, or add a table to projects you have worked on and possibly a contact form. Let your creativity flow, and please do share your projects in the comments section below — I’d love to see what you come up with!

Smashing Editorial (ks, il)
Introducing 15 Best New Portfolios, February 2020

Each month we publish a roundup of the best new portfolios, launched in the previous four weeks, by freelancers, agencies, and other creative professionals.

This month’s edition is packed with color and animation. Almost every site in this list animates some part of its interface, and many are dependent on animation entirely. You’ll find tons of great interaction design, but the real trend in 2020 is that personality is making its way back into our sites.

Sarah Drasner

Sarah Drasner’s personal portfolio site is wonderful because it conveys the simple joy she feels in technology. It opens with large type stating, “I Make Things.” But hover over it and you’ll find that she also says, “I Break Things”. The coded flowers that burst open for the break animation are delightfully rebellious. The whole site is packed with personality.

Six N. Five

The interaction design, especially the light-dark transition on Six N. Five’s portfolio site is something to behold. Cursor to the left, or right, to switch from studio work to films. Scroll through some exceptional work, and hover over thumbnails to see a preview. What we really love is the simplest of touches: when you scroll past the bottom of a case study, it automatically returns you to the home screen.

Franc

We have two agencies called Franc/Frank this month. This time, it’s an animation studio with a uniquely engaging, linear style. Franc’s work includes cell animation, which appears to be increasingly rare these days. The contemporary edge is provided by the very 2020 color palette, with bold hues cutting into softer, ice-cream pastels.

Special Offer, Inc.

The portfolio for Special Offer, Inc. could be a prototype for the colorful brutalism trend that we’ve carried over from 2019. The red on orange typography is by most measures, a real no-no, but as a way of searing the site into your eyeballs it does an awesome job. The overwhelming amount of content is part of the confident attitude, a minimalist site just isn’t right for many agencies, and it’s great we have so many options in 2020.

Sandy Dauneau

Sandy Dauneau’s portfolio is centered around her beautifully emotive animation, with a slider that offers various projects to enjoy. It features some really expressive typography, but nothing here outshines her delicate, and expertly observed animation. Make sure you check out her showreel, which really convey’s the best of her current work.

David William Baum

It’s difficult for photographers to come up with new ways of presenting their work. There’s only so many ways you can present a grid of thumbnails. The portfolio of David William Baum does an excellent job of solving this, with a moving grid of photos that responds to your cursor, then a stack of images to scroll through when you click a set, which feels a lot like flicking through a collection of printed hand-held photos.

Frank

When we’re designing portfolios, it’s easy to get carried away with all kinds of different effects like liquid effects and hover states. Fancy effects help get you noticed by design agencies, but if you’re a design agency selling to business, what works is simplicity. Frank has done an amazing job of keeping its portfolio simple, not because simplicity like this is difficult, but because it’s brave.

Corey Haggard

Corey Haggard has taken more of a traditional single-pager approach to his portfolio. He’s hopped on the out-sized typography trend, and if you click on any of the thumbnails on his site you’ll be rewarded with a flag-style enlarge effect, but basically this is a no-nonsense portfolio that shows off some inspiring work, and is well-worth a few minutes browsing.

Victor Costa

Victor Work 20’ is the 2020 portfolio of Victor Costa, a Brazilian designer/developer based in Toronto. Scroll through and you’ll find some nice flag effects on the portfolio thumbnails. What we really like is the cool wavy line transitions as you scroll from one area of the site to the next — it’s an awesome way to section sites, without subjecting us to hard, horizontal lines.

Davide Baratta

Davide Baratta’s site is one of the new breed of portfolio sites that really only work well on touch screens. If you check it out on a tablet, or a large-screen mobile device, it’s awesome. The simple slide back and forth, with taps for further exploration, feels like a native experience. A lot of time and effort has gone into making this site feel effortless. There’s also some great lettering in there.

Pierre Mouchan

It’s all about generative art these days, and Pierre Mouchan’s site is no exception. With a nod towards out-sized typography, what really grabs your attention is the giant pulsing blob in the center of the screen; it’s enough to trouble Steve McQueen. Each blob on the site represents a project and you can click on each for more info. It even works surprisingly well on mobile.

A Color Bright

It’s all very well presenting beautiful animation if that’s your focus, but what if your focus is on user experience? A Color Bright is a Berlin-based design agency that provides UX/UI design, product development, brand growth, and other digital design. Its portfolio is all about the potential of the user, with a focus on the dynamics of the team you’ll be working with if you hire them.

The Mill

The Mill’s site is a visual overload of motion design, VR, animation, and video. It works as a collection precisely because the lack of hierarchy allows you to delve in on a whim. Each video thumbnail links through to a case study, and the quality of the clients (Nike, Jeep, HBO, Spotify…) means that wherever you click you’ll be rewarded with a high-profile project.

Oxana Bayra

Oxana Bayra’s portfolio opens with glitch-effect artwork that’s growing increasingly popular. Cursor over one of the crystalline objects — each of which features expertly coded artwork — and the glitch-effect grows stronger. Bayra’s won dozens of awards for her generative art and design work, and much of it is on display in her portfolio.

Kevin van der Wijst

Kevin van der Wijst is a digital designer based in Valencia, and you can feel the influence of that sunny Spanish city in his site. In recent decades Valencia has become known for some of the most extraordinary public architecture in the world, and the geometric shapes of van der Wijst’s portfolio echo the shapes of sunlight on buildings. If you cursor over it, you’ll see there’s a liquid mouse trail effect, as if the buildings were reflected in pooled water.

Source
p img {display:inline-block; margin-right:10px;}
.alignleft {float:left;}
p.showcase {clear:both;}
body#browserfriendly p, body#podcast p, div#emailbody p{margin:0;}

Popular Design News of the Week: February 17, 2020 – February 23, 2020

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.

Free Vector Images for Commercial Use for Web Designers

 

5 Things I Wish I’d Known as a Young Web Designer

 

CSS Color Extractor

 

See the Logos AI Generated for Apple, Google, and Uber

 

8 Best Free Font Resources for Designers

 

Google Design Resources

 

20 Company Website Designs to Inspire your Small Business

 

What’s Coming in WordPress 5.4 (Features and Screenshots)

 

AI Songwriter – These Lyrics do not Exist

 

Plastic Humans – Just Another Illustration Set

 

What Designers Can Learn from Etsy’s Minimalist Icons

 

10+ Best Online Code Editors

 

Website SEO: How to Optimize your Content for Google

 

Web Design Best Practices for your Next Website Project

 

How to Design User Onboarding: Tips and Practices

 

13 Best Sites for Downloading Illustrations

 

Neumorphism - the Zombie Trend

 

Tips for Web Designers Who are Looking to Raise Brand Awareness

 

Earth View – Get 1000 Beautiful Google Earth Landscape Photos Free

 

3 Types of Feedback to Ignore

 

Page Builders Might not Be a Good Idea

 

Behavioural Science is a Powerful Design Tool

 

Consistency is Key – How to Build a Figma Design System

 

What is an “Aha!” Moment and How to Find It?

 

The Biggest Mistakes I Made as a New UX Designer

 

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

Source
p img {display:inline-block; margin-right:10px;}
.alignleft {float:left;}
p.showcase {clear:both;}
body#browserfriendly p, body#podcast p, div#emailbody p{margin:0;}

Fixed Headers and Jump Links? The Solution is scroll-margin-top

The problem: you click a jump link like <a href="#header-3">Jump</a> which links to something like <h3 id="header-3">Header</h3>. That’s totally fine, until you have a position: fixed; header at the top of the page obscuring the header you’re trying to link to!

Fixed headers have a nasty habit of hiding the element you’re trying to link to.

There used to be all kinds of wild hacks to get around this problem. In fact, in the design of CSS-Tricks as I write, I was like, “Screw it, I’ll just have a big generous padding-top on my in-article headers because I don’t mind that look anyway.”

But there is actually a really straightforward way of handling this in CSS now.

h3 { scroll-margin-top: 5rem; /* whatever is a nice number that gets you past the header */
}

We have an Almanac article on it, which includes browser support, which is essentially everywhere. It’s often talked about in conjunction with scroll snapping, but I find this use case even more practical.

Here’s a simple demo:

CodePen Embed Fallback

In a related vein, that weird (but cool) “text fragments” link that Chrome shipped takes you to the middle of the page instead, which I think is nice.

The post Fixed Headers and Jump Links? The Solution is scroll-margin-top appeared first on CSS-Tricks.

Inspiring high school students with HTML and CSS

Here’s a heartwarming post from Stephanie Stimac on her experience teaching kids the very basics of web development:

[…] the response from that class of high school students delighted me and grounded me in a way I haven’t experienced before. What I view as a simple code was absolute magic to them. And for all of us who code, I think we forget it is magic. Computational magic but still magic. HTML and CSS are magic.

Publishing anything on the web is always going to be magic to some degree but sometimes it’s easy to forget on a day to day basis. We have to brush off the cobwebs! Shake our tailfeathers! And remind ourselves and everyone around us that the basics of web development are precious and fun and exciting still. Especially so we can help inspire the next generation of web designers and developers.

Direct Link to ArticlePermalink

The post Inspiring high school students with HTML and CSS appeared first on CSS-Tricks.

iOS 13 Design Guidelines, Templates, and Downloads

Erik Kennedy wrote up a bunch of design advice for designing for the iPhone. Like Apple’s Human Interface Guidelines, only illustrated and readable, says Erik.

This is mostly for native iOS apps kinda stuff, but it makes me wonder how much of this is expected when doing a mobile Progressive Web App. On one hand, this kind of stuff looks fun to try to build on the web, and it would be kinda cool to make your web app feel super native. On the other hand, doesn’t that make it extra awkward for Android and other non-iOS platforms?

A few other thoughts:

  • How much of this stuff do you get “for free” with SwiftUI?
  • As I understand it, when you build apps with Flutter / Material, the native apps that get built do some smart cross-platform stuff, mimicking how that platform does things.

Erik also does very in-depth design training with enrollment only opening once in a while, the next opens March 4th.

Direct Link to ArticlePermalink

The post iOS 13 Design Guidelines, Templates, and Downloads appeared first on CSS-Tricks.

3 Strategies to Follow When Your Site is Failing

Here are 3 strategies you should consider if your website is struggling. We’ll cover:

  • Web analytics and split testing
  • In-person testing
  • Simplifying your sales process

If possible, implement these strategies ahead of time before you run into any issues. I’m going to cover why these strategies are effective and what they are good at resolving.

1. Analytics and Split Testing

If you don’t know when or where your users are leaving, then you’re missing ou; this is extremely unhelpful if you are selling something.

Analytics will let you see the average amount of time spent per page, and which page your customers are exiting your website from.

If a user views your website and leaves after visiting your homepage without going any further, then you know exactly what to change. If they are spending an excessive amount of time navigating through simple parts of your sales process, then you know something may be wrong, and you should address it.

AB split testing…is particularly good at resolving weak points on your website where visitors are…changing their minds

Depending on which page of your website they are on, you may want them spending more or less time on it. An abnormally high amount of users abandoning their shopping cart might mean your checkout isn’t providing the user with a positive experience.

AB split testing refers to displaying different versions of the same page to different visitors. It is particularly good at resolving weak points on your website where visitors are leaving or changing their minds about going ahead with what you want them to (e.g. buying a product).

Let’s say we have 2000 page visitors, and 70% are leaving immediately from the landing page, and 600 are proceeding forward (30% click-through rate). Instead of presenting one landing page to all visitors, we display two landing pages and show one landing page to half the visitors, and the second landing page to the other half.

We make some changes to the original landing page and send some of the users to the new version and some to the original version. We do this to see if the new landing page will have a better click-through than the original, 30%.

A quick example for a skydiving company: Group A visitors see ‘Book’ in a smaller sized button, whereas Group B visitors see ‘Skydive NOW!’ in a larger sized button. If the ‘Skydive NOW!’ button improves the number of bookings the site receives, we could consider using Group B as the new control and further work on optimising the booking page, perhaps by creating a modification in which ‘Skydive NOW!’ has a different color scheme or is placed in a different position on the page.

This could be a minor re-design, such as changing the color of a button, to something more enticing, or a major re-design.

You can also display more than two versions of a page simultaneously, making multiple modifications, displaying three or more versions to different users. In this case, we would have the original version, A, and two or more modified pages B, C … so on. This can make split testing quicker by immediately testing multiple possibilities but it adds complexity to the process.

2. In-Person Testing

In-person, or remote testing, is a strategy in which you recruit a user to test your website by undertaking various tasks e.g., Buy a specific product and ship it to your home, or find some specific information on your website.

This should be done regularly during the web building process as by doing so when you launch your website, you might uncover major or recurring problems that could have been prevented. If you do it in early development stages, you can use the information from the test to plan before you start building things that don’t work!

If your website is already live and you overlooked testing beforehand, it’s not too late

If your website is already live and you overlooked testing beforehand, it’s not too late. You can still employ a handful of individuals to test it now.

In-person testing is typically done where you supervise an individual and instruct them to carry out certain tasks and take note of how they are navigating your website by seeing the way they browse the page and/or move their mouse. Ask them to think out loud. You should also ask them why they selected that option over another, what they liked about a particular feature, etc. 



If you already know which areas of your website need to be worked on, but you’re unsure of how to improve on it, you could ask your tester for specific insight.

I typically choose three users for testing, as it’s quick, easy, cheap, and manages to uncover lots of flaws I may have overlooked. Having more users testing the website can be beneficial, but typically most users end up pointing out the same weaknesses.

This is an effective strategy because having a handful of people test your website is like having someone read over your writing. You may not pick up on your own mistakes, but someone else will. It’s also important to note that the way (you), a web-designer browses the web is different from how the average person browses the web. You may have a perfect understanding of what is happening on your website because you created it. Still, someone who is using it for the first time won’t have the same knowledge and experience as you and will try to undertake tasks in the simplest, most intuitive way.

Remote testing is the same principle as in-person testing but executed remotely. This may save you the hassle of meeting up, but might mean that you need to use software (such as a camcorder) to monitor their browsing, along with voice or video calling, to discuss the process with them.

3. Simplifying Your Sales Process

Are you taking care of your customers and guiding them through their purchases?

What happens after your user lands on your website? Is there a good value proposition (product, service, or information that is appealing) compelling them to purchase?

Excellent, now you need to make sure the process is transparent and straightforward.

Be upfront about any extra fees or shipping costs. Let them know how long shipping may take. Customers want to feel like they can trust you.

Customers want to feel like they can trust you

Write out an FAQ (Frequently Asked Questions) addressing common concerns a potential customer may have. E.g., Let’s say I’m buying a dual SIM mobile (two sim cards, one mobile), I want to know which country the product is from, I want to know about the warranty, I may especially want to know details about the phone will store numbers from different cards.

Have an FAQ section addressing general sales questions and a product-specific FAQ. Along with that, address the product specifications and show high-quality photos or videos.

When the customer is satisfied with what they’ve selected, make the checkout process easy. Allow guest checkout if it’s a suitable option for your website. 

Show your customers you care about them and create reasons for them to want to share your website and products. Once you’ve made your sale, send them a follow-up email or little thank you. This will lead to more engagement and a repeat customer. Remember, selling a product isn’t the end goal. Making someone become a lifelong customer is, and you need to facilitate that.

 

Featured image via Unsplash.

Source
p img {display:inline-block; margin-right:10px;}
.alignleft {float:left;}
p.showcase {clear:both;}
body#browserfriendly p, body#podcast p, div#emailbody p{margin:0;}

How To Build A Simple Cryptocurrency Blockchain In Node.js

How To Build A Simple Cryptocurrency Blockchain In Node.js

How To Build A Simple Cryptocurrency Blockchain In Node.js

Alfrick Opidi

2020-02-21T10:30:00+00:00 2020-02-22T01:36:04+00:00

The unprecedented rise of cryptocurrencies, and their underpinning blockchain technology, have taken the world by storm — from the humble beginnings of being an academic concept over a decade ago to current increased adoption in various industries.

The blockchain technology is receiving a lot of attention because of its ability to enhance security in trustless environments, enforce decentralization, and make processes efficient.

Traditionally, Python has been the de facto programming language for blockchain development. However, with the proliferation of this amazing technology, the development options have also increased — and Node.js has not been left behind.

In this tutorial, I’m going to talk about how to build a simple cryptocurrency blockchain in Node.js. It’s not going to be too fancy, but just sufficient to assist you to understand how a blockchain works.

I’ll call this simple cryptocurrency smashingCoin.

If you are a JavaScript developer who wants to take a leap into the burgeoning field of cryptocurrency, this article will equip you with the necessary skills to get started. Or, if you’re curious about how things work in the world of cryptocurrencies, then this tutorial may help in answering some of your questions.

Recommended reading: Understanding Subresource Integrity by Drew McLellan

Prerequisites

To follow this tutorial successfully, you’ll need to have the following:

  • Node.js installed on your machine. You can download it from here;
  • A code editor, such as Visual Studio Code, Sublime Text, or any other.

Let’s get started…

What Is A Blockchain?

Blockchain is the technology that powers digital currencies, such as Bitcoin and Ethereum. It is an innovative distributed public ledger technology that maintains a continuously growing list of records, referred to as blocks, which are connected securely using cryptography.

The term blockchain has earned its name because of the manner it keeps transaction data, i.e. in blocks that are connected to each other to create a chain. The size of the blockchain grows with an increase in the number of transactions undertaken.

Any valid transaction data is logged into the blockchain network, which is governed by peer-to-peer rules that the participants stipulate. For example, this data could contain the “value” of the block such as in digital currencies, a record of transactions (such as when parties exchange goods and services), or entitlement privileges such as when the chain records ownership information.

Besides the transaction data, every block may contain its own cryptographic hash (a unique identifier or digital footprint), its own nonce value (an arbitrary random number used once in cryptographic computations), the hash of the previous block, and a timestamp of recent authenticated transactions.

Since every new block should point to the previous block, if a block is incorporated into the chain without containing the right hash of the last block, it could render the entire blockchain invalid. This immutability property is key to the security of blockchains.

Furthermore, various types of consensus protocols are often applied to maintain the authenticity of the blockchain. Consensus ensures that all participants agree to the network-validated transactions.

For example, a commonly used consensus protocol is proof of work, which aims to identify a number that finds a solution to a complicated mathematical problem after completing a certain amount of computing work.

The main idea of proof work is that any participant in the blockchain network should find this number difficult to identify but easily verifiable. Consequently, it discourages spamming and tampering with the structure of the blockchain.

In the case of most cryptocurrencies, adding a new block to the blockchain requires solving a complex mathematical equation, which increases in difficulty over time as the blockchain grows. Consequently, any person who proves that they’ve done work by solving this problem is compensated with a digital currency, in a process referred to as “mining”.

How To Create A Block

Now, after introducing the blockchain technology and how it works, let’s see how we can apply the concepts in creating a block. As earlier mentioned, blocks are what interlink to each other to form a blockchain.

To create the smashingCoin currency, I’ll use JavaScript classes, which were introduced in ES6.

Ready?

Let’s get our hands dirty…

Here is the code for the CryptoBlock class:

const SHA256 = require('crypto-js/sha256');
class CryptoBlock{ constructor(index, timestamp, data, precedingHash=" "){ this.index = index; this.timestamp = timestamp; this.data = data; this.precedingHash = precedingHash; this.hash = this.computeHash(); } computeHash(){ return SHA256(this.index + this.precedingHash + this.timestamp + JSON.stringify(this.data)).toString(); } }

As you can see in the code above, I created the CryptoBlock class and added the constructor() method to it — just like it’s done in any other JavaScript class. Then, to initialize its properties, I assigned the following parameters to the constructor method:

indexIt’s a unique number that tracks the position of every block in the entire blockchain.
timestampIt keeps a record of the time of occurrence of each completed transaction.
dataIt provides data about the completed transactions, such as the sender details, recipient’s details, and quantity transacted.
precedingHashIt points to the hash of the preceding block in the blockchain, something important in maintaining the blockchain’s integrity.

Furthermore, I used the computeHash method to calculate the hash of the block based on its properties, as given in the data above.

As you can see, I imported the crypto-js JavaScript library and used its crypto-js/sha256 module to calculate the hash of each block. Since the module returns a number object, I used the toString() method to convert it into a string.

To add the crypto-js library to your project, go the terminal and run the following command to install it using npm:

npm install --save crypto-js

After running the above command, the node modules directory, which contains the library and other essential files, will be added to your project’s folder.

How To Create A Blockchain

As earlier explained, the blockchain technology is based on the concept that all the blocks are chained to one another. So, let’s create a CryptoBlockchain class that will be responsible for handling the operations of the entire chain. This is where the rubber is going to meet the road.

The CryptoBlockchain class will maintain the operations of the blockchain using helper methods that accomplish different tasks, such as creating new blocks and adding them to the chain.

Here is the code for the CryptoBlockchain class:

class CryptoBlockchain{ constructor(){ this.blockchain = [this.startGenesisBlock()]; } startGenesisBlock(){ return new CryptoBlock(0, "01/01/2020", "Initial Block in the Chain", "0"); } obtainLatestBlock(){ return this.blockchain[this.blockchain.length - 1]; } addNewBlock(newBlock){ newBlock.precedingHash = this.obtainLatestBlock().hash; newBlock.hash = newBlock.computeHash(); this.blockchain.push(newBlock); }
}

Let me talk about the roles of each of the helper methods that constitute the CryptoBlockchain class.

1. Constructor Method

This method instantiates the blockchain. Inside the constructor, I created the blockchain property, which refers to an array of blocks. Notice that I passed to it the startGenesisBlock() method, which creates the initial block in the chain.

2. Creating The Genesis Block

In a blockchain, the genesis block refers to the first-ever block created on the network. Whenever a block is integrated with the rest of the chain, it should reference the preceding block.

Conversely, in the case of this initial block, it does not have any preceding block to point to. Therefore, a genesis block is usually hardcoded into the blockchain. This way, subsequent blocks can be created on it. It usually has an index of 0.

I used the startGenesisBlock() method to create the genesis block. Notice that I created it using the afore-created CryptoBlock class and passed the index, timestamp, data, and precedingHash parameters.

3. Obtaining The Latest Block

Getting the latest block in the blockchain assists in ensuring the hash of the current block points to the hash of the previous block — thus maintaining the chain’s integrity.

I used the obtainLatestBlock() method to retrieve it.

4. Adding New Blocks

I used the addNewBlock() method to add a new block to the chain. To accomplish this, I set the previous hash of the new block to be equal to the hash of the last block in the chain — thus ensuring the chain is tamper-proof.

Since the properties of the new block get changed with every new calculation, it’s important to calculate its cryptographic hash again. After updating its hash, the new block is pushed into the blockchain array.

In reality, adding a new block to a blockchain is not that easy because of the several checks that have been placed. Nonetheless, for this simple cryptocurrency, it’s enough to demonstrate how a blockchain actually works.

Testing The Blockchain

Now, let’s test our simple blockchain and see if it works.

Here is the code:

let smashingCoin = new CryptoBlockchain();
smashingCoin.addNewBlock(new CryptoBlock(1, "01/06/2020", {sender: "Iris Ljesnjanin", recipient: "Cosima Mielke", quantity: 50}));
smashingCoin.addNewBlock(new CryptoBlock(2, "01/07/2020", {sender: "Vitaly Friedman", recipient: "Ricardo Gimenes", quantity: 100}) );
console.log(JSON.stringify(smashingCoin, null, 4));

As you can see in the code above, I created a new instance of the CryptoBlockchain class and named it as smashingCoin. Then, I added two blocks into the blockchain using some arbitrary values. In the data parameter, I used an object and added sender details, recipient’s details, and quantity transacted.

If I run the code on the terminal, here is the output I get:

How a blockchain looks like under the hood
Testing to see if our blockchain works. (Large preview)

That’s what the smashingCoin looks like!
It’s an object that contains the blockchain property, which is an array containing all the blocks in the chain. As you can see in the image above, each block references the hash of the previous block. For example, the second block references the hash of the first block.
After testing and seeing that our blockchain works, let’s add some more functionalities to enhance the features of the smashingCoin.

How To Verify The Blockchain’s Integrity

As earlier mentioned, a key characteristic of a blockchain is that once a block has been added to the chain, it cannot be changed without invalidating the integrity of the rest of the chain.

Therefore, to verify the integrity of the blockchain, I’ll add a checkChainValidity() method to the CryptoBlockchain class.

Hashes are critical for ensuring the validity and security of a blockchain because any change in the contents of a block will result in the production of an entirely new hash, and invalidating the blockchain.

As such, the checkChainValidity() method will make use of if statements to verify whether the hash of every block has been tampered with. Starting from the first created block, it’ll loop over the entire blockchain and check for its validity. Note that since the genesis block was hardcoded, it’ll not be checked.

Also, the method will verify whether the hashes of each two consecutive blocks are pointing to one another. If the integrity of the blockchain has not been compromised, it returns true; otherwise, in case of any anomalies, it returns false.

Here is the code:

checkChainValidity(){ for(let i = 1; i < this.blockchain.length; i++){ const currentBlock = this.blockchain[i]; const precedingBlock= this.blockchain[i-1]; if(currentBlock.hash !== currentBlock.computeHash()){ return false; } if(currentBlock.precedingHash !== precedingBlock.hash) return false; } return true; }

How To Add Proof Of Work

As earlier mentioned, proof of work is the concept applied to increase the difficulty entailed in mining or adding new blocks to the blockchain.

In the case of smashingCoin, I’ll employ a simple algorithm that deters people from generating new blocks easily or spamming the blockchain.

So, in the CryptoBlock class, I’ll add another method called proofOfWork().Essentially, this simple algorithm identifies a number, passed as a difficulty property, such that the hash of every block contains leading zeros that correspond to this difficulty level.

Ensuring the hash of every block begins with the number of zeros as set in the difficulty level requires a lot of computing power. The higher the difficulty level, the more time it takes to mine new blocks.

Furthermore, I’ll add a random nonce value to every hashed block such that, when rehashing takes place, the difficulty level restrictions can still be met.

Here is the code:

proofOfWork(difficulty){ while(this.hash.substring(0, difficulty) !==Array(difficulty + 1).join("0")){ this.nonce++; this.hash = this.computeHash(); } }

And, here is the updated computeHash() method with the nonce variable included:

computeHash(){ return SHA256(this.index + this.precedingHash + this.timestamp + JSON.stringify(this.data)+this.nonce).toString(); }

Additionally, to implement the proof of work mechanism in the generation of new blocks, I’ll include it in the addNewBlock() method:

addNewBlock(newBlock){ newBlock.precedingHash = this.obtainLatestBlock().hash; //newBlock.hash = newBlock.computeHash(); newBlock.proofOfWork(this.difficulty); this.blockchain.push(newBlock); }

Wrapping Up

Here is the entire code for building the smashingCoin cryptocurrency using Node.js:

const SHA256 = require("crypto-js/sha256");
class CryptoBlock { constructor(index, timestamp, data, precedingHash = " ") { this.index = index; this.timestamp = timestamp; this.data = data; this.precedingHash = precedingHash; this.hash = this.computeHash(); this.nonce = 0; } computeHash() { return SHA256( this.index + this.precedingHash + this.timestamp + JSON.stringify(this.data) + this.nonce ).toString(); } proofOfWork(difficulty) { while ( this.hash.substring(0, difficulty) !== Array(difficulty + 1).join("0") ) { this.nonce++; this.hash = this.computeHash(); } }
} class CryptoBlockchain { constructor() { this.blockchain = [this.startGenesisBlock()]; this.difficulty = 4; } startGenesisBlock() { return new CryptoBlock(0, "01/01/2020", "Initial Block in the Chain", "0"); } obtainLatestBlock() { return this.blockchain[this.blockchain.length - 1]; } addNewBlock(newBlock) { newBlock.precedingHash = this.obtainLatestBlock().hash; //newBlock.hash = newBlock.computeHash(); newBlock.proofOfWork(this.difficulty); this.blockchain.push(newBlock); } checkChainValidity() { for (let i = 1; i < this.blockchain.length; i++) { const currentBlock = this.blockchain[i]; const precedingBlock = this.blockchain[i - 1]; if (currentBlock.hash !== currentBlock.computeHash()) { return false; } if (currentBlock.precedingHash !== precedingBlock.hash) return false; } return true; }
} let smashingCoin = new CryptoBlockchain(); console.log("smashingCoin mining in progress....");
smashingCoin.addNewBlock( new CryptoBlock(1, "01/06/2020", { sender: "Iris Ljesnjanin", recipient: "Cosima Mielke", quantity: 50 })
); smashingCoin.addNewBlock( new CryptoBlock(2, "01/07/2020", { sender: "Vitaly Friedman", recipient: "Ricardo Gimenes", quantity: 100 })
); console.log(JSON.stringify(smashingCoin, null, 4));

If I run the code on the terminal, here is the output I get:

Output of creating a simple cryptocurrency in Node.js
At last, our smashingCoin cryptocurrency! (Large preview)

As you can see on the image above, the hashes now start with four zeros, which correspond with the difficulty level set in the proof of work mechanism.

Conclusion

That’s it! That’s how you can build a simple cryptocurrency blockchain using Node.js.

Of course, the smashingCoin cryptocurrency is far from complete. In fact, if you release it without making more improvements, it is unlikely to meet the current market demands for a secure, reliable, and intuitive digital currency — making you the only one using it!

Nonetheless, I hope that this tutorial has equipped you with some basic skills to get your feet wet in the thrilling world of cryptos.

If you have any comments or questions, please post them below.

Further Resources

Smashing Editorial (dm, il)
Animate SVG Path Changes in CSS

Every once in a while I’m motivated to attempt to draw some shapes with <path>, the all-powerful drawing syntax of SVG. I only understand a fragment of what it all can do, but I know enough to be dangerous. All the straight-line syntax commands (like L) are pretty straightforward and I find the curved Q command fairly intuitive. Box yourself into a viewBox="0 0 100 100" and drawing simple stuff doesn’t seem so bad.

Here’s a classic example of mine that draws things with all the basic commands, but also animates them with CSS (Chromium browsers only):

CodePen Embed Fallback

Weird but true:

<svg viewBox="0 0 10 10"> <path d="M2,2 L8,8" />
</svg>
svg:hover path { transition: 0.2s; d: path("M8,2 L2,8");
}

The other day I had a situation where I needed a UI element that has a different icon depending on what state it’s in. It was kind of a “log” shape so the default was straight lines, kinda like a hamburger menu (only four lines so it read more like lines of text), then other various states.

  1. DEFAULT
  2. ACTIVE
  3. SUCCESS
  4. ERROR

First I wrote the most complicated state machine in the world:

const indicator = document.querySelector(".element"); let currentState = indicator.dataset.state; indicator.addEventListener("click", () => { let nextState = ""; if (currentState == "DEFAULT") { nextState = "ACTIVE"; } else if (currentState == "ACTIVE") { nextState = "SUCCESS"; } else if (currentState == "SUCCESS") { nextState = "ERROR"; } else { nextState = "DEFAULT"; } indicator.dataset.state = nextState; currentState = nextState;
});

That opened the door for styling states with data-attributes:

.element { &[data-state="DEFAULT"] { } &[data-state="ACTIVE"] { } &[data-state="SUCCESS"] { } &[data-state="ERROR"] { } }

So now if my element starts with the default state of four lines:

<div class="element" data-state="DEFAULT"> <svg viewBox="0 0 100 100" class="icon"> <path d="M0, 20 Q50, 20 100, 20"></path> <path d="M0, 40 Q50, 40 100, 40"></path> <path d="M0, 60 Q50, 60 100, 60"></path> <path d="M0, 80 Q50, 80 100, 80"></path> </svg>
</div>

…I can alter those paths in CSS for the rest of the states. For example, I can take those four straight lines and alter them in CSS.

Note the four “straight” lines conveniently have an unused curve point in them. Only paths that have the same number and type of points in them can be animated in CSS. Putting the curve point in there opens doors.

These four new paths actually draw something close to a circle!

.editor-indicator { &[data-state="ACTIVE"] { .icon { :nth-child(1) { d: path("M50, 0 Q95, 5 100,50"); } :nth-child(2) { d: path("M100, 50 Q95, 95 50,100"); } :nth-child(3) { d: path("M50,100 Q5, 95 0, 50"); } :nth-child(4) { d: path("M0, 50 Q5, 5 50, 0"); } } } }

For the other states, I drew a crude checkmark (for SUCCESS) and a crude exclamation point (for FAILURE).

Here’s a demo (again, Chromium), where you can click it to change the states:

CodePen Embed Fallback

I didn’t end up using the thing because neither Firefox nor Safari support the d: path(); thing in CSS. Not that it doesn’t animate them, it just doesn’t work period, so it was out for me. I just ended up swapping out the icons in the different states.

If you need cross-browser shape morphing, we have a whole article about that.

The post Animate SVG Path Changes in CSS appeared first on CSS-Tricks.

Privacy Settings
We use cookies to enhance your experience while using our website. If you are using our Services via a browser you can restrict, block or remove cookies through your web browser settings. We also use content and scripts from third parties that may use tracking technologies. You can selectively provide your consent below to allow such third party embeds. For complete information about the cookies we use, data we collect and how we process them, please check our Privacy Policy
Youtube
Consent to display content from Youtube
Vimeo
Consent to display content from Vimeo
Google Maps
Consent to display content from Google