Is it possible to create these shadows with CSS? - css

Here is an image I created of a board with a shadow behind it. The board is supposed to be leaning against a wall so the shadow is in a triangular shape on both sides.
Is it possible to create a shadow like this using only CSS? Also, if possible, is the method cross-browser compatible?

Is it possible to create a shadow like this using only CSS?
Yes, using pseudoelements, box shadows, and 2D transformations – specifically, a rotation. An example is at the end of this answer.
Is the method cross-browser compatible?
Sort of. The ideal code isn't fully compatible with older versions of IE. To get that support, you'll need to make some compromises, which I'll list below:
Here's the support breakdown:
:before and :after – IE8+ only. For deeper support, you could replace these with less-semantic div elements.
rotation – IE6+ with IE-specific rules; a reference that shows these rules is in the note at the end of the example
box-shadow – IE9+ To make these shadow work in IE6+, you could use CSSPie.
Example of the ideal code
Here's a very quick example to get you started.
<div id="board">
Place image here!
</div>
CSS
#board {
position: absolute;
left: 50px;
top: 50px;
background: #e5e5e5;
text-align: center;
width: 100px;
height: 100px;
}
#board:before {
z-index: -1;
position: absolute;
content: "";
bottom: 0;
left: 5px;
width: 5px;
height: 50%;
background: rgba(0, 0, 0, 0.7);
-webkit-box-shadow: -5px 0 10px rgba(0,0,0, 0.7);
-moz-box-shadow: -5px 0 10px rgba(0, 0, 0, 0.7);
box-shadow: -5px 0 10px rgba(0, 0, 0, 0.7);
-webkit-transform: rotate(6deg);
-moz-transform: rotate(6deg);
-o-transform: rotate(6deg);
-ms-transform: rotate(6deg);
transform: rotate(6deg);
}
#board:after {
z-index: -1;
position: absolute;
content: "";
bottom: 0;
right: 5px;
width: 5px;
height: 50%;
background: rgba(0, 0, 0, 0.7);
-webkit-box-shadow: 5px 0 10px rgba(0,0,0, 0.7);
-moz-box-shadow: 5px 0 10px rgba(0, 0, 0, 0.7);
box-shadow: 5px 0 10px rgba(0, 0, 0, 0.7);
-webkit-transform: rotate(-6deg);
-moz-transform: rotate(-6deg);
-o-transform: rotate(-6deg);
-ms-transform: rotate(-6deg);
transform: rotate(-6deg);
}
Where should I go from here?
You'll want to implement the syntax for rotations in early IEs, or use a Javascript library to add the support, both of which can be read about over here.
You might also want the shadows to cut off like they do in your image. This could be done by covering up the part of the shadow that sticks out with an element that's beneath it.
I also threw that together pretty quickly, so you might want to adjust it to get the shadows looking just like how you want them.

Related

Display issue with CSS viewport units

I'm working on a child theme of WP's Twentyseventeen, which uses VH in order to adjust certain heights, such as the header portion. In the header all I really want to change is to add a sort of slanted divider to make it more "stylish" but no matter what I do, I'm getting the following issue in certain displays:
As you can see, 1px of the background is showing below the divider. (BTW, this doesn't only happen in mobile displays, and it happens in several browsers.)
Now, here's my code pertaining to this part (as well as 2017's code that I know 2017 has something to do with this section; but I can't be sure the theme doesn't have some code or script somewhere that's affecting this behaviour):
HTML:
<div class="custom-header">
<div class="custom-header-media">
<?php the_custom_header_markup(); ?>
</div>
<?php get_template_part( 'template-parts/header/site', 'branding' ); ?>
<div class="custom-header-bottom-divider">
<svg id="divider-bottom" xmlns="http://www.w3.org/2000/svg" version="1.1" width="100%" height="100" viewBox="0 0 100 100" preserveAspectRatio="none"><path d="M0 100 L100 0 L100 100 Z"></path></svg>
</div>
</div><!-- .custom-header -->
CSS:
.custom-header {
position: relative;
overflow: hidden;
}
.has-header-image.twentyseventeen-front-page .custom-header,
.has-header-video.twentyseventeen-front-page .custom-header,
.has-header-image.home.blog .custom-header,
.has-header-video.home.blog .custom-header {
display: table;
height: 300px;
height: 75vh;
width: 100%;
}
.custom-header-media {
bottom: 0;
left: 0;
overflow: hidden;
position: absolute;
right: 0;
top: 0;
width: 100%;
}
.custom-header-media:before {
/* Permalink - use to edit and share this gradient: http://colorzilla.com/gradient-editor/#000000+0,000000+100&0+0,0.3+75 */
background: -moz-linear-gradient(to top, rgba(0, 0, 0, 0) 0%, rgba(0, 0, 0, 0.3) 75%, rgba(0, 0, 0, 0.3) 100%); /* FF3.6-15 */
background: -webkit-linear-gradient(to top, rgba(0, 0, 0, 0) 0%, rgba(0, 0, 0, 0.3) 75%, rgba(0, 0, 0, 0.3) 100%); /* Chrome10-25,Safari5.1-6 */
background: linear-gradient(to bottom, rgba(0, 0, 0, 0) 0%, rgba(0, 0, 0, 0.3) 75%, rgba(0, 0, 0, 0.3) 100%); /* W3C, IE10+, FF16+, Chrome26+, Opera12+, Safari7+ */
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr="#00000000", endColorstr="#4d000000", GradientType=0); /* IE6-9 */
bottom: 0;
content: "";
display: block;
height: 100%;
left: 0;
position: absolute;
right: 0;
z-index: 2;
}
.has-header-image .custom-header-media img,
.has-header-video .custom-header-media video,
.has-header-video .custom-header-media iframe {
position: fixed;
height: auto;
left: 50%;
max-width: 1000%;
min-height: 100%;
min-width: 100%;
min-width: 100vw; /* vw prevents 1px gap on left that 100% has */
width: auto;
top: 50%;
padding-bottom: 1px; /* Prevent header from extending beyond the footer */
-ms-transform: translateX(-50%) translateY(-50%);
-moz-transform: translateX(-50%) translateY(-50%);
-webkit-transform: translateX(-50%) translateY(-50%);
transform: translateX(-50%) translateY(-50%);
}
.custom-header-bottom-divider {
position: absolute;
bottom: 0;
left: 50%;
width: 100%;
min-width: 1000px;
text-align: center;
line-height: 1;
transform: translateX(-50%);
-webkit-transform: translateX(-50%);
-moz-transform: translateX(-50%);
-o-transform: translateX(-50%);
-ms-transform: translateX(-50%);
z-index: 2;
}
.custom-header-bottom-divider svg {
display: block;
fill: #fff;
}
I'm 99% sure this has to do with the fact that 2017 uses VH to establish the header's height. I.e. this means that often the result in pixels won't be an integer but rather something like 932.45. Now, I'm thinking that in theory the browser can't position an object between two pixels, but if it's rounding up or down, then I'm thinking for some reason there could be a discrepancy between the pixel it takes to be 0 for bottom: 0 and the actual pixel it takes to be the bottom border of the header, thereby positioning the child 1px above the actual bottom.
Temp Solution / Workaround:
So this isn't an actual solution, at least not as far as I'm concerned. It's just a temp fix until I can figure out what's going on and how to really solve it. It should be pretty straightforward: if you set an element's height through CSS respective to the viewport, a child element set to bottom: 0 should actually be placed at the absolute bottom. But it's not happening for some reason. Perhaps it's a known issue with viewport units or perhaps the 2017 theme has some other code os script that's mucking about. At any rate, I'm now using JS to manage the issue:
var headerHeight = $customHeader.innerHeight();
$customHeader.animate({height: headerHeight});
I corroborated that innerHeight actually retrieves the height as displayed, i.e. in full pixels—integer values—, as a pose to the precise height that is given through vh, which tends to have decimals.
So I'm dynamically resetting the height to that integer value, thereby avoiding the need for the browser to round up or down when displaying.
I believe the issue is that, for some reason, the parent's height and the child's position are being drawn apart when rounding; or the child's position is being set before the parent's height is rounded. At any rate, I'm pretty sure that that 1px gap has to do with the fact that non-integer values are involved in the CSS.
You could try modifying the bottom attribute for the divider, changing it to -1px
.custom-header-bottom-divider {
position: absolute;
bottom: -1px;
left: 50%;
width: 100%;
min-width: 1000px;
text-align: center;
line-height: 1;
transform: translateX(-50%);
-webkit-transform: translateX(-50%);
-moz-transform: translateX(-50%);
-o-transform: translateX(-50%);
-ms-transform: translateX(-50%);
z-index: 2;
}

Is it possible to generate a box-shadow that follows the shape of a clip-path polygon?

Let's say I have this clip path (a triangle generated here)
-webkit-clip-path: polygon(50% 0%, 0% 100%, 100% 100%);
clip-path: polygon(50% 0%, 0% 100%, 100% 100%);
Is it possible to create a box-shadow from this clip path?
Something like this:
box-shadow: 20px 25px 50px -25px #000;
You can use a filter on the containing div, try:
.container {
filter: drop-shadow(0px 10px 5px rgba(0,0,0,0.1))
}
eg: https://plnkr.co/edit/kePuv7OLQwawPjiBLg3J?p=preview
I'm assuming you mean, is it possible to create the shadow along the polygon. If so, then no. box-shadow is unfortunately only a "box", so it can't follow the clip path. It'd still apply to the rectangle of the element itself.
You could however pair it with another element that has the same clipping, but is set below it and offset and create a pseudo-shadow:
#box {
position: relative;
width: 200px;
height: 200px;
}
#content {
width: 100%;
height: 100%;
background: #3CF;
-webkit-clip-path: polygon(0 100%, 0 0, 100% 0, 80% 100%);
}
#shadow {
position: absolute;
z-index: -1;
content: "";
background: rgba(0, 0, 0, .5);
width: 200px;
height: 200px;
left: 5px;
top: 5px;
-webkit-clip-path: polygon(0 100%, 0 0, 100% 0, 80% 100%);
}
<div id="box">
<div id="content"></div>
<div id="shadow"></div>
</div>
Depending on your use-case, with some clever use of a background image, multiple borders, and/or gradients, you could make the background look between with a fading shadow and what not.
It's not possible, I think. I would suggest you this work around.
.triangle {
font-size:100px;
color:blue;
text-shadow:0 0 10px black;
}
<span class="triangle">▲</span>

scaling div and make content not scale

I've been trying to scale a div, but not the content for a long time now. I've looked at examples and saw ways it was supposed to work, but it seems like it might be impossible to make it work :( the problem is that the image inside the div becomes blurry on scale. (on hover.)
Here's my codepen link
http://codepen.io/SusanneLundblad/pen/5cf90a3d7b3e2f592ebcb0ebb9d07bf9
.child
position: absolute
height: 450px
width: 20%
background-color: #1f2733
border-radius: 0
background-position: 50% 50%
background-size: cover
-webkit-transform: translate3d(0,0,0)
top: 0
overflow: hidden
z-index: 0
transition: all 0.05s ease-in-out
transform: translate3d(0,0,0)
&:hover
transform: scale(1.03)
z-index: 2
border-radius: 4px
cursor: pointer
box-shadow: 2px 0px 10px rgba(0, 0, 0, 0.5)
.child__content
transform: translate(-50%,-50%) scale(.947)
thank you for any help

Chrome CSS transform scale display issues

I'm getting some issues trying to use the transform scale CSS property.
Here's my CSS on hover:
#pricing-table .pricing-column:not(.labels):hover {
position: relative;
z-index: 50;
-webkit-transform: scale(1.02);
-moz-transform: scale(1.02);
-ms-transform: scale(1.02);
-o-transform: scale(1.02);
transform: scale(1.02);
-webkit-box-shadow: 0 0 3px rgba(1, 1, 1, 0.3);
-moz-box-shadow: 0 0 3px rgba(1, 1, 1, 0.3);
box-shadow: 0 0 3px rgba(1, 1, 1, 0.3); }
Here's the result, note the weird grey border on some of the list items:
Screenshot of issue
I've had similar issues with chrome and CSS3 transforms before and have never been able to figure out how to solve them. Would appreciate any insight! Thanks
Here's the live demo:
Demo Link
U can try to add borders. I checked your code and this worked.
#pricing-table .pricing-column:not(.labels) li,
#pricing-table .pricing-column:not(.labels):hover li {
border: 1px solid #FFF;
}
U can use nth child to remove it from first li if that bothers u.
#pricing-table .pricing-column:not(.labels):hover li:first-of-type {
border: none;
}

CSS3 flexible/responsive Flip card loses back face at end of transform

Similar to a few other examples of flip cards:
similar example 1
However the answer is normally to ensure no background is on the containing card, and specified on the front and back face of the card. however this will not work for my example, due to the fact the back face with text on it, will not occupy the same height as the picture on the front.
I have occasionally had it working correctly, but then after a refresh of the page, it returns to being broken again.
My Code
.flipper{
//transform: perspective(1000px);
transform-style: preserve-3d;
position: relative;
width: 100%;
min-height: 345px;
transition: 0.6s;
background-color: rgb(242,245,245);
box-shadow: 1px 2px 20px rgba(255, 255, 255, 0.6) inset, 1px 2px 5px 1px rgba(0, 0, 0, 0.5);
}
I have yet to start any cross-browser testing on this, but what sort of usable(non animated) support am I looking at?
I realise this is very similar to others questions, however this case should differ enough in terms of not declaring a fixed height on the card, and that the background will likely be required to be applied on the card itself opposed to the faces
Ok so I took a look at it and made some tweaks as you can see on the jsFiddle.
http://jsfiddle.net/nsUZB/1/
Mainly I removed the background-color and min-height on the flipper and set the lightBlue color on the front and back faces.
.flipper{
//transform: perspective(1000px);
transform-style: preserve-3d;
position: relative;
width: 100%;
//min-height: 345px;
transition: 0.6s;
//background-color: rgb(242,245,245);
box-shadow: 1px 2px 20px rgba(255, 255, 255, 0.6) inset, 1px 2px 5px 1px rgba(0, 0, 0, 0.5);
}
.front, .back{
backface-visibility: hidden;
//transition: 0.6s;
transform-style: preserve-3d;
position: absolute;
top: 0;
left: 0;
width: 100%;
background: lightBlue;
}
Let me know if this is going in the right direction.

Resources