Inner rounded shadows inside div - html

I have a div which looks something like this:
.box{
box-sizing: border-box;
border: solid 0.01rem #2e2e2e;
border-radius: 3px;
width:100px;
height:100px;
background:red;
}
<div class="box"/>
And I'm trying to achieve this effect. How can I make this box look with such shadows from the inside of the div?

linear gradient
blur filter
absolute positioning
pseudo-elements
flexbox
.box {
box-sizing: border-box;
border-radius: 10%;
width: 100px;
height: 100px;
background: linear-gradient(270deg, red, #c10606);
position: relative;
}
.box:before {
position: absolute;
content: '';
top: 10%;
right: 10%;
bottom: 10%;
left: 10%;
background: linear-gradient(90deg, red, #c10606);
border-radius: 12%;
filter: blur(1px); /* optional for a softer effect */
}
/* optional layout and styling for box contents */
.box {
display: flex;
align-items: center;
text-align: center;
font-family: arial;
color: #ddd;
font-weight: bold;
}
.box * {
position: relative; /* puts interior content over the pseudo-element */
}
<div class="box">
<span>Interior content</span>
</div>

CSS box-shadow
I think the answer posted by #isherwood works as the best one for your use-case. But, there is a way to make the shadow show on the inside of the element by setting the last parameter of box-shadow as inset.
There are a few catches for this solution though. A few things which I could not achieve:
I am unable to implement linear gradient to the shadow.
I am unable to give a border-radius to the inner boundary of the shadow.
div.box {
background: linear-gradient(90deg, hsl(26, 68%, 26%), hsl(26, 68%, 45%));
height: 100px;
width: 100px;
box-shadow: 0 0 0 12px hsl(26, 68%, 35%) inset;
border-radius: 10px;
}
<div class="box"></div>
Reference: How to create an inner shadow using CSS

Well, I edited your code. Here is the demo.
Basically, I added one more div and added some style. Hope it will give you an idea.
Also, I added a snippet down below:-
.box {
box-sizing: border-box;
border: solid 0.01rem #2e2e2e;
border-radius: 15px;
width: 100px;
height: 100px;
background: red;
padding: 10px 0px 10px 0px;
}
.inner-div {
box-sizing: border-box;
border-radius: 15px;
width: 78px;
height: 78px;
background: #ee1717;
margin: 0 auto;
}
<div class="box"/>
<div class="inner-div"></div>
<div>

Related

Backdrop filter not working with overflow: hidden on parent

I'm trying to use backdrop-filter(blur in this case) on a div only to discover the overflow: hidden property prevents it from applying. The browser is Chrome 78.
Say I've got a div.filter inside a div.block that's wrapper inside a div.container.
div.container > div.block > div.filter
If I apply overflow: hidden to both .container and .block the effect of the filter suddenly disappears. Furthermore, other properties of the .block prevents the filter from being applied.
Seems like the overflow: hidden on .container triggers this erratic behavior. Do you guys have any idea what's going on here?
Demo here: https://codepen.io/marcel_pi/pen/VwYvmGv
Please check the code below:
.container{
overflow: hidden; /* delete to resume normal behavior */
border-radius: 20px;
}
.block{
width: 400px;
height: 400px;
border: 4px solid black;
background: linear-gradient(90deg, transparent 50%, rgba(152,47,138,.5) 50%) antiquewhite;
background-size: 30px;
font-weight: bold;
/* the properties below prevent the filter from being applied once the overflow: hidden is applied to .container */
border-radius: 20px; /* delete to resume normal behavior */
overflow: hidden; /* delete to resume normal behavior */
position: relative; /* delete to resume normal behavior */
}
.filter{
position: absolute;
top: 0;
left: 205px;
width: 230px;
height: 230px;
background: #42add77d;
backdrop-filter: blur(6px); /* the blur filter */
border-radius: 20px;
}
<div class="container">
<div class="block">
<div class="filter"></div>
</div>
</div>
If you apply a filter (0px) to the same element that you apply the overflow property to, it will work.
.container{
overflow: hidden; /* delete to resume normal behavior */
border-radius: 20px;
}
.block{
width: 400px;
height: 400px;
border: 4px solid black;
background: linear-gradient(90deg, transparent 50%, rgba(152,47,138,.5) 50%) antiquewhite;
background-size: 30px;
font-weight: bold;
/* the properties below prevent the filter from being applied once the overflow: hidden is applied to .container */
-webkit-filter: blur(0px);
border-radius: 20px; /* delete to resume normal behavior */
overflow: hidden; /* delete to resume normal behavior */
position: relative; /* delete to resume normal behavior */
}
.filter{
position: absolute;
top: 0px;
left: 205px;
width: 230px;
height: 230px;
background: #42add77d;
backdrop-filter: blur(4px);
border-radius: 20px;
}
<div class="container">
<div class="block">
<div class="filter"></div>
</div>
</div>
You can test it here as well..
It's a stacking order issue. If you do a simple test of adding, z-index to your block element, you'll see the filter working as expected.
I did a little digging around about overflow and how it's properties affect stacking order, but couldn't find any conclusive documentation.
That said, just add z-index: 1 to your block.
Caveat: This will not work on Firefox unless you set the layout.css.backdrop-filter.enabled preference to true in about:config.
https://caniuse.com/#search=backdrop-filter
.container {
overflow: hidden;
/* delete to resume normal behavior */
border-radius: 20px;
}
.block {
width: 400px;
height: 400px;
border: 4px solid black;
background: linear-gradient(90deg, transparent 50%, rgba(152, 47, 138, .5) 50%) antiquewhite;
background-size: 30px;
font-weight: bold;
border-radius: 20px;
overflow: hidden;
position: relative;
z-index: 1;
}
.filter {
position: absolute;
top: 0px;
left: 205px;
width: 230px;
height: 230px;
background: #42add77d;
backdrop-filter: blur(4px);
border-radius: 20px;
z-index: 10;
}
<div class="container">
<div class="block">
<div class="filter"></div>
</div>
</div>
There were some bugs in Chrome with filter / backdrop-filter, border-radius and overflow: hidden:
Asked in May 2013 (Chrome 27): webkit-filter breaks overflow: hidden
Asked in April 2016: Backdrop Filter extends beyond Border Radius.
Should be fixed already: https://bugs.webkit.org/show_bug.cgi?id=142662.
For me, the only property that is not working is .block's overflow: hidden, but you can just remove it, position .filter so that it doesn't overflow and apply its border-radius only to the corners that need it (in this example, border-radius: 0 4px 0 16px):
body {
display: flex;
justify-content: center;
margin: 0;
height: 100vh;
}
.container {
position: relative;
box-sizing: border-box;
flex: 1 1 100%;
margin: 16px;
padding: 16px;
border: 4px solid black;
border-radius: 12px;
overflow: hidden;
}
.block {
position: relative;
box-sizing: border-box;
width: 100%;
height: 100%;
border: 4px solid black;
border-radius: 8px;
background: linear-gradient(90deg, transparent 50%, rgba(152,47,138,.5) 50%) antiquewhite;
background-size: 20px 20px;
font-weight: bold;
/* This is the only one what won't work: */
/* overflow: hidden; */
}
.filter {
position: absolute;
top: 0;
right: 0;
width: 50%;
height: 50%;
background: #42ADD77D;
backdrop-filter: blur(4px);
/*
Add border-radius only top right corner (which should match the parent's border-radius minus its
border-width) and bottom left corner:
*/
border-radius: 0 4px 0 16px;
}
<div class="container">
<div class="block">
<div class="filter"></div>
</div>
</div>
I'm using Chrome Version 78.0.3904.108 (Official Build) (64-bit) on Windows 10.

Is there a CSS solution for this design?

Here's my issue:
I have a mockup from a design company that wants a text block with a 'broken' square border behind some big text that looks like this (description: there is a small white frame behind large text that is broken up by the text, and then a smaller text link below):
Image of an element on client's website,
In the design, the text is displayed accross the white square frame. The way I have implemented it right now is to make the big text's background color gray. Because the current image's background is gray the desired effect is achieved.
What is needed is to achieve that effect (of breaking the white frame) REGARDLESS of the appearance of the image. Because right now, this happens:
the gray background of the text appears like a box in front of the image -- it ought to be transparent
To further illustrate, if I set the background-color of the big text to transparent, the whole frame is shown (the desired effect is a broken frame):
background: transparent #1
More info if it helps:
The white frame element is just a div with a white border.
I am not sure exactly what to search for in this case, if there is an appropriate CSS solution (preferrable) or if I need to use SVG or maybe a PNG? Thank you for any help.
As #Temani Afif pointed out in the comments, it's not one box, but two separate shapes in CSS.
I made an example to illustrate this using flexbox.
.page {
background-color: black;
width: 400px;
height: 400px;
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
}
.box-top {
width: 100px;
height: 10px;
border-color: white;
border-width: 2px;
border-style: solid;
border-bottom: none;
}
.box-bottom {
width: 100px;
height: 30px;
border-color: white;
border-width: 2px;
border-style: solid;
border-top: none;
}
.separator {
color: white;
width: 100%;
margin: 5px 0;
padding: 0;
font-size: 40px;
text-align: center;
}
<div class="page">
<div class="box-top"></div>
<p class="separator">
Headline
</p>
<div class="box-bottom"></div>
</div>
You can make a square element with a border and use a mask on it:
body {
margin: 0;
min-height: 100vh;
background: black;
box-sizing: border-box;
padding-top: 1px;
}
h2.fancy {
position: relative;
text-align: center;
color: white;
padding-top: 12px;
}
h2.fancy:before {
content: '';
position: absolute;
left: 50%;
top: 0;
transform: translateX(-50%);
width: 100px;
height: 100px;
border: 5px solid white;
clip-path: polygon(0 0, 100% 0, 100% 10px, 0 10px, 0 40px, 100% 40px, 100% 100%, 0 100%);
}
<h2 class=fancy>I'm a fancy title...</h2>
The advantage of this solution is that you can make it scale easily with what might change on various screen sizes. For example, with the title's font-size:
document.querySelector('input.font-size').addEventListener('input', function(e) {
document.querySelector('h2').style.fontSize = e.target.value + 'px';
})
body {
margin: 0;
min-height: 100vh;
background: url(https://picsum.photos/800) center /cover;
box-sizing: border-box;
padding-top: 1px;
}
.overlay {
position: absolute;
top: 0;
width: 100%;
height: 100%;
background-color: rgba(0,0,0,.5);
}
h2.fancy {
z-index: 1;
position: relative;
text-align: center;
color: white;
padding-top: 12px;
}
h2.fancy:before {
content: '';
position: absolute;
left: 50%;
top: 0;
transform: translateX(-50%);
width: 100px;
height: 100px;
display: block;
border: 5px solid white;
clip-path: polygon(0 0, 100% 0, 100% 10px, 0 10px, 0 calc(10px + 1.3em), 100% calc(10px + 1.3em), 100% 100%, 0 100%);
}
input[type=range] {
position: absolute;
bottom: 1rem;
left: 1rem;
z-index: 1;
}
<h2 class=fancy>I'm a fancy title...</h2>
<div class=overlay></div>
<input type=range min=12 max=36 class=font-size>
The disadvantage is that it doesn't work in IE or Edge lower than 18 or in Opera mini. This particular example works in IE 18, though, as it only uses polygon().

Half-circle with a full-circle CSS one element

I am trying to create an element which is a half-circle with a complete circle border. Like this:
I have no problem doing it with using 2 elements, but don't fully understand how to do it within one DIV.
Right now all I have is a half circle:
.element {
height: 10px;
width: 10px;
border-bottom-left-radius: 20px;
border-top-left-radius: 20px;
background-color: #00a680;
}
You can simply use gradient:
.box {
width: 150px;
height: 150px;
border: 15px solid #00a680;
border-radius: 50%;
padding: 15px;
background: linear-gradient(to right, #00a680 50%, transparent 0) content-box;
box-sizing:border-box;
}
<div class="box">
</div>

Apply border on box shadow

Is there a way to apply a border onto the box shadow itself without having to create two individual divs?
Trying to create something like this:
This is how I would go about it with pseudo elements so you don't have to add anymore html.
HTML
<div class="box">
</div>
CSS
.box {
width: 300px;
height: 80px;
background: black;
position: relative;
}
.box:after {
content: "";
display: block;
width: 300px;
height: 80px;
box-sizing: border-box;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
position: absolute;
top: 10px;
left: 10px;
border: 1px solid black;
}
Finally a fiddle: Demo
Here is a fiddle with a box-shadow on it: Demo or Demo
You can use multiple box shadows like so:
http://jsfiddle.net/chriscoyier/Vm9aM/
img {
box-shadow:
0 0 0 10px hsl(0, 0%, 80%),
0 0 0 15px hsl(0, 0%, 90%);
}

CSS3 Moon Eclipse shape

How can I make the following shape in CSS3, without using pseudo-classes like ":before"?
I did it very easy with :before, but the thing is that I don't want to have a solid element on the gray area (see JSFiddle - http://jsfiddle.net/aUdLr/2/)
div{
width: 100px;
height: 100px;
background-color: red;
border-radius: 100%;
position: relative;
}
div:before{
content: "";
width: 100%;
height: 110%;
background: gray;
position: absolute;
left: 5px;
top: -5%;
border-radius: 100%;
}
You can use border width:
div{
width: 100px;
height: 100px;
border-radius: 100%;
border-width: 0;
border-left:solid 10px red;
}
Scientifically inaccurate example: http://jsfiddle.net/aUdLr/4/
Keep in mind that the outer shape is not a perfect circle, because the border is added to the width. You can compensate by reducing the width, or by using Box-sizing: Border-box.
To get the effect of a small circle eclipsed by a larger circle, you can add a shadow to a transparent element:
div{
width: 100px;
height: 100px;
border-radius: 100%;
background-color:transparent;
box-shadow: -23px 0 0px -15px #ff8;
}
Example: http://jsfiddle.net/aUdLr/6/
Simplest CSS3 solution that comes to my mind:
div:before {
font: 80px serif;
color: red;
content: "(";
}
Here's a fiddle.
(Now seriously- if you want a good amount of control over the shape, I suggest to use SVG.)