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);
}
Related
I have an element with a known ID I can target. How could I create a bestseller-badge like this with css only? I cannot change the html.
I know how to create this but only if I could edit the html, which I cannot:
.box {
width: 200px; height: 300px;
position: relative;
border: 1px solid #BBB;
background: #EEE;
}
.ribbon {
position: absolute;
right: -5px; top: -5px;
z-index: 1;
overflow: hidden;
width: 75px; height: 75px;
text-align: right;
}
.ribbon span {
font-size: 10px;
font-weight: bold;
color: #FFF;
text-transform: uppercase;
text-align: center;
line-height: 20px;
transform: rotate(45deg);
-webkit-transform: rotate(45deg);
width: 100px;
display: block;
background: #79A70A;
background: linear-gradient(#9BC90D 0%, #79A70A 100%);
box-shadow: 0 3px 10px -5px rgba(0, 0, 0, 1);
position: absolute;
top: 19px; right: -21px;
}
.ribbon span::before {
content: "";
position: absolute; left: 0px; top: 100%;
z-index: -1;
border-left: 3px solid #79A70A;
border-right: 3px solid transparent;
border-bottom: 3px solid transparent;
border-top: 3px solid #79A70A;
}
.ribbon span::after {
content: "";
position: absolute; right: 0px; top: 100%;
z-index: -1;
border-left: 3px solid transparent;
border-right: 3px solid #79A70A;
border-bottom: 3px solid transparent;
border-top: 3px solid #79A70A;
}
<div class="box">
<div class="ribbon"><span>Bestseller</span></div>
</div>
The thing is I only have the parent box and not the ribbon inside. I cant input html.
Because in pseudo elements you can't put any html markup, you need to get clever with just using simple shapes and combining them together. Additionally, you can't have multiple :after pseudo elements, so we are limited to just two shapes (one for :after and one for :before). The one in :after could be the bestseller front of the badge, with text. The trickiest part was to get the clip-path: polygon(...points) to get right so that we get the effect of trimmed ribbon. Fortunately, Firefox dev tools have a nifty polygon modification tool that was very helpful. Getting the two little corners that make the "wrap around" effect was a bit trickier, but putting it in a :before pseudo element with z-index: -1 and a little hand-tweaked offset did the trick. The end effect is below:
.box {
width: 200px; height: 300px;
position: relative;
border: 1px solid #BBB;
background: #EEE;
margin: 20px;
display: inline-block;
}
.bestseller:before {
content: "";
z-index: -1;
overflow: hidden;
transform: rotate(-135deg);
width: 120px;
display: block;
background: #79A70A;
background: linear-gradient(#9BC90D 0%, #79A70A 100%);
box-shadow: 0 3px 10px -5px rgba(0, 0, 0, 1);
position: absolute;
top: 34px;
right: -16px;
clip-path: polygon(120px 20px, 90px -10px, 30px -10px, 0px 20px, 10px 30px, 110px 30px);
height: 20px;
width: 120px;
}
.bestseller:after {
content: "bestseller";
z-index: 1;
overflow: hidden;
font-size: 10px;
font-weight: bold;
color: #FFF;
text-transform: uppercase;
text-align: center;
line-height: 20px;
transform: rotate(45deg);
width: 120px;
display: block;
background: #79A70A;
background: linear-gradient(#9BC90D 0%, #79A70A 100%);
box-shadow: 0 3px 10px -5px rgba(0, 0, 0, 1);
position: absolute;
top: 20px; right: -30px;
clip-path: polygon(120px 20px, 90px -10px, 30px -10px, 0px 20px, 10px 30px, 110px 30px)
}
<div class="box">
</div>
<div class="box bestseller">
</div>
With the help of only CSS using pseudo class, we cannot create exactly the same but similar to that is possible. Add the id "ribbon" to div with class "box" and try with the below css. Increment/decrement the height, top right, etc based on the size of your div.
#ribbon:before {
content: "";
width: 60px;
display: block;
position: absolute;
top: 14px;
right: -28px;
transform: rotate(45deg);
-webkit-transform: rotate(45deg);
border-left: 30px solid transparent;
border-right: 30px solid transparent;
border-bottom: 30px solid green;
height: 0;
}
#ribbon:after {
content: "Bestseller";
font-size: 10px;
font-weight: bold;
color: #FFF;
text-transform: uppercase;
text-align: center;
line-height: 30px;
transform: rotate(45deg);
-webkit-transform: rotate(45deg);
width: 60px;
display: block;
position: absolute;
top: 14px;
right: 2px;
height: 30px;
}
Instead of trying with border for the background color of ribbon, you can also try using an ribbon image as background and use the text on top of it.
I'm trying to create an 'easy' button shape with css pseudeo :after/:before class.
I've read some blogs and articles about that, but no shape looked like mine. So I tried it on my own. But this I something, I can't figure out.
button{
height: 50px;
width: 250px;
border: solid 2px #000;
border-bottom: none;
background: orange;
}
button:after{
height: 0;
width: 125px;
content:"";
position: absolute;
border-top: transparent 30px
border-right: solid 2px #000;
}
button:before{
height: 0;
width: 125px;
content:"";
position: absolute;
border-top: transparent 30px
border-left: solid 2px #000;
}
<button>Let's do it</button>
Can someone give me a hint?
You can create this with :before and :after pseudo elements one for border and other one above for orange background.
button {
height: 50px;
width: 250px;
border: solid 2px #000;
border-bottom: none;
background: orange;
position: relative;
}
button:after,
button:before {
border-style: solid;
border-width: 50px 110px 0 140px;
border-color: #FFA500 transparent transparent transparent;
content: '';
position: absolute;
left: -2px;
top: 100%;
}
button:after {
transform: translateY(-1px);
}
button:before {
border-color: black transparent transparent transparent;
}
<button>Let's do it</button>
Not exactly the same size but you can play with the following one:
#pentagon {
margin-top: 45px;
position: relative;
width: 250px;
border-width: 70px 0 0;
border-style: solid;
border-color: orange transparent;
}
#pentagon:after {
content: "";
position: absolute;
height: 0;
width: 0;
top: -30px;
left: 0px;
border-width: 50px 125px 0 125px;
border-style: solid;
border-color: orange white;
}
<div id="pentagon"></div>
You could play with this, it has a border like your image http://www.cssarrowplease.com/
I want to add a label on some of my elements on a website and design for a label that is a flag with an inverted V-shaped cut at the bottom.
So far I have this:
HTML
<div class="css-shapes"></div>
CSS
.css-shapes{
border-left: 99px solid #f00fff;
border-right: 99px solid #f00fff;
border-bottom: 39px solid transparent;
}
http://jsfiddle.net/yhexkm4u/2/
However, I need the background to be white and border around this shape in purple and 1px. I was trying to fit the same shape just in white inside of this one, but everything got messy and didn't go as expected.
Maybe it is a wrong approach, but I want to end up with labels that would look something like this:
With CSS:
You can use CSS transforms on pseudo elements to create the background with a transparent inverted triangle at the bottom:
body{background:url('http://lorempixel.com/image_output/food-q-c-640-480-1.jpg');background-size:cover;}
p{
position: relative;
width: 150px; height: 150px;
overflow: hidden;
border-top:3px solid #EF0EFE;
}
p:before, p:after{
content: '';
position: absolute;
top: -3px;
height: 100%; width: 50%;
z-index: -1;
border:2px solid #EF0EFE;
box-sizing:border-box;
}
p:before{
left: 0;
transform-origin: 0 0;
transform: skewY(-20deg);
border-width:0 0 4px 3px;
}
p:after{
right: 0;
transform-origin: 100% 0;
transform: skewY(20deg);
border-width:0 3px 4px 0;
}
<p>Some text ... </p>
Note that you will need to add vendor prefixes on the transform and transform-origin properties to maximize browser support. See canIuse for more information.
With SVG
Another approach is to use an inline SVG with the polygon element:
body{background: url('http://lorempixel.com/image_output/food-q-c-640-480-1.jpg');background-size: cover;}
div{position: relative;width: 100px; height: 150px;}
svg{position: absolute;width: 100%;height: 100%;z-index: -1;}
<div>
<svg viewbox="-1.5 -1.5 103 153">
<polygon points="100 0, 100 100, 50 85, 0 100, 0 0" fill="transparent" stroke-width="3" stroke="#ef0efe"/>
</svg>
<p>Some text ... </p>
</div>
Here is a slightly different method using pseudo-elements and transform rotations to create an outlined banner like this:
This angled shape is created with position: absolute pseudo-elements, :before and :after:
The excess is cut off with overflow: hidden on the parent to form our banner:
The outline is created with box-shadow and the two angles are prevented from overlapping by pulling / pushing the x-axis by 46px — box-shadow: 46px 0 0 3px #000
Full Example
div {
height: 100px;
width: 100px;
margin: 100px auto;
position: relative;
overflow: hidden;
border: solid 3px #000;
border-bottom: none;
text-align: center;
}
div:before,
div:after {
content: '';
display: block;
height: 100%;
width: 200%;
transform: rotate(20deg);
box-shadow: 46px 0 0 3px #000;
position: absolute;
top: 1px;
right: -120%;
}
div:after {
transform: rotate(-20deg);
left: -120%;
box-shadow: -46px 0 0 3px #000;
}
<div>Text</div>
STOLEN FROM CSS-SHAPES
#flag {
width: 110px;
height: 56px;
padding-top: 15px;
position: relative;
background: red;
color: white;
font-size: 11px;
letter-spacing: 0.2em;
text-align: center;
text-transform: uppercase;
}
#flag:after {
content: "";
position: absolute;
left: 0;
bottom: 0;
width: 0;
height: 0;
border-bottom: 13px solid #eee;
border-left: 55px solid transparent;
border-right: 55px solid transparent;
}
DEMO:
#flag {
width: 110px;
height: 56px;
padding-top: 15px;
position: relative;
background: red;
color: white;
font-size: 11px;
letter-spacing: 0.2em;
text-align: center;
text-transform: uppercase;
}
#flag:after {
content: "";
position: absolute;
left: 0;
bottom: 0;
width: 0;
height: 0;
border-bottom: 13px solid #eee;
border-left: 55px solid transparent;
border-right: 55px solid transparent;
}
<div id="flag"></div>
My Approach
My approach uses skewed elements, and allows you to quickly position them to your needs.
div {
height: 100px;
width: 100px;
position: relative;
border-left: 10px solid tomato;
border-top: 10px solid tomato;
border-right: 10px solid tomato;
text-align: center;
line-height: 100px;
font-size: 30px;
}
div:before {
content: "";
position: absolute;
height: 50%;
width: 50%;
left: -10px; /*width of border*/
bottom: -30px;
z-index: -2;
-webkit-transform: skewY(-20deg);
transform: skewY(-20deg);
border-bottom: 10px solid tomato;
border-left: 10px solid tomato;
}
div:after {
content: "";
position: absolute;
height: 50%;
width: 50%;
right: -10px; /*width of border*/
bottom: -30px;
z-index: -2;
-webkit-transform: skewY(20deg);
transform: skewY(20deg);
border-bottom: 10px solid tomato;
border-right: 10px solid tomato;
}
div:hover, div:hover:before, div:hover:after{
background:lightgray;
}
<div>TEXT</div>
I've had a go at updating your CSS to create the effect you want:
.css-shapes {
height: 250px;
width: 0px;
border-left: 99px solid #f00fff;
border-right: 99px solid #f00fff;
border-bottom: 39px solid transparent;
position: relative
}
.n-shape {
height: 248px;
width: 0px;
border-left: 95px solid #ffffff;
border-right: 95px solid #ffffff;
border-bottom: 39px solid transparent;
position: absolute;
top: -6px;
right: -95px;
}
.top {
position: absolute;
top: 0px;
width: 198px;
height: 2px;
background-color: #f00fff;
left: -99px;
border-bottom: 1px solid #f00fff;
}
<div class="css-shapes">
<div class="n-shape"></div>
<div class="top"></div>
</div>
Fiddle: http://jsfiddle.net/dywhjwna/
Here is what I came up with.
Link Fiddle
It correspond to what you were looking for however I guess there should be a "better way" to it rather than playing with border.
HTML
<div id="text-div">
Text
</div>
<div id="pacman">
<div id="left-triangle"></div>
<div id="right-triangle"></div>
</div>
CSS
#text-div {
width: 118px;
height: 60px;
text-align: center;
border: 1px solid purple;
border-bottom: 0px;
line-height: 60px;
}
#pacman {
width: 0px;
height: 0px;
border-right: 60px solid purple;
border-top: 0px;
border-left: 60px solid purple;
border-bottom: 60px solid transparent;
}
#left-triangle{
position: relative;
left: -59px;
border-right: 58px solid transparent;
border-top: 0px;
border-left: 58px solid white;
border-bottom: 58px solid transparent;
}
#right-triangle{
position: relative;
top: -59px;
left: -57px;
border-right: 58px solid white;
border-top: 0px;
border-left: 58px solid transparent;
border-bottom: 58px solid transparent;
}
A quick workaround is to rotate it:
transform: rotate(90deg);
Fiddle
Another solution would be an SVG path, here's a fiddle!.
A better solution with text easily positioned in the middle, using a rectangle background and a triangle at the bottom.
.css-shapes{
position: relative;
height: 250px;
width: 150px;
background: #FFD05B;
color: #fff;
text-align: center;
line-height:225px;
font-size: 90px;
box-sizing: border-box;
}
.css-shapes:after{
content: '';
position:absolute;
left:0;
bottom: 0;
display: block;
width: 100%;
height:50px;
border-bottom: 25px solid #fff;
border-left: 75px solid transparent;
border-right: 75px solid transparent;
box-sizing: border-box;
}
<div class="css-shapes">1</div>
How can I make css like this as picture below:
Can be achieved using manipulating border radius
CSS
.graph {
height: 100px;
width: 200px;
background: transparent;
border-radius: 0px 0px 0px 370px/225px;
border: solid 5px grey;
border-top:none;
border-right:none;
margin:20px;
}
.graph:before {
height:20px;
width: 10px;
border: 5px solid grey;
border-radius: 30px 30px 0px 0px /75px 75px 0px 0px ;
display: block;
content: "";
border-bottom:none;
position:relative;
top: -9px;
left: -12px;
}
HTML
<div class = "graph"><div>
https://jsfiddle.net/u663m81s/
You could use a pseudo element for this:
div {
height: 300px;
width: 300px;
background: lightgray;
position: relative;
border-bottom: 5px solid black;
border-right: 5px solid black;
}
div:after {
content: "";
position: absolute;
height: 100%;
width: 100%;
border: 3px solid transparent;
border-bottom-color: black;
top: -5px;
left: 50%;
border-radius: 50%;
transform: rotate(45deg);
}
<div></div>
You could then play with the height and width properties of the pseudo element to 'stretch' the line. Please note: this may require small adjustments to the top and left properties for positioning
Change height as per requirement !
You can play with parameters to suit your needs !!
.box{
width:100px; height:80px;
border:solid 3px #000;
border-color:transparent transparent #000 #000;
border-radius: 0px 0px 0px 250px;
}
<div class="box"></div>
An arrow in css, from css-tricks.com/ShapesOfCSS
#curvedarrow {
position: relative;
width: 0;
height: 0;
border-top: 9px solid transparent;
border-right: 9px solid red;
-webkit-transform: rotate(10deg);
-moz-transform: rotate(10deg);
-ms-transform: rotate(10deg);
-o-transform: rotate(10deg);
}
#curvedarrow:after {
content: "";
position: absolute;
border: 0 solid transparent;
border-top: 3px solid red;
border-radius: 20px 0 0 0;
top: -12px;
left: -9px;
width: 12px;
height: 12px;
-webkit-transform: rotate(45deg);
-moz-transform: rotate(45deg);
-ms-transform: rotate(45deg);
-o-transform: rotate(45deg);
}
<div id="curvedarrow"></div>
You can alternatively use SVG: http://codepen.io/gaelb/pen/mJePGM
Does CSS gives any option to show background image at the corner a transparent.
instead of showing white background in (DEMO)
avoid white area
#octagon {
width: 100px;
height: 100px;
background: red;
position: relative;
margin: 50px auto 0;
}
#octagon:before {
content: "";
position: absolute;
top: 0;
left: 0;
border-bottom: 29px solid red;
border-left: 29px solid red;
border-right: 29px solid #eee;
width: 42px;
height: 0;
}
http://jsfiddle.net/L8JUJ/4/
Working Fiddle
Made small changes and adjustments in margins.
CSS:
body{
background: url(http://placehold.it/350x150&text=FooBar1) repeat;
}
#octagon {
width: 100px;
height: 71px;
background: red;
position: relative;
margin: 99px 10px 0px 100px;
}
#octagon:before {
content: "";
position: absolute;
top: -29px;
left: 0;
border-bottom: 29px solid red;
border-left: 29px solid red;
border-right: 29px solid transparent;
width: 42px;
height: 0;
}
#octagon:before {
content: "";
position: absolute;
top: 0;
left: 0;
border-bottom: 29px solid red;
border-left: 29px solid red;
border-right: 29px solid #eee;
width: 42px;
height: 0;
opacity:0.6;
}
For a transparent border you can modify #octagon:before border-right with
border-right: 29px solid rgba(0,0,0,0.5);
That will not give you the effect you want because in the back there is the element that already has a background color, so the only way to do this and work would be to add some js to your code, such as:
http://jquery.malsup.com/corner/