CSS Slanding Div edges over an Image

Viewed 56

I am trying to design a simple report with the format as shown in the following Figma file using React and Material UI. However, I am encountering a challenge when designing the slanting edges of the divs as shown on the report. Plus the purple border. This is what I have done so far, but it is far from being perfect:

const leftDiv = {
    content: "",
    position: "absolute",
    top: "50%",
    right: 0,
    width: "100%",
    height: "50%",
    backgroundColor: 'rgb(255, 255, 255)',
    clipPath: "polygon(0 0, 0% 0%, 100% 100%, 0% 100%)"
}

const rightDiv = {
    position: "absolute",
    bottom: 0,
    right: 0,
    display: 'inline-block',
    width: 0,
    height: 0,
    borderStyle: 'solid',
    borderWidth: '0 0 500px 100vw',
    borderColor: 'transparent transparent #FFFFFF transparent',
}

const contentDiv = {
    backgroundColor: 'rgb(255, 255, 255)',
    width: "100%",
    height: "100%",
    clipPath: "polygon(100% 0, 100% 0%, 100% 100%, 0% 100%)"
}

const Coverpage = () => {
    return (
        <Container>
            <Grid>
                <Paper>
                    <Box sx={{ position: 'relative', width: '100%' }}>
                        <CardMedia 
                            component='img'
                            alt="cover page image"
                            image='https://unsplash.com/photos/vbxyFxlgpjM'
                        />
                        <Box style={leftDiv}></Box>
                        <Box  style={rightDiv}>
                            <Box style={contentDiv}>
                                <Box sx={{ width: '100%', height: '100%', display: 'flex', flexDirection: 'column', justifyContent: 'flex-end', alignItems: 'flex-end', textAlign: 'right', pr: 8 }}>
                                    <Typography sx={{ fontSize: '24px', mb: 2 }}>Lorem ipsum</Typography>
                                    <Typography sx={{ fontSize: '48px', fontWeight: 'bold', textTransform: 'uppercase', color: '#000133' }}>Lorem ipsum</Typography>
                                    <Typography sx={{ fontSize: '64px', fontWeight: 'bold', textTransform: 'uppercase', color: 'blue' }}>Lorem ipsum</Typography>
                                </Box>
                            </Box>
                        </Box>
                    </Box>
                </Paper>
            </Grid>
        </Container>
    );
}

export default Coverpage;

I found using clipPath as the easiest, even though I would prefer using triangles to design the slanting edges since later, I am planning to use react-pdf-renderer which I am not sure if it supports clipPath in its CSS styling.

I will appreciate a pointer to the right direction.

2 Answers

You just need to use a simple CSS transform on the element.

transform: skew(-15deg, -15deg);

Dan touched on the purple border. About the slanted div you can use this trick:

.slanted{
   height: 0;
   width: 0;
   border-top: solid 100px transparent;
   border-right: solid 50vw blue;
   border-left: solid 50vw blue;
   border-bottom: solid 100px blue;
}

You're making a div with no height or width. The borders meet along a diagonal line and so you can have a triangle effect.

You can use an additional div for the text

Edit: making the borders responsive

To make the border trick dynamic you can use some JS:

function App() {

  const footerRef = React.useRef()

  useEffect(() => {
    window.addEventListener('resize', setBorders)
    return () => {
      window.removeEventListener('resize', setBorders)
    }
  }, [])

  useEffect(() => {
    if (!footerRef.current) return
    setBorders()
  }, [footerRef])

  const setBorders = () => {
    let containerWidth = document.querySelector('.container').clientWidth
    let footerStyle = footerRef.current.style
    footerStyle.borderRightWidth = containerWidth/2+'px'
    footerStyle.borderLeftWidth = containerWidth/2+'px'
  }

  return (
    <div className='App'>

      <div className='container'>
        <div className='footer' ref={footerRef}>
        </div>
      </div>

    </div>
  );
}
export default App

We are adding a 'resize' eventListener to the window that will trigger the setBorders() function. In this function we select the container element and set the width of the footer borders to be half of it.

To make sure the function also fires on initial load I added a useEffect which will fire when the footer is created and its Ref is set. You can also use a callback ref instead.

The css, I assumed the footer will be static height:

.container{
  height: 200px;
  width: 100%;
  background: red;
}
.footer{
  position: relative;
  height: 0;
  width: 0;
  top: calc(100% - 100px);
  /*border-top width + border-bottom width = 100px*/

  border-top: 50px solid transparent;
  border-bottom: 50px solid green;
  border-right: solid blue;
  border-left: solid blue;
}

If you don't mind making the container position: relative; you can then just do:

.footer{
   position: absolute;
   bottom: 0;
}
Related