Drawing angled lines in CSS - css

What I'm trying to do LOOKS simple, but I can't seem to figure out how to do it.
As you can see in my image there are a couple of red lines that go across the bottom, then bend upwards close to the right side.
Is there a way in CSS to draw a line like this?

You can create angled lines in CSS by using skew transforms (transform: skew(Xdeg)). Below is a sample snippet:
.shape {
height: 50px;
width: 200px;
border-bottom: 2px solid red;
border-right: 2px solid red;
-moz-transform: skew(-45deg);
-webkit-transform: skew(-45deg);
transform: skew(-45deg);
}
<div class="shape"></div>
Double line with one above the content area and one behind it can also be done using a single element (and a couple of pseudos) like in the below snippet:
.shape:before {
position: absolute;
bottom: -5px;
left: -5px;
content: '';
height: 50px;
width: 100%;
border-bottom: 3px solid red;
border-right: 4px solid red;
-webkit-transform: skew(-45deg);
-moz-transform: skew(-45deg);
transform: skew(-45deg);
}
.shape:after {
position: absolute;
content: '';
bottom: -10px;
left: 0px;
height: 55px;
width: 100%;
border-bottom: 3px solid red;
border-right: 4px solid red;
-webkit-transform: skew(-45deg);
-moz-transform: skew(-45deg);
transform: skew(-45deg);
z-index: -1;
}
.shape {
position: relative;
height: 80px;
width: 400px;
background: whitesmoke;
}
<div class="shape">
Some text that goes within the element...
</div>

Related

CSS Star outline

Is there any way to make a css star shape outline?
I know you can make a filled in one, with the following css
.star-five {
margin: 50px 0;
position: relative;
display: block;
color: red;
width: 0px;
height: 0px;
border-right: 100px solid transparent;
border-bottom: 70px solid red;
border-left: 100px solid transparent;
-moz-transform: rotate(35deg);
-webkit-transform: rotate(35deg);
-ms-transform: rotate(35deg);
-o-transform: rotate(35deg);
}
.star-five:before{
...
}
.star-five:after {
...
}
Working example here: jsfiddle
But what about a transparent fill with a red outline?
I know this isn't quite the answer you were looking for, but I'm gonna post it anyway. For my knowledge there's no way of doing this with pure CSS. However, in my website I took a more easy approach. I had to style a rating bar with stars. Instead of creating the star with CSS, I simply did this:
<span>☆</span>
You can style this star however you like (and even fill it with the CSS content property).
Hope this help, and looking forward to see the other answers here.
You could use an SVG:
<svg width="320" height="320"><path d="
M 160.000 180.000
L 183.511 192.361
L 179.021 166.180
L 198.042 147.639
L 171.756 143.820
L 160.000 120.000
L 148.244 143.820
L 121.958 147.639
L 140.979 166.180
L 136.489 192.361
L 160.000 180.000
" stroke="#f00" stroke-width="1" fill="none"/></svg>
I used this site to generate it if it helps: http://www.smiffysplace.com/stars.html
Here is a pure CSS solution using the same Fiddle you provided. I just scaled a star in and made it white.
body {
margin: 0px;
}
.star-five {
margin: 50px 0;
position: relative;
display: block;
color: red;
width: 0px;
height: 0px;
border-right: 100px solid transparent;
border-bottom: 70px solid red;
border-left: 100px solid transparent;
-moz-transform: rotate(35deg);
-webkit-transform: rotate(35deg);
-ms-transform: rotate(35deg);
-o-transform: rotate(35deg);
}
.star-five:before {
border-bottom: 80px solid red;
border-left: 30px solid transparent;
border-right: 30px solid transparent;
position: absolute;
height: 10px;
width: 0;
top: -45px;
left: -65px;
display: block;
content: '';
-webkit-transform: rotate(-35deg);
-moz-transform: rotate(-35deg);
-ms-transform: rotate(-35deg);
-o-transform: rotate(-35deg);
}
.star-five:after {
position: absolute;
display: block;
color: red;
top: 3px;
left: -105px;
width: 0px;
height: 0px;
border-right: 100px solid transparent;
border-bottom: 70px solid red;
border-left: 100px solid transparent;
-webkit-transform: rotate(-70deg);
-moz-transform: rotate(-70deg);
-ms-transform: rotate(-70deg);
-o-transform: rotate(-70deg);
content: '';
}
.star-outline>.star-five,
.star-outline>.star-five:before,
.star-outline>.star-five:after {
border-bottom-color: white;
}
.star-outline {
position: absolute;
top: 0px;
left: 0px;
transform: scale(0.9);
}
<div class="star">
<span class="star-five" width="10" height="10">
</span>
<div class="star-outline">
<span class="star-five">
</span>
</div>
</div>
Use below CSS properties:
-webkit-text-stroke-width: 2px;
-webkit-text-stroke-color: red;
Visualization:
Hope this could help ~ RDaksh

How can I create this particular shape?

Is there an easier or better way to create this particular shape/combination of shapes in CSS3 than what am I currently doing? I have tried a few different things already.
The downward facing triangle should be sitting just below the three lines, but I can't seem to get it there.
I want it to look like this:
https://jsfiddle.net/s6bcjzjr/
.triangle-container {
top: 0;
width: 30px;
height: 40px;
position: relative;
border-bottom: 2px solid #e74c3c;
}
.triangle {
position: relative;
margin: auto;
top: 30px;
left: 0;
right: 0;
width: 21px;
height: 21px;
transform: rotate(45deg);
-webkit-transform: rotate(45deg);
-moz-transform: rotate(45deg);
-o-transform: rotate(45deg);
-ms-transform: rotate(45deg);
border-right: 2px solid #e74c3c;
border-bottom: 2px solid #e74c3c;
}
.line {
width: 30px;
position: relative;
border-bottom: 2px solid #e74c3c;
margin-top: 3px;
}
<a href="#" class="open">
<div class="line"></div>
<div class="line"></div>
<div class="line"></div>
<div class="triangle-container">
<div class="triangle"></div>
</div>
</a>
I switch the triangle container's border to top and adjusted the margins
* {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
.triangle-container {
top: 0;
width: 30px;
height: 40px;
position: relative;
border-top: 2px solid #e74c3c;
margin-top: 3px;
}
.triangle {
position: relative;
margin: auto;
top: -10.5px;
left: 0;
right: 0;
width: 21px;
height: 21px;
transform: rotate(45deg);
-webkit-transform: rotate(45deg);
-moz-transform: rotate(45deg);
-o-transform: rotate(45deg);
-ms-transform: rotate(45deg);
border-right: 2px solid #e74c3c;
border-bottom: 2px solid #e74c3c;
}
.line {
width: 30px;
position: relative;
border-bottom: 2px solid #e74c3c;
margin: 3px 0 0 0;
}
<a href="#" class="open">
<div class="line"></div>
<div class="line"></div>
<div class="line"></div>
<div class="triangle-container">
<div class="triangle"></div>
</div>
</a>
Using SVG:
You can create this easily using SVG. There is nothing complex and all that you would need is three line elements and one path element.
All three line elements have two co-ordinates where (x1,y1) represent the starting point of the line and (x2,y2) represent the ending point of the line.
The path element takes a path (d) and it value can be interpreted as follows:
M5,20 - Move to the point which is 5px to the right of the container and 20px down.
L95,20 - Draw a line from the previous point (5,20) to (95,20).
L50,45 - Draw a line from the previous point (95,20) to (50,45).
z - Close the path. That is, draw a line connecting the point (50,45) and the starting point.
svg {
height: 100px;
width: 50px;
}
line,
path {
stroke: #e74c3c;
stroke-width: 2;
}
path {
fill: none;
stroke-linejoin: bevel;
}
<svg viewBox='0 0 100 100' preserveAspectRatio='none'>
<g id='graphic'>
<line x1='5' y1='5' x2='95' y2='5' />
<line x1='5' y1='10' x2='95' y2='10' />
<line x1='5' y1='15' x2='95' y2='15' />
<path d='M5,20 L95,20 L50,45z' />
</g>
</svg>
Using CSS with single element:
You can achieve the same shape using a single element also with CSS. Below is a sample snippet for the same. Below is an explanation of how the shape is achieved.
The parent anchor tag which has the height and width of the container.
The :before pseudo-element which is positioned absolutely with respect to the container and is 20px tall. The background of this element is a linear-gradient which has the required color for 2px and is transparent for the remaining part. Gradients by default repeat to fill its container and so this single background pattern produces the three lines.
The :after element is again positioned absolutely with respect to the container. This pseudo-element is then rotated such that its left and bottom borders produce angled parts of the triangle. Another linear-gradient background produces the top line of the triangle.
I have calculated height and width of the :after pseudo using Pythagoras theorem. If container is not a square then you have to manually calculate the values.
a {
position: relative;
display: inline-block;
height: 50px;
width: 50px;
}
a:before {
position: absolute;
content: '';
top: 3px;
left: 0px;
height: 20px;
width: 100%;
background: linear-gradient(to bottom, #e74c3c 2px, transparent 2px);
background-size: 100% 5px;
}
a:after {
position: absolute;
content: '';
top: 50%;
left: 50%;
height: calc(50px / 1.414);
width: calc(50px / 1.414);
border-bottom: 2px solid #e74c3c;
border-left: 2px solid #e74c3c;
transform: translateX(-50%) translateY(-50%) rotate(-45deg);
background: linear-gradient(to top right, transparent 46%, #e74c3c 46%, #e74c3c 50%, transparent 50%);
}
<a href='#'></a>
.triangle-container {
top: -35px;
width: 30px;
height: 40px;
position: relative;
border-bottom: 2px solid #e74c3c;
}
https://jsfiddle.net/s6bcjzjr/6/
i've updated your fiddle and now your shape looks perfect. What I did is changed the border-bottom to border-top of the triangle-container, and adjusted height and margin to align the triangle perfectly
here is the fiddle - https://jsfiddle.net/s6bcjzjr/5/
The answer is:
.triangle-container {
top: -36px;
}
See it here:
.triangle-container {
top: -36px;
width: 30px;
height: 40px;
position: relative;
border-bottom: 2px solid #e74c3c;
}
.triangle {
position: relative;
margin: auto;
top: 30px;
left: 0;
right: 0;
width: 21px;
height: 21px;
transform: rotate(45deg);
-webkit-transform: rotate(45deg);
-moz-transform: rotate(45deg);
-o-transform: rotate(45deg);
-ms-transform: rotate(45deg);
border-right: 2px solid #e74c3c;
border-bottom: 2px solid #e74c3c;
}
.line {
width: 30px;
position: relative;
border-bottom: 2px solid #e74c3c;
margin-top: 3px;
}
<a href="#" class="open">
<div class="line"></div>
<div class="line"></div>
<div class="line"></div>
<div class="triangle-container">
<div class="triangle"></div>
</div>
</a>
A one element method using before and after (fiddle):
.down-arrow {
display: inline-block;
position: relative;
width: 30px;
height: 14px;
border-top: 2px solid #e74c3c;
border-bottom: 2px solid #e74c3c;
}
.down-arrow::before {
display: block;
position: absolute;
top: 3px;
right: 0;
left: 0;
height: 3px;
border-top: 2px solid #e74c3c;
border-bottom: 2px solid #e74c3c;
content: '';
}
.down-arrow::after {
display: block;
position: relative;
top: 4px;
left: 0;
right: 0;
width: 21px;
height: 21px;
margin: 0 auto;
transform: rotate(45deg);
-webkit-transform: rotate(45deg);
-moz-transform: rotate(45deg);
-o-transform: rotate(45deg);
-ms-transform: rotate(45deg);
border-right: 2px solid #e74c3c;
border-bottom: 2px solid #e74c3c;
content: '';
}
.triangle-container {
top: 0px;
width: 30px;
height: 1px;
position: relative;
border-top: 2px solid #e74c3c;
margin-top: 3px;
}
.triangle {
position: absolute;
margin: auto;
top: -12px;
left: 0;
right: 0;
width: 21px;
height: 21px;
transform: rotate(45deg);
-webkit-transform: rotate(45deg);
-moz-transform: rotate(45deg);
-o-transform: rotate(45deg);
-ms-transform: rotate(45deg);
border-right: 2px solid #e74c3c;
border-bottom: 2px solid #e74c3c;
}
.line {
width: 30px;
position: relative;
border-bottom: 2px solid #e74c3c;
margin-top: 3px;
}

CSS - style horizontal line

I need to style a horizontal line <hr> like the picture attached. Is there any way to do this with pure css that would also work in IE8?
EDIT: Sorry, I missed your IE8 requirement...this probably won't work there. I apologize. I don't have access to it to check.
You can use the :before and create a box, rotate it, apply some border, absolutely position it and voila, there you have it:
http://jsfiddle.net/v7y1bp9s/1/
HTML:
<div class="container">
<hr class="line"></hr>
</div>
CSS:
.container {
float: left;
width: 100%;
height: 50px;
background-color: #1978a4;
line-height: 50px;
}
hr.line {
border-color: #fff;
position: relative;
}
hr.line:before {
content: '';
height: 10px;
width: 10px;
-webkit-transform: rotate(45deg);
-moz-transform: rotate(45deg);
-o-transform: rotate(45deg);
-ms-transform: rotate(45deg);
transform: rotate(45deg);
position: absolute;
left: 50px;
border-bottom: 1px solid #fff;
border-right: 1px solid #fff;
background-color: #1978a4;
top: -5px;
}

CSS to create an acute isosceles triangle with curved edges

I am trying to create a triangle using purely CSS which has curved edges.
Is this possible without it being totally over the top?
I've added an example below of what I'm trying to achieve (the curved lines - not the straight lines).
So far I have been working with the following code but it's not quite what I'm looking for.
#inner {
transform: rotate(45deg);
-ms-transform: rotate(45deg);
-webkit-transform: rotate(45deg);
-o-transform: rotate(45deg);
-moz-transform: rotate(45deg);
background-color: silver;
width: 100px;
height: 100px;
top: 20px;
left: -50px;
position: relative;
-moz-border-radius: 20px;
border-radius: 20px;
}
#outer {
position: absolute;
width: 70px;
height: 140px;
top: 20px;
left: 50px;
overflow: hidden;
border: 1px solid red;
}
<div id="outer">
<div id="inner"> </div>
</div>
How about an svg solution?
<svg width="200" height="200" viewBox="-2 0 252 212">
<path fill="rosybrown" d="M125 0 c-81.6 60 -113.3 130 -125 200 c83.3 40 166.6 40 250 0 c-11.7 -70 -43.4 -140 -125 -200" fill="none" stroke-width="2" stroke="black" />
</svg>
Just another posibility, without using any rotation. Just clipping different circles.
.triangle {
position: relative;
width: 200px;
height: 200px;
border-radius: 50%;
background-color: lightblue;
overflow: hidden;
}
.triangle div {
position: absolute;
width: 100%;
height: 100%;
top: 31%;
left: 16%;
background-color: lightyellow;
border-radius: 50%;
overflow: hidden;
}
.triangle div:after {
content: "";
position: absolute;
width: 100%;
height: 100%;
right: 30%;
background-color: red;
border-radius: 50%;
}
<div class="triangle">
<div></div>
</div>
The light colors are there just to make the construction of the triangle more visible
solution 1: Using two elements
The first example is not perfect, but does sort of answers your question:
.wrapper{
/*overflow:hidden;*/
width:0;
border-top:100px solid transparent;
border-left:100px solid red;
position:relative;
margin:50px;
transform:rotate(135deg);
}
.triangle{
width:20px;
height:100px;
background:red;
border-radius:50%;
transform:translate(-110px);
position:absolute;
top:-100px;
left:0;
}
.triangle:after{
content:"";
width:100px;
height:20px;
background:red;
border-radius:50%;
transform:translate(0px);
position:absolute;
top:90px;
left:10px;
}
.triangle:before{
content:"";
width:140px;
height:20px;
background:red;
border-radius:50%;
transform:rotate(225deg);
position:absolute;
top:40px;
left:-10px;
}
<div class="wrapper">
<div class="triangle"></div>
</div>
Please note This isn't an equilateral triangle, more of an isosceles one and could be edited into a better one no doubt!!
Solution 2: Using a single element
I was trying to create this shape using a single div element, but i was only able to generate two sides of the triangle. So, from this, I deduced that using css along requires two elements:
Two sides Of the Triangle Shown:
div {
border-left: 100px solid transparent;
border-bottom: 126px solid blue;
border-right: 100px solid transparent;
width: 0;
border-radius:50%;
position: relative;
}
div:after,
div:before {
content: "";
position: absolute;
height: 130px;
width: 20px;
border-radius: 50%;
top: -15px;
background: blue;
}
div:after {
left: -50px;
transform: rotate(40deg);
}
div:before {
left: 30px;
transform: rotate(-40deg);
}
<div></div>
I am guessing that svg may be a better option (note: I do not know svg, that seems like #chipChocolate.pys's area of expertise). So using 'just pseudo effects', I think you're looking to use two elements (but I'd like to see be proved wrong!). The 'single element' doesn't quite seem right, but may or may not be perfect for you
Pure CSS
Using different transforms.
I created three sectors using transform: rotate(30deg); and transform-origin: 0% 100%; Then I transformed their parent containers (scaleX: -1; for the left side). Done.
This can be done with just one pair of #cont and #circ elements, but I used different tags just for demonstrating better.
#cont {
height: 300px;
width: 300px;
overflow: hidden;
position:relative;
}
#circ {
height: 300px;
width: 300px;
background: black;
border-radius: 0 300px 0 0;
transform: rotate(30deg);
transform-origin: 0% 100%;
}
#cont:nth-of-type(2){
top: -300px;
transform: scaleX(-1);
}
#cont:nth-of-type(3){
top: -600px;
transform: rotate(30deg);
transform-origin: 0% 100%;
}
#cont:nth-of-type(3) > #circ {
border-radius: 0 0 300px 0;
transform-origin: 0% 0%;
}
<div id="cont">
<div id="circ">
</div>
</div>
<div id="cont">
<div id="circ">
</div>
</div>
<div id="cont">
<div id="circ">
</div>
</div>
Note: For a real website, almost always use SVG. But creating shapes with CSS is an art which mustn't be killed.
Here is my attempt at this. I think this is the best way to do it, using 1 element and :before :after.
Using the div as the base element (the bottom) we can line up the other 2 above it keeping the size and shape equal.
div {
width: 120px;
height: 60px;
background: red;
border-radius: 50%;
position: relative;
margin: 100px;
}
div:before, div:after {
content: "";
display: block;
background: red;
border-radius: 50%;
position: absolute;
width: 60px;
height: 120px;
top: -70px;
}
div:before {
transform: rotate(30deg);
left: 8px;
}
div:after {
transform: rotate(-30deg);
right: 8px;
}
<div></div>
Edit:
Another Attempt, slight tweaking from the first.
div {
width: 100px;
height: 50px;
background: red;
border-radius: 50%;
position: absolute;
top: 10px;
left: 70px;
margin: 100px;
}
div:before,
div:after {
content: "";
display: block;
background: red;
border-radius: 50%;
position: absolute;
width: 36px;
height: 106px;
top: -65px;
}
div:before {
transform: rotate(28deg);
left: 8px;
border-right: 10px solid red;
}
div:after {
transform: rotate(-28deg);
right: 8px;
border-left: 9px solid red;
}
<div></div>
I like the challenge :)
I recently have come to love the more complex border radius variations. I'm sure with some more fiddling and decent math calculations you can get rid of the rough edges where the different sides meet. No time for it now unfortunately.
.triangle {
position: absolute;
top: 100px;
left: 100px;
border-left: 25px solid transparent;
border-bottom: 40px solid blue;
border-right: 25px solid transparent;
width: 0;
border-bottom-right-radius: 80px 70px;
border-bottom-left-radius: 0 0;
transform: rotate(160deg);
}
.triangle:after {
content: '';
position: absolute;
border-left: 25px solid transparent;
border-bottom: 40px solid CornflowerBlue;
border-right: 25px solid transparent;
width: 0;
left: -54px;
top: -12px;
border-bottom-right-radius: 80px 70px;
border-bottom-left-radius: 0 0;
transform: rotate(120deg);
}
.triangle:before {
content: '';
position: absolute;
border-left: 25px solid transparent;
border-bottom: 40px solid darkblue;
border-right: 25px solid transparent;
width: 0;
top: -30px;
left: -29px;
border-bottom-right-radius: 80px 70px;
border-bottom-left-radius: 0 0;
transform: rotate(240deg);
}
<div class="triangle"></div>

Right trapezoid outline shape (with transparency)

I'm trying to emulate an angled path line similar to this image.
The way I'm doing it is using two trapezoid shapes, and overlapping one with another that would be the same as the background as seen in this jsFiddle.
But I realized I want the rest of the shape to be transparent instead of being able to overlap other objects.
The core is just a little bit of CSS, an outlineMaker div inside of a rightTrapezoid div.
.rightTrapezoid {
border-bottom: 100px solid red;
border-left: 0 solid transparent;
border-right: 50px solid transparent;
height: 0;
width: 100px;
}
.outlineMaker {
border-bottom: 80px solid white;
border-left: 0 solid transparent;
border-right: 40px solid transparent;
height: 20px;
width: 80px;
}
Is there a neat and concise way to do this?
Complete example following nice using #Feng Huo tip.
HTML Markup
<div class="trapezoidLine1">
<div class="trapezoidLine2"/>
</div>
<div class="trapezoidLine3">
<div class="trapezoidLine4"/>
</div>
CSS
.trapezoidLine1 {
position: absolute;
width: 200px;
height: 2px;
background: blue;
}
.trapezoidLine3 {
position: relative;
margin-top:45px;
width: 207px;
height: 2px;
background:blue;
}
.trapezoidLine2 {
position: absolute;
width: 47px;
height: 2px;
background: blue;
left: 200px;
-webkit-transform-origin: 0% 0%;
-webkit-transform: rotateZ(80deg);
}
.trapezoidLine4 {
position: absolute;
width: 45px;
height: 2px;
background: blue;
-webkit-transform-origin: 0% 0%;
-webkit-transform: rotateZ(270deg);
}
Try the fiddle
http://jsfiddle.net/TNW63/
Instead of trying to force this way to work with a twist somehow. I gave it a couple minutes of thought and realized DUHHHHHHH, I can just do this:
<div class="trapezoidLine1">
<div class="trapezoidLine2"/>
</div>
.trapezoidLine1 {
position: absolute;
width: 200px;
height: 10px;
background: blue;
}
.trapezoidLine2 {
position: absolute;
width: 200px;
height: 10px;
background: blue;
left: 200px;
-webkit-transform-origin: 0% 0%;
-webkit-transform: rotateZ(45deg);
}
Herp a derp...

Resources