What is the best method for performing shape subtraction in CSS?

Is there a way to create a frame with a border radius of '150px 30px 30px 30px', but have the top left corner flat instead? See the image for reference here.

I tried using a rotated rectangle in the ::before pseudo element to achieve the desired look, by subtracting it from the frame.

<Box sx={{
  position: 'relative',
  width: '360px',
  height: '506px',
  border: `3px solid ${palette.black[900]}`,
  borderRadius: '150px 30px 30px 30px',
  boxShadow: `10px 10px 0px ${palette.black[900]}`,
  '&::before': {
    content: '""',
    position: 'absolute',
    width: '100%',
    height: '100%',
    top: '100px',
    left: '-100px',
    maxHeight: '100px',
    maxWidth: '300px',
    transform: 'rotate(-45deg)',
    transformOrigin: '0 0',
    background: '#D9D9D9',
    border: `3px solid ${palette.black[900]}`,
    zIndex: 0,
    backgroundColor: 'transparent',
  },
}}/>

Answer №1

If you're looking to create a unique border shape, consider using a pseudo element.

  • Start by removing the border from the actual Box and add it to the pseudo element instead.
  • Give the stacking context a non-auto z-index value to position the pseudo element behind content while keeping it visible.
  • Eliminate the top-left border-radius as we will be crafting our chamfered edge.
<Box sx={{
  position: 'relative',
  zIndex: 0,
  width: '360px',
  height: '506px',
  borderRadius: '0 30px 30px 30px',
  boxShadow: `10px 10px 0px ${palette.black[900]}`,
}} />

To style the pseudo element:

  • Make it fill the parent element with position: absolute; inset: 0.
  • Ensure it sits behind all content by giving it a negative z-index.
  • Transfer the border properties to the pseudo element.
  • Inherit the parent's border-radius.
<Box sx={{
  …
  '&::before': {
    position: 'absolute',
    inset: 0,
    zIndex: -10,
    border: `3px solid ${palette.black[900]}`,
    borderRadius: 'inherit',
    content: '""',
  },
}} />

Next, let's add the clip-path for the chamfered edge:

<Box sx={{
  …
  '&::before': {
    …
    clipPath: 'polygon(100% 0, 100% 100%, 0 100%, 0 150px, 150px 0)',
  },
}} />

The issue arises when the border doesn't follow the clip-path. To work around this, use a background linear-gradient():

<Box sx={{
  …
  '&::before': {
    …
    background: 'linear-gradient(135deg, black 50%, transparent 50%) no-repeat top left / 149px 149px',
  },
}} />

Here's the complete example of how to achieve this effect:

const { Box } = MaterialUI;

const palette = { black: { '900': '#000' } };

function App() {
  return (
    <Box sx={{
      position: 'relative',
      zIndex: 0,
      width: '360px',
      height: '506px',
      borderRadius: '0 30px 30px 30px',
      boxShadow: `10px 10px 0px ${palette.black[900]}`,
      '&::before': {
        position: 'absolute',
        inset: 0,
        zIndex: -10,
        border: `3px solid ${palette.black[900]}`,
        borderRadius: 'inherit',
        content: '""',
        clipPath: 'polygon(100% 0, 100% 100%, 0 100%, 0 150px, 150px 0)',
        background: 'linear-gradient(135deg, black 50%, transparent 50%) no-repeat top left / 149px 149px',
      },
    }} />
  );
}


ReactDOM.createRoot(document.getElementById('app')).render(<App/>);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.2.0/umd/react.production.min.js" integrity="sha512-8Q6Y9XnTbOE+JNvjBQwJ2H8S+UV4uA6hiRykhdtIyDYZ2TprdNmWOUaKdGzOhyr4dCyk287OejbPvwl7lrfqrQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.2.0/umd/react-dom.production.min.js" integrity="sha512-MOCpqoRoisCTwJ8vQQiciZv0qcpROCidek3GTFS6KTk2+y7munJIlKCVkFCYY+p3ErYFXCjmFjnfTTRSC1OHWQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script src="https://unpkg.com/@mui/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="cca1adb8a9bea5ada08cbaf9e2fdf8e2fd">[email protected]</a>/umd/material-ui.production.min.js"></script>

<div id="app"></div>

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

Aligning an element vertically with the surrounding text on the same line

Trying to incorporate inline input range elements in a way that aligns with the line while also aligning with the right edge of the outer div has proven to be challenging. The HTML on the site is formatted using prettify, resulting in <span> elements ...

Result box not displaying the expected JQuery UI Autocomplete results

Can someone assist me with Autocomplete? When I search for an RTO code, the result box appears but without a list (refer to Screen : 1). However, when I press the down arrow button on the keyboard, the list starts appearing one by one (as shown in Screen : ...

What other option is there instead of using a span tag?

Take a look at this illustration. <span id="s1">Goodbye</span> <span id="s2">cruel</span> <span id="s3">world</span> <span id="s4">this</span> <span id="s5">is</span> <span id="s6">a</sp ...

Is there a way to create a responsive navbar using flexbox that automatically transitions into two rows at smaller screen sizes?

I've designed a sleek navbar located at the bottom of my webpage featuring a central logo leading to the home page, with two links on each side directing users to specific pages. Using @media CSS, I made it responsive by reducing its size as the scree ...

Enhancing the Search Form Minimum Width in Bootstrap 4 Navbar

Looking for a way to create a search form with a width of 100% and a minimum width within a Bootstrap 4 navbar? Check out my code snippet here. <nav class="navbar navbar-expand-md navbar-light bg-faded"> <a href="/" class="navbar-brand">Brand& ...

achieving outcomes beyond iframe boundaries

I currently have an IFRAME that is responsible for loading my login page. Here is the code: <iframe src="loginForm.html"></iframe> Once the form in the IFRAME is submitted, I am looking for a way to retrieve and display the results on the p ...

The mysterious result of the <em> tag in a WordPress theme

My new WordPress theme is unexpectedly outputting an <em> tag, even though I haven't used any <em> tags in my theme. This is causing issues and affecting the design. Below is the content of my index.php file: <?php get_header(); ?> ...

Imitate adjustment of orientation without the need to resize the browser window

Is there a way to simulate page portrait orientation on a PC browser without resizing the window? In my HTML code, I have a <div> element that displays content dynamically based on screen orientation. Is it possible to use JavaScript to trick this & ...

Efficiently styling table Spans with styled components in React

Can anyone help me with a frustrating CSS problem I'm facing? I am trying to render these tags as spans, but they are not separating properly as shown in the image below. They appear stuck together and I can't figure out why. I am using styled co ...

Is it possible for Bootstrap to hide a grid column on extra small screens by setting its column width to zero?

Is there a specific Bootstrap class that allows me to hide a grid column for certain screen sizes without using media queries and the "display:none" style? ...

Angular Material List Component with Material Table

In this code snippet, everything seems to be functioning perfectly. When you click on the magnifying glass icon, some additional information is displayed: <mat-card *ngIf="(bills && bills.length > 0) && all" style="overflow-x: auto;" ...

I seem to be having trouble with this JavaScript code. Could it be a syntax error, or is it possibly another issue causing it

I am encountering an issue with this code, as it is not functioning as intended. Although, I am unsure about the root of the problem. Code: <body> var randNumForQuote = Math.floor((Math.random() * 11)); if (randNumForQuote == 0) { docum ...

What is the best way to evenly distribute input elements horizontally within the parent container?

I am working on a layout with five select inputs that I want to arrange horizontally within the parent div. However, the current code setup is not achieving the desired layout: <div id="divtable"> <select class="abc"></select> ...

How to center text both horizontally and vertically in the heart of an HTML/CSS layout

I need to center the text vertically and horizontally in the nav div. Below are both the HTML and CSS code snippets. Here is the HTML snippet: <html> <head> </head> <title> Dom Chronicles </title> <body> <div id=" ...

Unable to conceal HTML5 video in mobile devices through media query

I've been struggling to find a solution for hiding a video on mobile devices. Despite going through numerous posts and attempting different methods, I haven't been successful in using @media queries to hide the video and show an image instead. He ...

Guide on navigating to a specific page with ngx-bootstrap pagination

Is there a way to navigate to a specific page using ngx-bootstrap pagination by entering the page number into an input field? Check out this code snippet: ***Template:*** <div class="row"> <div class="col-xs-12 col-12"> ...

How to strategically break Bootstrap 5 button groups for different resolutions?

Is there a way to create a line break in a specific place within a button group on a certain screen size? I have a button group with 4 buttons in a row, and I would like to split it into two lines after the first button if there isn't enough space. ...

A method to ensure that inline <div> elements occupy the entire available width

The typical solution for this issue is using float, however, it does not work in my situation. I attempted to utilize flexbox and overflow:hidden for the parent element, but unfortunately, it did not resolve the issue. Currently, I am dealing with three i ...

How can JavaScript be used to apply CSS formatting to text that appears as a new HTML element?

It's unclear if the question accurately reflects what I want to achieve. If I have a form that fades out and is then determined whether to display again through a cookie, can the confirmation message be styled using CSS? For example, I would like to ...

Ensuring the bottom border of an element extends to the edge of the screen when utilizing a 960 grid in HTML/CSS

I am currently working on creating a website layout using the 960 grid system developed by Nathansmith. I am facing an issue in extending the bottom border of an element to reach till the end of the screen while keeping the element inside a container div. ...