Avoiding Overlapping Drop Shadows on Irregular CSS Shapes - html

I am creating a popover in CSS which is made up of a regular rectangle and a small tab at the top. I am wanting to add a drop shadow to the popover, but can not get the shadow at the bottom of the tab to hide.
See image of popover below:
... and the code to produce:
.popover-test {
background-color: #fff;
border: 1px solid #929292;
box-shadow: 0 0 10px 1px #929292;
height: 100px;
position: relative;
width: 200px;
&::before {
background-color: #fff;
border: 1px solid #929292;
border-bottom: 1px solid #fff;
border-top-left-radius: 4px;
border-top-right-radius: 4px;
box-shadow: 0 0 10px 1px #929292;
top: -20px;
content: "";
height: 20px;
left: 100px;
position: absolute;
width: 50px;
}
}
How can I keep the drop shadow around the border of the irregular shape, but remove it from the base of the tab at the top?

Wrap the tab in something with z-index:1; and then you can move your before/after behind and on top like this. You will get some issues, but nothing that can't be cleaned up with some basic css
https://jsfiddle.net/ptb7n90w/1/
.wrapper {
z-index:1;
}
.popover-test {
background-color: #fff;
border: 1px solid #929292;
box-shadow: 0 0 10px 1px #929292;
height: 100px;
position: relative;
width: 200px;
}
.popover-test::before {
background-color: #fff;
border-bottom: 1px solid #fff;
border-top-left-radius: 4px;
border-top-right-radius: 4px;
top: -10px;
content:"";
height: 20px;
left: 101px;
width: 50px;
position: absolute;
z-index:1;
}
.popover-test::after {
background-color: #fff;
border: 1px solid #929292;
border-bottom: 1px solid #fff;
border-top-left-radius: 4px;
border-top-right-radius: 4px;
box-shadow: 0 0 10px 1px #929292;
top: -20px;
content:"";
height: 20px;
left: 100px;
width: 50px;
position: absolute;
z-index:-1;
}

Related

How to hover over whole shape created with pseudo selectors?

I am trying to apply shadow to the whole shape. But the shape defined with ::after is not affected. How do i work with the shape as a unit?
style.css
.diag{
position: relative;
top: 0px;
left: 100px;
width: 150px;
height: 90px;
background-color: gray;
border-radius: 10px;
}
.diag::after{
content: "";
position: absolute;
left: -50px;
top: 35px;
width: 0;
height: 0;
border-top: 10px solid transparent;
border-right: 50px solid gray;
border-bottom: 10px solid transparent;
}
.diag:hover{
box-shadow: 2px 2px 2px 2px;
}
You can try this:
.diag {
position: relative;
top: 0px;
left: 100px;
width: 150px;
height: 90px;
background-color: gray;
border-radius: 10px;
}
.diag::after {
content: "";
position: absolute;
left: -50px;
top: 35px;
width: 0;
height: 0;
border-top: 10px solid transparent;
border-right: 50px solid gray;
border-bottom: 10px solid transparent;
}
.diag:hover {
box-shadow: 0px 0px 4px 4px black;
}
<div class="diag">
</div>

How to make a border triangle using css?

How to create border triangle?
The only thing I can think of to make this is to make a triangle
.triangle {
width: 0;
height: 0;
border-left: 15px solid transparent;
border-right: 15px solid transparent;
border-bottom: 20px solid #8e8e8e;
}
But this is a solid triangle, is there a way to make it look like the triangle extends the border
Create an :after or :before element that absolutely positions at the bottom of your div.
.box {
position: relative;
background-color: #F00;
border: 1px solid #000;
width: 50px;
height: 50px;
}
.box:after {
content: "";
width: 16px;
height: 16px;
position: absolute;
background-color: #FFF;
bottom: -8px; /* half of the elements width/height */
left: 50%;
transform: translateX(-50%) rotate(45deg);
border-bottom: 1px solid #000;
border-right: 1px solid #000;
}
<div class="box">
I've made the :after element white so you can see what's happening inside of it.
You need to move triangle element to under sub layout.
I added more triangle for the border design.
.balon {
width: 350px;
height: 120px;
border: 5px solid #2C6DBF;
margin: 50px auto;
position: relative;
border-radius: 8px;
}
.balon::after, .balon::before {
width: 0;
height: 0;
content: '';
border-left: 15px solid transparent;
border-right: 15px solid transparent;
border-top: 21px solid #fff;
position: absolute;
bottom: -19px;
right: 0;
left: 0;
margin: auto;
}
.balon::before {
border-left-width: 20px;
border-right-width: 20px;
border-top-width: 25px;
border-top-color: #2C6DBF;
bottom: -25px;
}
<div class="balon">
</div>

Regular border + offset border on button using CSS

css button with double border
I'm trying to acheive the same border effect on the button above.
The closest I can get is the following, but the bottom right corner of the bottom border is not properly rounded:
>
.login__button {
background: transparent;
border: none;
border-width: 2px 1px 2px 2px;
border-style: solid;
border-color: pink;
border-radius: 4px;
color: pink;
margin-bottom: 100px;
position: relative !important;
text-transform: uppercase;
height: 33px;
width: 102px;
box-shadow:
3.5px 4px 0px black,
1.5px 0px 0px pink,
3.5px 4px 0px black,
2px 6px 0px pink;
}
.login__button::before {
background: pink;
content: '';
position: absolute;
height: 35px;
width: 3.0px;
border-radius: 3px;
top: 3%;
right: -2.8px;
}
>
I feel like this should be possible using just box-shadows but there doesnt appear to be a way to modify the width of the box shadow to get just the black portion inset properly.
So the idea is to make the .login__button:before basically look the same as .login__button, but to change the positioning, and to give it a lower z-index than .login__button.
.login__button {
background-color: black;
border: 2px solid #FF00A0;
border-radius: 4px;
color: #FF00A0;
position: relative;
font-size: 15px;
height: 33px;
width: 102px;
cursor: pointer;
}
.login__button:before {
content: '';
background-color: black;
border: 2px solid #FF00A0;
border-radius: 4px;
position: absolute;
width: 100%;
height: 34px;
top: -2px;
left: -2px;
z-index: -1;
cursor: pointer;
box-shadow: 0 0 20px rgb(255,0,160);
}
.login__button:active {
background-color: gold;
}
.login__button:active:before {
background-color: gold;
}
<button class="login__button">LOG IN</button>
And just for the sake of it, I've added a style for then the button is pressed.
.login__button:active {
background-color: gold;
}
.login__button:active:before {
background-color: gold;
}
Here's my attempt.
.login__button {
background: black;
border: 4px solid #FF69B4;
color: #FF69B4;
position: relative;
text-transform: uppercase;
padding: 1em;
display: inline-block;
border-radius: 3px;
}
.login__button::before {
content: '';
background: black;
border: 4px solid #FF69B4;
margin-left: -4px;
position: absolute;
border-radius: 3px;
width: 100%;
height: 100%;
top: 12px;
left: 0;
z-index: -1;
}
Link
I don't know if this is what you're looking for, but here's what I'd probably do.
#a, #b{
border: 2px solid magenta;
border-radius: 4px;
}
#a{
border-top: none;
width: 20%;
box-shadow: 0 0 8px magenta;
background: linear-gradient(to bottom, magenta 0%, black 24%);
}
#b{
color: magenta;
background-color: black;
padding: 4px;
margin-bottom: 4px;
text-align: center;
}
<div id='a'>
<div id='b'>
Button
</div>
</div>
* {
box-sizing: content-box;
}
body { padding: 50px; }
.login__button {
border: 2px solid fuchsia;
border-radius: 4px;
color: fuchsia;
background: black;
text-transform: uppercase;
height: 33px;
width: 102px;
position: relative;
box-shadow: 0 8px 20px 8px rgba(227,37,243,0.3);
}
.login__button::before {
background: black;
border: 2px solid fuchsia;
content: '';
position: absolute;
border-radius: 4px;
width: 100%;
height: 5px;
bottom: -7px;
left: -2px;
}
<button class="login__button">LOG IN</button>

How to get 'div' shaped as a flag with CSS

I want to add a label on some of my elements on a website and design for a label that is a flag with an inverted V-shaped cut at the bottom.
So far I have this:
HTML
<div class="css-shapes"></div>
CSS
.css-shapes{
border-left: 99px solid #f00fff;
border-right: 99px solid #f00fff;
border-bottom: 39px solid transparent;
}
http://jsfiddle.net/yhexkm4u/2/
However, I need the background to be white and border around this shape in purple and 1px. I was trying to fit the same shape just in white inside of this one, but everything got messy and didn't go as expected.
Maybe it is a wrong approach, but I want to end up with labels that would look something like this:
With CSS:
You can use CSS transforms on pseudo elements to create the background with a transparent inverted triangle at the bottom:
body{background:url('http://lorempixel.com/image_output/food-q-c-640-480-1.jpg');background-size:cover;}
p{
position: relative;
width: 150px; height: 150px;
overflow: hidden;
border-top:3px solid #EF0EFE;
}
p:before, p:after{
content: '';
position: absolute;
top: -3px;
height: 100%; width: 50%;
z-index: -1;
border:2px solid #EF0EFE;
box-sizing:border-box;
}
p:before{
left: 0;
transform-origin: 0 0;
transform: skewY(-20deg);
border-width:0 0 4px 3px;
}
p:after{
right: 0;
transform-origin: 100% 0;
transform: skewY(20deg);
border-width:0 3px 4px 0;
}
<p>Some text ... </p>
Note that you will need to add vendor prefixes on the transform and transform-origin properties to maximize browser support. See canIuse for more information.
With SVG
Another approach is to use an inline SVG with the polygon element:
body{background: url('http://lorempixel.com/image_output/food-q-c-640-480-1.jpg');background-size: cover;}
div{position: relative;width: 100px; height: 150px;}
svg{position: absolute;width: 100%;height: 100%;z-index: -1;}
<div>
<svg viewbox="-1.5 -1.5 103 153">
<polygon points="100 0, 100 100, 50 85, 0 100, 0 0" fill="transparent" stroke-width="3" stroke="#ef0efe"/>
</svg>
<p>Some text ... </p>
</div>
Here is a slightly different method using pseudo-elements and transform rotations to create an outlined banner like this:
This angled shape is created with position: absolute pseudo-elements, :before and :after:
The excess is cut off with overflow: hidden on the parent to form our banner:
The outline is created with box-shadow and the two angles are prevented from overlapping by pulling / pushing the x-axis by 46px — box-shadow: 46px 0 0 3px #000
Full Example
div {
height: 100px;
width: 100px;
margin: 100px auto;
position: relative;
overflow: hidden;
border: solid 3px #000;
border-bottom: none;
text-align: center;
}
div:before,
div:after {
content: '';
display: block;
height: 100%;
width: 200%;
transform: rotate(20deg);
box-shadow: 46px 0 0 3px #000;
position: absolute;
top: 1px;
right: -120%;
}
div:after {
transform: rotate(-20deg);
left: -120%;
box-shadow: -46px 0 0 3px #000;
}
<div>Text</div>
STOLEN FROM CSS-SHAPES
#flag {
width: 110px;
height: 56px;
padding-top: 15px;
position: relative;
background: red;
color: white;
font-size: 11px;
letter-spacing: 0.2em;
text-align: center;
text-transform: uppercase;
}
#flag:after {
content: "";
position: absolute;
left: 0;
bottom: 0;
width: 0;
height: 0;
border-bottom: 13px solid #eee;
border-left: 55px solid transparent;
border-right: 55px solid transparent;
}
DEMO:
#flag {
width: 110px;
height: 56px;
padding-top: 15px;
position: relative;
background: red;
color: white;
font-size: 11px;
letter-spacing: 0.2em;
text-align: center;
text-transform: uppercase;
}
#flag:after {
content: "";
position: absolute;
left: 0;
bottom: 0;
width: 0;
height: 0;
border-bottom: 13px solid #eee;
border-left: 55px solid transparent;
border-right: 55px solid transparent;
}
<div id="flag"></div>
My Approach
My approach uses skewed elements, and allows you to quickly position them to your needs.
div {
height: 100px;
width: 100px;
position: relative;
border-left: 10px solid tomato;
border-top: 10px solid tomato;
border-right: 10px solid tomato;
text-align: center;
line-height: 100px;
font-size: 30px;
}
div:before {
content: "";
position: absolute;
height: 50%;
width: 50%;
left: -10px; /*width of border*/
bottom: -30px;
z-index: -2;
-webkit-transform: skewY(-20deg);
transform: skewY(-20deg);
border-bottom: 10px solid tomato;
border-left: 10px solid tomato;
}
div:after {
content: "";
position: absolute;
height: 50%;
width: 50%;
right: -10px; /*width of border*/
bottom: -30px;
z-index: -2;
-webkit-transform: skewY(20deg);
transform: skewY(20deg);
border-bottom: 10px solid tomato;
border-right: 10px solid tomato;
}
div:hover, div:hover:before, div:hover:after{
background:lightgray;
}
<div>TEXT</div>
I've had a go at updating your CSS to create the effect you want:
.css-shapes {
height: 250px;
width: 0px;
border-left: 99px solid #f00fff;
border-right: 99px solid #f00fff;
border-bottom: 39px solid transparent;
position: relative
}
.n-shape {
height: 248px;
width: 0px;
border-left: 95px solid #ffffff;
border-right: 95px solid #ffffff;
border-bottom: 39px solid transparent;
position: absolute;
top: -6px;
right: -95px;
}
.top {
position: absolute;
top: 0px;
width: 198px;
height: 2px;
background-color: #f00fff;
left: -99px;
border-bottom: 1px solid #f00fff;
}
<div class="css-shapes">
<div class="n-shape"></div>
<div class="top"></div>
</div>
Fiddle: http://jsfiddle.net/dywhjwna/
Here is what I came up with.
Link Fiddle
It correspond to what you were looking for however I guess there should be a "better way" to it rather than playing with border.
HTML
<div id="text-div">
Text
</div>
<div id="pacman">
<div id="left-triangle"></div>
<div id="right-triangle"></div>
</div>
CSS
#text-div {
width: 118px;
height: 60px;
text-align: center;
border: 1px solid purple;
border-bottom: 0px;
line-height: 60px;
}
#pacman {
width: 0px;
height: 0px;
border-right: 60px solid purple;
border-top: 0px;
border-left: 60px solid purple;
border-bottom: 60px solid transparent;
}
#left-triangle{
position: relative;
left: -59px;
border-right: 58px solid transparent;
border-top: 0px;
border-left: 58px solid white;
border-bottom: 58px solid transparent;
}
#right-triangle{
position: relative;
top: -59px;
left: -57px;
border-right: 58px solid white;
border-top: 0px;
border-left: 58px solid transparent;
border-bottom: 58px solid transparent;
}
A quick workaround is to rotate it:
transform: rotate(90deg);
Fiddle
Another solution would be an SVG path, here's a fiddle!.
A better solution with text easily positioned in the middle, using a rectangle background and a triangle at the bottom.
.css-shapes{
position: relative;
height: 250px;
width: 150px;
background: #FFD05B;
color: #fff;
text-align: center;
line-height:225px;
font-size: 90px;
box-sizing: border-box;
}
.css-shapes:after{
content: '';
position:absolute;
left:0;
bottom: 0;
display: block;
width: 100%;
height:50px;
border-bottom: 25px solid #fff;
border-left: 75px solid transparent;
border-right: 75px solid transparent;
box-sizing: border-box;
}
<div class="css-shapes">1</div>

Making an outline border for a pointy button in CSS

Is it possible to make a button in CSS like the image below. I have tried in jsfiddle and I can get a solid shape but not one with a outline border?
jsfiddle code:
<div class="point-btn"></div>
.point-btn
{
width: 148px;
height: 34px;
background: #0a187e;
position: relative;
-moz-border-radius:3px 0 0 3px;
-webkit-border-radius:3px 0 0 3px;
border-radius:3px 0 0 3px;
margin-left:50px;
}
.point-btn:before
{
content:"";
position: absolute;
left: 100%;
width: 0;
height: 0;
border-top: 17px solid transparent;
border-left: 14px solid #0a187e;
border-bottom: 17px solid transparent;
}
Not too pretty- but you should get a decent starting point, simply use another pseudo element overlain on your existing triangle shape:
Demo Fiddle
.point-btn {
width: 148px;
height: 28px;
border: 2px solid #0a187e;
background: #fff;
position: relative;
-moz-border-radius: 3px 0 0 3px;
-webkit-border-radius: 3px 0 0 3px;
border-radius: 3px 0 0 3px;
margin-left: 50px;
}
.point-btn:after {
content: "";
position: absolute;
left: 100%;
width: 0;
height: 0;
top: 0px;
border-top: 14px solid transparent;
border-left: 10px solid #fff;
border-bottom: 14px solid transparent;
}
.point-btn:before {
content: "";
position: absolute;
left: 100%;
width: 0;
top: -4px;
height: 0;
border-top: 18px solid transparent;
border-left: 14px solid #0a187e;
border-bottom: 17px solid transparent;
}
<div class="point-btn"></div>
Set a child element and overlay triangle as well.
You need to tweak up your markup a bit by adding span as a child element.
Demo
Here, what I did is, am cloning your triangle with different dimensions and overlay on your blue triangle, that will give your triangle a border effect, and next, I set absolute span element which is again positioned absolute to the parent element. If you want you can also use margin to set the element right and get rid of the /absolute position.
.point-btn {
width: 148px;
height: 34px;
background: #0a187e;
position: relative;
-moz-border-radius: 3px 0 0 3px;
-webkit-border-radius: 3px 0 0 3px;
border-radius: 3px 0 0 3px;
margin-left: 50px;
}
.point-btn:before {
content: "";
position: absolute;
left: 148px;
width: 0;
height: 0;
border-top: 17px solid transparent;
border-left: 14px solid #0a187e;
border-bottom: 17px solid transparent;
}
.point-btn:after {
content: "";
position: absolute;
left: 147px;
width: 0;
height: 0;
top: 4px;
border-top: 13px solid transparent;
border-left: 10px solid #fff;
border-bottom: 13px solid transparent;
}
.point-btn span {
width: 142px;
background: #fff;
height: 25px;
position: absolute;
top: 4px;
left: 5px;
}
<div class="point-btn"><span></span>
</div>