Search code examples
htmlcssshadowdropshadow

My code is not working. How can I add after and before elements on a clipped div?


This is my code in which I want to develop a navigation bar similar to the attached image. For shadow I searched and found that on wrapping the parent div we can give shadow using dropshadow() but now I want to give solid 2px border for this, I tried ::before but that didn't work. I am unable to understand the reason.

.mybar{
   
    background-color: black;
    width: 90%;
    height: 40px;
    clip-path: polygon(0 0,100% 0%,95% 100%,5% 100%);
    padding: 0px;
  
    
}
.forshadow{filter: drop-shadow(0 0 0.45rem #ac04cb);}

.mybar::before{
    content: " ";
    background-color:#d673ff ;
    width:93%;
    height: 43px;
}
<div class="forshadow">
                  
      <div class="mybar">
                            
      </div>
                  
</div>

enter image description here


Solution

  • You may want to use an svg for this. Because of the clip-path property, the borders will be cut out of the viewport.

    There are three solutions that come to my mind:

    1. You could use an svg
    2. Draw a rectangle with a clip-path and then have two pseudo-elements on the left and right side that will be drawn as triangles (transparent with a border)
    3. Use an image instead (I suggest the .gif format, since its all the same color)

    .forshadow {
      filter: drop-shadow(0 0 0.45rem #ac04cb);
      width: 800px; /* the container width - adjust */
      height: 50px; /* the container height - adjust */
    }
    
    .mybar {
      width: 100%; /* 100% of the container - will always adapt to the container */
      height: 100%; /* 100% of the container - will always adapt to the container */
      fill: #000000; /* background */
      stroke: hotpink; /* border color */
      stroke-width: 2; /* border size */
    }
    <div class="forshadow">
      <svg class="mybar" viewbox="0 0 100 100" preserveAspectRatio="none">
        <polygon points="0,0 100,0 95,50 5,50" vector-effect="non-scaling-stroke"/>
      </svg>
    </div>

    I suggest the svg-solution. It is made to be scaleable. You can just edit the parameters and play around with it.

    Hope this is what you were looking for.

    EDIT:

    You can save the svg as a file (.svg). And then add it as a background-image to the container.

    <!DOCTYPE html>
    <html>
    	<head>
    		<style type="text/css">
    			.navbar {
    			  filter: drop-shadow(0 0 0.45rem #ac04cb);
    			  width: 800px; /* the container width - adjust */
    			  height: 50px; /* the container height - adjust */
            color: white;
    			  background-image: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB2aWV3Ym94PSIwIDAgMTAwIDUwIiB3aWR0aD0iMTAwIiBoZWlnaHQ9IjUwIiBwcmVzZXJ2ZUFzcGVjdFJhdGlvPSJub25lIj4KCTxwb2x5Z29uIGNsYXNzPSJteWJhciIgcG9pbnRzPSIwLDAgMTAwLDAgOTUsNTAgNSw1MCIgdmVjdG9yLWVmZmVjdD0ibm9uLXNjYWxpbmctc3Ryb2tlIi8+Cjwvc3ZnPg==");
    			  /* alternative, non-base-64: background-image: url("your-file.svg");*/
    			  background-size: 100% 100%;
    			}
    
          /* this will style the <polygon> element inside the svg */
    			.mybar {
    			  width: 100%; /* 100% of the container - will always adapt to the container */
    			  height: 100%; /* 100% of the container - will always adapt to the container */
    			  fill: #000000; /* background */
    			  stroke: hotpink; /* border color */
    			  stroke-width: 2; /* border size */
    			}
    		</style>
    	</head>
    	<body>
    		<nav class="navbar">
          <div>The svg is just a background image - we can write on it.</div>
        </nav>
    	</body>
    </html>

    The svg-file that I have used and decoded:

    <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewbox="0 0 100 50" width="100" height="50" preserveAspectRatio="none">
        <polygon class="mybar" points="0,0 100,0 95,50 5,50" vector-effect="non-scaling-stroke"/>
    </svg>