I have wasted 2 days to create a shadow effect like here.
You see, the front white buttons look not flat, don't know how to describe. I bet this is because of box shadow effect, inset or something like that. But I can't make the same.
Can anyone help to make such a button with the same design, effect?
My example
.button {
background-size: 400% auto;
background: linear-gradient(to top right, rgb(247, 212, 167), #eef2f3);
border-radius: 7%;
box-shadow: inset 4px -4px 1px 1px rgb(252, 205, 144), inset -4px 4px 1px 1px white, -15px 25px 25px 0px rgba(0, 0, 0, .3);
width: 200px;
height: 200px;
-webkit-transition: all .1s linear;
transition: all .2s linear;
left: 0;
transform: rotate(45deg);
}
<div class="button main-circle"></div>
Here is an idea using some gradient and pseudo elements:
.box {
width: 100px;
height: 100px;
margin: 100px;
border: 3px solid #e0e1e6;
border-radius: 10px;
background: linear-gradient(to right, #b9b7dc, #a7a7c9);
transform: rotate(45deg);
position: relative;
z-index: 0;
box-sizing: border-box;
}
.box:before {
content: "";
position: absolute;
z-index: 2;
top: 30%;
left: -32%;
width: 100px;
height: 100px;
border: 3px solid #fefefe;
border-radius: 10px;
background: linear-gradient(to right, #e0e0e0, #fefefe);
box-sizing: border-box;
}
.box:after {
content: "";
position: absolute;
z-index: 1;
top: 30%;
left: -31%;
width: 100px;
height: 100px;
border-radius: 10px;
background: linear-gradient(to right, rgba(0,0,0,0.3),rgba(0,0,0,0.1));
box-sizing: border-box;
transform: skewY(11deg) scaleX(1.15);
filter: blur(4px);
transform-origin: top left;
}
body {
background: pink;
}
<div class="box"></div>
Related
I have an element with a known ID I can target. How could I create a bestseller-badge like this with css only? I cannot change the html.
I know how to create this but only if I could edit the html, which I cannot:
.box {
width: 200px; height: 300px;
position: relative;
border: 1px solid #BBB;
background: #EEE;
}
.ribbon {
position: absolute;
right: -5px; top: -5px;
z-index: 1;
overflow: hidden;
width: 75px; height: 75px;
text-align: right;
}
.ribbon span {
font-size: 10px;
font-weight: bold;
color: #FFF;
text-transform: uppercase;
text-align: center;
line-height: 20px;
transform: rotate(45deg);
-webkit-transform: rotate(45deg);
width: 100px;
display: block;
background: #79A70A;
background: linear-gradient(#9BC90D 0%, #79A70A 100%);
box-shadow: 0 3px 10px -5px rgba(0, 0, 0, 1);
position: absolute;
top: 19px; right: -21px;
}
.ribbon span::before {
content: "";
position: absolute; left: 0px; top: 100%;
z-index: -1;
border-left: 3px solid #79A70A;
border-right: 3px solid transparent;
border-bottom: 3px solid transparent;
border-top: 3px solid #79A70A;
}
.ribbon span::after {
content: "";
position: absolute; right: 0px; top: 100%;
z-index: -1;
border-left: 3px solid transparent;
border-right: 3px solid #79A70A;
border-bottom: 3px solid transparent;
border-top: 3px solid #79A70A;
}
<div class="box">
<div class="ribbon"><span>Bestseller</span></div>
</div>
The thing is I only have the parent box and not the ribbon inside. I cant input html.
Because in pseudo elements you can't put any html markup, you need to get clever with just using simple shapes and combining them together. Additionally, you can't have multiple :after pseudo elements, so we are limited to just two shapes (one for :after and one for :before). The one in :after could be the bestseller front of the badge, with text. The trickiest part was to get the clip-path: polygon(...points) to get right so that we get the effect of trimmed ribbon. Fortunately, Firefox dev tools have a nifty polygon modification tool that was very helpful. Getting the two little corners that make the "wrap around" effect was a bit trickier, but putting it in a :before pseudo element with z-index: -1 and a little hand-tweaked offset did the trick. The end effect is below:
.box {
width: 200px; height: 300px;
position: relative;
border: 1px solid #BBB;
background: #EEE;
margin: 20px;
display: inline-block;
}
.bestseller:before {
content: "";
z-index: -1;
overflow: hidden;
transform: rotate(-135deg);
width: 120px;
display: block;
background: #79A70A;
background: linear-gradient(#9BC90D 0%, #79A70A 100%);
box-shadow: 0 3px 10px -5px rgba(0, 0, 0, 1);
position: absolute;
top: 34px;
right: -16px;
clip-path: polygon(120px 20px, 90px -10px, 30px -10px, 0px 20px, 10px 30px, 110px 30px);
height: 20px;
width: 120px;
}
.bestseller:after {
content: "bestseller";
z-index: 1;
overflow: hidden;
font-size: 10px;
font-weight: bold;
color: #FFF;
text-transform: uppercase;
text-align: center;
line-height: 20px;
transform: rotate(45deg);
width: 120px;
display: block;
background: #79A70A;
background: linear-gradient(#9BC90D 0%, #79A70A 100%);
box-shadow: 0 3px 10px -5px rgba(0, 0, 0, 1);
position: absolute;
top: 20px; right: -30px;
clip-path: polygon(120px 20px, 90px -10px, 30px -10px, 0px 20px, 10px 30px, 110px 30px)
}
<div class="box">
</div>
<div class="box bestseller">
</div>
With the help of only CSS using pseudo class, we cannot create exactly the same but similar to that is possible. Add the id "ribbon" to div with class "box" and try with the below css. Increment/decrement the height, top right, etc based on the size of your div.
#ribbon:before {
content: "";
width: 60px;
display: block;
position: absolute;
top: 14px;
right: -28px;
transform: rotate(45deg);
-webkit-transform: rotate(45deg);
border-left: 30px solid transparent;
border-right: 30px solid transparent;
border-bottom: 30px solid green;
height: 0;
}
#ribbon:after {
content: "Bestseller";
font-size: 10px;
font-weight: bold;
color: #FFF;
text-transform: uppercase;
text-align: center;
line-height: 30px;
transform: rotate(45deg);
-webkit-transform: rotate(45deg);
width: 60px;
display: block;
position: absolute;
top: 14px;
right: 2px;
height: 30px;
}
Instead of trying with border for the background color of ribbon, you can also try using an ribbon image as background and use the text on top of it.
Upon click of button, I display a popover.
however if you notice the pointer of the popover slides from a completely different direction.
Not quiet able to fix this. Kindly advise.
.popover {
position: absolute;
top: 50px;
left: -175px;
width: 400px;
height: 200px;
background-color: rgb(233, 212, 222);
border-radius: 4px;
box-shadow: 3px -2px 4px #AAA;
transition: all linear 0.5s;
}
.popover-arrow {
position: absolute;
top: -16px;
left: 180px;
border-left: 20px solid transparent;
border-right: 20px solid transparent;
border-bottom: 20px solid rgb(233, 212, 222);
width: 0;
height: 0;
transition: all linear 0.01s;
}
plnkr: http://plnkr.co/edit/SiwYgmkZjh2NuszI0q2E
Expected behavior would be for the pointer of the popover to also animate the same was the popover does (from top to bottom)
THis is due to the ng-hide class that is added to your .popover class. It has set position before animation.
top: -18px;
left: 20px;
Override it with this:
.ng-hide {
top: -16px;
left: -175px;
}
Thanks to #Valius79 .. i got something working
.popover {
position: absolute;
top: 50px;
left: -175px;
width: 400px;
height: 200px;
background-color: rgb(233, 212, 222);
border-radius: 4px;
box-shadow: 3px -2px 4px #AAA;
transition: all linear 0.5s;
}
.popover.ng-hide {
height: 0;
width: 0;
background-color: transparent;
top:-18px;
left: 20px;
}
.popover-arrow {
position: absolute;
top: 35px;
left: 5px;
border-left: 20px solid transparent;
border-right: 20px solid transparent;
border-bottom: 20px solid rgb(233, 212, 222);
width: 0;
height: 0;
transition: all linear 0.5s;
}
.popover-arrow.ng-hide {
top: -36px;
left: 5px;
}
http://plnkr.co/edit/SiwYgmkZjh2NuszI0q2E?p=preview
I would like to create this page (see image) with css shadow. Is this possible? So to have the page peel css box shadow bottom left and right and the shadow left and right?
You can do this with pseudo elements :before and :after. Creating two new areas which have their own box-shadows and placing them where required you can create the illusion of the shadow getting bigger as the page goes down.
body {
background: lightgrey;
}
div {
background: white;
margin: 40px auto;
height: 500px;
width: 300px;
position: relative;
padding: 10px;
}
div:before,
div:after {
height: 97%;
z-index: -10;
position: absolute;
content: "";
bottom: 15px;
left: 8px;
width: 30%;
top: 2%;
max-width: 300px;
background: transparent;
box-shadow: -10px 0px 5px rgba(0, 0, 0, 0.3);
transform: rotate(1deg);
}
div:after {
transform: rotate(-1deg);
right: 8px;
left: auto;
box-shadow: 10px 0px 5px rgba(0, 0, 0, 0.3);
}
<div>
test
</div>
An alternative is using CSS transforms to change the perspective of a single :before pseudo element.
This was done by Harry **
body {
background: lightgrey;
}
div {
background: white;
margin: 40px auto;
height: 500px;
width: 300px;
position: relative;
padding: 10px;
box-shadow: 10px 0px 5px -10px gray, -10px 0px 5px -10px gray;
}
div:after {
content: '';
position: absolute;
bottom: 10px;
left: 0px;
height: 50%;
width: 100%;
transform-origin: 50% 100%;
transform: perspective(100px) rotateX(1deg);
box-shadow: 5px 0px 10px gray, -5px 0px 10px gray;
z-index: -1;
}
<div></div>
CSS :before & :after
I have created product box that shows product image, when hovered on flips around to show details of a product and this works well. Problem is when this product has ribbon on it and flips, text in the ribbon becomes flipped as well (it's position is correct), I need to somehow extra transform this text so it shows correctly TOP even when flipped. Is it possible?
.ribbon-wrapper-green {
width: 85px;
height: 88px;
overflow: hidden;
position: absolute;
top: -3px;
right: -3px;
z-index: 5;
}
.ribbon-green {
font: bold 15px Sans-Serif;
color: #333;
text-align: center;
text-shadow: rgba(255,255,255,0.5) 0px 1px 0px;
-webkit-transform: rotate(45deg);
-moz-transform: rotate(45deg);
-ms-transform: rotate(45deg);
-o-transform: rotate(45deg);
position: relative;
padding: 7px 0;
left: -5px;
top: 15px;
width: 120px;
background-color: #BFDC7A;
background-image: -webkit-gradient(linear, left top, left bottom, from(#BFDC7A), to(#8EBF45));
background-image: -webkit-linear-gradient(top, #BFDC7A, #8EBF45);
background-image: -moz-linear-gradient(top, #BFDC7A, #8EBF45);
background-image: -ms-linear-gradient(top, #BFDC7A, #8EBF45);
background-image: -o-linear-gradient(top, #BFDC7A, #8EBF45);
color: #6a6340;
-webkit-box-shadow: 0px 0px 3px rgba(0,0,0,0.3);
-moz-box-shadow: 0px 0px 3px rgba(0,0,0,0.3);
box-shadow: 0px 0px 3px rgba(0,0,0,0.3);
}
.ribbon-green:before, .ribbon-green:after {
content: "";
border-top: 3px solid #6e8900;
border-left: 3px solid transparent;
border-right: 3px solid transparent;
position: absolute;
bottom: -3px;
}
.ribbon-green:before {
left: 0;
}
.ribbon-green:after {
right: 0;
}
.product-box {
width: 292px;
height: 340px;
}
.thumb-wrapper {
height: 100%;
background-color: purple;
}
.product-box img {
width: 100%;
position: absolute;
display: block;
backface-visibility: hidden;
}
.product-box .thumb-detail {
width: 100%;
height: 100%;
position: absolute;
background: blue;
backface-visibility: hidden;
}
.product-box.flip {
perspective: 800px;
}
.product-box.flip .thumb-wrapper {
transition: transform 1s;
transform-style: preserve-3d;
}
.product-box.flip .thumb-detail, .product-box.flip:hover .thumb-wrapper {
transform: rotateY(-180deg);
}
<div class="product-box flip">
<div class="thumb-wrapper">
<div class="ribbon-wrapper-green"><div class="ribbon-green">TOP</div></div>
<img src="#" alt="" title="" height="262" width="262">
<div class="thumb-detail">
</div>
</div>
</div>
Just duplicate the ribbon-wrapper-green and rotate it in the back
.card {
width: 180px;
height: 180px;
position: relative;
-webkit-perspective: 700;
margin: 0px auto;
}
.card:hover .front{
-webkit-transform: rotateY(-180deg);
}
.card:hover .back {
-webkit-transform: rotateY(0deg);
}
.card:hover .face {
-webkit-transition: all 0.3s ease-out;
}
.face {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
-webkit-backface-visibility: hidden;
-webkit-transition: all 0.8s ease-out;
}
.front {
-webkit-transform: rotateY(0deg);
}
.back {
background: #9dcc78;
-webkit-transform: rotateY(180deg);
}
.ribbon-wrapper-green {
width: 85px;
height: 88px;
overflow: hidden;
position: absolute;
top: -3px;
right: -3px;
z-index: 5;
}
.ribbon-green {
font: bold 15px Sans-Serif;
color: #333;
text-align: center;
text-shadow: rgba(255,255,255,0.5) 0px 1px 0px;
-webkit-transform: rotate(45deg);
-moz-transform: rotate(45deg);
-ms-transform: rotate(45deg);
-o-transform: rotate(45deg);
position: relative;
padding: 7px 0;
left: -5px;
top: 15px;
width: 120px;
background-color: #BFDC7A;
background-image: -webkit-gradient(linear, left top, left bottom, from(#BFDC7A), to(#8EBF45));
background-image: -webkit-linear-gradient(top, #BFDC7A, #8EBF45);
background-image: -moz-linear-gradient(top, #BFDC7A, #8EBF45);
background-image: -ms-linear-gradient(top, #BFDC7A, #8EBF45);
background-image: -o-linear-gradient(top, #BFDC7A, #8EBF45);
color: #6a6340;
-webkit-box-shadow: 0px 0px 3px rgba(0,0,0,0.3);
-moz-box-shadow: 0px 0px 3px rgba(0,0,0,0.3);
box-shadow: 0px 0px 3px rgba(0,0,0,0.3);
}
.ribbon-green:before, .ribbon-green:after {
content: "";
border-top: 3px solid #6e8900;
border-left: 3px solid transparent;
border-right: 3px solid transparent;
position: absolute;
bottom: -3px;
}
.ribbon-green:before {
left: 0;
}
.ribbon-green:after {
right: 0;
}
.back .ribbon-wrapper-green {
top: -4px;
left: -1px;
-webkit-transform: rotateZ(-90deg);
-moz-transform: rotateZ(-90deg);
transform: rotateZ(-90deg);
}
<div class='card'>
<div class='front face'>
<div class="ribbon-wrapper-green"><div class="ribbon-green">TOP</div></div>
<img src='http://placehold.it/180x180'/>
</div>
<div class="back face">
<div class="ribbon-wrapper-green"><div class="ribbon-green">TOP</div></div>
<img src='http://placehold.it/180x180'/>
</div>
</div>
Note: I had initially misunderstood the question and posted a wrong answer. Did not want to delete it and hence have modified the original answer to still solve the problem albeit making it more complex in the process. The best approach is provided in Tambo's answer. You can use this method if you for some reason wish to achieve the effect without duplicating elements.
You can do it by adding the rotateY(-180deg) on the div with class="ribbon-wrapper-green" and positioning it on the other side. The original positioning is right: -3px and on hover, we change it to left: -3px or right: 210px; (box width 292px + offset 3px - width of ribbon container 85px).
After this, the whole ribbon is translated by the required pixels (the complex part) to get positioned on the left side of the screen. Now, even though the position is correct, the ribbon has to be rotated in the reverse direction to make it look properly like a ribbon and so a rotate(-90deg) is added (-90 degrees the element is originally rotated by 45 degree which has to be nullified to come back to a normal position and then we have to rotate another 45 degree in the reverse direction).
Note: The animation/transition effect is not great but I think you can work that out.
.ribbon-wrapper-green {
width: 85px;
height: 88px;
overflow: hidden;
position: absolute;
top: -3px;
right: -3px;
z-index: 5;
}
.ribbon-green {
font: bold 15px Sans-Serif;
color: #333;
text-align: center;
text-shadow: rgba(255, 255, 255, 0.5) 0px 1px 0px;
-webkit-transform: rotate(45deg);
-moz-transform: rotate(45deg);
-ms-transform: rotate(45deg);
-o-transform: rotate(45deg);
position: relative;
padding: 7px 0;
left: -5px;
top: 15px;
width: 120px;
background-color: #BFDC7A;
background-image: -webkit-gradient(linear, left top, left bottom, from(#BFDC7A), to(#8EBF45));
background-image: -webkit-linear-gradient(top, #BFDC7A, #8EBF45);
background-image: -moz-linear-gradient(top, #BFDC7A, #8EBF45);
background-image: -ms-linear-gradient(top, #BFDC7A, #8EBF45);
background-image: -o-linear-gradient(top, #BFDC7A, #8EBF45);
color: #6a6340;
-webkit-box-shadow: 0px 0px 3px rgba(0, 0, 0, 0.3);
-moz-box-shadow: 0px 0px 3px rgba(0, 0, 0, 0.3);
box-shadow: 0px 0px 3px rgba(0, 0, 0, 0.3);
}
.ribbon-green:before,
.ribbon-green:after {
content: "";
border-top: 3px solid #6e8900;
border-left: 3px solid transparent;
border-right: 3px solid transparent;
position: absolute;
bottom: -3px;
}
.ribbon-green:before {
left: 0;
}
.ribbon-green:after {
right: 0;
}
.product-box {
width: 292px;
height: 340px;
}
.thumb-wrapper {
height: 100%;
background-color: purple;
}
.product-box img {
width: 100%;
position: absolute;
display: block;
backface-visibility: hidden;
}
.product-box .thumb-detail {
width: 100%;
height: 100%;
position: absolute;
background: blue;
backface-visibility: hidden;
}
.product-box.flip {
perspective: 800px;
}
.product-box.flip .thumb-wrapper {
-webkit-transition: -webkit-transform 1s;
transition: transform 1s;
-webkit-transform-style: preserve-3d;
transform-style: preserve-3d;
}
.product-box.flip .thumb-detail,
.product-box.flip:hover .thumb-wrapper {
-webkit-transform: rotateY(-180deg);
transform: rotateY(-180deg);
}
.product-box.flip:hover .thumb-wrapper .ribbon-wrapper-green {
left: -3px;
-webkit-transform: rotateY(-180deg) translate(-212px) rotate(-90deg);
transform: rotateY(-180deg) translate(-212px) rotate(-90deg);
}
<div class="product-box flip">
<div class="thumb-wrapper">
<div class="ribbon-wrapper-green">
<div class="ribbon-green">TOP</div>
</div>
<img src="#" alt="" title="" height="262" width="262">
<div class="thumb-detail">
</div>
</div>
</div>
I found a switch I'd like to use http://codepen.io/katmai7/pen/fyzuH . There is a working example at the above link but there are errors in the code and I ran this thru a code checker but wasn't able to figure out how to fix it. Do you know how to fix it? Here is what the code checker said:
Sorry! We found the following errors (6)
URI : TextArea
27 .wrap Parse Error .line{ position: absolute; top: 50px; width: 100%; border-top: 1px solid #1B1B1C; border-bottom: 1px solid #323334; }
28 .wrap Parse Error }
43 .switch Property user-select doesn't exist : none
45 .switch Lexical error at line 45, column 3. Encountered: "&" (38), after : "" &
48 :hover Parse Error .slide:after{ opacity: .05; }
49 :hover Parse Error Lexical error at line 51, column 3. Encountered: "&" (38), after : ""
html{
height: 100%;
}
body{
height: 100%;
background: #C1D1DA;
background: radial-gradient(ellipse at center, rgba(92,93,95,1) 0%,rgba(47,48,49,1) 100%);
}
.wrap{
position:relative;
margin: 100px auto;
width: 90px;
height: 100px;
border: 1px solid #1F1F20;
border-radius: 5px;
background: linear-gradient(to bottom, rgba(58,59,60,1) 0%,rgba(28,28,29,1) 100%);
box-shadow:inset 0 3px 4px -2px rgba(94,96,96, 1), 0 0 6px -1px rgba(0,0,0, .8), 0 2px 7px -1px rgba(0,0,0, .5);
.line{
position: absolute;
top: 50px;
width: 100%;
border-top: 1px solid #1B1B1C;
border-bottom: 1px solid #323334;
}
}
.switch{
position: relative;
display: block;
margin: 13px 17px;
width: 55px;
height: 25px;
border: 1px solid #1A1A1B;
border-radius: 20px;
background: linear-gradient(to bottom, rgba(31,31,32,1) 0%,rgba(58,58,58,1) 100%);
box-shadow: 0 1px 1px 0 rgba(130,132,134, .6), inset 0 4px 0 -3px rgba(0,0,0, .3);
cursor: pointer;
transition: box-shadow .5s ease .27s, border-color .5s ease .27s;
user-select: none;
&:hover{
.slide:after{
opacity: .05;
}
}
&.p2{
margin-top: 25px;
}
&:after{
display: block;
width: 100%;
height: 100%;
border-radius: 20px;
background: green;
background: linear-gradient(to bottom, rgba(186,101,82,1) 0%,rgba(215,151,101,1) 100%);background: linear-gradient(to bottom, rgba(186,101,82,1) 0%,rgba(215,151,101,1) 100%);
content: "";
opacity: 0;
transition: opacity .5s ease .27s;
}
/some context/
&:before{
position: absolute;
display: block;
width: 95%;
height: 60%;
border-radius: 20px;
background: #fff;
content: "";
opacity: .03;
}
.icon-off, .icon-eye-open{
position: absolute;
z-index: 2;
display: block;
line-height: 25px;
font-size: 18px;
}
.icon-eye-open{
left: 5px;
color: #EDD6CD;
text-shadow: 0 1px 0 #97614B;
}
.icon-off{
top: 1px;
right: 5px;
color: #6D6F70;
}
.slide{
position: absolute;
top: -1px;
left: -2px;
z-index:5;
width: 25px;
height: 25px;
border: 1px solid #171718;
border-radius: 50%;
background: linear-gradient(to bottom, rgba(64,65,66,1) 0%,rgba(30,30,31,1) 100%);
box-shadow:inset 0 1px 2px 0 rgba(93,94,95, .8), 1px 3px 5px -2px rgba(0,0,0, .7);
transition: left .4s ease-in, border-color .4s ease-in .1s;
&:after{
display: block;
width: 100%;
height: 100%;
border-radius: 50%;
background: linear-gradient(to bottom, rgba(243,232,223,1) 0%,rgba(204,169,140,1) 100%);
content: "";
opacity: 0;
transition: opacity .4s ease .1s;
}
}
}
input[type=checkbox]{
display: none;
&:checked{
+ .switch{
border-color: #4D2318;
box-shadow: 0 1px 1px 0 rgba(130,132,134, .6), inset 0 4px 0 -3px rgba(0,0,0, .3), 0 0 15px 0 rgba(213,147,99, .7);
&:after{
opacity: 1;
}
.slide{
left: 29px;
border-color: #704F3F;
&:after{
opacity: 1;
}
}
}
}
}
You are using a CSS parser on LESS syntax, which will definitely throw errors.
LESS allows for selector nesting like this:
.wrap {
/* some css */
.line {
/* some more CSS */
}
}
You can't do this in pure CSS, which is why your CSS checker is throwing all these errors. The code is basically equivalent to:
.wrap { ... }
.wrap .line { ... }