First of all, this question might be similar to this, but the shape in my case is different, so it couldn't really help me out.
The trapezoid code is the following:
#light {
/*setting the element*/
border-bottom: 164px solid grey;
border-left: 148px solid transparent;
border-right: 165px solid transparent;
height: 0;
width: 80px;
}
<div id="light"></div>
Just to clarify, I am trying to add the shadow effect, similar to the following example:
#bulb {
/*setting the element*/
background: grey;
width: 200px;
height: 200px;
border-radius: 50%;
/*adding "light" (shadow)*/
box-shadow: 0 0 100px 10px rgba(128, 128, 128, 0.5);
}
<div id="bulb"></div>
When I try to add the regular box-shadow:, my trapezoid becomes a regular rectangle with white parts.
Instead of a box-shadow you could use a drop-shadow filter, e.g.
filter: drop-shadow(0 0 40px #222);
#light {
/*setting the element*/
border-bottom: 164px solid grey;
border-left: 148px solid transparent;
border-right: 165px solid transparent;
height: 0;
width: 80px;
filter: drop-shadow(0 0 40px #222);
}
<div id="light"></div>
More info on MDN
I would create the shape differently using pseudo element with a blur effect:
#light {
width:400px;
height:160px;
position:relative;
}
#light:before,
#light:after{
content:"";
position:absolute;
top:0;
left:0;
right:0;
bottom:0;
background:
/*triangle on the right*/
linear-gradient(to top right,grey 49.5%,transparent 50%) right/150px 100%,
/*triangle on the left*/
linear-gradient(to top left, grey 49.5%,transparent 50%) left /150px 100%,
/*rectangle at the center*/
linear-gradient(grey,grey) center/100px 100%;
background-repeat:no-repeat;
}
#light:before {
filter:blur(20px);
}
<div id="light">
</div>
based on css-tricks Double-Box Method you can "have a container box with hidden overflow and another box inside it which is rotate and hangs out of it"
.light {
width: 350px;
height: 135px;
position: relative;
overflow: hidden;
box-shadow: 0 16px 10px -17px rgba(0, 0, 0, 0.5);
}
.light:after {
content: "";
position: absolute;
width: 300px;
height: 300px;
background: #999;
transform: rotate(45deg);
top: 25px;
left: 25px;
box-shadow: -1px -1px 10px -2px rgba(0, 0, 0, 0.5);
}
<div class="light"></div>
In your example, you can't add a proper box-shadow without having these white parts on each side. That is because the CSS border colouring the grey shaped trapeziod DIV.
In the example above, they are using an .SVG file (image), since it is an image, the original shape of it is a trapezoid, not a rectangle with white side like yours.
You will need to draw an .svg in the shape and color you want, and then add a shadow to the element itself.
Here are more informations about SVG.
I hope it helps.
Related
I want to create a shape, which i would describe as "inverse circle":
The image is somehow inaccurate, because the black line should continue along the outer border of the div element.
Here is a demo of what i have at the moment: http://jsfiddle.net/n9fTF/
Is that even possible with CSS without images?
Update: CSS3 Radial Background Gradient Option
(For those browsers supporting it--tested in FF and Chrome--IE10, Safari should work too).
One "problem" with my original answer is those situations where one does not have a solid background that they are working against. This update creates the same effect allowing for a transparent "gap" between the circle and it's inverse cutout.
See example fiddle.
CSS
.inversePair {
border: 1px solid black;
display: inline-block;
position: relative;
height: 100px;
text-align: center;
line-height: 100px;
vertical-align: middle;
}
#a {
width: 100px;
border-radius: 50px;
background: grey;
z-index: 1;
}
#b {
width: 200px;
/* need to play with margin/padding adjustment
based on your desired "gap" */
padding-left: 30px;
margin-left: -30px;
/* real borders */
border-left: none;
-webkit-border-top-right-radius: 20px;
-webkit-border-bottom-right-radius: 20px;
-moz-border-radius-topright: 20px;
-moz-border-radius-bottomright: 20px;
border-top-right-radius: 20px;
border-bottom-right-radius: 20px;
/* the inverse circle "cut" */
background-image: -moz-radial-gradient(
-23px 50%, /* the -23px left position varies by your "gap" */
circle closest-corner, /* keep radius to half height */
transparent 0, /* transparent at center */
transparent 55px, /*transparent at edge of gap */
black 56px, /* start circle "border" */
grey 57px /* end circle border and begin color of rest of background */
);
background-image: -webkit-radial-gradient(-23px 50%, circle closest-corner, rgba(0, 0, 0, 0) 0, rgba(0, 0, 0, 0) 55px, black 56px, grey 57px);
background-image: -ms-radial-gradient(-23px 50%, circle closest-corner, rgba(0, 0, 0, 0) 0, rgba(0, 0, 0, 0) 55px, black 56px, grey 57px);
background-image: -o-radial-gradient(-23px 50%, circle closest-corner, rgba(0, 0, 0, 0) 0, rgba(0, 0, 0, 0) 55px, black 56px, grey 57px);
background-image: radial-gradient(-23px 50%, circle closest-corner, rgba(0, 0, 0, 0) 0, rgba(0, 0, 0, 0) 55px, black 56px, grey 57px);
}
Original Answer
Took more effort than I expected to get the z-indexing to work (this seems to ignore the negative z-index), however, this gives a nice clean look (tested in IE9, FF, Chrome):
HTML
<div id="a" class="inversePair">A</div>
<div id="b" class="inversePair">B</div>
CSS
.inversePair {
border: 1px solid black;
background: grey;
display: inline-block;
position: relative;
height: 100px;
text-align: center;
line-height: 100px;
vertical-align: middle;
}
#a {
width: 100px;
border-radius: 50px;
}
#a:before {
content:' ';
left: -6px;
top: -6px;
position: absolute;
z-index: -1;
width: 112px; /* 5px gap */
height: 112px;
border-radius: 56px;
background-color: white;
}
#b {
width: 200px;
z-index: -2;
padding-left: 50px;
margin-left: -55px;
overflow: hidden;
-webkit-border-top-right-radius: 20px;
-webkit-border-bottom-right-radius: 20px;
-moz-border-radius-topright: 20px;
-moz-border-radius-bottomright: 20px;
border-top-right-radius: 20px;
border-bottom-right-radius: 20px;
}
#b:before {
content:' ';
left: -58px;
top: -7px;
position: absolute;
width: 114px; /* 5px gap, 1px border */
height: 114px;
border-radius: 57px;
background-color: black;
}
I can't really tell from your drawing how rounded you want the points, but here's one possibility:
http://jsfiddle.net/n9fTF/6/
If the points need to be more rounded, you'll need to put some circles on the ends so they blend with the big scoop.
Different approach : Box-shadows
This approach uses CSS box shadows which are supported by IE9+ (canIuse)
DEMO
Output :
HTML :
<div id="a">
<div id="b"></div>
</div>
CSS :
#a{
overflow:hidden;
border-radius:20px;
position:relative;
display:inline-block;
}
#a:before, #a:after{
content:'';
width: 100px;
border-radius: 50%;
}
#a:before {
height: 100px;
float:left;
border: 1px solid black;
background: grey;
}
#a:after {
position:absolute;
left:14px; top:-6px;
height:114px;
box-shadow: 1px 0px 0px 0px #000, 110px 0px 0px 68px #808080;
background:none;
z-index:-1;
}
#b {
width: 200px;
height: 100px;
background:none;
margin-left:-15px;
border: 1px solid black;
border-left:none;
float:left;
border-top-right-radius: 20px;
border-bottom-right-radius: 20px;
}
This is a very interesting question. I've recently posted a tutorial on how to make Inverse Border Radius in CSS (here) and I think this could easily be adapted for your case.
The trick is to create a span that generates the inverse border using a very simple concept - very thick borders. And use the inside section by hiding them. What you would have to do in addition to my script provided is add another border-radius to the top-left corner as I am only using the top-right one. Make the span aligned to the left of the item you want by absolute positioning, and increase the height/width of span accordingly and voila you have your inverse border-radius.
Using clip path this can be done .
let precision = 64;
let radius = 50;
let c = [...Array(precision)].map((_, i) => {
let a = -i/(precision-1)*Math.PI*2;
let x = Math.cos(a)*radius + 100;
let y = Math.sin(a)*radius + 50;
return `${x}% ${y}%`
})
document.querySelector('.circleContainer').style.clipPath =
`polygon(100% 50%, 100% 100%, 0 100%, 0 0, 100% 0, 100% 50%, ${c.join(',')})`;
.container{
display: flex;
position: relative;
width: 200px;
}
.left{
background: blue;
width: 100px;
height: 100px;
border-top-left-radius: 50%;
border-bottom-left-radius: 50%;
}
.circleContainer {
background: blue;
width: 100px;
height: 100px;
}
.innerCircle{
width: 80px;
height: 80px;
border-radius: 50%;
background: orange;
position: absolute;
top: 10px;
right: -40px;
}
<div class='container'>
<div class='left'></div>
<div class='circleContainer'></div>
<div class='innerCircle'></div>
</div>
Using an approah which I found here
Someone else done it somewhere from what I found...
JSFiddle: http://jsfiddle.net/ajeN7/
and the question: CSS3 Inverted Rounded Corner
Hopefully that helps!
Introduce an absolutely positioned borderless white circle which sits behind the gray circle at an offset. You will need to set the z-index of the dark circle to ensure that it sits above the white circle:
#c {
position: absolute;
border: 0;
left: 30px;
width: 100px;
height: 100px;
border-radius: 50px;
background: white;
}
Demo.
I am creating a triangle with pointing towards bottom using html and css. Here I need to reduce the top width and increase the height of down pointer little bit, I tried with lots of modification, it does not work.
.triangle-with-shadow {
width: 100px;
height: 100px;
position: relative;
overflow: hidden;
}
.triangle-with-shadow:after {
content: "";
position: absolute;
width: 50px;
height: 50px;
background: #999;
transform: rotate(45deg);
bottom: 75px;
left: 25px;
box-shadow: -1px -1px 10px -2px rgba(0,0,0,0.5);
}
.triangle-with-shadow:hover, .triangle-with-shadow:hover:after {
box-shadow: none;
}
<div class="triangle-with-shadow"></div>
In CSS everything is treated as rectangle (BOX-MODEL). It’s annoying, but makes sense, If you try to apply box-shadow on rectangle layout, it's back-breaking task. So Instated of using box-shadow you can use Filter drop-shadow. Filters are not bound to the box model. That means the outline of our triangle is recognized and the transparency around it is ignored so that the intended shape receives the shadow.
Try this code:
.triangle-with-shadow {
width: 100px;
height: 100px;
position: relative;
overflow: hidden;
}
.triangle-with-shadow:after {
content: "";
position: absolute;
border-style: solid;
border-width: 40px 20px 0 20px;
border-color: #999 transparent transparent transparent;
-webkit-filter: drop-shadow(1px 1px 1px rgba(0, 0, 0, 0.5));
filter: drop-shadow(-1px -1px 2px rgba(0, 0, 0, 0.5));
}
.triangle-with-shadow:hover,
.triangle-with-shadow:hover:after {
box-shadow: none;
}
<div class="triangle-with-shadow"></div>
I'm trying to create a background for a banner using css where one side has a color and on the other side has another one with a 45° cut like this
I've been able to recreate the above image except for the drop shadow that doesn't stay in the right position.
Any advice would be greatly appreciated.
This is my code code:
#container {
height: 100px;
width: 400px;
overflow: hidden;
background-color: #2962ff;
}
#triangle-topleft {
width: 0;
height: 0;
border-top: 100px solid #2196f3;
border-right: 400px solid transparent;
-webkit-box-shadow: 5px 5px 20px 0px rgba(0,0,0,0.75);
-moz-box-shadow: 5px 5px 20px 0px rgba(0,0,0,0.75);
box-shadow: 5px 5px 20px 0px rgba(0,0,0,0.75);
}
<div id="container">
<div id="triangle-topleft"></div>
</div>
The CSS triangle trick with border can not be used for this, as a shadow will still be applied to the box, and not only to the triangle.
You will have to create a pseudo element, rotate it and THEN apply shadow to it.
#container {
position: relative;
height: 200px;
width: 200px;
overflow: hidden;
background-color: grey;
}
#container:before {
content: '';
position: absolute;
left: 20%;
width: 100%;
height: 200%;
background-color: rgb(255, 255, 255); /* fallback */
background-color: rgba(255, 255, 255, 0.5);
top: 0;
-webkit-transform: rotate(45deg);
-moz-transform: rotate(45deg);
transform: rotate(45deg);
box-shadow: inset 0 0 20px 10px #333;
}
<div id="container"></div>
Basically you create a rectangle which is larger than the parent, then rotate it and apply a shadow. You can tweak the colors and rotation-degree for your needs
Demo: http://jsfiddle.net/b5TnZ/2032/
You can add multiple color stops in Linear Gradients. Use two color set.
Gradient generated using Shapy
.canvas {
display: flex;
height: 100vh;
align-items: center;
justify-content: center;
min-height: 100%;
min-width: 100%;
}
.gradient-canvas {
max-height: 100%;
max-width: 100%;
width: 100%;
height: 100%;
background: linear-gradient(127deg, rgb(31, 163, 209) 0%, rgb(31, 163, 209) 50%, rgb(25, 64, 208) 0%, rgb(46, 101, 223) 52%) 50% 50% / 100% 100% no-repeat;
}
<div class="canvas"><div class="gradient-canvas"></div></div>
You can try gradient like below:
#container {
height: 150px;
background:
linear-gradient(135deg,#2962ff 49.8%,rgba(0,0,0,0.75) 50%, #2196f3 calc(50% + 10px));
background-color:#2196f3;
}
<div id="container">
</div>
And simply replace the deg with to bottom right if you want the diagonal result:
#container {
height: 150px;
width:50%;
background:
linear-gradient(to bottom right,#2962ff 50%,rgba(0,0,0,0.75) 50%, #2196f3 calc(50% + 10px));
background-color:#2196f3;
}
<div id="container">
</div>
Inspired by this link and this link, I am trying to make pure CSS folding effect with two requirements:
fully transparent background to show an <IMAGE> behind it (!)
being able to use the FULL height of the <DIV> element inside it (!)
I've tried making mine work but the topright corner doesnt become transparent. If I replace...
border-top: 60px solid red;
with
border-top: 60px solid transparent;
then the background of the rectangle box appears through it. Is there a way to solve this with pure CSS solution? If yes how? If not, then what alternatives are they that come close to CSS? The code/coordinations should be readable, interpretable and easily changeable by humans without the need of a vector based program such as inkscape.
The DEMO where I'm stuck:
https://jsfiddle.net/cg7hoyt3/
Perhaps use a linear-gradient instead of an solid color as a background to your primary div.
The border-width and the gradient stop have a ratio of 1 / sqrt(2) = .7071.
If you're using CSS Custom Properties or a CSS preprocessor this becomes much simpler.
Codepen Demo of variable use
body {
background-image: url("http://hdbackgroundspic.com/wp-content/uploads/2017/09/drop-of-water-background.jpg");
}
div {
width: 230px;
height: 230px;
margin: 50px auto;
background: linear-gradient(-135deg, transparent, transparent 45px, gold 45px, gold);
position: relative;
}
div::after {
content: " ";
position: absolute;
top: 0;
right: 0;
height: 0px;
width: 0px;
z-index: 2;
border-width: 30px; /* note .7071 of gradient-stop */
border-style: solid;
border-color: transparent transparent yellow yellow;
filter: drop-shadow(-2px 6px 6px rgba(0, 0, 0, .5));
}
<div></div>
As suggested in the comments, this can be done with a clipping mask:
clip-path: polygon(0 0, 210px 0, 100% 60px, 100% 100%, 0 100%);
While this can look rather daunting, it is actually really easy to read: just read the points one-by-one, starting from the top left. The points draw a polygon around what will be visible.
Note that clip-mask will only work with modern browsers (IE + Edge not included). See Can I use for up-to-date browser support and Mozilla Plotform Status for up-to-date development status.
Here is the code:
body {background-image: url("http://hdbackgroundspic.com/wp-content/uploads/2017/09/drop-of-water-background.jpg")}
.page {
width: 230px;
height: 230px;
margin: 50px auto;
background: gold;
padding: 20px;
}
.fold {
position: relative;
-webkit-box-shadow: -5px 7px 5px rgba(0,0,0,0.8);
-moz-box-shadow: -5px 7px 5px rgba(0,0,0,0.8);
box-shadow: -5px 7px 5px rgba(0,0,0,0.8);
-webkit-clip-path: polygon(0 0, 210px 0, 100% 60px, 100% 100%, 0 100%);
clip-path: polygon(0 0, 210px 0, 100% 60px, 100% 100%, 0 100%);
}
.fold:before, .fold:after {
content: "";
position: absolute;
top: 0%;
right: 0%;
width: 0px;
height: 0px;
}
.fold:before {
border-bottom: 60px solid #BBB;
border-right: 60px solid transparent;
-webkit-box-shadow: -5px 5px 5px 5px rgba(0,0,0,0.1);
-moz-box-shadow: -5px 5px 5px 5px rgba(0,0,0,0.1);
box-shadow: -5px 5px 5px 5px rgba(0,0,0,0.1);
}
.fold:after {
border-top: 60px solid transparent;
border-left: 60px solid yellow;
}
<div class="page fold">
<h2>Dear Bettie</h2>
Will you please erase that darn red corner from this folded note love?<br><br>
Thanks xxx<br>Sandra
</div>
i was wondering if its possible to add gradients to border top without it affecting border right or border left which in this case are transparent. i tried adding a gradient color but it would affect border left and border right im trying to let border left and border right to be transparent
#borderone {
border-top: 33px solid #354658;
border-left: 33px solid transparent;
border-right: 33px solid transparent;
margin: 0 auto;
min-width: 1277px;
}
<div id='borderone'></div>
as you can see this is what i want it to do although i want a gradient background color instead of this solid dark blue color http://jsfiddle.net/EHELN/
See this :
http://css-tricks.com/examples/GradientBorder/
It is enough for me in my career .
For example:
#borderone:first-child:before {
content:'';
position:absolute;
width:100%;
height:4px;
background:linear-gradient(to left, #354658, #9EBBDA);
top:-33px;
left:-5;
}
For your case , you should use before & first-child pseudo-selectors CSS in the same time.
top(in pseudo selector) = -border height = -33 px
FIDDLE: http://jsfiddle.net/abdennour/EHELN/2/
You can get this efect using background for the gradient, and the 2 pseudo elements at the left and right to get the slanted corners
.test {
border-left: 33px solid transparent;
border-right: 33px solid transparent;
height: 33px;
background: linear-gradient(90deg, black, blue);
margin: 0 auto;
min-width: 42px;
background-clip: content-box;
position: relative;
}
.test:before, .test:after {
content: '';
position: absolute;
width: 33px;
height: 100%;
}
.test:before {
background: linear-gradient(45deg, transparent 50%, black 50%);
right: 100%;
}
.test:after {
background: linear-gradient(315deg, transparent 50%, blue 50%);
left: 100%;
}
demo
Looks like I missunderstood the direction. Try this to make it the other way (for webkit)
.test {
border-left: 33px solid transparent;
border-right: 33px solid transparent;
height: 33px;
background: linear-gradient(0deg, black, red);
margin: 0 auto;
min-width: 42px;
background-clip: content-box;
position: relative;
}
.test:before, .test:after {
content: '';
position: absolute;
width: 45px;
height: 45px;
bottom: 0px;
}
.test:before {
-webkit-transform: rotate(45deg);
-webkit-transform-origin: bottom right;
background: linear-gradient(-45deg, black 0, red 32px, transparent 32px);
right: 100%;
}
.test:after {
-webkit-transform: rotate(-45deg);
-webkit-transform-origin: bottom left;
background: linear-gradient(45deg, black 0, red 32px, transparent 32px);
left: 100%;
}
demo 2
if you want to draw a gradient on your border, then you could use border-image or translucide borders with a gradient in bg : DEMO
But then :
You can even drop your translucide borders and make it a padding: DEMO
#borderone {
position:relative;
padding:33px 33px 0;/* well this is just like transparent borders :) */
margin: 0 auto;
height:100px;
background:linear-gradient(
to bottom,
#354658,
#9EBBDA 33px,
transparent 33px
);
}
http://www.colorzilla.com/gradient-editor/
This is for the background and not the border, but you can likely create the same effect you are looking for by using this tool.