css3 - CSS triangular cutout with border and transparent gap -


i need draw following pattern css separator between sections of page:

separator

using skewx() technique this answer, able mimic triangular cutout accurately (two pseudo-elements appended top of lower section, 1 skewed left , 1 skewed right, background of upper section shows through):

enter image description here

but can't figure out how add border, shown in first image.

the problem gap between border , lower section has transparent, because background of upper section can gradient, image, etc. therefore, can't use image triangular cutout, because can't know content behind it.

is there possible way css?

it possible css approach find complex 1 using fair amount of gradients mimic borders. couldn't done normal borders because resulted in either borders extending beyond meeting point or inner area never meeting. couldn't done box shadow's because gap between border , filled area need transparent. (not saying cannot done couldn't work, maybe there way too).

the below how i've managed achieve border:

  • four linear gradients used create borders required.
  • the 1st , 2nd solid colors (that is, there no change 1 color another) had used gradients because allows control background-size. these 2 produce solid horizontal line 1 positioned on left , positioned on right bit above transparent cut produced using pseudo-elements.
  • the 3rd , 4th produce angled lines same thickness required border.
  • the size , position of 4 gradients set such produce border effect.

the output - can see hovering element - responsive too.

div {    position: relative;    height: 200px;    width: 300px;    background: linear-gradient(#ddd, #ddd), /* horizontal border line on left */                linear-gradient(#ddd, #ddd),  /* horizontal border line on right */                linear-gradient(to top right, transparent calc(50% - 2px), #ddd calc(50% - 2px), #ddd calc(50% + 2px), transparent calc(50% + 2px)), /* angled border on left of center */                linear-gradient(to top left, transparent calc(50% - 2px), #ddd calc(50% - 2px), #ddd calc(50% + 2px), transparent calc(50% + 2px)), /* angled border on right of center */                radial-gradient(circle, #3f9cba 0%, #153346 100%) /* actual background */;    background-size: calc(50% - 38px) 4px,                      calc(50% - 38px) 4px,                      40px 40px, /* size of 1 half of triangle */                     40px 40px, /* size of 1 half of triangle */                     auto auto /* size of actual bg */;    background-position: 0% calc(100% - 44px),                          100% calc(100% - 44px),                          calc(50% - 18px) calc(100% - 8px),                          calc(50% + 18px) calc(100% - 8px),                          0px 0px;    background-repeat: no-repeat;    overflow: hidden;    border-bottom: 20px solid #ddd;  }  div:before,  div:after {    position: absolute;    content: '';    height: 40px;    width: 50%;    bottom: 0;    background: #ddd;    backface-visibility: hidden;  }  div:before {    left: 0;    transform-origin: left bottom;    transform: skewx(45deg);  }  div:after {    right: 0;    transform-origin: right bottom;    transform: skewx(-45deg);  }    /* demo */    div {    transition: 1s;  }  div:hover {    height: 250px;    width: 550px;  }
<div></div>


the following how background properties need set based on required border color , width (all calculations 45 degree skew angle, different angle need different calculations):

  • the colors used within gradient same border color. so, if border color needs red instead of #ddd color values should changed red.
  • the thickness of border determined using background-size first 2 gradients , using gradient's color-stop points next 2 gradients.

    • for first two, background-size in y-axis nothing border thickness. change suit needed thickness. background-size in x-axis nothing 50% minus height of pseudo minus half of border thickness
    • for next two, color stop points of gradient should set such color starts (and transparent ends) @ 50% - half border thickness , color ends (transparnet starts) , 50% + half border thickness (so produces stroke of required thickness).
  • the background-position should set such required gap there between colored area , border.
    • for first two, background-position in x-axis should left edge (0%) , right edge (100%) respectively. position in y-axis should above pseudo-element , should 100% minus pseudo-element's height minus spacing.
    • for next two, background-position involves more complex calculation involving border spacing, thickness , pseudo-element's height. logic present below.
background: linear-gradient([color, [color]),             linear-gradient([color], [color]),              linear-gradient(to top right,                              transparent calc(50% - [border-thickness/2]),                              [color] calc(50% - [border-thickness/2]),                              [color] calc(50% + [border-thickness/2]),                             transparent calc(50% + [border-thickness/2])),             linear-gradient(to top left,                              transparent calc(50% - [border-thickness/2]),                             [color] calc(50% - [border-thickness/2]),                              [color] calc(50% + [border-thickness/2]),                              transparent calc(50% + [border-thickness/2])),                              radial-gradient(circle, #3f9cba 0%, #153346 100%) /* actual background */;  background-size: calc(50% - [pseudo-height - border-thickness/2]) [border-thickness],                   calc(50% - [pseudo-height - border-thickness/2]) [border-thickness],                   [pseudo-height] [pseudo-height],                   [pseudo-height] [pseudo-height],                   auto auto /* size of actual bg */;  background-position: 0% calc(100% - [pseudo-height + border-space]),                       100% calc(100% - [pseudo-height + border-space]),                       calc(50% - [(pseudo-height - border-space)/2]) calc(100% - [border-space + border-thickness/2]),                       calc(50% + [(pseudo-height - border-space)/2]) calc(100% - [border-space + border-thickness/2]),                       0px 0px; 

if need transparent cut border on top part of lower div achieve in below snippet.

div {    height: 200px;    width: 300px;  }  div:nth-child(1) {    background: radial-gradient(circle, #3f9cba 0%, #153346 100%);    background-repeat: no-repeat;  }  div:nth-child(2) {    position: relative;    margin-top: -48px;    padding-top: 48px;    background: linear-gradient(#ddd, #ddd), linear-gradient(#ddd, #ddd), linear-gradient(to top right, transparent calc(50% - 2px), #ddd calc(50% - 2px), #ddd calc(50% + 2px), transparent calc(50% + 2px)), linear-gradient(to top left, transparent calc(50% - 2px), #ddd calc(50% - 2px), #ddd calc(50% + 2px), transparent calc(50% + 2px)), linear-gradient(#ddd, #ddd);    background-size: calc(50% - 38px) 4px, calc(50% - 38px) 4px, 40px 40px, 40px 40px, auto auto;    background-position: 0% 0px, 100% 0px, calc(50% - 18px) 0px, calc(50% + 18px) 0px, 0px 0px;    background-repeat: no-repeat;    background-clip: border-box, border-box, border-box, border-box, content-box;    overflow: hidden;  }  div:nth-child(2):before,  div:nth-child(2):after {    position: absolute;    content: '';    height: 40px;    width: 50%;    top: 8px;    background: #ddd;    backface-visibility: hidden;  }  div:before {    left: 0;    transform-origin: left bottom;    transform: skewx(45deg);  }  div:after {    right: 0;    transform-origin: right bottom;    transform: skewx(-45deg);  }  /* demo */    div {    transition: 1s;  }  body:hover > div {    height: 250px;    width: 550px;  }
<div></div>  <div></div>


Comments

Popular posts from this blog

Django REST Framework perform_create: You cannot call `.save()` after accessing `serializer.data` -

Why does Go error when trying to marshal this JSON? -