Create paper "cut" borders using HTML canvas or pseudo-elements

As a designer with a penchant for pain, I am striving to achieve an "art nouveau" aesthetic on paper for my NextJS project with MUI as the main design solution. Despite the abundance of CSS in the background, I am faced with the challenge of creating inner borders with "cut corners" that must have specific colors and sizes.

I want these borders to adapt to their parent's width and height for full responsiveness, as the Paper will eventually serve as a container for text, images, and more.

How can I create such borders?

My current code structure is straightforward:

<div className="mainWrapper">
   <div className="border1">
      // any text or content
   </div>
</div>
  • Initially, I experimented with the ::after pseudo-element and the clip-path property, but found it challenging to make it responsive while also supporting borders...

  • I then attempted to utilize the <canvas> element with useRef due to my SSR setup, but the outcomes fell short of my desired result...

Answer №1

You can achieve this effect using just a single after pseudo-element and linear gradients.

Below is the HTML code snippet:

<div class="box">Lorem Ipsum</div>

Feel free to test it out on this Codepen link:

https://codepen.io/UniqueCoder/pen/jPzKwA?editors=1100

Answer №2

If you're struggling with a complex shape, I have just the solution for you! Check out this online generator for custom corners that will make your life easier:

.box {
  width: 400px;
  aspect-ratio: 2;
  margin: 50px;
  position: relative;
}
.box:before {
  content: "";
  position: absolute;
  inset: 0;
  background: red;
  clip-path: polygon(0 50.00px,50.00px 0,calc(100% - 50.00px) 0,100% 50.00px,100% calc(100% - 50.00px),calc(100% - 50.00px) 100%,50.00px 100%,0 calc(100% - 50.00px),0 50.00px,3px  calc(50.00px + 1.24px),3px calc(100% - 50.00px - 1.24px),calc(50.00px + 1.24px) calc(100% - 3px),calc(100% - 50.00px - 1.24px) calc(100% - 3px),calc(100% - 3px) calc(100% - 50.00px - 1.24px),calc(100% - 3px) calc(50.00px + 1.24px),calc(100% - 50.00px - 1.24px) 3px,calc(50.00px + 1.24px) 3px,3px calc(50.00px + 1.24px));
}

.box:after {
  content: "";
  position: absolute;
  inset: 10px;
  border: 3px solid red;  
}
<div class="box"></div>

Answer №3

After much effort and complexity due to CSS, I believe I have discovered a method:

    const styles = {
        mainSurface: {
            width: "100%",
            backgroundColor: "blue"
        },
        bordersContainer: {
            backgroundColor: "blue!important",
            content: "''",
            position: "relative"
        },
        borderTL: {
            content: "''",
            position: "absolute",
            height: 32,
            width: 32,
            top: 16,
            left: 16,
            backgroundColor: "transparent",
            borderRight: "4px solid",
            borderColor: "red",
            transform: "rotate(45deg)"
        },
        borderBL: {
            content: "''",
            position: "absolute",
            height: 32,
            width: 32,
            bottom: 16,
            left: 16,
            backgroundColor: "transparent",
            borderTop: "4px solid",
            borderColor: "red",
            transform: "rotate(45deg)"
        },
        ...(remaining code remains the same)
    }

    return (
        <>
           <Box sx={styles.mainSurface}>
               <Box sx={styles.bordersContainer}>
                   <Box sx={styles.borderTL}></Box>
                   <Box sx={styles.borderTR}></Box>
                   <Box sx={styles.borderBL}></Box>
                   <Box sx={styles.borderBR}></Box>
                   <Box sx={styles.borderLeft}></Box>
                   <Box sx={styles.borderRight}></Box>
                   <Box sx={styles.borderTop}></Box>
                   <Box sx={styles.borderBottom}></Box>
                   <Box sx={styles.contentBox}>
                       {props.children}
                   </Box>
               </Box>
           </Box>
        </>
    )

This approach results in a clean and responsive design, as illustrated here:

https://i.sstatic.net/9RGIW.png

I am grateful for all attempted assistance! Hopefully, this solution proves helpful to others in the future.

I plan to further optimize and share this code at a later time...

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

What is the best way to center the input on the page?

Does anyone know how to align the <input type="text"> in the center? I'm trying to create a login form but having trouble with positioning the input element. ...

Dealing with the mystery of the Next.js Stripe webhook elusive function error

I've been working on setting up a Stripe webhook in my NextJS app to write data to Firebase Firestore, but for some reason, stripe.webhook.constructEvent is showing up as undefined even though everything seems to be properly configured. I'm usin ...

Encountering a issue when trying to render an image retrieved from an API in Next JS

I encountered an issue where I am unable to retrieve the image from the API. Strangely, it works fine with the img tag but throws an error when switching to the NextJS Image tag. import React, { useState, useEffect } from "react"; import ...

Is there a way to create a layout with a row containing two columns and another row with just one column using MUI Grid?

Is it possible to achieve the design displayed in the image using MUI components? I am facing an issue where I am unable to properly insert a third Button into the MUI grid with the same width as the other two buttons. Any suggestions on how to solve this ...

What steps should be taken to acquire the most recent CSS files for a theme?

We are facing an issue with implementing a versioning system for our CSS files. Currently, we append a build number to the CSS link programmatically (e.g. \themes\ssss\abc.css?1011) so that clients always receive the latest CSS files with ea ...

Best practices for retrieving information from the user interface

My journey with NextJS has been a learning experience as I navigate connecting the frontend to the backend. Initially, I attempted to create a Restful API for CRUD operations from the frontend, but encountered authentication issues that left me puzzled. A ...

Using Javascript to display an element when scrolling within a specific container and each item of an array reaches the top

I'm just starting out with JavaScript and I'm attempting to create a scrollable div that includes items from an array. As the user scrolls and each item reaches the top, I want a hidden element to be displayed. Here's what I have so far: ...

Is there a way to change the route in nextjs without causing a refresh?

As I navigate through routes such as: /welcome/article/article-slug-1 /welcome/article/article-slug-2 /welcome/article/article-slug-3 The dynamic element is the article-slug, which functions as a query parameter. The structure of my pages is as follows: ...

Resetting initial values with Velocity.js post-animation

After animating elements into view on a page, I want to defer further animation through CSS classes. However, Velocity keeps all animated properties in the style= tag, hindering CSS transitions. My solution involves resetting the CSS upon completion, but ...

Issue with CSS File not being recognized by React Component

After using the webpack create-react-app with npx, I encountered an issue with my component styling. Despite having a CSS file named header.css in the src directory alongside Header.js, my component does not seem to be styled correctly. Here is how my comp ...

Customizing form validation in React using Zod resolver for optional fields

I am currently working on creating a form using React-hook-form and zod resolver. My goal is to have all fields be optional, yet still required despite being marked as optional in the zod schema: const schema = z.object({ name: z.string().min(3).max(50 ...

Elements inside the Bootstrap 3 navbar are actually external

I am having trouble with the collapsible navbar, specifically the alignment of the right side. Here is the code snippet related to it: <div class="collapse navbar-collapse navHeaderCollapse"> <ul class="nav navbar-nav navbar-right"> ...

Improving efficiency of basic image carousel in Angular 8

In my Angular 8 app, I am developing a basic carousel without relying on external libraries like jQuery or NgB. Instead, I opted to use pure JS for the task. However, the code seems quite cumbersome and I believe there must be a more efficient way to achie ...

Does the padding and margin of an element alter when the position is set to relative?

By utilizing relative positioning, an element can be moved in relation to its original position in normal flow. - Citation from the book "HTML&CSS: design and build websites" by John Duckett If an element has a relative position property, it opens up ...

Struggling to float <aside> to the left of <article> for proper alignment?

tldr; I'm attempting to position the aside-section to the left of the article-section (similar to a sidebar/side column), but my "float" property doesn't seem to be working at all. Is there a way to achieve this without modifying the HTML code an ...

Proper HTML style linking with CSS

Describing the file structure within my project: app html index.html css style.css The problem arises when trying to link style.css as follows: <link rel="stylesheet" type="text/css" href="css/style.css"/> S ...

What is the best way to make a hyperlink in HTML open in the same page or window, without relying on the <iframe> tag or JavaScript?

I have two html files and one css file. My question is how to open the link monday.html on the same page or window in my content section. For example, when someone clicks on the Monday navigation button, I want the result to show up in the content section ...

How to Prevent Scrolling When Modal is in Use on Full Page JS

I am trying to achieve the functionality where when the modal is open, I want to prevent full-page scrolling in JavaScript. The issue arises when I open the modal and try to scroll, it ends up moving the content that's behind the modal, which is actua ...

Create a radial-gradient() that covers two separate elements

Seeking to create a spherical appearance for a circle made of two semi-circular divs using background: radial-gradient(). Any ideas on achieving this effect without combining the two semi-circle divs into one circular div? [The decision to use two semi-ci ...

Try utilizing an image to hold text content rather than a traditional div container

I am seeking help with displaying a brief image description at the bottom of an image. Currently, the display looks like this: https://www.bootply.com/render/Gwde8WHtot However, I would like the green background to align with the actual image rather than ...