i am making block with arrow and border looks like
And i have tried this.
* {
box-sizing: border-box;
}
.block-arr {
background: purple;
margin: 20px;
margin-right: 100px;
position: relative;
}
.block-arr .inner {
min-height: 100px;
display: flex;
padding: 20px;
align-items: center;
position: relative;
}
.block-arr .inner:after {
border-top: 50px solid transparent;
border-bottom: 50px solid transparent;
border-left: 50px solid purple;
content: '';
position: absolute;
left: 100%;
top: 0;
}
.block-arr:after {
border-top: 50px solid transparent;
border-bottom: 50px solid transparent;
border-left: 50px solid purple;
content: '';
position: absolute;
left: 100%;
top: 0;
}
<div class="block-arr">
<div class="inner">
<strong>Main Heading</strong>
<span>Sub Heading</span>
</div>
</div>
How can i make block like image? And can we make this arrow height responsive?
I would consider a mix of skew transformation, inset box-shadow and some linear-gradient:
* {
box-sizing: border-box;
}
.block-arr {
padding: 50px;
margin: 20px;
margin-right: 100px;
position: relative;
background: linear-gradient(#fff, #fff)2px 0/2px 100% no-repeat, purple;
border-left: 2px solid purple;
z-index: 0;
}
.block-arr:before {
content: "";
position: absolute;
top: 0;
bottom: 50%;
left: 0;
right: 0;
background: purple;
border: 5px solid purple;
border-bottom: none;
border-left: none;
box-shadow: -2px 2px 0px #fff inset;
transform: skew(25deg);
transform-origin: top left;
z-index: -1;
}
.block-arr:after {
content: "";
position: absolute;
top: 50%;
bottom: 0;
left: 0;
right: 0;
background: purple;
border: 5px solid purple;
border-top: none;
border-left: none;
box-shadow: -2px -2px 0px #fff inset;
transform: skew(-25deg);
transform-origin: bottom left;
z-index: -1;
}
<div class="block-arr">
<strong>Main Heading</strong>
<span>Sub Heading</span>
</div>
<div class="block-arr">
<strong>Main Heading</strong><br/>
<span>Sub Heading</span>
</div>
<div class="block-arr">
</div>
And here is a more compressed version with some CSS variable to easily handle color. You can also do the same to handle others variables:
* {
box-sizing: border-box;
}
.block-arr {
--c1:purple;
--c2:#fff;
padding: 50px;
margin: 20px;
margin-right: 100px;
position: relative;
background: linear-gradient(var(--c2), var(--c2))2px 0/2px 100% no-repeat, var(--c1);
border-left: 2px solid var(--c1);
z-index: 0;
}
.block-arr:before,
.block-arr:after {
left: 0;
right: 0;
content: "";
position: absolute;
background: var(--c1);
border: 5px solid var(--c1);
border-left: none;
z-index: -1;
}
.block-arr:before {
top: 0;
bottom: 50%;
border-bottom: none;
box-shadow: -2px 2px 0px var(--c2) inset;
transform: skew(25deg);
transform-origin: top left;
}
.block-arr:after {
top: 50%;
bottom: 0;
border-top: none;
box-shadow: -2px -2px 0px var(--c2) inset;
transform: skew(-25deg);
transform-origin: bottom left;
}
<div class="block-arr">
</div>
<div class="block-arr" style="--c1:red;--c2:yellow">
<strong>Main Heading</strong>
<span>Sub Heading</span>
<p>And yes it is reponsive and grow when height grow</p>
</div>
BONUS
Another fancy and more complex way with only linear-gradient:
* {
box-sizing: border-box;
}
.block-arr {
--c1:purple;
--c2:#fff;
padding: 50px;
margin: 20px;
margin-right: 100px;
position: relative;
border:1px solid;
background:
linear-gradient(to top left,transparent calc(50% + 4px),var(--c2) calc(50% + 4px),var(--c2) calc(50% + 6px),transparent 0) 100% 100%/50px 50% no-repeat,
linear-gradient(to bottom left,transparent calc(50% + 4px),var(--c2) calc(50% + 4px),var(--c2) calc(50% + 6px),transparent 0) 100% 0/50px 50% no-repeat,
linear-gradient(var(--c2),var(--c2)) 4px calc(100% - 4px)/calc(100% - 58px) 2px no-repeat,
linear-gradient(var(--c2),var(--c2)) 4px 4px/calc(100% - 58px) 2px no-repeat,
linear-gradient(var(--c2),var(--c2)) 4px 4px/2px calc(100% - 8px) no-repeat,
linear-gradient(to top left ,transparent 50%,var(--c1) 50%) 100% 100%/50px 50% no-repeat,
linear-gradient(to bottom left,transparent 50%,var(--c1) 50%) 100% 0/50px 50% no-repeat,
linear-gradient(var(--c1),var(--c1)) 0 0/calc(100% - 50px) 100% no-repeat;
}
<div class="block-arr">
</div>
Using :after and :before pseudo elements, i have made this design.
Hope it fulfills your requirement.
Thanks
CSS and HTML:
* {
box-sizing: border-box;
}
p { margin:0; }
.block-arr {
background: purple;
margin: 20px;
margin-right: 100px;
position: relative;
}
.block-arr .inner {
min-height: 100px;
/*display: flex;*/
padding: 20px;
align-items: center;
position: relative;
}
.block-arr .inner:after {
border-top: 50px solid transparent;
border-bottom: 50px solid transparent;
border-left: 50px solid purple;
content: '';
position: absolute;
left: 100%;
top: 0;
}
.block-arr:after {
border-top: 50px solid transparent;
border-bottom: 50px solid transparent;
border-left: 50px solid purple;
content: '';
position: absolute;
left: 100%;
top: 0;
}
.bordered { position:relative; border:1px solid #fff; border-right:none; display: flex; align-items: center; padding:20px; }
.bordered:before, .bordered:after {
content: "";
position: absolute;
height: 72%;
width: 1px;
background: #fff;
top: 0;
right: 0;
z-index: 4;
}
.bordered:before {
transform: rotate(45deg);
top: auto;
right: -3.3%;
bottom: -11%;
}
.bordered:after {
transform: rotate(-45deg);
top: -12%;
right: -3.3%;
}
<div class="block-arr">
<div class="inner"><div class="bordered">
<p><strong>Main Heading</strong>
<span>Sub Heading</span></p>
</div></div>
</div>
Related
I want to build animation like this, but using only css:
I built a triangle, but I can't build a background of moving triangles which will move. See the example in the pictures.
My code:
HTML:
<div class="container">
<div class="triangle up">
</div>
<div class="triangle down-right">
</div>
<div class=" down-right1">
</div>
<div class="triangle down-left">
</div>
</div>
CSS:
.container {
position: relative;
left: 45%;
width: 300px;
height: 250px;
}
.triangle {
position: absolute;
width: 0;
height: 0;
border-left: 50px solid transparent;
border-right: 50px solid transparent;
border-bottom: 100px solid rgb(165,60,255);
background: linear-gradient(90deg, rgba(165,60,255,1) 0%, rgba(98,0,255,1) 100%);
z-index: 999999;
}
.up {
top: 0;
left: auto;
}
.down-right {
top: 100px;
left: 16.5%;
}
.down-right1 {
top: 105px;
left: 24%;
position: absolute;
width: 0;
height: 0;
border-left: 50px solid transparent;
border-right: 50px solid transparent;
border-bottom: 100px solid #c85e5e;
}
.down-left {
top: 100px;
left: -16.5%;
}
I want this animation to start when the page is loading.
An idea using skew tranformation and box-shadow.
.box {
position: fixed;
margin: auto;
top: 0;
left: 0;
right: 0;
bottom: 0;
width: 75px;
height: 64.5px;
transition: 0.5s all 0.5s;
transform-origin: 50% 63%;
}
.box::before,
.box::after,
.box i:before,
.box i:after {
content: "";
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
border-radius: 8px;
transform-origin: bottom;
transition: 0.5s all;
}
.box::before {
background: #5840bc;
box-shadow: 0px -20px #886df8, 0px -40px #c2b3f8;
transform: skewX(-30deg);
border-bottom-right-radius: 0;
}
.box::after {
background: #5844d9;
box-shadow: -20px 0 #7d69ca, -40px 0 #c7bee9;
transform: skewX(30deg);
border-top-right-radius: 0;
}
.box i:before {
background: #714ffe;
box-shadow: 0px -20px #7c6ade, 0px -40px #c7bee9;
transform: translateY(50%) rotate(120deg) skewX(-30deg);
transform-origin: center;
border-bottom-right-radius: 0;
}
.box i:after {
background: #fff;
z-index: 1;
clip-path: polygon(50% 0, 100% 100%, 0 100%);
border-radius: 0;
}
html:hover .box {
transform: rotate(60deg);
}
html:hover .box::before,
html:hover .box::after,
html:hover .box i:before,
html:hover .box i:after {
box-shadow: 0px 0 transparent, 0px 0 transparent;
}
<div class="box"><i></i></div>
I'm trying to achieve the shape as shown in this image:
To have 2 rectangle divs with cut corners , and 1 div positioned behind another div.
But the corners seems incorrect and I can't find the way to show the borders of the shapes.
.wrapper {
display: flex;
justify-content: center;
}
.connect {
width: 254px;
height: 50px;
background: red;
background: #FF2D5069;
border-top: 2px solid #FF2175;
position: absolute;
bottom: 0;
z-index: 5;
}
.connect::before {
content: '';
position: absolute;
bottom: 0;
right: -2px;
border-top: 52px solid white;
border-left: 42px solid transparent;
}
.connect::after {
content: '';
position: absolute;
bottom: 0;
left: -2px;
border-top: 52px solid white;
border-right: 42px solid transparent;
}
.connect-behind {
width: 300px;
height: 44px;
background: red;
background: #FF2D5069;
border-top: 2px solid #FF2175;
position: absolute;
bottom: 0;
}
.connect-behind::before {
content: '';
position: absolute;
bottom: 0;
right: -2px;
border-top: 46px solid white;
border-left: 26px solid transparent;
}
.connect-behind::after {
content: '';
position: absolute;
bottom: 0;
left: -2px;
border-top: 46px solid white;
border-right: 26px solid transparent;
}
<div class="wrapper">
<div class="connect"></div>
<div class="connect-behind"></div>
</div>
I took reference from other threads to use behind and after for the solution but it doesn't seem working correct for my problem. Please help, thanks.
You could use perspective and transform:
possible example (for infos : with grid instead absolute) :
.wrapper {
display: grid;
justify-content: center;
align-items: end;
height: 300px;
perspective: 50px;
}
.connect,
.connect-behind {
transform: rotatex(50deg);
background: red;
margin: 0 auto;
background: #FF2D5069;
border-top: 2px solid #FF2175;
grid-row: 1;
grid-column: 1;
transform-origin: bottom center;
}
.connect-behind {
width: 300px;
height: 44px;
}
.connect {
width: 254px;
height: 50px;
;
}
<div class="wrapper">
<div class="connect"></div>
<div class="connect-behind"></div>
</div>
to draw a border around the shape, drop-shadow could be usefull
.wrapper {
display: grid;
justify-content: center;
align-items: end;
height: 300px;
perspective: 50px;
filter:
drop-shadow( 1px 0px 0 )
drop-shadow(-1px 0px 0 )
drop-shadow( 0px 1px 0 )
drop-shadow( 0px -1px 0 );
}
.connect,
.connect-behind {
transform: rotatex(50deg);
background: red;
margin: 0 auto;
background:white;
grid-row: 1;
grid-column: 1;
transform-origin: bottom center;
background:#ffa500;
}
.connect-behind {
width: 254px;
height: 50px;
border-left:solid 2px;
border-right:solid 2px;
}
.connect {
background:#ed1c24;
width: 300px;
height: 44px;
;
}
<div class="wrapper">
<div class="connect"></div>
<div class="connect-behind"></div>
</div>
You can use clip-path for things like this. Works well in a ( I think ) most browsers. Some, like ie11 and older browsers won't render it correctly, though, so you may need a fallback for those cases.
body {
overflow: hidden;
}
.wrapper {
display: flex;
justify-content: center;
}
.connect {
width: 254px;
height: 80px;
background: red;
background: #FF2D5069;
border-top: 2px solid black;
position: absolute;
bottom: 0;
z-index: 5;
clip-path: polygon(20% 0%, 80% 0%, 100% 100%, 0% 100%);
}
.connect-border-left {
height: 80px;
width: 2px;
background: black;
left: calc(50% - 131px);
position: absolute;
bottom: -12px;
transform: rotate(34deg) translateX(-50%);
display: inline-block;
}
.connect-border-right {
height: 80px;
width: 2px;
background: black;
right: calc(50% - 131px);
position: absolute;
bottom: -12px;
transform: rotate(-34deg) translateX(-50%);
display: inline-block;
}
.connect-behind {
width: 300px;
height: 60px;
background: red;
background: #FF2D5069;
border-top: 2px solid black;
position: absolute;
bottom: 0;
clip-path: polygon(14% 0%, 86% 0%, 100% 100%, 0% 100%);
}
.connect-behind-border-right {
height: 100px;
width: 2px;
background: black;
right: calc(50% - 103px);
position: absolute;
bottom: -11px;
transform: rotate(-32deg) translateX(-50%);
display: inline-block;
}
.connect-behind-border-left {
height: 100px;
width: 2px;
background: black;
left: calc(50% - 103px);
position: absolute;
bottom: -11px;
transform: rotate(32deg) translateX(-50%);
display: inline-block;
}
<div class="wrapper">
<div class="connect"></div>
<div class="connect-border-left"></div>
<div class="connect-border-right"></div>
<div class="connect-behind"></div>
<div class="connect-behind-border-left"></div>
<div class="connect-behind-border-right"></div>
</div>
an idea with skew transformation, clip-path and multiple background:
.box {
--b:3px; /* border width */
--t:20px; /* top part width */
--s:30px; /* side part width */
margin:10px;
display:inline-block;
width:250px;
height:150px;
position:relative;
}
.box::before,
.box::after {
content:"";
position:absolute;
top:0;
bottom:0;
left:0;
width:50%;
border-style:solid;
border-width:var(--b) 0 0 var(--b);
background:
linear-gradient(black 0 0) 0 var(--t)/100% var(--b),
linear-gradient(black 0 0) var(--s) 0/var(--b) 100%,
linear-gradient(red 0 0) left/var(--s) 100%,
orange;
background-repeat:no-repeat;
transform-origin:bottom right;
transform:skew(-20deg);
clip-path:polygon(0 calc(var(--t) + var(--b)), calc(var(--s) + var(--b)) calc(var(--t) + var(--b)),calc(var(--s) + var(--b)) 0,60% 0,100% 100%,0 100%);
}
.box::after {
transform:scale(-1,1) skew(-20deg);
}
<div class="box"></div>
<div class="box" style="--b:2px;--t:30px;--s:15px;"></div>
can you help me to make like this div:
My Code:
body{
display: flex;
justify-content: center;
}
#talkbubble {
width: 160px;
height: 80px;
background: #bc0a14;
position: relative;
-moz-border-radius: 10px;
-webkit-border-radius: 10px;
border-radius: 10px;
}
#talkbubble:before {
content: "";
position: absolute;
right: 100%;
top: 26px;
width: 0;
height: 0;
border-top: 13px solid transparent;
border-right: 26px solid #bc0a14;
border-bottom: 13px solid transparent;
}
#talkbubble:after {
content: "";
position: absolute;
left: 100%;
top: 26px;
width: 0;
height: 0;
border-top: 13px solid transparent;
border-left: 26px solid #bc0a14;
border-bottom: 13px solid transparent;
}
<div id="talkbubble"></div>
I want to create this div with the same style in the image
here is an idea with pseudo element and radial-gradient. I used CSS variable to easily adjust the shape but it's not mandatory
.box {
width: 100px;
height: 50px;
margin:0 var(--w,20px);
display:inline-block;
border-radius: 15px;
background: var(--c,red);
position: relative;
}
.box:before,
.box:after {
content: "";
position: absolute;
top: 0;
bottom: 0;
width: var(--w,20px);
right:calc(100% - 2px);
background:
radial-gradient(107% 100% at top left,transparent 96%,var(--c,red) 100%) top,
radial-gradient(107% 100% at bottom left,transparent 96%,var(--c,red) 100%) bottom;
background-size:100% 50.1%;
background-repeat:no-repeat;
}
.box:after {
left:calc(100% - 2px);
right:auto;
transform:scaleX(-1);
}
<div class="box"></div>
<div class="box" style="--c:blue;--w:30px;"></div>
<div class="box" style="--c:purple;--w:10px;height:60px"></div>
please try this code:
body{
display: flex;
justify-content: center;
}
#talkbubble {
width: 180px;
height: 54px;
background: #bc0a14;
position: relative;
-moz-border-radius: 20px;
-webkit-border-radius: 20px;
border-radius: 24px;
}
#talkbubble:before {
content: "";
position: absolute;
right: 99%;
top: 17px;
width: 0px;
height: 1px;
border-top: 9px solid transparent;
border-right: 10px solid #bc0a14;
border-bottom: 9px solid transparent;
}
#talkbubble:after {
content: "";
position: absolute;
left: 99%;
top: 17px;
width: 0;
height: 1px;
border-top: 9px solid transparent;
border-left: 10px solid #bc0a14;
border-bottom: 9px solid transparent;
}
<div id="talkbubble"></div>
I'm nearly there after trawling various CSS sites and this one but would love some expert advice.
I'm trying to create a section header for a website that has 3 parts:
Title with button for a possible tooltip
Description
Call to Action button
Mockup attached.
I'm trying to adjust the arrow width so its not so "pointy" as it takes up additional space on the next area.
What I have so far is:
* {
box-sizing: border-box;
}
#RPheader {
float: left;
position: relative;
width: 40%;
padding: 10px;
height: 40px;
color: #FFFFFF;
background: #004851;
}
#RPheader:after {
content: "";
position: absolute;
left: 0;
bottom: 0;
width: 0;
height: 0;
}
#RPheader:before {
content: "";
position: absolute;
right: -20px;
bottom: 0;
width: 0;
height: 0;
border-left: 20px solid #004851;
border-top: 20px solid transparent;
border-bottom: 20px solid transparent;
z-index: 1;
}
#RPdesc {
float: left;
position: relative;
width: 50%;
padding: 10px;
height: 40px;
color: #555555;
background-color: #F1ECEA;
}
#RPdesc:after {
content: "";
position: absolute;
left: 0;
bottom: 0;
width: 0;
height: 0;
}
#RPdesc:before {
content: "";
position: absolute;
right: -20px;
bottom: 0;
width: 0;
height: 0;
border-left: 20px solid #F1ECEA;
border-top: 20px solid transparent;
border-bottom: 20px solid transparent;
}
#RPheaderButton {
float: left;
width: 10%;
padding: 10px;
height: 40px;
color: #FFFFFF;
background-color: #00afd7;
}
<div id="RPheaderRow">
<div id="RPheader">Header title here</div>
<div id="RPdesc">This is where my description will go...</div>
<div id="RPheaderButton"> CTA </div>
</div>
I haven't done the tooltip part as yet...I will try and figure that out after this is done..yikes!
Any help much appreciated.
Chris.
You were almost there, just needed to adjust the border-left on the :before elements to a 10px value and then change the right property as well to -10px. I also updated the left and right padding on the RPDesc element and RPheaderButton element.
https://jsfiddle.net/disinfor/evy952bc/10/
* {
box-sizing: border-box;
}
#RPheader {
float: left;
position: relative;
width: 40%;
padding: 10px;
height: 40px;
color: #FFFFFF;
background: #004851;
}
#RPheader:after {
content: "";
position: absolute;
left: 0;
bottom: 0;
width: 0;
height: 0;
}
#RPheader:before {
content: "";
position: absolute;
right: -5px;
bottom: 0;
width: 0;
height: 0;
border-left: 5px solid #004851;
border-top: 20px solid transparent;
border-bottom: 20px solid transparent;
z-index: 1;
}
#RPdesc {
float: left;
position: relative;
width: 50%;
padding: 10px 20px;
height: 40px;
color: #555555;
background-color: #F1ECEA;
}
#RPdesc:after {
content: "";
position: absolute;
left: 0;
bottom: 0;
width: 0;
height: 0;
}
#RPdesc:before {
content: "";
position: absolute;
right: -10px;
bottom: 0;
width: 0;
height: 0;
border-left: 10px solid #F1ECEA;
border-top: 20px solid transparent;
border-bottom: 20px solid transparent;
}
#RPheaderButton {
float: left;
width: 10%;
padding: 10px 10px 10px 20px;
height: 40px;
color: #FFFFFF;
background-color: #00afd7;
}
<div id="RPheaderRow">
<div id="RPheader">Header title here</div>
<div id="RPdesc">This is where my description will go...</div>
<div id="RPheaderButton"> CTA </div>
</div>
You can adjust those two values as needed, but that will get you closer to what you want.
You can consider background to achieve this easily without the need of pseudo element:
* {
box-sizing: border-box;
}
#RPheader {
float: left;
width: 40%;
padding: 10px;
height: 40px;
color: #FFFFFF;
background:
linear-gradient(to top right ,transparent 49.8%,#F1ECEA 50%) top right/20px 50%,
linear-gradient(to bottom right,transparent 49.8%,#F1ECEA 50%) bottom right/20px 50%,
#004851;
background-repeat:no-repeat;
}
#RPdesc {
float: left;
width: 50%;
padding: 10px;
height: 40px;
color: #555555;
background:
linear-gradient(to top right ,transparent 49.8%,#00afd7 50%) top right/20px 50%,
linear-gradient(to bottom right,transparent 49.8%,#00afd7 50%) bottom right/20px 50%,
#F1ECEA;
background-repeat:no-repeat;
}
#RPheaderButton {
float: left;
width: 10%;
padding: 10px;
height: 40px;
color: #FFFFFF;
background-color: #00afd7;
}
<div id="RPheaderRow">
<div id="RPheader">Header title here</div>
<div id="RPdesc">This is where my description will go ...</div>
<div id="RPheaderButton"> CTA </div>
</div>
You can also optimize your code like below:
* {
box-sizing: border-box;
}
#RPheaderRow > div {
float: left;
padding: 10px;
height: 40px;
color:#fff;
background:
linear-gradient(to top right ,transparent 49.5%,var(--c,transparent) 50%) top right/var(--s,20px) 50%,
linear-gradient(to bottom right,transparent 49.5%,var(--c,transparent) 50%) bottom right/var(--s,20px) 50%;
background-repeat:no-repeat;
}
div#RPheader {
width: 40%;
--c:#F1ECEA; /*adjust the color*/
background-color:#004851;
}
div#RPdesc {
width: 50%;
color: #555555;
--c:#00afd7;
--s:10px; /*adjust the size of the arrow*/
background-color:#F1ECEA;
}
div#RPheaderButton {
width: 10%;
background-color: #00afd7;
}
<div id="RPheaderRow">
<div id="RPheader" >Header title here</div>
<div id="RPdesc" >This is where my description will go ...</div>
<div id="RPheaderButton" > CTA </div>
</div>
I would add a top arrow and a bottom arrow in the section before to simulate this arow you're trying to get.
* {
box-sizing: border-box;
}
#RPheader {
float: left;
position: relative;
width: 40%;
padding: 10px;
height: 40px;
color: #FFFFFF;
background: #004851;
}
#RPheader:after {
content: "";
position: absolute;
right: -20px;
bottom: 0;
width: 0;
height: 0;
border-bottom: 20px solid #F1ECEA;
border-left: 20px solid transparent;
border-right: 20px solid transparent;
}
#RPheader:before {
content: "";
position: absolute;
right: -20px;
top: 0;
width: 0;
height: 0;
border-top: 20px solid #F1ECEA;
border-left: 20px solid transparent;
border-right: 20px solid transparent;
}
#RPdesc {
float: left;
position: relative;
width: 50%;
padding: 10px;
height: 40px;
color: #555555;
background-color: #F1ECEA;
}
#RPdesc:after {
content: "";
position: absolute;
right: -20px;
bottom: 0;
width: 0;
height: 0;
border-bottom: 20px solid #00afd7;
border-left: 20px solid transparent;
border-right: 20px solid transparent;
}
#RPdesc:before {
content: "";
position: absolute;
right: -20px;
top: 0;
width: 0;
height: 0;
border-top: 20px solid #00afd7;
border-left: 20px solid transparent;
border-right: 20px solid transparent;
}
#RPheaderButton {
float: left;
width: 10%;
padding: 10px;
height: 40px;
color: #FFFFFF;
background-color: #00afd7;
}
<div id="RPheaderRow">
<div id="RPheader">Header title here</div>
<div id="RPdesc">This is where my description will go...</div>
<div id="RPheaderButton"> CTA </div>
</div>
I need to add borders to this "shape". It's kinda difficult because the shape is made with the after and before pseudo-elements. I can't find the right way.
What I need to achieve:
The code I have so far:
https://jsfiddle.net/jimmyadaro/xfcjfz3d/
#octagon {
width: 300px;
height: 200px;
background: red;
position: relative;
-webkit-box-sizing: content-box;
-moz-box-sizing: content-box;
box-sizing: content-box;
display: block;
}
#octagon:before,
#octagon:after {
content: "";
position: absolute;
left: 0;
right: 0;
}
#octagon:before {
top: 0;
border-bottom: 30px solid red;
border-left: 30px solid #fff;
border-right: 30px solid #fff;
}
#octagon:after {
bottom: 0;
border-top: 30px solid red;
border-left: 30px solid #fff;
border-right: 30px solid #fff;
}
<div id="octagon"></div>
I tried with shadows and outlines without success.
Thanks for reading.
Note: I'll use a solid background color, if that matters.
Here's my solution. No solid background color is required. This may or may not suit your actual use case.
JSFiddle
#octagon {
display: flex;
justify-content: center;
align-items: center;
width: 300px;
height: 200px;
overflow: hidden;
position: relative;
}
#octagon:before,
#octagon:after {
content: "";
display: block;
width: 300px;
padding-top: 100%;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%) rotate(45deg);
z-index: -1;
}
#octagon:before {
background: red;
}
#octagon:after {
background:
linear-gradient(
45deg,
#0e0 calc(50% - 150px + 10px), transparent 0,
transparent calc(50% + 150px - 10px), #0e0 0%),
linear-gradient(
-45deg,
#0e0 calc(50% - 100px + 10px), transparent 0,
transparent calc(50% + 100px - 10px), #0e0 0);
box-shadow: 0 0 0 10px #0e0 inset;
}
<div id="octagon">Hello World!</div>
Well, this is the only way I could think of approaching it in pure CSS:
JSfiddle here: https://jsfiddle.net/xfcjfz3d/7/
body {
background:#fff;
}
#octagon {
position:relative;
width: 300px;
height: 200px;
background: green;
position: relative;
-webkit-box-sizing: content-box;
-moz-box-sizing: content-box;
box-sizing: content-box;
display: block;
}
#octagon:before,
#octagon:after {
content: "";
position: absolute;
left: 0;
right: 0;
}
#octagon:before {
top: 0;
border-bottom: 30px solid green;
border-left: 30px solid #fff;
border-right: 30px solid #fff;
}
#octagon:after {
bottom: 0;
border-top: 30px solid green;
border-left: 30px solid #fff;
border-right: 30px solid #fff;
}
.tall {
position:absolute;
background:red;
width:230px;
height:190px;
left:35px;
top:5px;
z-index:1;
}
.wide {
position:absolute;
background:red;
width:290px;
height:130px;
left:5px;
top:35px;
z-index:1;
}
.corner {
position:absolute;
background:red;
width:45px;
height:43px;
z-index:1;
transform: rotate(45deg);
}
.topleft {
left:14px;
top:14px;
}
.topright {
//background:black;
left:241px;
top:13px;
}
.bottomleft {
background:red;
left:13px;
top:143px;
}
.bottomright {
background:red;
left:241px;
top:143px;
}
<div id="octagon">
<div class="tall"></div>
<div class="wide"></div>
<div class="corner topleft"></div>
<div class="corner topright"></div>
<div class="corner bottomleft"></div>
<div class="corner bottomright"></div>
</div>