I have this simple container, and generated some vertical stripes to use as background.
export default function App() {
return <div className="container"></div>;
}
.container {
height: 200px;
width: 100%;
background-image: linear-gradient(
45deg,
#000000 12.5%,
#ffffff 12.5%,
#ffffff 50%,
#000000 50%,
#000000 62.5%,
#ffffff 62.5%,
#ffffff 100%
);
background-size: 11.31px 11.31px;
position: relative;
}
I want to create a pointer (arrow), that is positioned at the top, or bottom, but that has the same background as the parent. And no matter which value I give to left or right, it should have the stripes aligned with the parent's.
Right now, I have this code for the pseudo-element.
.container::after {
content: "";
position: absolute;
bottom: 100%;
background-image: inherit;
background-size: inherit;
width: 25px;
height: 25px;
clip-path: polygon(50% 0%, 0% 100%, 100% 100%);
left: 27px;
}
But as you can see in the Sandbox below, the stripes are not aligned correctly of the .container, I mean, they do not come as "continuation" of the said background. Is there a possible trick I can make it part of the same background?
Sandbox link: https://codesandbox.io/s/hopeful-browser-tnt8zq
Here's also a picture for reference. https://i.imgur.com/D3VbYAa.png
The stripes should blend like this, no matter where the arrow is positioned horizontally. https://i.imgur.com/kb0uQTK.png
You can make things quite flexible, easy to change, by using CSS variables.
This snippet removes the pseudo element, makes the container slightly larger, and crops the required shape. The way you are sure to get the background lined up correctly.
Set the width, height, and distance along the left side of the pointed bit as required in those CSS variables.
* { margin: 0; padding: 0; box-sizing: border-box; } body { padding: 50px; } .container { --aH: 25px; /* height of the arrow */ --aW: 25px; /* width of the arrow */ --aL: 27px; /* distance along the top of the start of the arrow */ --h: 200px; /* height of container */ height: calc(var(--h) + var(--aH)); width: 100%; background-image: linear-gradient( 45deg, #000000 12.5%, #ffffff 12.5%, #ffffff 50%, #000000 50%, #000000 62.5%, #ffffff 62.5%, #ffffff 100%); background-size: 11.31px 11.31px; position: relative; clip-path: polygon(0 var(--aH), var(--aL) var(--aH), calc(var(--aL) + (var(--aW) / 2)) 0, calc(var(--aL) + var(--aH)) var(--aH), 100% var(--aH), 100% 100%, 0 100%); } <div class="container"></div>UPDATE: There is a requirement for the height of the container to be set by its content, not by a px value. This snippet is like the previous one, except that the background image and its associated clip path are placed in the previous pseudo element of the container. That way you can take the height of the container and add more height to accommodate the arrow.
* { margin: 0; padding: 0; box-sizing: border-box; } body { padding: 50px; } .container { --aH: 25px; /* height of the arrow */ --aW: 25px; /* width of the arrow */ --aL: 27px; /* distance along the top of the start of the arrow */ position: relative; } .container::before { content: ''; position: absolute; top: 0; left: 0; width: 100%; --h: 100%; /* height of container */ height: calc(var(--h) + var(--aH)); width: 100%; transform: translateY(calc(-1 * var(--aH))); background-color: pink; background-image: linear-gradient( 45deg, #000000 12.5%, #ffffff 12.5%, #ffffff 50%, #000000 50%, #000000 62.5%, #ffffff 62.5%, #ffffff 100%); background-size: 11.31px 11.31px; clip-path: polygon(0 var(--aH), var(--aL) var(--aH), calc(var(--aL) + (var(--aW) / 2)) 0, calc(var(--aL) + var(--aH)) var(--aH), 100% var(--aH), 100% 100%, 0 100%); z-index: -1; } <div class="container">some stuff<br>some stuff<br>some stuff<br>some stuff<br>some stuff<br>some stuff<br></div>use this code
.container { height: 200px; width: 100%; background-image: linear-gradient( 45deg, #000000 12.5%, #ffffff 12.5%, #ffffff 50%, #000000 50%, #000000 62.5%, #ffffff 62.5%, #ffffff 100% ); background-size: 11.31px 11.31px; position: relative; } .container::after { content: ""; position: absolute; bottom: 100%; background-image: inherit; background-size: inherit; width: 25px; height: 25px; clip-path: polygon(50% 0%, 0% 100%, 100% 100%); left: 48%; top:50%; }We can play with clip-path values and position left values to get the desire outcome.
please try with below code.
.container::after {
content: "";
position: absolute;
bottom: 100%;
background-image: inherit;
background-size: inherit;
width: 25px;
height: 25px;
clip-path: polygon(40% 0%, 0% 100%, 100% 95%);
left: 20px;
}