DEV Community

Cover image for Programmers HATE This: How I Made A Code Beautifier Without Any Fancy Libraries!
Kavya Sahai
Kavya Sahai

Posted on • Edited on • Originally published at web-dev-free.netlify.app

Programmers HATE This: How I Made A Code Beautifier Without Any Fancy Libraries!

Remember we're building a house. We'd need two main things: the structure (the HTML) and how it looks (the CSS), and some logic to handle stuff like what happens when you click buttons (the JavaScript). Today, the webpage we'll build does that for a simple "Code Beautifier" tool that formats code for you.

1. index.html - The Structure of the tool

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Code Beautifier</title>
    <link rel="stylesheet" href="style.css">
</head>
<body>
    <header>
          <a href="/blog/" style="text-decoration: none; color: inherit; transition: opacity 0.3s; opacity: 0.8; padding-right: 20px;">Learn HTML, CSS and JS for free</a>     
    </header>
     <div id="notification-container"></div>
    <div class="container">
        <h1> Code Beautifier</h1>
        <textarea id="code-input" placeholder="Paste your code here..."></textarea>
        <div class="button-container">
          <button id="beautify-btn">Beautify</button>
          <button id="minify-btn">Minify</button>
        </div>

        <div class="code-output-container">
            <pre><code id="code-output"></code></pre>
            <button class="copy-code-btn">Copy</button>
            <button class="download-code-btn">Download</button>
          </div>
      </div>

    <script src="script.js"></script>
</body>
</html>
Enter fullscreen mode Exit fullscreen mode
  • <!DOCTYPE html>: Remember from the previous post, this is like saying, "Hey browser, this is a webpage!" It's just a standard thing all webpages have.
  • <html lang="en">: This is the root of the webpage. lang="en" means the main language is English(United States).
  • <head>: This part contains information about the webpage that isn't shown directly to the user, but important for SEO, we'll talk about it later
    • <meta charset="UTF-8">: This tells the browser how to handle text characters. Don't worry too much about it for now;
    • <meta name="viewport" ...>: This helps the page look good on different devices (phones, tablets, computers).
    • <title>Code Beautifier</title>: This is the text that appears in the browser tab, like a title for your webpage. For example, when one goes to youtube.com, YouTube is the title of the homepage of site.
    • <link rel="stylesheet" href="style.css">: This is where we'll link the stylesheet which is going to be used to define how the webpage looks.
    • <body>: This is the visible part of the webpage. This is where all the content that you see comes from
    • <header>: This is like the top part of the page, often containing a title or logo, some also call it the hero section, sound fancy, doesn't it?
      • <a href="/blog/" ...>Learn HTML, CSS and JS for free</a>: This is a link that says "Learn HTML, CSS and JS for free". It takes you to the blog if you click on it, try clicking on it over here: Code Beautifier.
    • <div id="notification-container"></div>: A container where notification messages will appear, like "Code copied" or "Error".
    • <div class="container">: This is like a big box to hold the main content of the tool.
      • <h1> Code Beautifier</h1>: This is the main heading, a big title on the page.
      • <textarea id="code-input" ...></textarea>: This is a big text box where you paste your code. The placeholder text is what the user will see inside before you type.
      • <div class="button-container">: A container to hold our buttons so we can style them together.
        • <button id="beautify-btn">Beautify</button>: A button that the user will click to make their code look nicer, we'll handle the logic of it later.
        • <button id="minify-btn">Minify</button>: A button you click to remove unnecessary spaces and make your code smaller, i.e, it will reduce redundancy.
      • <div class="code-output-container">: This is like a container for the code to be displayed in.
        • <pre><code id="code-output"></code></pre>: This is where the processed code will show up. pre preserves spacing, and code makes it look like code.
        • <button class="copy-code-btn">Copy</button>: A button to copy the displayed code.
        • <button class="download-code-btn">Download</button>: A button to download the displayed code as a file.
    • <script src="script.js"></script>: This is how you link the JavaScript code to your HTML. This is where the logic of the tool comes from; always remember, html is a markup language and not a programming language.

So, in short, the index.html file sets up all the pieces (like a text box, a title, buttons, and a place to show the results) that make up the Code Beautifier webpage.

2. script.js - The Brains of the Tool

This file makes the page interactive. It's what happens when you click the buttons!

document.addEventListener('DOMContentLoaded', function() {
    const inputArea = document.getElementById('code-input');
    const outputArea = document.getElementById('code-output');
    const beautifyButton = document.getElementById('beautify-btn');
    const minifyButton = document.getElementById('minify-btn');
    const copyButtons = document.querySelectorAll('.copy-code-btn');
    const downloadButton = document.querySelector('.download-code-btn');
    const notificationContainer = document.getElementById('notification-container');

    beautifyButton.addEventListener('click', function() {
       try {
        const code = inputArea.value;
        const language = detectLanguage(code);
        let formattedCode;

        switch (language) {
            case 'html':
                formattedCode = beautifyHTML(code);
                 break;
            case 'css':
                 formattedCode = beautifyCSS(code);
                 break;
            case 'json':
                 formattedCode = beautifyJSON(code);
                 break;
            case 'python':
                 formattedCode = beautifyPython(code);
                 break;
            default: // javascript
                formattedCode = beautifyCode(code);
        }
        outputArea.textContent = formattedCode;
         } catch (error) {
          showNotification('Error during beautifying.', 'error');
        }
    });

    minifyButton.addEventListener('click', function(){
        try {
          const code = inputArea.value;
          const language = detectLanguage(code);
          let minifiedCode;

           switch(language) {
               case 'html':
                 minifiedCode = minifyHTML(code);
                 break;
                case 'css':
                  minifiedCode = minifyCSS(code);
                  break;
                case 'json':
                     minifiedCode = minifyJSON(code);
                     break;
                case 'python':
                   minifiedCode = minifyPython(code);
                     break;
                default: // javascript
                   minifiedCode = minifyCode(code);
           }
           outputArea.textContent = minifiedCode;
       } catch (error) {
            showNotification('Error during minifying.', 'error');
        }
    });

    copyButtons.forEach(button => {
        button.addEventListener('click', function(){
            const codeToCopy = this.previousElementSibling.querySelector('code').textContent;
            copyCode(codeToCopy);
        });
    });

    downloadButton.addEventListener('click', function() {
        try {
            const code = outputArea.textContent;
            const language = detectLanguage(inputArea.value);
            let fileExtension;
              switch(language){
                  case 'html':
                    fileExtension = 'html';
                    break;
                    case 'css':
                        fileExtension = 'css';
                        break;
                   case 'json':
                    fileExtension = 'json';
                    break;
                   case 'python':
                    fileExtension = 'py';
                    break;
                   default:
                    fileExtension = 'js';
            }

            downloadCode(code, `code.${fileExtension}`);
            showNotification('Code downloaded successfully!', 'success');
        } catch(error) {
             showNotification('Error during download.', 'error');
         }
    });

     function detectLanguage(code) {
        const trimmedCode = code.trimStart();

          if(trimmedCode.startsWith('<!DOCTYPE html>') || trimmedCode.startsWith('<html')) {
            return 'html';
          } else if(trimmedCode.startsWith('{') || trimmedCode.startsWith('[')){
              try {
                  JSON.parse(trimmedCode);
                  return 'json';
              } catch (e){

              }
          } else if(trimmedCode.startsWith('/*') || trimmedCode.startsWith('.') || trimmedCode.startsWith('#') || trimmedCode.startsWith('@') || trimmedCode.startsWith('body') || trimmedCode.startsWith('div')){
                return 'css';
          } else if(trimmedCode.startsWith('def ') || trimmedCode.startsWith('import ') || trimmedCode.startsWith('class ' ) || trimmedCode.startsWith('from ') || trimmedCode.startsWith('print(') || trimmedCode.startsWith('if ') || trimmedCode.startsWith('while ') || trimmedCode.startsWith('for ') || trimmedCode.startsWith('try ') || trimmedCode.startsWith('except ') || trimmedCode.startsWith('finally ') || trimmedCode.startsWith('with ') || trimmedCode.startsWith('return ') || trimmedCode.startsWith('raise ') || trimmedCode.startsWith('assert ') || trimmedCode.startsWith('break ') || trimmedCode.startsWith('continue ') || trimmedCode.startsWith('global ') || trimmedCode.startsWith('nonlocal ') || trimmedCode.startsWith('lambda ') || trimmedCode.startsWith('pass ') || trimmedCode.startsWith('del ') || trimmedCode.startsWith('yield ') || trimmedCode.startsWith('async ') || trimmedCode.startsWith('await ')){
                return 'python'
          }
          else if(trimmedCode.startsWith('function ') || trimmedCode.startsWith('const ') || trimmedCode.startsWith('let ') || trimmedCode.startsWith('var ') || trimmedCode.includes('=>') || trimmedCode.includes('function(')){
              return 'javascript';
          }
          return 'javascript';
    }

    function beautifyCode(code) {
        let lines = code.split('\n');
        let indentLevel = 0;
        let beautifiedLines = [];

        for (let line of lines) {
            line = line.trim();
            if (line.endsWith('{')) {
                beautifiedLines.push('  '.repeat(indentLevel) + line);
                indentLevel++;
            } else if (line.startsWith('}')) {
                indentLevel = Math.max(0, indentLevel - 1);
                beautifiedLines.push('  '.repeat(indentLevel) + line);
            } else {
                beautifiedLines.push('  '.repeat(indentLevel) + line);
            }
        }
        return beautifiedLines.join('\n');
    }

    function minifyCode(code) {
        return code.replace(/\s+/g, ' ').trim();
    }

     function beautifyHTML(code) {
        return code.replace(/></g, '>\n<').replace(/<(.*?)>/g, '<$1>\n').replace(/\n\s*\n/g, '\n').trim();
    }


    function minifyHTML(code) {
       return code.replace(/>\s+</g,'><').replace(/\s+/g, ' ').trim();
    }

     function beautifyCSS(code) {
       return code.replace(/\{/g, '{\n  ').replace(/\}/g, '\n}\n').replace(/;/g, ';\n  ').replace(/\n\s*\n/g, '\n').trim();
    }

    function minifyCSS(code) {
        return code.replace(/\s+/g, ' ').replace(/{\s+/g, '{').replace(/\s+}/g, '}').replace(/:\s+/g, ':').replace(/;\s+/g,';').trim();
    }
     function beautifyJSON(code) {
            try {
                const parsed = JSON.parse(code);
                return JSON.stringify(parsed, null, 2);
            } catch (e) {
                 return code;
            }
     }

    function minifyJSON(code) {
         return code.replace(/\s+/g, '').trim();
    }
  function beautifyPython(code) {
     return code.replace(/:\s*\n/g,':\n    ').replace(/(\n\s*)?(def|class|for|if|while|with|try|except|finally)\b/g, '\n$2')
            .replace(/\n\s*\n/g, '\n')
           .trim();
    }

  function minifyPython(code){
      return code.replace(/\s+/g, ' ').trim();
  }
    function copyCode(text) {
        navigator.clipboard.writeText(text)
            .then(() => {
                 showNotification('Code copied to clipboard!', 'success');
            })
            .catch(err => {
                 showNotification('Failed to copy code.', 'error');
                console.error('Failed to copy text: ', err);
            });
    }
    function downloadCode(code, filename) {
        const blob = new Blob([code], { type: 'text/plain' });
        const url = URL.createObjectURL(blob);
        const a = document.createElement('a');
        a.href = url;
        a.download = filename;
        document.body.appendChild(a);
        a.click();
        document.body.removeChild(a);
        URL.revokeObjectURL(url);
    }
    function showNotification(message, type = 'success') {
        const notification = document.createElement('div');
        notification.classList.add('notification', type);
        notification.textContent = message;
        notificationContainer.appendChild(notification);
        setTimeout(() => {
            notification.classList.add('show');
        }, 10);

        setTimeout(() => {
            notification.classList.remove('show');
            setTimeout(() => {
                notificationContainer.removeChild(notification);
            }, 300);
        }, 2000);
    }
});
Enter fullscreen mode Exit fullscreen mode
  • document.addEventListener('DOMContentLoaded', function() { ... });: This is like saying, "Hey JavaScript, wait until the entire page is loaded before you start doing anything." This is to ensure that, our code, doesn't randomly change the entire page :D
  • const inputArea = document.getElementById('code-input');: This is how JavaScript finds the text box where you (the user will) paste code. It gets the element with the id code-input that we defined in the HTML file. Similar lines grab the other HTML elements like the buttons and the area for the output.
  • beautifyButton.addEventListener('click', function() { ... });: This says, "When the 'Beautify' button is clicked, do this stuff inside the curly brackets {}"
    • const code = inputArea.value;: Get the code from the text box.
    • const language = detectLanguage(code);: It tries to figure out what type of code you've pasted (HTML, CSS, JavaScript, etc).
    • let formattedCode; switch (language) { ... }: Depending on the code type, it does different things to "beautify" it. There are several beautify functions for different code languages such as beautifyCode(code) for JavaScript, beautifyHTML(code) for HTML, beautifyCSS(code) for CSS, beautifyJSON(code) for JSON and beautifyPython(code) for Python
    • outputArea.textContent = formattedCode;: Put the formatted code in the output area.
    • try{ ... } catch(error) { ... }: This tries to run the beautify code and catches errors, showing an error message if something goes wrong.
  • minifyButton.addEventListener('click', function() { ... });: This works very similarly to beautify, but instead uses the minify functions such as minifyCode(code) for JavaScript, minifyHTML(code) for HTML, minifyCSS(code) for CSS, minifyJSON(code) for JSON and minifyPython(code) for Python. These remove extra spaces to make the code smaller.
  • copyButtons.forEach(button => { ... });: This makes each copy button work. When clicked, it copies the text displayed next to the button.
  • downloadButton.addEventListener('click', function() { ... });: When the "Download" button is clicked, this downloads the formatted code as a file.
  • function detectLanguage(code) { ... }: A function that tries to figure out what kind of code was pasted in, by looking for keywords in it.
  • function beautifyCode(code) { ... }, function minifyCode(code) { ... } etc These functions contain the specific logic to format, each type of code. For example the beautifyCode function will add indentation to Javascript code, and minifyCode will remove the unnecessary spaces.
  • function copyCode(text) { ... }: copies text to the clipboard using the browser's functionality
  • function downloadCode(code, filename) { ... }: creates a downloadable file in the browser, that the user can save
  • function showNotification(message, type = 'success') { ... }: Displays a little notification on the screen to tell you what's happening.

In summary, script.js makes the buttons work, grabs the code, formats it, and shows the results. It handles errors, copies, downloads, and gives you little feedback messages. It's the action part of your tool.

How They Work Together

  1. HTML builds the structure: You create the text box, the buttons, and the output area in index.html.
  2. CSS styles the look: The CSS file (style.css, not shown yet) makes the webpage look pretty.
  3. JavaScript adds interactivity: script.js makes the buttons work when you click them. It grabs the code you paste in, formats it, shows it to you, and enables you to copy or download it.

style.css: The Style Guide for the Webpage

CSS (Cascading Style Sheets) is like the stylist for your website. While HTML provides the structure (like the walls and rooms of a house), CSS is responsible for how everything looks: colors, fonts, sizes, layouts, and more.

Main CSS Concepts

  • Selectors: This is how you target specific elements in your HTML. Examples in this code include body, header, h1, textarea, .container and #notification-container.
  • Properties: These are the things you want to change about the selected element, such as color, font-size, background-color and padding.
  • Values: These are the specific settings for each property. For instance, a color property might have the value red or #ff0000 (which is also red).
  • Units: These are used for sizing like px (pixels), rem (relative to font-size), em (relative to parent font-size) and vh (viewport height).
  • Comments: Lines starting with /* and ending with */ are ignored by the browser, used for comments and organization.
  • The Box Model: This is a fundamental CSS concept. Imagine each HTML element as a box, the box has the content, any padding, border and margin that it may have.

Walking Through the CSS Code

/* ===================================================================== Variables and Global Styles ===================================================================== */
:root {
  --primary-color: #6c63ff;
  --primary-color-light: #857dff;
  --secondary-color: #56ccf2;
  --secondary-color-light: #72d4f5;
  --background-color: #f5f7fa;
  --text-color: #2c3e50;
  --text-color-light: #47596a;
  --card-background: #ffffff;
  --shadow-color: rgba(0, 0, 0, 0.1);
  --code-background: #f7f7f7;
  --border-color: #e0e0e0;
  --border-color-light: #e8e8e8;
  --gradient-start: #e1f5fe;
  --gradient-end: #e3f2fd;
  /* Typography */
  --base-font: "Roboto", sans-serif;
  --heading-font: "Montserrat", sans-serif;
  --code-font: "Fira Code", monospace;
  /* Spacing */
  --base-padding: 3rem;
  --small-padding: 2.2rem;
  --tiny-padding: 1.7rem;
  /* Transitions */
  --base-transition: 0.3s ease-in-out;
  --fast-transition: 0.2s ease-in-out;
  /* Shadows */
  --shadow-sm: 0 2px 4px var(--shadow-color);
  --shadow-md: 0 4px 8px var(--shadow-color);
  --shadow-lg: 0 8px 20px var(--shadow-color);
}
Enter fullscreen mode Exit fullscreen mode
  • :root { ... }: This selects the root of your document. Here you're defining CSS variables, reusable values that you can use in your styles.
    • --primary-color: #6c63ff;: Defines a primary color. The prefix -- makes it a CSS variable. This color will be used for the main elements of the page
    • --base-font: "Roboto", sans-serif;: Defines the base font to be used throughout the website. If "Roboto" isn't available, then the default sans-serif font will be used.
    • --base-padding: 3rem;: Defines the base spacing.
    • --shadow-sm: 0 2px 4px var(--shadow-color);: Defines a box-shadow style using the var(--shadow-color) CSS variable which was already defined

These variables allow you to change the colours, spacing and fonts of your website in one place, without having to update each specific style.

/* ===================================================================== Body Styles ===================================================================== */
body {
  font-family: var(--base-font);
  margin: 0;
  background: linear-gradient(45deg, var(--gradient-start), var(--gradient-end));
  background-size: 300% 300%;
  animation: gradientAnimation 15s ease infinite;
  display: flex;
  flex-direction: column;
  min-height: 100vh;
  color: var(--text-color);
  transition: background-color var(--base-transition);
    background-attachment: fixed;
    overflow-x: hidden;
}

@keyframes gradientAnimation {
  0% {
    background-position: 0% 50%;
  }
  50% {
    background-position: 100% 50%;
  }
  100% {
    background-position: 0% 50%;
  }
}
Enter fullscreen mode Exit fullscreen mode
  • body { ... }: Styles the <body> element, which contains the visible content of your page.

    • font-family: var(--base-font);: Sets the font to the base font defined above.
    • margin: 0;: Removes the default margin (space around the element).
    • background: linear-gradient(45deg, var(--gradient-start), var(--gradient-end));: Sets a gradient background.
    • background-size: 300% 300%;: Makes the gradient bigger than the element, for the animation to work.
    • animation: gradientAnimation 15s ease infinite;: Starts a CSS animation named gradientAnimation (defined below) that runs for 15 seconds, infinitely.
    • display: flex; flex-direction: column; min-height: 100vh;: uses a flexbox layout. flex-direction: column makes items align vertically and min-height: 100vh makes the body fill the entire viewport height.
    • background-attachment: fixed; Sets the background to be fixed, and not scroll.
    • overflow-x: hidden; Removes any horizontal scroll.
  • @keyframes gradientAnimation { ... }: Defines the gradient animation to change the gradient position.

/* ===================================================================== Header Styles ===================================================================== */
header {
  padding: 1rem var(--base-padding);
  background-color: rgba(255, 255, 255, 0.15);
  backdrop-filter: blur(5px);
  display: flex;
  justify-content: flex-start;
    border-bottom: 1px solid rgba(0, 0, 0, 0.1);
    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
  transition: background-color var(--base-transition), box-shadow var(--base-transition);
}

header a {
  color: inherit;
  text-decoration: none;
  transition: opacity var(--fast-transition);
  opacity: 0.8;
  font-weight: 500;
    display: inline-block;
    padding-right: 20px;
}

header a:hover {
  opacity: 1;
}
Enter fullscreen mode Exit fullscreen mode
  • header { ... }: Styles the <header> element
    • padding: 1rem var(--base-padding);: Sets vertical padding of 1rem, and the horizontal padding is defined using the base-padding CSS variable.
    • background-color: rgba(255, 255, 255, 0.15);: Sets a translucent white background.
    • backdrop-filter: blur(5px); This is used to make the background appear blurred.
    • display: flex; justify-content: flex-start; This uses a flexbox layout, and aligns elements to the start
    • transition: background-color var(--base-transition);: Sets a transition for the background colour change.
  • header a { ... }: Styles the links within the header.

    • color: inherit;: Makes the link color the same as the header's text color.
    • text-decoration: none;: Removes the default underline.
    • display: inline-block; This allows the element to have both block and inline properties
  • header a:hover { ... }: Styles the links when you hover over them.

/* ===================================================================== Container Styles ===================================================================== */
.container {
  background-color: var(--card-background);
  padding: var(--base-padding);
  border-radius: 15px;
  box-shadow: var(--shadow-md);
  width: 92%;
  max-width: 800px;
    transition: box-shadow var(--base-transition), transform var(--base-transition);
  margin: auto;
  margin-top: 3rem;
  margin-bottom: 3rem;
}

.container:hover {
  transform: translateY(-3px);
    box-shadow: var(--shadow-lg);
}
Enter fullscreen mode Exit fullscreen mode
  • .container { ... }: Styles the container. The . means it targets an element with class container.
    • background-color: var(--card-background);: Sets a white background using the CSS variable
    • border-radius: 15px;: Makes the corners rounded.
    • box-shadow: var(--shadow-md);: Applies a shadow using the medium shadow variable.
    • width: 92%; max-width: 800px; This makes sure the container fills the screen, but doesn't expand too far, and keeps it centered in the screen.
    • margin: auto; margin-top: 3rem; margin-bottom: 3rem; These centers the container horizontally on the page, and provides margin on the top and bottom.
  • .container:hover { ... }: Adds a slight animation and larger shadow when you hover over it.
/* ===================================================================== Heading Styles ===================================================================== */
h1 {
  font-family: var(--heading-font);
  text-align: center;
  margin-bottom: 2rem;
  color: var(--primary-color);
    text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.06);
  font-size: 2.6rem;
  font-variant-numeric: lining-nums proportional-nums;
    letter-spacing: -0.02rem;
  line-height: 1.2;
  transition: color var(--base-transition), text-shadow var(--base-transition);
}
Enter fullscreen mode Exit fullscreen mode
  • h1 { ... }: Styles the main heading (<h1> tag)
    • font-family: var(--heading-font);: Sets the font to a heading-specific font.
    • text-align: center;: Centers the text
    • color: var(--primary-color);: Sets the color to the primary colour defined above.
    • text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.06);: Adds a subtle text shadow.
    • font-variant-numeric: lining-nums proportional-nums; Makes numbers look more sophisticated.
/* ===================================================================== Textarea Styles ===================================================================== */
textarea {
  width: 100%;
  min-height: 220px;
  padding: 16px;
  border: 2px solid var(--border-color);
  border-radius: 10px;
  box-sizing: border-box;
  font-family: var(--code-font);
  white-space: pre-wrap;
    overflow-wrap: break-word;
  resize: vertical;
  outline: none;
  transition: border-color var(--base-transition), box-shadow var(--base-transition);
    line-height: 1.6;
    box-shadow: var(--shadow-sm);
}

textarea:focus {
  border-color: var(--primary-color);
  box-shadow: 0 0 5px rgba(var(--primary-color), 0.25);
}
Enter fullscreen mode Exit fullscreen mode
  • textarea { ... }: Styles the text box
    • width: 100%;: Makes it fill the container horizontally.
    • min-height: 220px;: Sets a minimum height.
    • border: 2px solid var(--border-color);: Sets a border.
    • font-family: var(--code-font);: Uses the code font family.
    • white-space: pre-wrap; overflow-wrap: break-word; These properties deal with how text wrapping is handled.
    • resize: vertical;: Allows vertical resizing only.
    • outline: none;: Removes the default blue outline when focused.
    • box-shadow: var(--shadow-sm);: Adds a shadow
  • textarea:focus { ... }: Changes the style when you click inside the text box, with a focus.
/* ===================================================================== Preformatted Code Styles ===================================================================== */
.code-output-container {
  position: relative;
}

pre {
  background-color: var(--code-background);
  padding: 18px;
  border-radius: 10px;
  overflow-x: auto;
    white-space: pre-wrap;
  line-height: 1.7;
  font-family: var(--code-font);
    font-size: 1rem;
    box-shadow: var(--shadow-sm);
    margin-bottom: 2em;
    transition: background-color var(--base-transition), box-shadow var(--base-transition);
}

pre code {
  display: block;
}
Enter fullscreen mode Exit fullscreen mode
  • .code-output-container { ... }: Styles the container for the formatted code.
  • position: relative; Positions the code container relatively so that the buttons are positioned absolutely within.
  • pre { ... }: Styles the code display.
    • background-color: var(--code-background);: Sets the background to the code background color defined in the CSS variables.
    • white-space: pre-wrap; Allows the code to wrap on new lines
  • pre code { ... }: Styles the code element within the <pre> tag.
    • display: block;: Makes the code take up the full width.
/* ===================================================================== Button Styles ===================================================================== */
.button-container {
  display: flex;
  justify-content: center;
  margin: 2.5em 0;
}

button {
  margin: 0 16px;
  padding: 14px 28px;
  color: white;
  border: none;
  border-radius: 8px;
  cursor: pointer;
  transition: all var(--base-transition);
  box-shadow: var(--shadow-md);
    font-size: 1.1rem;
    font-weight: 500;
    position: relative;
    overflow: hidden;
    background: transparent;
}
button#beautify-btn{
    background: linear-gradient(135deg, var(--primary-color), var(--secondary-color));
}
button#minify-btn {
    background: #ffffff;
    color: var(--text-color);
    border: 1px solid var(--border-color);
}
button::before {
    content: "";
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background: rgba(255, 255, 255, 0.15);
    transform: scaleX(0);
    transform-origin: left;
    transition: transform 0.3s ease;
}
button:hover::before {
    transform: scaleX(1);
}
button#minify-btn:hover{
    background:#f5f7fa;
}
button:hover {
  transform: translateY(-3px);
  box-shadow: var(--shadow-lg);
}

button:focus {
  outline: none;
    box-shadow: 0 0 0 3px rgba(var(--primary-color), 0.3);
}
Enter fullscreen mode Exit fullscreen mode
  • .button-container { ... }: Styles the container for the buttons.
    • display: flex; justify-content: center;: Aligns the buttons horizontally at the center of the container.
  • button { ... }: Styles all buttons
    • background: transparent; Makes the initial background transparent
    • position: relative; overflow: hidden; Makes the buttons relative and hides any overflow of the before pseudo element.
    • transition: all var(--base-transition); A transition for all properties that the button has, to make it smooth.
  • button#beautify-btn { ... }: Styles the "Beautify" button specifically using the id selector.
    • background: linear-gradient(135deg, var(--primary-color), var(--secondary-color)); Adds a gradient background
  • button#minify-btn { ... }: Styles the "Minify" button using the id selector.
  • button::before { ... }: Styles the hover effect of the buttons.
    • content: ""; Allows the addition of content to the pseudo element.
    • transform: scaleX(0); transform-origin: left; Starts the element at scale 0 from the left.
    • transition: transform 0.3s ease; Adds a transition for smooth appearance.
  • button:hover::before { ... }: expands the pseudo element to show the hover effect
  • button:hover { ... }: styles all buttons when they're hovered over.
  • button:focus { ... }: Styles the button when it's focused with your keyboard.
/* ===================================================================== Copy Code Button Styles ===================================================================== */
.copy-code-btn {
    position: absolute;
    top: 10px;
    right: 10px;
    padding: 8px 12px;
    background-color: rgba(255, 255, 255, 0.8);
    border: 1px solid var(--border-color);
    border-radius: 6px;
    cursor: pointer;
    font-size: 0.85rem;
    color: var(--text-color);
    transition: background-color var(--base-transition), transform var(--fast-transition), box-shadow var(--base-transition);
    box-shadow: var(--shadow-sm);
}

.copy-code-btn:hover {
    background-color: rgba(255, 255, 255, 1);
    transform: translateY(-2px);
    box-shadow: var(--shadow-md)
}

.copy-code-btn:focus {
    outline: none;
    box-shadow: 0 0 0 2px rgba(var(--primary-color), 0.3);
}
Enter fullscreen mode Exit fullscreen mode
  • .copy-code-btn { ... }: Styles the "Copy Code" button using the class selector.
    • position: absolute; top: 10px; right: 10px;: Positions the button at the top right corner of its parent.
  • .copy-code-btn:hover { ... }: Styles the "Copy Code" button on hover.
  • .copy-code-btn:focus { ... }: Styles the "Copy Code" button when focused.
/* ===================================================================== Download Code Button Styles ===================================================================== */
.download-code-btn {
    position: absolute;
    top: 45px;
    right: 10px;
    padding: 8px 12px;
    background-color: rgba(255, 255, 255, 0.8);
    border: 1px solid var(--border-color);
    border-radius: 6px;
    cursor: pointer;
    font-size: 0.85rem;
    color: var(--text-color);
    transition: background-color var(--base-transition), transform var(--fast-transition), box-shadow var(--base-transition);
    box-shadow: var(--shadow-sm);
}

.download-code-btn:hover {
    background-color: rgba(255, 255, 255, 1);
    transform: translateY(-2px);
    box-shadow: var(--shadow-md)
}

.download-code-btn:focus {
    outline: none;
    box-shadow: 0 0 0 2px rgba(var(--primary-color), 0.3);
}
Enter fullscreen mode Exit fullscreen mode
  • .download-code-btn { ... }: Styles the "Download Code" button. Works very similarly to the copy button with a different position.
/* ===================================================================== Notification Styles ===================================================================== */
#notification-container {
  position: fixed;
  top: 20px;
  left: 50%;
  transform: translateX(-50%);
    z-index: 1000;
  display: flex;
  flex-direction: column;
    align-items: center;
    pointer-events: none; /* Allows clicks to pass through */
}

.notification {
  background-color: #ffffff;
  color: var(--text-color);
  padding: 12px 20px;
  border-radius: 8px;
  box-shadow: var(--shadow-md);
  margin-bottom: 10px;
    opacity: 0;
    transition: opacity 0.3s ease, transform 0.3s ease;
    transform: translateY(-20px);
  pointer-events: auto;
}

.notification.show {
    opacity: 1;
    transform: translateY(0);
}

.notification.success {
  background-color: #e8f5e9;
  color: #388e3c;
  border: 1px solid #c8e6c9;
}

.notification.error {
  background-color: #ffebee;
  color: #d32f2f;
  border: 1px solid #ef9a9a;
}
Enter fullscreen mode Exit fullscreen mode
  • #notification-container { ... }: Styles the container for notifications.
    • position: fixed; top: 20px; left: 50%; transform: translateX(-50%);: Keeps the notification at the top of the page, centered horizontally.
  • .notification { ... }: Styles the basic notification message.
    • pointer-events: auto;: This is used to allow hover effects on notifications, which are by default disabled because of their parent container.
  • .notification.show { ... }: Styles the notification when it is to be shown to the user.
  • .notification.success { ... }: Styles successful notifications in green.
  • .notification.error { ... }: Styles error notifications in red.
/* ===================================================================== Responsive Adjustments ===================================================================== */
@media (max-width: 768px) {
  body {
    padding: 0;
  }
  header {
    padding: 1rem var(--small-padding);
  }
  .container {
    padding: var(--small-padding);
    width: 95%;
    margin-top: 2rem;
    margin-bottom: 2rem;
  }
  h1 {
    font-size: 2.2rem;
    margin-bottom: 1.8em;
  }
  textarea {
    font-size: 0.95rem;
    min-height: 200px;
  }
  pre {
    font-size: 0.95rem;
  }
  button {
    padding: 12px 24px;
    font-size: 1rem;
    margin: 0 10px;
  }
  .copy-code-btn {
    padding: 6px 10px;
    font-size: 0.8rem;
    top: 8px;
    right: 8px;
  }
  .download-code-btn {
    padding: 6px 10px;
    font-size: 0.8rem;
    top: 40px;
    right: 8px;
  }
  #notification-container {
    top: 10px;
  }
}

@media (max-width: 576px) {
  header {
    padding: 1rem var(--tiny-padding);
  }
  .container {
    padding: var(--tiny-padding);
    margin-top: 1.5rem;
    margin-bottom: 1.5rem;
  }
  h1 {
    font-size: 2rem;
    margin-bottom: 1.5em;
  }
  textarea {
    font-size: 0.9rem;
    min-height: 180px;
  }
  pre {
    font-size: 0.85rem;
  }
  button {
    padding: 10px 20px;
    font-size: 0.95rem;
    margin: 0 8px;
  }
  .copy-code-btn {
    padding: 5px 8px;
    font-size: 0.75rem;
    top: 6px;
    right: 6px;
  }
  .download-code-btn {
      padding: 5px 8px;
    font-size: 0.75rem;
    top: 38px;
    right: 6px;
  }
}
Enter fullscreen mode Exit fullscreen mode
  • @media (max-width: 768px) { ... }: This is a media query. The styles within are only applied when the browser window is 768 pixels wide or less (for smaller screens like tablets). This section adjusts things like font size and padding to make the layout work on smaller screens.
  • @media (max-width: 576px) { ... }: Styles for even smaller screens (like smartphones).

Stylistic Choices and Why They Are Made

  • CSS Variables: Using variables makes the code easier to maintain and update. If you want to change the primary color, you can do it in one place instead of hunting down all its instances.
  • Box Shadows & Transitions: Adds a modern touch and makes the interface feel more interactive and polished.
  • Clean Typography: Uses legible fonts that make the page readable and visually appealing.
  • Responsive Design: The @media queries make sure the tool looks good on different devices, which is essential for good user experience, and ofcourse good ol' SEO.
  • Clear Visual Hierarchy: The heading is distinct, the textarea is clearly labeled, and the buttons are easy to find and click.
  • Emphasis on Code Blocks: The pre-formatted code block is given a different background and font to distinguish it from the other elements.

In summary, this CSS file styles your Code Beautifier tool, giving it a modern, clean, and user-friendly appearance. It uses variables, transitions, and responsive design to make the tool effective and easy to use.

This is a lot to take in at once, but with practice and time, these concepts will become second nature to you!

Top comments (4)

Collapse
 
we_kese_a887363c59609aae7 profile image
We Kese

Finally the new post is out!! Yay!

Collapse
 
kavya-sahai-god profile image
Kavya Sahai

YES!!

Collapse
 
imhardik profile image
Hardik Gayner

Hats Off !!! Awesome project idea and unique to

Collapse
 
attendancekeeper13 profile image
roughandtough03@gmail.com

Outstanding!

Some comments may only be visible to logged-in visitors. Sign in to view all comments.