Create inverted curved corners in CSS [duplicate] - javascript

I have a css code:
-moz-border-radius-topleft:50px;
I get the result:
Is there any possibilities to give like this:

Just to update this, it seems you can in multiple ways.
Lea Verou posted a solution
Here is mine using border-image
Using border image
html
<div><img src="https://s3.amazonaws.com/resized-images-new/23292454-E6CD-4F0F-B7DA-0EB46BC2E548" /></div>
css
div {
width: 200px;
border-width: 55px;
-moz-border-image: url(http://i47.tinypic.com/2qxba03.png) 55 repeat;
-webkit-border-image: url(http://i47.tinypic.com/2qxba03.png) 55 repeat;
-o-border-image: url(http://i47.tinypic.com/2qxba03.png) 55 repeat;
border-image: url(http://i47.tinypic.com/2qxba03.png) 55 repeat;
margin: 50px auto;
}
Using radial gradient
Lea Verou's solution
html
<div class="inner-round"></div>
css
.inner-round {
background-image:
radial-gradient(circle at 0 0, rgba(204,0,0,0) 14px, #c00 15px),
radial-gradient(circle at 100% 0, rgba(204,0,0,0) 14px, #c00 15px),
radial-gradient(circle at 100% 100%, rgba(204,0,0,0) 14px, #c00 15px),
radial-gradient(circle at 0 100%, rgba(204,0,0,0) 14px, #c00 15px);
}

In modern browsers, you can use mask-image:
#aux-container {
width: 100px;
height: 100px;
background: #f00;
-webkit-mask-image: radial-gradient(circle 10px at 0 0, transparent 0, transparent 20px, black 21px);
}
<div id="aux-container"></div>
http://jsbin.com/eViJexO/1/
Additionally, take a look at http://www.html5rocks.com/en/tutorials/masking/adobe/, which describes how to achieve similar result using mask-box-image.

You can also use and inline svg with a path element:
body{background:url('http://i.imgur.com/RECDV24.jpg');background-size:cover;}
svg{width:30%;}
<svg viewbox="0 0 10 10">
<path d="M9 1 V9 H1 V3 Q3 3 3 1" fill="#fff"/>
</svg>
In this example, I use a cubic bezier curve for the inverted round edge.
With this approach, you can also fill the shape with an image or gradient:
body{background:url('http://i.imgur.com/RECDV24.jpg');background-size:cover;}
svg{width:30%;}
<svg viewbox="0 0 10 6.7">
<defs>
<clipPath id="clip">
<path d="M9 1 V6.7 H1 V3 Q3 3 3 1" fill="#fff"/>
</clipPath>
</defs>
<image xlink:href="http://i.imgur.com/qi5FGET.jpg" x="0" y="0" height="6.7" width="10" clip-path="url(#clip)"/>
</svg>

This can be done with a radial gradient.
div {
width: 20vw;
height: 20vw;
background: radial-gradient(circle at top left,transparent 4vw, darkblue 4.1vw);
}
<div></div>
Just for fun, additional inverted corners can be added by defining multiple backgrounds - one for each corner:
div {
width: 40vw;
height: 40vw;
position: relative;
background-color: darkblue;
--circle: radial-gradient(circle,white 8vw, darkblue 8.1vw);
}
div:before {
content: '';
position: absolute;
width: 100%;
height: 100%;
background-image: var(--circle), var(--circle), var(--circle), var(--circle);
background-size: 18vw 18vw;
background-position: -40% -40%, 140% -40%, -40% 140%, 140% 140%;
background-repeat: no-repeat;
}
<div></div>

Update: There are a plethora of options available now. Check out one of the other answers.
Original answer:
Unfortunately, there is currently not a solution based on official or implemented CSS Specs :(
However, as other people have added, there are possible solutions (or cheats?) you can do to achieve the same effect using JS libraries or complex HTML/CSS implementations. I came across this issue whilst looking for a way to make even more complex corners than the OP without using images.
I have filed a bug (Feature Request) over at the webkit site - as there does not appear to be one filed already.
Bug 62458 - Feature Request: Inverse rounded corners

For a plain background-color, you actually can, using pseudo element and box shadow to draw background-color instead, and it will not hide backgrounds of parent's container, you will actually see them through.
What you need is a browser that understands :before/:after and box-shadow :) ...
For IE8 , you can draw hudge borders instead shadows. http://codepen.io/anon/pen/fFgDo
box-shadow approach : http://codepen.io/anon/pen/FwLnd
div {
margin:2em; /* keep it away from sides to see result */
padding:2em;/* for test to size it when empty */
position:relative; /* reference to set pseudo element where you wish */
overflow:hidden;/* you do not want the box-shadow all over the page */
}
div:before {
content:'';
position:absolute;
width:80px;
height:80px;
top:-40px;
left:-40px;
border-radius:100%;
box-shadow:0 0 0 2000px #1D005D;/* here draw the shadow inside its parent , maybe z-index will be required for content */
}
pseudo element can take any shape, and transform via css and set any where in its element to draw kind of holes through : examples : http://codepen.io/gc-nomade/pen/nKAka

I made an online generator to easily get the code of any combination you want: https://css-generators.com/custom-corners/
A few examples:
.one {
--mask: radial-gradient(40px at 40px 40px,#0000 98%,#000) -40px -40px;
-webkit-mask: var(--mask);
mask: var(--mask);
}
.two {
--mask:
radial-gradient(40px at 0 0,#0000 98%,#000) 0/51% 100% no-repeat,
radial-gradient(40px at 100% 100%,#0000 98%,#000) 100%/51% 100% no-repeat;
-webkit-mask: var(--mask);
mask: var(--mask);
}
.three {
--mask:
radial-gradient(60px at 60px 60px,#0000 calc(98% - 10px),#000 calc(100% - 10px) 98%,#0000) -60px -60px,
linear-gradient(90deg,#000 20px,#0000 0) -10px 50% /100% calc(100% - 120px + 10px) repeat-x,
linear-gradient( #000 20px,#0000 0) 50% -10px/calc(100% - 120px + 10px) 100% repeat-y;
-webkit-mask: var(--mask);
mask: var(--mask);
}
.four {
--mask: radial-gradient(60px at 0 0,#0000 98%,#000);
-webkit-mask: var(--mask);
mask: var(--mask);
}
.five {
--mask:
radial-gradient(60px at 100% 0,#0000 calc(98% - 10px),#000 calc(100% - 10px) 98%,#0000),
conic-gradient(from 90deg at 10px 10px,#0000 25%,#000 0) 0 0/calc(100% - 60px + 10px) 100% repeat-y,
conic-gradient(at bottom 10px right 10px,#000 75%,#0000 0) 0 100%/100% calc(100% - 60px + 10px) repeat-x;
-webkit-mask: var(--mask);
mask: var(--mask);
}
.box {
width: 150px;
aspect-ratio:1;
display:inline-block;
background:linear-gradient(red,blue);
}
<div class="box one"></div>
<div class="box two"></div>
<div class="box three"></div>
<div class="box four"></div>
<div class="box five"></div>

There are ways you could solve this issue by using just CSS - however it would depend on the colour of your background (if solid its easier) if you have a pattern for background it might be slightly more complex.
I cover a basic example here of how to make an Inverse Border Radius in CSS (here). This uses a trick with the size of Border to use the inside, you might have to do some positioning to get it to work properly however as you can see its possible. Especially if you specify a background-color for each span.
If you want all 4 corners you would have to add a separate class for each span inside your div, and each class would simulate a corner, top left, top right etc.

No.
If you have solid background you can probably use css to create the bite.
Otherwise, there isn't anything special you can do beyong using PNGs, much like you'd create round corners before border-radius.

actually there's one way, like this:
<div style="background-color: red;height: 12px; width: 12px;">
<div style="margin-top: 40px; height: 12px; width: 12px; moz-border-radius-topright: 12px;
-webkit-border-top-right-radius: 12px; border-top-right-radius: 12px; background-color:#fff">
</div>
</div>
but as #Domenic says you'll need a solid background, otherwise you'll get this:
<div style=" background-color:#666">
<div style="background-color: red;height: 12px; width: 12px;">
<div style="margin-top: 40px; height: 12px; width: 12px; moz-border-radius-topright: 12px;
-webkit-border-top-right-radius: 12px; border-top-right-radius: 12px; background-color:#fff">
</div>
</div>

Related

How to make a fluid div with a custom shape

I have a div that will be the header of the site I'm working on that is a custom shape. The issue I am having is that the header needs to resize horizontally while retaining the integrity of the border radius and curves that are part of the shape. The problem with just using a transparent div with the shape as a background SVG is that when the window is resized, the integrity of the border radius and the angled section of the graphic are lost, meaning they get distorted into another shape. Here is an image of the shape:
The initial way I attempted to create this element was by placing it as an SVG, and resizing one of the line segments of the SVG in Javascript, but the performance on this was very poor, it was overly-complicated, and it was difficult to get the sizing correct.
The closest I got to the desired result was by cutting the right side tail of the SVG and using it as an :after element, which gave me the horizontal fluidity I was looking for, but encountered issues with matching the border color of the div and the stroke of the SVG. The div uses a translucent white background and a translucent colored border. Since the border is technically "on top" of the white background, the resulting color value is dynamic depending on the background of the page. This makes it difficult to match the stroke of the SVG and the border color of the div. There was also an issue where a vertical line would show up at different resolutions between the div and :after SVG element. You can see in the picture below that this method is not ideal, the SVG border color and width does not match the div on the left, and if you look closely there is a gap between the two elements (much more visible on a dark background which the site will be using).
body {
background-color: black;
margin: 10px 20px;
}
.header {
background-color: rgb(217 217 217 / 0.5);
border: 3px solid rgb(122 112 158 / 0.5);
border-bottom-left-radius: 24px;
border-right: none;
display: block;
width: calc(100% - 305px);
height: 60px;
position: relative;
}
.header:after {
background-image: url("data:image/svg+xml,%3Csvg width='308' height='65' viewBox='0 0 308 65' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M0.00179921 3.00586H293.755C296.737 3.00586 299.597 4.08424 301.706 6.00378C303.815 7.92331 305 10.5268 305 13.2414V22.7809C305 25.4955 303.815 28.099 301.706 30.0185C299.597 31.938 296.737 33.0164 293.755 33.0164H126.396C75.9048 33.0164 52.8027 61.9625 0 61.9625L0.00179921 3.00586Z' fill='%23D9D9D9' fill-opacity='0.5'/%3E%3Cpath d='M293.755 0.00585938C297.447 0.00585938 301.037 1.33813 303.726 3.78519C306.424 6.24078 308 9.6351 308 13.2414V22.7809C308 26.3872 306.424 29.7815 303.726 32.2371C301.037 34.6842 297.447 36.0164 293.755 36.0164H126.396C101.996 36.0164 84.1741 42.9185 65.6587 50.0893L65.1482 50.287C46.4357 57.5333 27.0057 64.9625 9.15527e-05 64.9625V61.9625C1.01084 61.9625 2.01071 61.9519 3.00009 61.9311C28.1433 61.4023 46.5167 54.2861 64.6923 47.2465C83.1648 40.0919 101.433 33.0164 126.396 33.0164H293.755C296.737 33.0164 299.597 31.938 301.706 30.0185C303.815 28.099 305 25.4955 305 22.7809V13.2414C305 10.5268 303.815 7.92331 301.706 6.00378C299.597 4.08424 296.737 3.00586 293.755 3.00586H0.00189066L0 0.00585938H293.755Z' fill='rgb(122 112 158 / .50)' /%3E%3C/svg%3E%0A");
content: "";
background-size: contain;
background-repeat: no-repeat;
width: 310px;
height: 66px;
left: 100%;
top: -3px;
position: absolute;
}
<div class="header">
</div>
You were on the right track with splitting up the image. You could either split the png you provided in your example, or if you have access to the tools, you could make three svgs.
Using the png you provided as an example, I made a new image 50px wide starting from the left. I made a second image 500px wide starting from the right. Finally, for the center, I made a third image that was only 1px wide taken from the horizontal center of the provided png. That 1px can be repeated horizontally to give the illusion that it is one image.
There are many ways to assemble them for the header. You could use a table, a grid, divs with positioning and float. I chose to use flex.
body {
background-color: black;
margin: 10px 20px;
}
.header {
display: flex;
flex-direction: row;
flex-wrap: nowrap;
height: 96px;
}
.header_left {
flex-grow: 0;
background-image: url("h_left.png");
background-repeat: no-repeat;
width: 50px;
max-width: 50px;
min-width: 50px;
}
.header_middle {
flex-grow: 1;
display: block;
background-image: url("h_mid.png");
background-repeat: repeat-x;
}
.header_right {
flex-grow: 0;
display: block;
background-image: url("h_right.png");
background-repeat: no-repeat;
width: 500px;
max-width: 500px;
min-width: 500px;
}
<body>
<div class="header">
<div class="header_left"></div>
<div class="header_middle"></div>
<div class="header_right"></div>
</div>
</body>

update css radius to straight line (jsfiddle attached) [duplicate]

This question already has answers here:
How do CSS triangles work?
(23 answers)
Closed 1 year ago.
I have a jsfiddle link as follows
https://jsfiddle.net/utLhbc3g/
As you can see, i am trying to make a right angle triangle on the left side bottom of the box. but it shows a curve.
.box{
position:relative;
background:#fff;
display:block;
width:100px;
height:100px;
border-radius: 100% / 0 0 0 100px;
}
.box::before{
position:absolute;
z-index:-1;
width:100%;
height:100%;
background:#f9955e;
content:"";
}
Can someone please let me know how to straighten that curve line.
Hmm. It's just not going to happen for you using border radius. Border radius applies rounding to corners. If we add a border we can see what's really happening here.
.box {
position: relative;
background: #fff;
display: block;
width: 100px;
height: 100px;
border-radius: 100% / 0 0 0 100px;
border: 5px solid black;
}
.box::before {
position: absolute;
z-index: -1;
width: 100%;
height: 100%;
background: red;
content: "";
}
<div class="box"></div>
You have other options, however. CSS triangles provide a nice alternative.
.box {
width: 0;
height: 0;
border-style: solid;
border-width: 120px 0 0 120px;
border-color: transparent transparent transparent #4f46e5;
}
<div class="box"></div>
See here: https://www.fetoolkit.io/widget/css-triangle
You might also consider the clip-path property, depending on your use case.
clip-path: polygon(0 0, 0% 100%, 100% 100%) 👈 that will give you an equivalent object.
See here for a nice clip-path visualization tool (and it gives you code):
https://bennettfeely.com/clippy/
Good luck!

CSS Transparent Windows

This idea comes from the idea of an arcade cabinet. Let's say you have 2 layers in a project. Layer 1 with z-index of -1 has a background of blue. I want the upper most div to be black with the inner area of the div to be semi-transparent, similar to a window on an arcade cabinet. How would I solve this issue?
To give you an idea it would look like:
Arcade Cabinet Screen
Here you are:
body {
display: flex;
align-items: center;
justify-content: center;
height: 100vh;
perspective: 1000px;
}
#s {
border-radius: 7vh;
width: 102vh;
height: 77vh;
box-shadow: 0 0 0 50vw #000;
transform: rotateX(-3deg);
background: linear-gradient(0, rgba(0, 0, 0, .3) 1px, transparent 0) 0 / 1px 3px, url(https://picsum.photos/800/600) 0 0 /cover
}
<div id="s"></div>
You can't do that... in the way you want. You would need to have multiple layers compose the "cabinet" facade. These would sit on the top. The blue could be in the background at -1. If you wanted to then have the "semi-transparent" part in there, then that would probably be a separate layer.
The facade below is in four "pieces": top, right, bottom, left. The screen itself sits in one layer. The glare sits in another.
.screen{
z-index:-1;
right:0;top:0;left:0;bottom:0;
background-color:blue;
position:absolute;
}
.screen div{
margin-top:90px;
color: yellow;
text-align: center;
font-family: fantasy;
}
.piece{
z-index:1;
background-color:black;
position:absolute;
}
.top{
height:4%;width:100%;
top:0;left:0;
}
.bottom{
height:4%;width:100%;
bottom:0;left:0;
}
.right{
height:100%;width:2%;
top:0;right:0;
}
.left{
height:100%;width:2%;
top:0;left:0;
}
.glare{
z-index:0;
background: radial-gradient(75% 35%, rgba(200,200,200,0.5), rgba(240,240,240,0.3));
right:0;top:0;left:0;bottom:0;
position:absolute;
}
<div class="top piece"></div>
<div class="right piece"></div>
<div class="bottom piece"></div>
<div class="left piece"></div>
<div class="glare"></div>
<div class="screen">
<div>press any button to continue...</div>
</div>
Try using three layers.
The Screen can be blue and behind that you have a big black div as the screen frame. On top of the screen you can put a transparent div.
The problem you'd face when using two divs is that the frame of the screen would look grey instead of the desired black effect.
To accomplish what you want, you need to think of layering in a different manner then how an arcade machine is built.
The black screen bezel is the lowest layer (#bezel)
The screen is the middle layer (#screen)
The overlay is the top layer (#overlay)
#bezel,
#overlay,
#screen {
height: 240px;
width: 256px;
}
#overlay,
#screen img {
border-radius: 20px;
}
#bezel {
background-color: black;
padding: 50px;
}
#overlay {
z-index: 2;
position: absolute;
background-color: rgba(0, 0, 255, 0.4);
}
<section id="bezel">
<section id="overlay"></section>
<section id="screen">
<img src="https://www.mobygames.com/images/shots/l/116293-rad-racer-ii-nes-screenshot-driving-off-into-the-sunset.png" />
</section>
</section>

Blurring background in only a select area (behind text)

I'm creating a homepage using HTML/CSS/Javascript, on this page I have text floating on the top left portion of the screen. I have a number of backgrounds saved from Reddit and a script which randomly selects one upon start, my problem is that because this background can be any colour it is difficult for the text to be readable, so my idea was to blur the background around just the text in order to make it readable. Ideally, it would follow just the text and blur the outline of it but I tried placing it in a box, however, because it uses relative layout it was difficult to have the box fill and blur the minimum space possible.
How can I improve the readability of text by blurring the background just around the text? I'm also open to other suggestions to improve readability (remembering the background changes)
Try using the CSS3 filters: https://www.inserthtml.com/2012/06/css-filters/
The link above should have a guide on how to blur image and you should be able to modify this to fit your requirements.
You have chosen the difficult way. Simply use CSS text-shadow Property. For example if the text is in black, use white shadow color for it.
Example:
body {
background-image: url('https://images.template.net/wp-content/uploads/2015/09/01191816/Perfect-Summer-Background-Free-Download.png');
background-size: cover
}
.text {
color: #000;
font-size: 3em;
text-shadow: 0 0 10px #fff, 0 0 10px #fff, 0 0 10px #fff
}
<div class="text">Some Text</div>
It's a quick n dirty fix... but I usually just add a contrast background color to the text wrapper (like the first one in the example below). You can also use blur filter if you want. I referred to this article frosting glass css filter for the second one. But in the comment of that article, some say there's a trade off of performance.
#bg {
background: url(https://picsum.photos/500/400?image=0) center center no-repeat;
background-size: cover;
width: 500px;
height: 300px;
margin-bottom: 30px;
}
#text-wrap1 {
padding: 30px;
background-color: rgba(255,255,255,0.7);
text-shadow: 1px 1px 1px white;
width: 150px;
}
#text-wrap2 {
padding: 30px;
width: 150px;
position: relative;
}
#text-wrap2 p {
position: relative;
text-shadow: 1px 1px 1px white;
}
#text-wrap2:before {
content: '';
display: block;
width: 100%;
height: 100%;
background-color: white;
position: absolute;
left:0;
top:0;
-webkit-filter: url('#blur');
filter: url('#blur');
-webkit-filter: blur(5px);
filter: blur(5px);
background-size: cover;
opacity: 0.7;
}
<div id="container">
<div id="bg">
<div id="text-wrap1">
This is a random paragraph
</div>
</div>
<div id="bg">
<div id="text-wrap2">
<p>This is a random paragraph</p>
</div>
</div>
</div>

Diagonally split/combine div/image with CSS

I'm trying to achieve something like the following:
The diagonal split should go from the top right corner to the bottom left corner, at an exact angle so that both sides are totally equally proportioned.
I found an example online, but it was for wide aspect images, while trying to modify it to fit my 1:1 ratio purpose, I can't seem to get the bottom image to line up properly, but the top one works fine.
The diagonal split is also off-center, and the yellow background is there to show the area that should be filled by the lower image. The lower image should be the same size as the top one, just with the bottom half instead of the top half showing.
I have created a fiddle to demonstrate: https://jsfiddle.net/uxuv17at/2/
HTML
<div class="split-image-container">
<div class="split-image-bottom">
<img src="https://merkd.com/usr/members/icons/thumb.php?src=1435366066.9.png&w=300" alt="Just Another Clan" title="Just Another Clan" />
</div>
<img src="https://merkd.com/usr/teams/icons/thumb.php?src=1441676463.1.jpg&w=300" alt="ExtraordinaryKillers" title="ExtraordinaryKillers" />
</div>
CSS
.split-image-container{
height: 300px;
width: 300px;
overflow: hidden;
position: relative;
border: 1px solid black;
padding: 0;
background-color: green;
}
/*Rotate this div and position it to cut the rectangle in half*/
.split-image-bottom{
transform: rotate(315deg);
position: absolute;
top: 85px;
left: 70px;
overflow: hidden;
height: 350px;
width: 350px;
background: yellow;
}
/*Apply exact opposite amount of rotation to the .image2 class so image appears straight */
/*Also align it with the top of the rectangle*/
.split-image-bottom img{
transform: rotate(45deg);
position: absolute;
top: -50px;
left: 15px;
}
CSS Only
Pure CSS solution using the clip-path property. Browser support is pretty bad though.
.split-image-container{
height: 300px;
width: 300px;
position: relative;
}
img{
width:100%;
height:100%;
position:absolute;
}
.clip{
-webkit-clip-path: polygon(100% 0%, 0% 100%, 100% 100%);
clip-path: polygon(100% 0%, 0% 100%, 100% 100%);
}
<div class="split-image-container">
<img src="https://merkd.com/usr/members/icons/thumb.php?src=1435366066.9.png&w=300" alt="Just Another Clan" title="Just Another Clan"/>
<img src="https://merkd.com/usr/teams/icons/thumb.php?src=1441676463.1.jpg&w=300" alt="ExtraordinaryKillers" title="ExtraordinaryKillers" class="clip"/>
</div>
SVG
This one uses the svg clippath. Browser support should be a lot better.
<svg viewBox='0 0 100 100' preserveAspectRatio='none'>
<clipPath id="clipPolygon">
<polygon points="100 0,0 100,100 100">
</polygon>
</clipPath>
<image viewBox='0 0 100 100' preserveAspectRatio='none' height="100" width="100" xlink:href="https://merkd.com/usr/members/icons/thumb.php?src=1435366066.9.png&w=300" />
<image viewBox='0 0 100 100' preserveAspectRatio='none' height="100" width="100" clip-path="url(#clipPolygon)" xlink:href="https://merkd.com/usr/teams/icons/thumb.php?src=1441676463.1.jpg&w=300" />
</svg>

Categories

Resources