I have CSS code
#box {
width: 200px;
height: 50px;
background-color: blue;
border-top-left-radius: 9999px;
border-bottom-left-radius: 9999px;
position: relative;
margin: 30px;
text-align: center;
color: white;
padding-top: 10px;
}
#box::before,
#box::after {
content: "";
width: 0;
height: 0;
right: 0;
position: absolute;
}
#box::before {
border-right: 10px solid blue;
border-top: 10px solid blue;
border-left: 10px solid transparent;
border-bottom: 10px solid transparent;
bottom: -20px;
}
#box::after {
border-right: 10px solid blue;
border-top: 10px solid transparent;
border-left: 10px solid transparent;
border-bottom: 10px solid blue;
position: absolute;
top: -20px;
}
<div id="box">#box</div>
which gives some shape like
shape I need is
I need curved line instead of hypotenuse in triangles at top-right (#box::before) and bottom-right (#box::after) as in image.
Is there any way to achieve using pure CSS ?
codesandbox demo
Thanks
You can create a concaved radius using the box-shadow property.
This technique creates a transparant square with overflow hidden.
It then creates a transparant circle with a box shadow.
We then adjust the position of the circle to only view 1 quarter of
it.
SNIPPET
#box {
position: relative;
width: 200px;
height: 50px;
background-color: blue;
border-radius: 9999px 0 0 9999px;
margin: 30px;
text-align: center;
color: #fff;
padding-top: 10px;
}
#top,
#bottom {
position: absolute;
height: 30px;
width: 30px;
right: 0;
overflow: hidden;
}
#top {
top: -30px;
}
#bottom {
bottom: -30px;
}
#top::before,
#bottom::before {
content: '';
position: absolute;
right: 0;
height: 200%;
width: 200%;
border-radius: 100%;
box-shadow: 10px 10px 5px 100px blue;
z-index: -1;
}
#top::before {
top: -100%;
}
<div id="box">
<div id="top"></div>
#box
<div id="bottom"></div>
</div>
You can easily achieve this by using svg background images like in this snippet. Here the curves may not the way you want but surely you can change the path in the svg to your needs.
#box {
width: 200px;
height: 50px;
background-color: blue;
border-top-left-radius: 9999px;
border-bottom-left-radius: 9999px;
position: relative;
margin: 30px;
}
#box::before,
#box::after {
content: "";
width: 20px;
height: 20px;
right: 0;
position: absolute;
}
#box::before {
background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg"><path fill="blue" d="M0 0 Q20 0 20 20 L20 0Z" /></svg>');
bottom: -20px;
}
#box::after {
background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg"><path fill="blue" d="M0 20 Q20 20 20 0 L20 20Z" /></svg>');
top: -20px;
}
<div id="box"></div>
Can you use negative space? You could have a container with the same background color as your shape, then round the corners surrounding elements to create the illusion.
.container {
background-color: blue;
width: 100%;
}
.negat {
background-color: white;
height: 100px;
}
.posit-bg {
background-color: white;
}
.posit {
background-color: blue;
height: 100px;
border-radius: 50px 0px 0px 50px;
}
.top {
border-radius: 0px 0px 50px 0px;
}
.bot {
border-radius: 0px 50px 0px 0px;
}
<div class="container">
<div class="negat top"></div>
<div class="posit-bg">
<div class="posit"></div>
</div>
<div class="negat bot"></div>
</div>
#box{
width:200px;
height:50px;
background-color:blue;
color:#ffffff;
text-align:center;
padding-top:30px;
border-radius:9999px 0 0 9999px;
}
.sq{
width:25px;
height:25px;
background-color:blue;
}
#sq1,#sq2,#sq11,#sq22{
border-radius:-999px;
margin-left:175px;
}
.sq1{
background-color:#ffffff;
height:25px;
width:25px;
}
#sq11{
border-bottom-right-radius:9999px;
margin-bottom:-25px;
position: relative;
z-index:1;
}
#sq22{
border-top-right-radius:9999px;
margin-top:-25px;
position: relative;
z-index:1;
}
<div class="sq1" id="sq11"></div>
<div class="sq" id="sq1"></div>
<div id="box">#box</div>
<div class="sq" id="sq2"></div>
<div class="sq1" id="sq22"></div>
Related
This question already has answers here:
How can I show only corner borders?
(20 answers)
Closed 3 years ago.
Here's a CSS brainteaser for you. I want to create a border with just the corners around a text field, like the image below:
I thought about creating 2 rectangle divs, one with blue border and the other white and then overlaying them, but this didn't seem very elegant (e.g. it wouldn't work well if I wanted to vary the background).
Any ideas how else I might do this?
EDIT:
Here's the HTML:
<div class="blue white1 white">text</div>
.blue {
border: blue 4px solid;
etc..
}
Using one div, and one node for targeting. http://jsfiddle.net/eCEds/2/
HTML:
<div class="blue white1 white"><p>Text</p></div>
CSS:
.blue {position:relative;width:400px;height:300px;}
.blue:before, .blue:after, .blue>:first-child:before, .blue>:first-child:after {
position:absolute;
width:80px; height: 80px;
border-color:blue;
border-style:solid;
content: ' ';
}
.blue:before {top:0;left:0;border-width: 4px 0 0 4px}
.blue:after {top:0;right:0;border-width: 4px 4px 0 0}
.blue>:first-child:before {bottom:0;right:0;border-width: 0 4px 4px 0}
.blue>:first-child:after {bottom:0;left:0;border-width: 0 0 4px 4px}
.text
{
border: 1px solid #00f;
height: 200px;
position: relative;
width: 200px;
}
.text:after
{
position:absolute;
top: 10%;
height: 80%;
content: "";
width: 99%;
left: -3px;
border-left: 5px solid #fff;
border-right: 5px solid #fff;
}
.text:before
{
position:absolute;
left: 10%;
height: 99%;
content: " ";
width: 80%;
top: -3px;
border-top: 5px solid #fff;
border-bottom: 5px solid #fff;
}
<div class="text">test test gfgfgf gfg f</div>
This is my variant.
Something like this is achievable with CSS gradients and multiple backgrounds: http://jsbin.com/usegup/1/edit. But probably SVG background will be more suitable for such cases.
Do you mean something like this: http://jsfiddle.net/FlameTrap/F5bC6/
HTML
<div class="text">
<span class="corner TL"></span>
<span class="corner TR"></span>
<span class="corner BL"></span>
<span class="corner BR"></span>
<div class="text">Text</div>
</div>
CSS
.text {
background: #fff;
width: 300px;
height: 200px;
position: relative;
z-index: 3;
}
.corner {
position: absolute;
background: blue;
width: 20px;
height: 20px;
z-index: 2;
}
.TL {
top: -10px;
left: -10px
}
.TR {
top: -10px;
right: -10px
}
.BL {
bottom: -10px;
left: -10px
}
.BR {
bottom: -10px;
right: -10px
}
Something like this would work and give you less issues in older browsers to boot:
<style>
.blue {
width: 500px;
height: 500px;
position: relative;
}
.corner {
position: absolute;
border-color: blue;
width: 30px;
height: 30px;
}
.tl {
top: 0;
left: 0;
border-top: 2px solid;
border-left: 2px solid;
}
.tr {
top: 0;
right: 0;
border-top: 2px solid;
border-right: 2px solid;
}
.br {
bottom: 0;
right: 0;
border-bottom: 2px solid;
border-right: 2px solid;
}
.bl {
bottom: 0;
left: 0;
border-bottom: 2px solid;
border-left: 2px solid;
}
</style>
<div class="blue">
<div class="tl corner"></div>
<div class="tr corner"></div>
<div class="bl corner"></div>
<div class="br corner"></div>
</div>
Here is the shape I'm trying to create in pure CSS:
I have a more complete jsfiddle http://jsfiddle.net/8Lxr5s57/7/. Is there a better, more efficient way to achieve this same result?
.angled_container {
background-color: #fff;
height: 200px;
position: relative;
overflow: hidden;
clear: both;
}
.angled_container:before,
.angled_container:after {
content: "";
width: 110%;
height: 100%;
display: block;
position: absolute;
top: 0;
}
.angled_container:before {
background-color: #606060;
transform: rotate(12deg);
-webkit-transform-origin: left top;
left: 0;
}
.angled_container:after {
background-color: #6bb2c6;
transform: rotate(-12deg);
-webkit-transform-origin: right top;
left: -10%;
}
.angled_container--open-left:before {
background-color: #6bb2c6;
z-index: 2;
}
.angled_container--open-left:after {
background-color: #606060;
z-index: 1;
}
<div class="angled_container angled_container--open-right"></div>
CSS
I would suggest using skewY() instead of rotate() for the two triangles. it will avoid some positioning issues and prevent using wider pseudo elements than the container :
.angled_container {
height: 200px;
position: relative;
overflow: hidden;
}
.angled_container:before,
.angled_container:after {
content: "";
width: 100%; height: 100%;
display: block;
position: absolute;
top: 0; left: 0;
}
.angled_container:before {
background-color: #606060;
transform: skewY(12deg);
transform-origin: left top;
}
.angled_container:after {
background-color: #6bb2c6;
transform: skewY(-12deg);
transform-origin: right top;
}
<div class="angled_container angled_container--open-right"></div>
SVG
Alternatively, you can use an inline SVG with 2 polygon elements. This is totaly responsive and probably easier to make/maintain as you can style the triangles in CSS with the fill property :
svg{display:block; width:100%;}
.first{
fill:#606060;
}
.second{
fill:#6bb2c6;
}
<svg viewbox="0 0 100 30">
<polygon class="first" points="0 0 100 28 0 25 0 28"/>
<polygon class="second" points="0 28 0 25 100 0 100 28 52 28 50 30 48 28 0"/>
</svg>
Break them down into triangles. This supports IE8+.
.container {
position: relative;
width: 1000px;
height: 260px;
border-bottom: 40px solid #65abc2;
}
.grey {
position: absolute;
top: 0;
left: 0;
width: 0;
height: 0;
border-bottom: 260px solid #595959;
border-right: 1000px solid transparent;
}
.blue {
position: absolute;
top: 0;
left: 0;
width: 0;
height: 0;
border-bottom: 260px solid #65abc2;
border-left: 1000px solid transparent;
}
.container:after {
content: '';
display: block;
position: absolute;
bottom: -53px;
/* included thickness of border-bottom */
left: 50%;
margin-left: -17px;
width: 0px;
height: 0px;
border-top: 13px solid #65abc2;
border-left: 17px solid transparent;
border-right: 17px solid transparent;
}
<div class="container">
<div class="grey"></div>
<div class="blue"></div>
</div>
You can do it all with CSS triangles but I'm not sure its any better than what you have already. You'll need the pseudo elements ::before and ::after to get the extra space at the bottom and the mini arrow.
div {
width:0;
height:0;
margin-top:55px;
border-top:130px solid white;
border-right:500px solid #6DB1C3;
border-bottom:140px solid #6DB1C3;
border-left:500px solid #5F5F5F;
position:relative;
}
div:before {
content:" ";
position:absolute;
bottom:-170px;
width:1000px;
height:30px;
left:-500px;
background:#6DB1C3;
}
div:after {
content:" ";
position:absolute;
bottom:-202px;
left:-20px;
width:0;
height:0;
border:20px solid transparent;
border-top:12px solid #6DB1C3;
}
<div></div>
How would i create a div shape like this? I have read a lot of techniques but i could not figure this one out. Inside the div is text that should not be distorted.
Every technique is welcome it does not have to be pure css.
My HTML structure:
<div class="intro">
<div class="intro-header">
<h1>Headline WOW</h1>
</div>
<div class="intro-text">
<p>Mieleni minun tekevi, aivoni ajattelevi lähteäni laulamahan, saa'ani sanelemasaa'ani sanelema sanelemasaa'ani sanelema </p>
</div>
</div>
you could use some skewed pseudo elements for this:
.first,
.last {
text-align: center;
line-height: 80px;
height: 80px;
background: green;
position: relative;
display: inline-block;
width: 400px;
margin-bottom: 20px;
}
.first:after {
content: "";
position: absolute;
bottom: 0;
left: 0;
height: 50%;
width: 100%;
transform: SkewY(2deg);
transform-origin: bottom left;
background: inherit;
}
.last:before {
content: "";
position: absolute;
top: 0;
left: 0;
height: 50%;
width: 100%;
transform: SkewY(2deg);
transform-origin: bottom right;
background: inherit;
}
<div class="first">FIRST LINE</div>
<div class="last">LAST LINE</div>
An alternative (possibly) would be to use a gradient (although this may lead to jagged edges). Solution credit to Harry
body {
background: -webkit-linear-gradient(0deg, crimson, indianred, purple);
}
div {
height: 400px;
width: 400px;
background: -webkit-linear-gradient(75deg, lightseagreen 45%, transparent 45%, transparent 55%, lightseagreen 55%);
}
<div></div>
You can do this with border cut-offs.
As an example:
.top {
height: 300px;
background: red;
position: relative;
width: 300px
}
.top:before {
content: '';
position: absolute;
bottom: 0;
right: 0;
border-bottom: 10px solid white;
border-right: 300px solid red;
width: 0;
}
.bottom {
height: 300px;
background: red;
position: relative;
width: 300px;
padding-top: 10px;
margin-top: 0px;
}
.bottom:before {
content: '';
position: absolute;
top: 0;
right: 0;
border-top: 10px solid white;
border-left: 300px solid red;
width: 0;
}
<div class="top">Text</div>
<div class="bottom">Text</div>
This should do it.
html,body{
margin:0;
height:100%;
}
.intro{
width:400px;
display:inline-block;
background:red;
padding:50px;
}
.intro-header,.intro-text{
width:100%;
display:inline-block;
background:#ccc;
text-align:center;
position:relative;
}
.intro-header{
margin-bottom:50px;
}
.intro-header:after{
position:absolute;
left:0;
content:"";
width: 0;
height: 0;
border-left: 400px solid transparent;
border-top: 20px solid #ccc;
}
.intro-text:after{
position:absolute;
top:-20px;
left:0;
content:"";
width: 0;
height: 0;
border-right: 400px solid transparent;
border-bottom: 20px solid #ccc;
}
Example: CodePen
I recently came across an article detailing how to create responsive triangles with pure CSS. I was wanting to take this a step further to incorporate it into a current design.
I was able to get four triangles placed within a square div perfectly (creating an origami-type effect) and they are responsive.
However when I try to incorporate a hover effect, it does not change the color of the triangle - only the empty space around it.
Also, when my square's width changes (keeping with the responsiveness) the bottom triangle separates from the others - because I used absolute positioning and bottom: 0; to place the triangles within the square.
Does anyone know a way around this to achieve my desired effect in pure CSS? Here is the relevant code : JSFiddle
HTML:
<body>
<div class="container">
<div class="box">
<div class="triSectionTop"></div>
<div class="triSectionRight"></div>
<div class="triSectionBottom"></div>
<div class="triSectionLeft"></div>
</div>
</div>
</body>
SCSS:
.container {
box-sizing: border-box;
height: 400px;
width: 400px;
}
.box {
position: relative;
box-sizing: border-box;
height: 400px;
width: 100%;
}
.triSectionTop {
position: absolute;
top: 0;
width: 100%;
height: 0;
padding-left: 50%;
padding-top: 50%;
overflow: hidden;
&:after {
content: "";
display: block;
width: 0;
height: 0;
margin-left: -200px;
margin-top: -200px;
border-left: 200px solid transparent;
border-right: 200px solid transparent;
border-top: 200px solid #41a5e8;
}
}
.triSectionRight {
position: absolute;
right: 0;
width: 50%;
height: 0;
padding-top: 50%;
padding-bottom: 50%;
overflow: hidden;
&:after {
content: "";
display: block;
width: 0;
height: 0;
margin-top: -200px;
border-top: 200px solid transparent;
border-bottom: 200px solid transparent;
border-right: 200px solid #4eb2f5;
}
}
.triSectionBottom {
position: absolute;
bottom: 0;
width: 100%;
height: 0;
padding-left: 50%;
padding-bottom: 50%;
overflow: hidden;
&:after {
content: "";
display: block;
width: 0;
height: 0;
margin-left: -200px;
border-left: 200px solid transparent;
border-right: 200px solid transparent;
border-bottom: 200px solid #5abeff;
}
}
.triSectionLeft {
position: absolute;
left: 0;
width: 0;
height: 0;
padding-top: 50%;
padding-bottom: 50%;
padding-left: 50%;
overflow: hidden;
&:after {
content: "";
display: block;
width: 0;
height: 0;
margin-top: -200px;
margin-left: -200px;
border-top: 200px solid transparent;
border-bottom: 200px solid transparent;
border-left: 200px solid #67cbff;
}
}
You can achieve the hover effect (background-color change and outside box-shadow) by making the triangles with transform-rotate.
This will allow you to triger the hover event only when the shape is actualy hovered :
DEMO
.box{
width:500px;
height:500px;
position:relative;
overflow:hidden;
}
.box > div{
position:absolute;
bottom:50%; left:50%;
width:75%; height:75%;
transform-origin:0 100%;
z-index:1;
}
.triSectionTop{
-webkit-transform:rotate(-45deg);
-ms-transform:rotate(-45deg);
transform:rotate(-45deg);
background:#41A5E8;
}
.triSectionRight{
-webkit-transform:rotate(45deg);
-ms-transform:rotate(45deg);
transform:rotate(45deg);
background:#4EB2F5;
}
.triSectionBottom{
-webkit-transform:rotate(135deg);
-ms-transform:rotate(135deg);
transform:rotate(135deg);
background:#5ABEFF;
}
.triSectionLeft{
-webkit-transform:rotate(225deg);
-ms-transform:rotate(225deg);
transform:rotate(225deg);
background:#67CBFF;
}
.box > div:hover{
background:teal;
box-shadow: 0 0 10px 0 #656565;
z-index:2;
}
<div class="box">
<div class="triSectionTop"></div>
<div class="triSectionRight"></div>
<div class="triSectionBottom"></div>
<div class="triSectionLeft"></div>
</div>
This will work try this
Here is the Html
<div class="arrow-up"></div>
<div class="arrow-down"></div>
<div class="arrow-left"></div>
<div class="arrow-right"></div>
Here is the CSS
.arrow-up {
width: 0;
height: 0;
border-left: 5px solid transparent;
border-right: 5px solid transparent;
border-bottom: 5px solid black;
}
.arrow-down {
width: 0;
height: 0;
border-left: 20px solid transparent;
border-right: 20px solid transparent;
border-top: 20px solid #f00;
}
.arrow-right {
width: 0;
height: 0;
border-top: 60px solid transparent;
border-bottom: 60px solid transparent;
border-left: 60px solid green;
}
.arrow-left {
width: 0;
height: 0;
border-top: 10px solid transparent;
border-bottom: 10px solid transparent;
border-right:10px solid blue;
}
here is the source
This question already has answers here:
How can I show only corner borders?
(20 answers)
Closed 3 years ago.
Here's a CSS brainteaser for you. I want to create a border with just the corners around a text field, like the image below:
I thought about creating 2 rectangle divs, one with blue border and the other white and then overlaying them, but this didn't seem very elegant (e.g. it wouldn't work well if I wanted to vary the background).
Any ideas how else I might do this?
EDIT:
Here's the HTML:
<div class="blue white1 white">text</div>
.blue {
border: blue 4px solid;
etc..
}
Using one div, and one node for targeting. http://jsfiddle.net/eCEds/2/
HTML:
<div class="blue white1 white"><p>Text</p></div>
CSS:
.blue {position:relative;width:400px;height:300px;}
.blue:before, .blue:after, .blue>:first-child:before, .blue>:first-child:after {
position:absolute;
width:80px; height: 80px;
border-color:blue;
border-style:solid;
content: ' ';
}
.blue:before {top:0;left:0;border-width: 4px 0 0 4px}
.blue:after {top:0;right:0;border-width: 4px 4px 0 0}
.blue>:first-child:before {bottom:0;right:0;border-width: 0 4px 4px 0}
.blue>:first-child:after {bottom:0;left:0;border-width: 0 0 4px 4px}
.text
{
border: 1px solid #00f;
height: 200px;
position: relative;
width: 200px;
}
.text:after
{
position:absolute;
top: 10%;
height: 80%;
content: "";
width: 99%;
left: -3px;
border-left: 5px solid #fff;
border-right: 5px solid #fff;
}
.text:before
{
position:absolute;
left: 10%;
height: 99%;
content: " ";
width: 80%;
top: -3px;
border-top: 5px solid #fff;
border-bottom: 5px solid #fff;
}
<div class="text">test test gfgfgf gfg f</div>
This is my variant.
Something like this is achievable with CSS gradients and multiple backgrounds: http://jsbin.com/usegup/1/edit. But probably SVG background will be more suitable for such cases.
Do you mean something like this: http://jsfiddle.net/FlameTrap/F5bC6/
HTML
<div class="text">
<span class="corner TL"></span>
<span class="corner TR"></span>
<span class="corner BL"></span>
<span class="corner BR"></span>
<div class="text">Text</div>
</div>
CSS
.text {
background: #fff;
width: 300px;
height: 200px;
position: relative;
z-index: 3;
}
.corner {
position: absolute;
background: blue;
width: 20px;
height: 20px;
z-index: 2;
}
.TL {
top: -10px;
left: -10px
}
.TR {
top: -10px;
right: -10px
}
.BL {
bottom: -10px;
left: -10px
}
.BR {
bottom: -10px;
right: -10px
}
Something like this would work and give you less issues in older browsers to boot:
<style>
.blue {
width: 500px;
height: 500px;
position: relative;
}
.corner {
position: absolute;
border-color: blue;
width: 30px;
height: 30px;
}
.tl {
top: 0;
left: 0;
border-top: 2px solid;
border-left: 2px solid;
}
.tr {
top: 0;
right: 0;
border-top: 2px solid;
border-right: 2px solid;
}
.br {
bottom: 0;
right: 0;
border-bottom: 2px solid;
border-right: 2px solid;
}
.bl {
bottom: 0;
left: 0;
border-bottom: 2px solid;
border-left: 2px solid;
}
</style>
<div class="blue">
<div class="tl corner"></div>
<div class="tr corner"></div>
<div class="bl corner"></div>
<div class="br corner"></div>
</div>