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
CodePudding user response:
You can make things quite flexible, easy to change, by using CSS variables.
This snippet scraps the pseudo element, makes the container a bit bigger and cuts out the shape required. The way you are assured of getting the correctly aligned background.
Set the width, height and distance along the left of the pointy bit as you require 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 ></div>
UPDATE: there is a requirement to have the container height fixed by its content, not a px value. This snippet is as above except the background image and its associated clip path is put onto the container's before pseudo element. That way it can pick up the height of the container and add further 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 >some stuff<br>some stuff<br>some stuff<br>some stuff<br>some stuff<br>some stuff<br></div>
CodePudding user response:
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%;
}
CodePudding user response:
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;
}