Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Create a Spiders web under a hr element in CSS

I'm trying to generate a spider's web under a <hr /> element, but am having some issue when it comes to the 'circular parts'.

I'm avoiding inserting/using SVG since this may or may not be inserted by the user (i.e. user may include an hr element in a post, for example, and I want the web to appear there also).

This would suggest that the hr element would need to be styled in such a way that this would appear under all instances of the hr element (suggesting little->no extra HTML elements).

I have included a quick mockup of what I'm trying to achieve below:

Wanted result

Something like this image portrays:

enter image description here

Current Code

At present, I'm struggling to make the 'spindles' between the two pseudo elements, and the closest way I've generated the 'spindles' is like this:

html{
    margin:0;
    padding:0;
    background:rgba(0,0,0,0.1);
    color:black;    
}
hr{
    height:30px;
    border-bottom:none;
    border-right:none;
    position:relative;    
}
hr:before, hr:after{
    content:"m";
    position:absolute;
    height:40px;
    width:1px;
    top:0;
    left:0;
    transform-origin:top left;
    transform:rotate(-20deg);
    background:black;
}
hr:after{
transform:rotate(-40deg);    
}
<hr />

This, of course, looks terrible (mainly to do with the horrible 'm's overlapping ) - but I can't seem to find a way of generating this kind of shape without them.

Attempts so far

  • I have attempted to make the 'web links' by using different letters within the content of the pseudo elements

  • I have tried using curves/overflow hidden, but this failed (miserably I might add)


I would really appreciate any and all responses to this, and if it was possible using pure CSS it would be even better! But right now I'm at a lose as to how to achieve this sort of functionality.

like image 824
jbutler483 Avatar asked Feb 18 '15 17:02

jbutler483


2 Answers

Note: This answer is posted only to show that this effect is achievable using CSS. However, I would recommend SVG or PNG image etc for such shapes/effects as CSS is not really intended to do this.

CSS Approach:

The spider web effect is achieved using the following:

  1. The right angle borders on the left and top are the actual borders of the hr element. Height is assigned explicitly to the hr element because hr element by default has only the border height.
  2. The diagonal-ish lines in the middle are achieved using a pseudo-element which is skewed both along the X and Y axes.
  3. The circular parts are achieved using another pseudo-element which has a 50% border-radius and also extra box-shadows projected on either side of it and below it. The central circle/ellipse on the first row from top is the actual element while the rest are shadows. The size of the shadow is increased for the shapes in the second row from top by assigning an extra spread radius to the shadow.
  4. The shadow is actual formed using two shadows where one is placed on top of the other (because we just need an arc and not a solid ellipse).

hr{
    border-left: 2px solid black;
    border-top: 2px solid black;
    height: 200px;
    overflow: hidden;   
    position: relative;
    border-right: none;
    border-bottom: none;
}
hr:after{
    position: absolute;
    content: '';
    top: 0px;
    left: 0px;
    height: 100%;
    width: 100%;
    border-left: 2px solid black;
    border-top: 2px solid black;
    -webkit-transform: skewY(30deg) skew(30deg);
    -moz-transform: skewY(30deg) skew(30deg);
    transform: skewY(30deg) skew(30deg);
    -webkit-transform-origin: left top;
    -moz-transform-origin: left top;
    transform-origin: left top;
}
hr:before{
    position: absolute;
    content: '';
    top: 0px;
    left: 0px;
    height: 30px;
    width: 36px;
    border-radius: 50%;
    border-top: 2px solid;
    -webkit-transform: translate(20px, 26px) rotate(-45deg);
    -moz-transform: translate(20px, 26px) rotate(-45deg);
    transform: translate(20px, 26px) rotate(-45deg);
    box-shadow: -35px -2px 0px white, -35px -4px 0px black,35px -1px 0px white, 34px -3px 0px black, -4px 56px 0px 16px white, -4px 53px 0px 15px black, -65px 56px 0px 16px white, -65px 53px 0px 15px black, -4px 53px 0px 15px black, 62px 56px 0px 20px white, 61px 52px 0px 18px black;
}
<hr>

Just for an understanding how the box-shadows were used to create arcs, here is a sample snippet where the shadows are colored differently from the background.

hr{
    border-left: 2px solid black;
    border-top: 2px solid black;
    height: 200px;
    overflow: hidden;   
    position: relative;
    border-right: none;
    border-bottom: none;
}
hr:after{
    position: absolute;
    content: '';
    top: 0px;
    left: 0px;
    height: 100%;
    width: 100%;
    border-left: 2px solid black;
    border-top: 2px solid black;
    -webkit-transform: skewY(30deg) skew(30deg);
    -moz-transform: skewY(30deg) skew(30deg);
    transform: skewY(30deg) skew(30deg);
    -webkit-transform-origin: left top;
    -moz-transform-origin: left top;
    transform-origin: left top;
}
hr:before{
    position: absolute;
    content: '';
    top: 0px;
    left: 0px;
    height: 30px;
    width: 36px;
    border-radius: 50%;
    border-top: 2px solid;
    -webkit-transform: translate(20px, 26px) rotate(-45deg);
    -moz-transform: translate(20px, 26px) rotate(-45deg);
    transform: translate(20px, 26px) rotate(-45deg);
    box-shadow: -35px -2px 0px red, -35px -4px 0px black,35px -1px 0px red, 34px -3px 0px black, -4px 56px 0px 16px red, -4px 53px 0px 15px black, -65px 56px 0px 16px red, -65px 53px 0px 15px black, -4px 53px 0px 15px black, 62px 56px 0px 20px red, 61px 52px 0px 18px black;
}
<hr>

This snippet has three rows of the circular/elliptical parts. Below is a screenshot of its output.

enter image description here


SVG Approach:

Below is a quick SVG implementation of the spider web pattern using path element and a (arc) commands.

div.vector {
  margin: 10px auto;
  height: 250px;
  width: 600px;
  overflow: hidden;
  position: relative;
}
svg {
  height: 100%;
  width: 100%;
}
line,
path {
  stroke: #CCC;
  stroke-width: 2px;
  fill: none;
}
#top {
  stroke-width: 2px;
}
/* Just for demo */

body {
  background: #000;
}
<div class='vector'>
  <svg viewBox='0 0 600 250' preserveAspectRatio='none'>
    <line x1='1' y1='1' x2='600' y2='1' id='top' />
    <line x1='1' y1='1' x2='1' y2='250' />
    <line x1='1' y1='1' x2='450' y2='250' />
    <line x1='1' y1='1' x2='175' y2='250' />
    <path d='M 1,80 a 12,15 45 1,1 37,-26 a 10,12 0 1,1 14,-24 a 25,20 -45 1,1 40,-30' />
    <path d='M 1,160 a 17,20 45 1,1 75,-52 a 17,20 0 1,1 30,-48 a 30,25 -45 1,1 60,-70' />
    <path d='M 1,240 a 22,25 45 1,1 113,-78 a 23,26 0 1,1 46,-72 a 35,30 -45 1,1 90,-110' />
  </svg>
</div>
like image 52
Harry Avatar answered Sep 28 '22 16:09

Harry


My best try ...

Couldn't get the third sector with only 2 pseudo elements ...

.spider:after, .spider:before {
    content: "";
    position: absolute;
    left: 40px;
    width: 100px;
    height: 80px;
    border: solid 3px transparent;
    border-top-color: black;
    border-left-color: black;
    transform: skewX(50deg);
    background-image: radial-gradient(ellipse at bottom right,  
        transparent 100px, black 100px, 
        black 102px, transparent 102px,
        transparent 120px, black 120px, 
        black 122px, transparent 122px
    );
    background-repeat: no-repeat;
    transform-origin: top left;
}

.spider:before {
    transform: skewX(50deg);
}
.spider:after {
    transform:  rotate(38deg) skewX(60deg);
}
<div class="spider"></div>
like image 31
vals Avatar answered Sep 28 '22 15:09

vals