Develop an Awesome Glassmorhism CSS generator - #vercelHashnode project

Develop an Awesome Glassmorhism CSS generator - #vercelHashnode project

ยท

18 min read

Hello Coders ๐Ÿ‘‹, Today, I would like to share an awesome, useful, efficient project that I built for hackathon powered by Vercel. I was in search of a product that is less in number but has a huge impact on the community. After a search, I decided to develop an awesome Glassmorphism CSS generator.

Today, I will show you the glassmorphism CSS generator I have built as well as how you can also develop your own glassmorphism CSS generator. I will be going through the complete build process and I hope I could do it in my best way.

Glassmorphism CSS generator

Live Demo
Github Code

Inspiration

Glassmorphism is one of the leading trend of 2021 and need keeps on rising. The absence of an efficient glassmorphism generator is a major cause for web developers not using glassmorphsim trend. (Execept the glassmorphism generator built by Hype4)

So, I decided to stop that problem as well as to educate my fellow coders how you could create a glassmorhism css generator with React.

Why Glassmorphism CSS generator

This Glassmorphism CSS generator built by me is super simple, powerful, easy to use, simple minimal UI design. It is well enough to be used on a daily basis. It auto-updates and saves a lot of time. The awesome features of Glassmorphism CSS generator we're gonna build -

  • Efficient to manage blur effect
  • Mange the transparency
  • Support the outline
  • Choose your own color for the background
  • Auto-updating the live preview
  • Simple, minimal UI

Live Demo: https://glassmorphism-css-generator.vercel.app
Github Code: https://github.com/divyaxavier/glassmorphism-css-generator

Tech stack

glassmorphism.gif We're gonna build this project in React. React is an open-source, front end, JavaScript library for building user interfaces or UI components. It is maintained by Facebook and a community of individual developers and companies.

  • React
  • HTML
  • CSS
  • Javascript

How I built it

I built the project completely on React and hosted it with Vercel. I used material-ui and react-color for the UI and functionality. The useState hook plays the main role here, It does the main job. It controls the slider movements and updates and generates code.

Challenges I ran into

I spend a lot of time discussing and designing the UI and UX. I needed it to be simple, yet good. I did want my app to be of good code - that means others could also read it. It was the first time I hosted a react app on Vercel, I was using vercel for most of my code, but I haven't used it for react. Vercel is wonderful, It hosted my app so fast and it updates the app on my every commit ASAP. I did got errors but somehow I managed to overcome them. Another thing that stricked me is that I should convert the hex code into RGBA to make the app work along with transparency. Thanks to StackOverflow for figuring me how.

Accomplishments that I'm proud of

This project falls under the category of devtools

I'm proud enough to be part of this hackathon and was able to create a very useful devtools. I learned a lot while doing this and I have made it happen.

What's next

I'm planning for a lot of features to this project and here are some of this which I will say sure.

  • Develop a chrome extension with generate glassmorphism css
  • More previews for glassmorphism in the website
  • Copy code button
  • Color popup
  • Feature of downloading the glassmorphism preview as SVG

License

The project is licensed under MIT

Contributing

Feel free to add an issue or a pull request because your words matter.

Development

So, it is time to get onto coding this project. I hope you have got a basic understanding of what we're gonna build.

Let's start Coding

As I have said earlier, we're gonna code this project in React. For creating a react app we should open the terminal and type the create-react-app command

npx create-react-app glassmorphism-css-generator

After opening the folder in your favorite code editor. And then remove unwanted files from the src folder. This is the file structure of our app.

root/
โ”œโ”€โ”€ public/
         โ”œโ”€โ”€ index.html
         โ”œโ”€โ”€ logo.png
         โ”œโ”€โ”€ maifest.json
         โ””โ”€โ”€ robots.txt
โ”œโ”€โ”€ src/
         โ”œโ”€โ”€ Box/
                โ”œโ”€โ”€ Box.css
                โ”œโ”€โ”€ Box.js
         โ”œโ”€โ”€ App.css
         โ”œโ”€โ”€ App.js
         โ”œโ”€โ”€ App.test.js
         โ”œโ”€โ”€ index.js
         โ”œโ”€โ”€ reportWebVitals.js
         โ””โ”€โ”€ setupTests.js
โ”œโ”€โ”€ LICENSE
โ”œโ”€โ”€ .eslintcache
โ”œโ”€โ”€ README.md
โ”œโ”€โ”€ package-lock.json 
โ””โ”€โ”€ package.json

Now, lets start our project by running npm start. Then you could see this output.

For this project we're gonna use 2 npm packages

  • @material-ui/core
  • react-color

Install both of them by,

npm i @material-ui/core react-color

After installing them, lets head over to App.js. First, we should import them on our project directory. We use material-ui for the checkbox and slider and react-color for the color box. After the import we should define our useState hooks and store the data. The handleChange function is just to change the checkbox from checked to unchecked and vice-versa. After this we should return or render our app, So here goes the complete code for App.js


import { Slider } from "@material-ui/core";
import { useState } from "react";
import "./App.css";
import Box from "./Box/Box";
import Checkbox from "@material-ui/core/Checkbox";
import { SketchPicker } from "react-color";

function App() {
  const [blur, setBlur] = useState(40);
  const [transparency, setTransparency] = useState(25);
  const [checked, setChecked] = useState(true);
  const [color, setColor] = useState("#ffffff");

  const handleChange = (event) => {
    setChecked(event.target.checked);
  };

  return (
    <div className="app">
      <div className="controls">
        <h2>Glass Morphism Generator</h2>

        <div className="control_input">
          <div className="control_top">
            <h4>Blur Value:</h4>
            <input type="text" value={blur / 10} />
          </div>
          <Slider
            min={0}
            max={200}
            value={blur}
            onChange={(e, blur) => setBlur(blur)}
          />
        </div>
        <div className="control_input">
          <div className="control_top">
            <h4>Transparency</h4>
            <input type="text" value={transparency / 100} />
          </div>
          <Slider
            min={0}
            max={100}
            value={transparency}
            onChange={(e, transparency) => setTransparency(transparency)}
          />
        </div>

        <div className="control_input checkInput">
          <div className="control_top">
            <h4>Outline:</h4>
            <Checkbox
              checked={checked}
              color="primary"
              onChange={handleChange}
              inputProps={{ "aria-label": "primary checkbox" }}
            />
          </div>
        </div>

        <div className="control_input">
          <SketchPicker
            color={color}
            onChangeComplete={(color) => setColor(color.hex)}
          />
        </div>
      </div>
      <Box
        blur={blur}
        transparency={transparency}
        checked={checked}
        color={color}
      />
    </div>
  );
}

export default App;

As you can see here at the bottom I have rendered a component called Box, box act as the preview part of our app. I have passed the attributes blur, transparency, checked and color so that it could be used at Box.js.

Now, lets jump onto App.css and write some css styles to make app look good.

@import url(https://fonts.googleapis.com/css?family=Raleway:100,200,300,regular,500,600,700,800,900,100italic,200italic,300italic,italic,500italic,600italic,700italic,800italic,900italic);
* {
  margin: 0;
  padding: 0;
  font-family: "Raleway", sans-serif;
}

.app {
  height: 100vh;
  width: 100%;
  background: #eaf7ff;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
}
.controls {
  height: 100%;
  width: 45%;
  padding: 70px;
  display: flex;
  justify-content: center;
  flex-direction: column;
}
.control_input {
  width: 100%;
}
.control_top {
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: space-between;
}
.control_top input {
  border: 2px solid #8acfff;
  font-size: 14px;
  color: #000;
  padding: 5px;
  width: 40px;
}
.checkInput {
  width: 15%;
  display: flex;
  justify-content: flex-end;
  align-items: center;
}
input:focus {
  outline: none;
}
h2 {
  font-size: 2.2em;
  margin-bottom: 20px;
}
@media (max-width: 600px) {
  .app {
    display: block;
    overflow-y: visible;
  }
  h1 {
    margin-bottom: 10px;
  }
  .controls {
    width: 100%;
    padding: 30px;
    overflow: hidden;
  }
  .control_input {
    width: 80%;
  }
}

These are just the CSS styles. It fully depends on you. You could create them in your way.

After adding CSS styles, let's start editing Box.js. First, I'm destructing the attributes passed from App.js. After that I have defined a function hexToRgb, this function changes the value we get from color attribute into RGBA. This is done to make the app work with transparency. Also I have created a if else argument to make the outline true when checkbox is checked and vice versa. After completing this, We should return our Box component.


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

const Box = ({ blur, transparency, checked, color }) => {
  const hexToRgb = (color) => {
    const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(color);
    return result
      ? {
          r: parseInt(result[1], 16),
          g: parseInt(result[2], 16),
          b: parseInt(result[3], 16),
        }
      : null;
  };
  const outline = "";
  if (checked) {
    outline = "border: 1px solid rgba( 255, 255, 255, 0.18 )";
    console.log(outline);
  } else {
    outline = "";
    console.log(outline);
  }
  return (
    <div className="box">
      <div
        className="box_preview"
        style={{
          background: `rgba( ${hexToRgb(color).r}, ${hexToRgb(color).g}, ${
            hexToRgb(color).b
          }, ${transparency / 100} )`,
          boxShadow: "0 8px 32px 0 rgba( 31, 38, 135, 0.37 )",
          backdropFilter: `blur( ${blur / 10}px )`,
          borderRadius: "10px",
          border: `${outline.slice(8)}`,
        }}
      >
        <textarea
          value={`background: rgba( ${hexToRgb(color).r}, ${
            hexToRgb(color).g
          }, ${hexToRgb(color).b}, ${
            transparency / 100
          } ), \nbox-shadow: rgb(31 38 135, 0.37 ) \nbackdrop-filter: blur(${
            blur / 10
          }px);\nborder-radius: 10px;\n${outline}`}
        ></textarea>
      </div>
    </div>
  );
};

export default Box;

Inside the Box component, I have created a div in which our glassmorphism effect occurs and updates. Inside the box div, There is a textarea, the generated glassmorphism CSS code comes as the value of the textarea.

So, to make our Box component better. Here goes the code for Box.css

.box {
  height: 100%;
  width: 55%;
  background-color: #00b7ff;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='540' height='450' viewBox='0 0 1080 900'%3E%3Cg fill-opacity='.1'%3E%3Cpolygon fill='%23444' points='90 150 0 300 180 300'/%3E%3Cpolygon points='90 150 180 0 0 0'/%3E%3Cpolygon fill='%23AAA' points='270 150 360 0 180 0'/%3E%3Cpolygon fill='%23DDD' points='450 150 360 300 540 300'/%3E%3Cpolygon fill='%23999' points='450 150 540 0 360 0'/%3E%3Cpolygon points='630 150 540 300 720 300'/%3E%3Cpolygon fill='%23DDD' points='630 150 720 0 540 0'/%3E%3Cpolygon fill='%23444' points='810 150 720 300 900 300'/%3E%3Cpolygon fill='%23FFF' points='810 150 900 0 720 0'/%3E%3Cpolygon fill='%23DDD' points='990 150 900 300 1080 300'/%3E%3Cpolygon fill='%23444' points='990 150 1080 0 900 0'/%3E%3Cpolygon fill='%23DDD' points='90 450 0 600 180 600'/%3E%3Cpolygon points='90 450 180 300 0 300'/%3E%3Cpolygon fill='%23666' points='270 450 180 600 360 600'/%3E%3Cpolygon fill='%23AAA' points='270 450 360 300 180 300'/%3E%3Cpolygon fill='%23DDD' points='450 450 360 600 540 600'/%3E%3Cpolygon fill='%23999' points='450 450 540 300 360 300'/%3E%3Cpolygon fill='%23999' points='630 450 540 600 720 600'/%3E%3Cpolygon fill='%23FFF' points='630 450 720 300 540 300'/%3E%3Cpolygon points='810 450 720 600 900 600'/%3E%3Cpolygon fill='%23DDD' points='810 450 900 300 720 300'/%3E%3Cpolygon fill='%23AAA' points='990 450 900 600 1080 600'/%3E%3Cpolygon fill='%23444' points='990 450 1080 300 900 300'/%3E%3Cpolygon fill='%23222' points='90 750 0 900 180 900'/%3E%3Cpolygon points='270 750 180 900 360 900'/%3E%3Cpolygon fill='%23DDD' points='270 750 360 600 180 600'/%3E%3Cpolygon points='450 750 540 600 360 600'/%3E%3Cpolygon points='630 750 540 900 720 900'/%3E%3Cpolygon fill='%23444' points='630 750 720 600 540 600'/%3E%3Cpolygon fill='%23AAA' points='810 750 720 900 900 900'/%3E%3Cpolygon fill='%23666' points='810 750 900 600 720 600'/%3E%3Cpolygon fill='%23999' points='990 750 900 900 1080 900'/%3E%3Cpolygon fill='%23999' points='180 0 90 150 270 150'/%3E%3Cpolygon fill='%23444' points='360 0 270 150 450 150'/%3E%3Cpolygon fill='%23FFF' points='540 0 450 150 630 150'/%3E%3Cpolygon points='900 0 810 150 990 150'/%3E%3Cpolygon fill='%23222' points='0 300 -90 450 90 450'/%3E%3Cpolygon fill='%23FFF' points='0 300 90 150 -90 150'/%3E%3Cpolygon fill='%23FFF' points='180 300 90 450 270 450'/%3E%3Cpolygon fill='%23666' points='180 300 270 150 90 150'/%3E%3Cpolygon fill='%23222' points='360 300 270 450 450 450'/%3E%3Cpolygon fill='%23FFF' points='360 300 450 150 270 150'/%3E%3Cpolygon fill='%23444' points='540 300 450 450 630 450'/%3E%3Cpolygon fill='%23222' points='540 300 630 150 450 150'/%3E%3Cpolygon fill='%23AAA' points='720 300 630 450 810 450'/%3E%3Cpolygon fill='%23666' points='720 300 810 150 630 150'/%3E%3Cpolygon fill='%23FFF' points='900 300 810 450 990 450'/%3E%3Cpolygon fill='%23999' points='900 300 990 150 810 150'/%3E%3Cpolygon points='0 600 -90 750 90 750'/%3E%3Cpolygon fill='%23666' points='0 600 90 450 -90 450'/%3E%3Cpolygon fill='%23AAA' points='180 600 90 750 270 750'/%3E%3Cpolygon fill='%23444' points='180 600 270 450 90 450'/%3E%3Cpolygon fill='%23444' points='360 600 270 750 450 750'/%3E%3Cpolygon fill='%23999' points='360 600 450 450 270 450'/%3E%3Cpolygon fill='%23666' points='540 600 630 450 450 450'/%3E%3Cpolygon fill='%23222' points='720 600 630 750 810 750'/%3E%3Cpolygon fill='%23FFF' points='900 600 810 750 990 750'/%3E%3Cpolygon fill='%23222' points='900 600 990 450 810 450'/%3E%3Cpolygon fill='%23DDD' points='0 900 90 750 -90 750'/%3E%3Cpolygon fill='%23444' points='180 900 270 750 90 750'/%3E%3Cpolygon fill='%23FFF' points='360 900 450 750 270 750'/%3E%3Cpolygon fill='%23AAA' points='540 900 630 750 450 750'/%3E%3Cpolygon fill='%23FFF' points='720 900 810 750 630 750'/%3E%3Cpolygon fill='%23222' points='900 900 990 750 810 750'/%3E%3Cpolygon fill='%23222' points='1080 300 990 450 1170 450'/%3E%3Cpolygon fill='%23FFF' points='1080 300 1170 150 990 150'/%3E%3Cpolygon points='1080 600 990 750 1170 750'/%3E%3Cpolygon fill='%23666' points='1080 600 1170 450 990 450'/%3E%3Cpolygon fill='%23DDD' points='1080 900 1170 750 990 750'/%3E%3C/g%3E%3C/svg%3E");
  background-size: cover;
  display: flex;
  align-items: center;
  justify-content: center;
}
.box_preview {
  height: 70%;
  width: 70%;
  border-radius: 20px;
  display: flex;
  align-items: center;
  justify-content: center;
}
.box textarea {
  resize: none;
  width: 70%;
  height: 29%;
  background: #fff;
  border-radius: 5px;
  border: 1.5px solid #8acfff;
  font-size: 14px;
  color: #000;
  padding: 10px;
  overflow: hidden;
  font-family: "Poppins", sans-serif;
}
.box textarea:focus {
  outline: none;
}
@media (max-width: 600px) {
  .box {
    width: 100%;
    height: 80%;
  }
  .box_preview {
    height: 70%;
    width: 80%;
  }
  .box textarea {
    width: 85%;
    height: 40%;
  }
}

I have also tried to make the app fully responsive, So you could see the code for that in the styles.

Yeah, that's it. It is working nicely and is fully responsive.

Now lit is time to check our app whether it is working perfectly. To check, just go to http://localhost:3000/.

screenshot.png

Take help from the Github repo if you get stuck.

Live Demo ๐Ÿš€
Github Code ๐Ÿ‘Š

Wrapping up

Yeah, thanks for being with me till the end. Thanks for reading. Give your feedback and comments. I'd love to read them. Don't forget to add your reactions. I hope you loved reading this post and were able to create your own glassmorphism CSS generator. I hope you enjoyed it and looking forward to your words.

Find me ๐ŸŒ

Thanks, Wish you a wonderful day!