How to create an arrow in css3? [closed] - css

It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 10 years ago.
How to create arrow in css3?
As like this .
jsfiddle http://jsfiddle.net/BdSP4/1/

--- SEE DEMO ----
<div class="triangle-left">
<div></div>
</div>​
.triangle-left {
border-color: transparent black transparent transparent;
border-style: solid;
border-width: 20px;
width: 0;
height: 0;
}
.triangle-left div
{
border-color: transparent white transparent transparent;
border-style: solid;
border-width: 10px;
width: 0;
height: 0;
position:relative;
top:-9px;
left:0px;
}​
This is a triangle with a white triangle positioned inside, giving the appearance of an arrow. For more information on CSS3 triangles see here:
http://jonrohan.me/guide/css/creating-triangles-in-css/

See JsFiddle
HTML
<div class="angle"></div>
CSS
.angle:after { /* Thanks to :after just one div is necessary */
content: '.';
border-top: 20px solid #000; /* NW triangle gap */
border-bottom: 20px solid #000; /* SW triangle gap */
border-left: none;
border-right: 20px solid transparent; /* W triangle */
position: relative;
left: 20px;
}
.angle {
font-size: 0px; line-height: 0%; width: 0px; /* Necessary to not screw up the layout */
border-top: 20px solid transparent; /* NE triangle gap */
border-bottom: 20px solid transparent; /* SE triangle gap */
border-left: none;
border-right: 20px solid #000; /* E triangle */
}
Update: Smaller version
These are 2 overlapping triangles. One is black, one is white.
JsFiddle
Same HTML, different CSS
.angle:after {
content: '.';
border-top: 10px solid transparent;
border-bottom: 10px solid transparent;
border-left: none;
border-right: 10px solid white;
position: relative;
left: 5px;
}
.angle {
font-size: 0px; line-height: 0%; width: 0px; /* Necessary to not screw up the layout */
border-top: 10px solid transparent;
border-bottom: 10px solid transparent;
border-left: none;
border-right: 10px solid #000;
}

You don't have to use CSS 3 - create it with an HTML entity:
<span>‹</span>

Just adding alternative using CSS3's rotate
Demo
CSS
.arrow { width: 20px; height: 20px; overflow: hidden; }
.arrow span {
display: block;
border: 4px #000 solid;
background: #fff;
width: 14px;
height: 14px;
float:right;
margin-right: -12px;
-webkit-transform: rotate(45deg);
-moz-transform: rotate(45deg);
-ms-transform: rotate(45deg);
-o-transform: rotate(45deg);
transform: rotate(45deg);
filter: progid:DXImageTransform.Microsoft.Matrix(
M11=0.7071067811865476, M12=-0.7071067811865475, M21=0.7071067811865475, M22=0.7071067811865476, sizingMethod='auto expand');
zoom: 1;
}
HTML
<div class="arrow"><span></span></div>

Related

Hover-effect on a :before class doesn't work as expected

I have realized a dropdown menue with a triangle at the top like this:
Now, when the cursor only rolls over the triangle it looks like this:
But if the cursor is over the div the rollover-effect for both gets triggered like this:
I want the hover-effect for both elements triggered, when the cursor moves over the triangle as well. Can someone tell me what I am doing wrong here?
This is my CSS:
.msg_archivedropdown {
position: absolute;
color: #fff;
left: 40px;
top:0%;
background-color: #659DBD;
z-index: 100;
display:none;
border-radius: 2px;
border-top-left-radius: 0px;
box-shadow: 1px 1px 1px #000000;
}
.msg_archivedropdown:before {
content:"";
display: block;
position:absolute;
width:0;
height:0;
left:-7px;
top:0px;
border-top: 10px solid transparent;
border-bottom:10px solid transparent;
border-right:7px solid #659DBD;
}
.msg_archivedropdown:hover::before {
border-right:7px solid #fff;
color: #659DBD;
}
.msg_optiondropdownpoint {
padding-top: 10px;
padding-bottom: 10px;
padding-left: 30px;
padding-right: 30px;
}
.msg_optiondropdownpoint:hover {
background-color: #fff;
color: #659DBD;
}
Just use a gradient to fake the empty space on the left. Then position your ::before element just inside the parent. Just keep in mind that you need to double the padding on the left to complete the visual trick:
Codepen Demo
HTML:
<div class="parent-element">
<p>
I have reset the sensors to scan for frequencies outside the usual range. By emitting harmonic vibrations to shatter the lattices. We will monitor and adjust the frequency of the resonators. He has this ability of instantly interpreting and extrapolating any verbal communication he hears. It may be due to the envelope over the structure, causing hydrogen-carbon helix patterns throughout. I'm comparing the molecular integrity of that bubble against our phasers.
</p>
</div>
CSS:
.parent-element{
background:deeppink;
background: linear-gradient(to left, deeppink calc(100% - 16px), rgba(0,0,0,0) 10%);
padding:16px;
padding-left:32px;
width:320px;
border-radius:4px;
color:white;
position:relative;
margin:48px auto;
}
.parent-element:hover{
background: linear-gradient(to left, deepskyblue calc(100% - 16px), rgba(0,0,0,0) 10%);
}
.parent-element::before{
content:'';
display:block;
position:absolute;
width: 0;
height: 0;
border: 0 solid transparent;
border-top-width: 16px;
border-bottom-width: 16px;
border-right: 16px solid deeppink;
top:calc(50% - 8px);
left:0px;
}
.parent-element:hover::before{
border-right: 16px solid deepskyblue;
pointer-events:auto;
}

how can i add to rectangle with arrows border [duplicate]

I would like to make a button like these one just with CSS without using another element.
Button Image
Since the button has a border attached, I think I normally need both, the :before and :after elements to create just one arrow at one side. So to make one arrow at each side I would need another span element inside the link.
The second method I tried is the one you see below. But with this solution they are not properly centered and each side of the arrow is different in length.
Has someone a solution?
/* General Button Style */
.button {
display: block;
position: relative;
background: #fff;
width: 300px;
height: 80px;
line-height: 80px;
text-align: center;
font-size: 20px;
text-decoration: none;
text-transform: uppercase;
color: #e04e5e;
margin: 40px auto;
font-family: Helvetica, Arial, sans-serif;
box-sizing: border-box;
}
/* Button Border Style */
.button.border {
border: 4px solid #e04e5e;
}
.button.border:hover {
background: #e04e5e;
color: #fff;
}
/* Button Ribbon-Outset Border Style */
.button.ribbon-outset.border:after,
.button.ribbon-outset.border:before {
top: 50%;
content: " ";
height: 43px;
width: 43px;
position: absolute;
pointer-events: none;
background: #fff;
}
.button.ribbon-outset.border:after {
left: -3px;
margin-top: -40px;
transform-origin: 0 0;
box-sizing: border-box;
border-bottom: 4px solid #e04e5e;
border-left: 4px solid #e04e5e;
transform: rotate(57.5deg) skew(30deg);
}
.button.ribbon-outset.border:before {
right: -46px;
margin-top: -40px;
transform-origin: 0 0;
box-sizing: border-box;
border-top: 4px solid #e04e5e;
border-right: 4px solid #e04e5e;
transform: rotate(57.5deg) skew(30deg);
}
.button.ribbon-outset.border:hover:after {
background: #e04e5e
}
.button.ribbon-outset.border:hover:before {
background: #e04e5e
}
Click me!
CodePen Demo
Here is another alternate way to get this done with only one element.
This approach works like below:
Two pseudo-elements :before and :after which are about half the size (including borders) of the main .button element. The height of each pseudo-element is 34px + 4px border on one side (top/bottom) and 2px on the other side.
The top half of the shape is achieved using the :before element whereas the bottom half is achieved using the :after element.
Using a rotateX with perspective to achieve the tilted effect and positioning to place the two elements such that they form the expected shape.
/* General Button Style */
.button {
position: relative;
display: block;
background: transparent;
width: 300px;
height: 80px;
line-height: 80px;
text-align: center;
font-size: 20px;
text-decoration: none;
text-transform: uppercase;
color: #e04e5e;
margin: 40px auto;
font-family: Helvetica, Arial, sans-serif;
box-sizing: border-box;
}
.button:before,
.button:after {
position: absolute;
content: '';
width: 300px;
left: 0px;
height: 34px;
z-index: -1;
}
.button:before {
transform: perspective(15px) rotateX(3deg);
}
.button:after {
top: 40px;
transform: perspective(15px) rotateX(-3deg);
}
/* Button Border Style */
.button.border:before,
.button.border:after {
border: 4px solid #e04e5e;
}
.button.border:before {
border-bottom: none; /* to prevent the border-line showing up in the middle of the shape */
}
.button.border:after {
border-top: none; /* to prevent the border-line showing up in the middle of the shape */
}
/* Button hover styles */
.button.border:hover:before,
.button.border:hover:after {
background: #e04e5e;
}
.button.border:hover {
color: #fff;
}
<!-- Library included to avoid browser prefixes -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script>
Click me!
Fixed Width Demo | Dynamic Width Demo
Output Screenshot:
This is tested in Chrome v24+, Firefox v19+, Opera v23+, Safari v5.1.7, IE v10.
As-is, this would degrade quite well in IE 8 and IE 9 into a square button with borders. However, due to the nullification of one border (border-bottom for :before and border-top for :after) it would leave a white area (resembling a strike-through line) in the middle. This can be overcome by adding a couple of IE < 10 specific styles using conditional comments like in this demo.
<!--[if IE]>
<style>
.button.border:after{
top: 38px;
}
.button.border:hover:before, .button.border:hover:after {
border-bottom: 4px solid #e04e5e;
}
</style>
<![endif]-->
Output Screenshot from IE 9 and IE 8:
This is just a simpler alternative to Harry's answer.
This approach uses scale() and rotate(45deg) transforms. Using this approach, you can very easily change the angle of right and left chevrons.
Fiddle
div {
height: 70px;
width: 200px;
margin-left: 40px;
border-top: 4px solid #E04E5E;
border-bottom: 4px solid #E04E5E;
position: relative;
text-align: center;
color: #E04E5E;
line-height: 70px;
font-size: 21px;
font-family: sans-serif;
}
div:before, div:after {
content:'';
position: absolute;
top: 13px;
height: 40px;
width: 40px;
border: 4px solid #E04E5E;
-webkit-transform: scale(0.8,1.25) rotate(45deg);
-moz-transform: scale(0.8,1.25) rotate(45deg);
-ms-transform: scale(0.8,1.25) rotate(45deg);
transform: scale(0.8,1.25) rotate(45deg);
}
div:before {
left: -22px;
border-top: 0px solid transparent;
border-right: 0px solid transparent;
}
div:after {
right: -22px;
border-bottom: 0px solid transparent;
border-left: 0px solid transparent;
}
div:hover, div:hover:before, div:hover:after {
background-color: #E04E5E;
color: #EEE;
}
<div>HELLO!</div>
Want a wider arrow? Simply decrease scale() transform's x value : Fiddle (wide)
Narrower one? Increase scale() transform's x value : Fiddle (narrow)
Note: IE 8 and below don't support CSS Transforms (9 supports with -ms- prefix), so you can check out this site for supporting them: IE Transform Translator
I forked your Pen
Codepen Demo
The essential changes are that I removed the side borders from the main button (as they were superflous
/* Button Border Style */
.button.border {
border-top: 4px solid #e04e5e;
border-bottom: 4px solid #e04e5e;
}
and changed a couple of values to tweak it all into place
/* Button Ribbon-Outset Border Style */
.button.ribbon-outset.border:after,
.button.ribbon-outset.border:before {
top: 50%;
content: " ";
height: 43px;
width: 43px;
position: absolute;
pointer-events: none;
}
.button.ribbon-outset.border:after {
left:0;
margin-top:-40px;
transform-origin:0 0;
box-sizing:border-box;
border-bottom:4px solid #e04e5e;
border-left:4px solid #e04e5e;
transform:rotate(57.5deg) skew(30deg);
}
.button.ribbon-outset.border:before {
right:-43px;
margin-top:-40px;
transform-origin:0 0;
box-sizing:border-box;
border-top:4px solid #e04e5e;
border-right:4px solid #e04e5e;
transform:rotate(57.5deg) skew(30deg);
}
I got the answer myself. It was a problem of the transform property of the :before and :after elements.
CSS changed:
/* Button Border Style */
.button.border {
border-top:4px solid #e04e5e;
border-bottom:4px solid #e04e5e;
}
/* Button Ribbon-Outset Border Style */
.button.ribbon-outset.border:after, .button.ribbon-outset.border:before {
height: 42px;
width: 42px;
}
.button.ribbon-outset.border:after {
left:0;
border-bottom:5px solid #e04e5e;
border-left:5px solid #e04e5e;
transform:rotate(45deg) skew(19deg,19deg);
}
.button.ribbon-outset.border:before {
right:-42px;
border-top:5px solid #e04e5e;
border-right:5px solid #e04e5e;
transform:rotate(45deg) skew(19deg,19deg);
}
Updated Codepen

How to make a gradient div in the shape of a trapezoid?

I'm trying to make this image I found on Dribbble using Codepen.
I've made the bike, but I can't get the light.
I've tried several times using overflow:hidden and it isn't working.
Do you have an idea of how to do this?
What I'm trying to do is :
web here
Use triangles instead of a trapezium. You can cover the tip of said triangle with the light.
Tweak the numbers, but here's the general idea: http://jsfiddle.net/cZQmH/ http://jsfiddle.net/cZQmH/1/ (added browser compatibility)
<div class="light">
<div class="top triangle"></div>
<div class="bottom triangle"></div>
</div>
Where each "triangle" is actually just covering up the corner
.light { /* Just a big box. Where the magic happens*/
padding:50px 0px;
position: absolute;
background: -webkit-linear-gradient(left, rgba(255,255,255,1),rgba(255,255,255,1), rgba(255,255,0,0)); /* should add other compatibility things */
height: 75px;
width:200px;
}
.triangle {
width: 50px;
position: absolute;
left: 0;
}
.top { /*Covers top corner*/
top:0;
border-top: 100px solid #ff0;
border-right: 100px solid transparent;
}
.bottom { /* Covers bottom corner */
bottom:0;
border-bottom: 100px solid #ff0;
border-right: 100px solid transparent;
}
The final CSS is a bit verbose, but if you're using LESS or SASS it should come out pretty cleanly.
What it comes down to is not using the border itself, but using a gradient negative image. You could experiment with the border-image it's just as well supported as Gradients but I came up with this solution first. It does look like it's possible however
Also: could you post a link to the completed bike? I'd be curious to see how you handle all of those curves.
html
<div class="light">
<div id="trapezoid"></div>
<div id="trapezoid-two"></div>
</div>
css
.light{
background-color: yellow;
width: 400px;
height: 200px;
}
#trapezoid {
top: 50px;
left: 150px;
position: absolute;
border-top: 40px solid transparent;
border-bottom: 40px solid transparent;
height: 16px;
border-right-width: 160px;
border-right-style: dashed;
border-right-color: white;
}
#trapezoid:before {
content: '';
position: absolute;
width: 40px;
height: 10px;
-webkit-box-shadow: 3px 0 130px 80px white;
left: 160px;
border-radius: 50px;
background-color: white;
}
#trapezoid-two{
top: 60px;
left: 200px;
position: absolute;
border-top: 35px solid transparent;
border-bottom: 35px solid transparent;
height: 6px;
border-right-width: 160px;
border-right-style: solid;
border-right-color: white;
}

making borders around CSS shapes

So I'm drawing elements in CSS, using this tutorial as a guide. I need some help with borders, though. For instance, here's my code for a curved trapezoid:
.foobar {
height: 0px;
width: 140px;
position: relative;
border-bottom: 200px solid red;
border-left: 30px solid transparent;
border-right: 30px solid transparent;
border-bottom-left-radius: 150px 70px;
border-bottom-right-radius: 100px 25px;
}
The problem: I want to draw a 1px line border around the foobar element, but I'm already using the border properties to draw the element in the first place.
Is there an easy way to do this? My sense is that I'll have to create a shadow element that is the same shape as -- but slightly larger than -- the foobar element.
Thanks in advance!
You can position a :pseudo element behind with slightly adjusted dimensions.
.foobar, .foobar:before {
height: 0px;
width: 140px;
position: relative;
border-bottom: 200px solid red;
border-left: 30px solid transparent;
border-right: 30px solid transparent;
border-bottom-left-radius: 150px 70px;
border-bottom-right-radius: 100px 25px;
}
.foobar:before {
content: "";
display:block;
position: absolute;
left: -31px;
top: -1px;
width: 142px;
z-index: -1;
border-bottom: 202px solid black;
/* add these lines if you're a pixel perfectionist */
border-bottom-left-radius: 150px 71px;
border-bottom-right-radius: 100px 26px;
}
http://jsfiddle.net/4vNGL/2
You can use a pseudo element drawn behind with same rules with a small increase of scale.
.foobar, .foobar:before {
height: 0px;
width: 140px;
position: relative;
border-bottom: 200px solid red;
border-left: 30px solid transparent;
border-right: 30px solid transparent;
border-bottom-left-radius: 150px 70px;
border-bottom-right-radius: 100px 25px;
position:relative;
}
.foobar:before {
content:'';
position:absolute;
display:block;
z-index:-1;
top:0;
left:-30px;
width: 140px;
-webkit-transform-origin:center;
-webkit-transform:scale(1.03);/* adapt here the width of your fake border */
transform-origin:center;
transform:scale(1.03);
border-bottom: 200px solid black; /* color of fake border */
}
http://codepen.io/gc-nomade/pen/eDIGJ
You can even play with both pseudo-element and still add some shadows: http://codepen.io/gc-nomade/pen/axmsc

Border within border CSS

With the help of CSS Triangle tutorial, I learnt to create triangle shapes.
.arrow-down {
width: 0;
height: 0;
border-left: 20px solid transparent;
border-right: 20px solid transparent;
border-top: 20px solid #ccc;
}
I'm trying to add a border to the triangle but I was unable to do it.
what I achieved:
Expected:(trying something similar border with gray)
Check this JSFiddle
Stuck up no where to start this. I tried outline, but none worked(I know it won't work).
Thanks for taking time to read my question.
Any help is appreciated.
Note: I'm trying this in CSS instead of using images.
When the main triangle or arrow is itself created using the CSS borders, it is impossible to add another border to it without using extra elements. The below are a few options.
Option 1: Using a bigger size pseudo-element and positioning it behind the parent to produce a border-effect.
.arrow-down {
position: relative;
width: 0;
height: 0;
border-left: 20px solid transparent;
border-right: 20px solid transparent;
border-top: 20px solid #ccc;
}
.arrow-down:before {
position: absolute;
content: "";
left: -22px;
top: -20px;
height: 0px;
width: 0px;
border-left: 21px solid transparent;
border-right: 21px solid transparent;
border-bottom: 21px solid transparent;
border-top: 21px solid black;
z-index: -1;
}
<div class="arrow-down"></div>
.arrow-down:before {
position: absolute;
content: "";
left: -22px;
top: -20px;
height: 0px;
width: 0px;
border-left: 21px solid transparent;
border-right: 21px solid transparent;
border-bottom: 21px solid transparent;
border-top: 21px solid black;
z-index: -1;
}
Option 2: Rotating the element (which has the border hack to produce the triangle) and then adding a box-shadow to it.
.arrow-down {
width: 0;
height: 0;
margin: 10px;
border-left: 0px solid transparent;
border-right: 30px solid transparent;
border-top: 30px solid #ccc;
-ms-transform: rotate(225deg); /* IE 9 */
-webkit-transform: rotate(225deg); /* Chrome, Safari, Opera */
-moz-transform: rotate(225deg);
transform: rotate(225deg);
box-shadow: 0px -3px 0px -1px #444;
}
<div class="arrow-down"></div>
.arrow-down {
width: 0;
height: 0;
margin: 10px;
border-left: 0px solid transparent;
border-right: 30px solid transparent;
border-top: 30px solid #ccc;
transform: rotate(225deg); /* browser prefixes added in snippet */
box-shadow: 0px -3px 0px -1px #444;
}
Tested in Chrome v24 and Safari v5.1.7. Should work in other CSS3 compatible browsers also.
The following options do not directly answer the question as it doesn't do a border within border but are others way of producing an arrow/triangle with a border.
Option 3: Using linear-gradients on an element, rotating it to produce the triangle and then adding a border to it using the normal border property.
.arrow-down {
width: 30px;
height: 30px;
margin: 10px;
border-left: 2px solid #444;
background: -webkit-linear-gradient(45deg, #ccc 50%, transparent 50%);
background: -moz-linear-gradient(45deg, #ccc 50%, transparent 50%);
background: -o-linear-gradient(45deg, #ccc 50%, transparent 50%);
background: linear-gradient(45deg, #ccc 50%, transparent 50%);
-webkit-transform: rotate(-45deg);
-moz-transform: rotate(-45deg);
transform: rotate(-45deg);
-webkit-backface-visibility:hidden; /** <-- to prevent diagonal line aliasing in chrome **/
}
<div class="arrow-down"></div>
.arrow-down {
width: 30px;
height: 30px;
margin: 10px;
border-left: 2px solid #444;
background: linear-gradient(45deg, #ccc 50%, transparent 50%);
transform: rotate(-45deg);
backface-visibility:hidden;
}
Option 4: Using a rotated pseudo-element (with background as the color of the triangle) to produce the triangle and then adding a normal border to it. The parent element's overflow is set to hidden and the pseudo-element is positioned appropriately so as to display only half of it (creating the illusion of a triangle).
.arrow-down {
position: relative;
height: 50px;
width: 50px;
overflow: hidden;
}
.arrow-down:before {
position: absolute;
content: '';
top: -webkit-calc(100% * -1.414 / 2);
top: calc(100% * -1.414 / 2);
left: 0px;
height: 100%;
width: 100%;
background: #CCC;
border-left: 2px solid #444;
-webkit-transform: rotate(-45deg);
-moz-transform: rotate(-45deg);
transform: rotate(-45deg);
}
<div class="arrow-down"></div>
.arrow-down:before {
position: absolute;
content: '';
top: calc(100% * -1.414 / 2);
left: 0px;
height: 100%;
width: 100%;
background: #CCC;
border-left: 2px solid #444;
transform: rotate(-45deg);
}
Try adding these lines to your CSS:
.arrow-down:before {
content: "";
display: block;
border-left: 26px solid transparent;
border-right: 26px solid transparent;
border-top: 26px solid #0f0;
position: relative;
left: -26px;
top: -20px;
z-index: -1;
}
This will draw a 3px green border.
Check the result here: jsfiddle
Demo: http://jsfiddle.net/3fFM7/
.arrow {
border-bottom: 60px solid transparent;
border-left: 60px solid black;
border-top: 60px solid transparent;
height: 0;
margin-left: 50px;
width: 0;
behavior:url(-ms-transform.htc);
-moz-transform:rotate(90deg);
-webkit-transform:rotate(90deg);
-o-transform:rotate(90deg);
-ms-transform:rotate(90deg);
}
.arrow > div {
border-bottom: 59px solid transparent;
border-left: 59px solid red;
border-top: 59px solid transparent;
left: -60px;
position: relative;
top: -63px;
width: 0;
}
<div class="arrow"><div></div></div>
Play with transform rotate :)
Or:
DEMO: http://jsfiddle.net/tKY25/1/
<div class="triangle-with-shadow"></div>
.triangle-with-shadow {
width: 100px;
height: 100px;
position: relative;
overflow: hidden;
transform: rotate(180deg);
}
.triangle-with-shadow:after {
content: "";
position: absolute;
width: 50px;
height: 50px;
background: #999;
transform: rotate(45deg);
top: 75px;
left: 25px;
box-shadow: 0px -5px 0 0px rgba(0,0,0,100);
}

Resources