How do I make an arrow with curved edges - css

I used border-radius but it doesn't make all the edges round. I want to make a down angle arrow.
.drop-arrow {
border: solid #FFDD00;
border-width: 0px 20px 20px 0;
display: inline-block;
padding: 40px;
transform: rotate(45deg);
}
<span class='drop-arrow'></span>

You can rely on pseudo element to curve all the edges:
.drop-arrow {
--b:20px; /* border-width */
border: solid #FFDD00;
border-width: 0px var(--b) var(--b) 0;
border-bottom-right-radius:var(--b);
display: inline-block;
padding: 40px;
transform: rotate(45deg);
margin:30px;
position:relative;
}
.drop-arrow::before,
.drop-arrow::after {
content:"";
position:absolute;
width:var(--b);
height:var(--b);
background:#FFDD00;
border-radius:50%;
}
.drop-arrow::before {
top:calc(-1*var(--b)/2);
right:0;
transform:translateX(100%);
}
.drop-arrow::after {
left:calc(-1*var(--b)/2);
bottom:0;
transform:translateY(100%);
}
<span class='drop-arrow'></span>
<span class='drop-arrow' style="--b:30px;"></span>
<span class='drop-arrow' style="--b:15px;"></span>
To add a rounded edge to the inside part, you can add a gradient coloration like below:
.drop-arrow {
--b:20px; /* border-width */
border: solid #FFDD00;
border-width: 0px var(--b) var(--b) 0;
border-bottom-right-radius:var(--b);
background:
radial-gradient(farthest-side at top left,transparent 98%,#FFDD00 100%)
bottom -0.5px right -0.5px/var(--b) var(--b) no-repeat;
display: inline-block;
padding: 40px;
transform: rotate(45deg);
margin:30px;
position:relative;
}
.drop-arrow::before,
.drop-arrow::after {
content:"";
position:absolute;
width:var(--b);
height:var(--b);
background:#FFDD00;
border-radius:50%;
}
.drop-arrow::before {
top:calc(-1*var(--b)/2);
right:0;
transform:translateX(100%);
}
.drop-arrow::after {
left:calc(-1*var(--b)/2);
bottom:0;
transform:translateY(100%);
}
<span class='drop-arrow'></span>
<span class='drop-arrow' style="--b:30px;"></span>
<span class='drop-arrow' style="--b:15px;"></span>

Your code looks like you are using a font-framework with the arrow integretated - maybe something like https://fontawesome.com/.
There is no arrow in your css described. Have a look at the font you are using to find the symbol.
To get another arrow, either the font needs to support another arrow or you'll have to use another font/build your own font.

Related

How to create Button with cut edges? [duplicate]

I'm looking for an easy way with a single tag (just <a>)to create a skew effect on the borders, but keep the text the way it is.
I would know how do with a span in- or outside, but I don't want to have additional, pretty much zero meaning HTML on the page.
Example below.
You can unskew the child element i.e. provide the opposite skew co-ordinates as you specified for the parent.
Here is a working example
Suppose you have below as you html,
<div class="btn">
<button><div class="btn-text">Click</div></button>
</div>
If we skew the parent element by 20deg then we should skew the child element by -20deg as,
.btn {
-ms-transform: skewX(20deg); /* IE 9 */
-webkit-transform: skewX(20deg); /* Safari */
transform: skewX(20deg);
}
.btn-text {
-ms-transform: skewX(-20deg); /* IE 9 */
-webkit-transform: skewX(-20deg); /* Safari */
transform: skewX(-20deg);
padding: 20px;
}
You can simply accompish desired effect using CSS triangle tricks.
Just add some styles for the ::before and :: after pseudo-classes.
.skewed_button {
background: #32CD32;
color: #000;
text-decoration: none;
font-size: 20px;
display: inline-block;
height: 30px;
margin-left: 15px;
padding: 6px 10px 0;
}
.skewed_button::before {
content: "";
float: left;
margin: -6px 0 0 -25px;
border-left: 15px solid transparent;
border-bottom: 36px solid #32CD32;
height: 0px;
}
.skewed_button::after {
content: "";
float: right;
margin: -6px -25px 0 0 ;
border-left: 15px solid #32CD32;
border-bottom: 36px solid transparent;
height: 0px;
}
Some Text
You can also use clip-path for this, eg:
clip-path: polygon(14px 0%, 100% 0%, calc(100% - 14px) 100%, 0% 100%);
.skewed_button {
background: yellow;
text-decoration: none;
display: inline-block;
padding: 10px 20px;
clip-path: polygon(14px 0%, 100% 0%, calc(100% - 14px) 100%, 0% 100%);
}
Some Text
One solution is to use css triangles on :before and :after. This solution leaves the cleanest HTML.
This jsfiddle demonstrates
.is-skewed {
width: 80px;
height: 40px;
background-color: #f07;
display: block;
color: #fff;
margin-left: 40px;
}
.is-skewed:before,
.is-skewed:after {
content: '';
width: 0;
height: 0;
}
.is-skewed:before {
border-bottom: 40px solid #f07;
border-left: 20px solid transparent;
float:left;
margin-left: -20px;
}
.is-skewed:after {
border-top: 40px solid #f07;
border-right: 20px solid transparent;
float:right;
margin-right: -20px;
}
CSS triangles use thick borders on elements with 0 dimensions with the points at which the borders meet providing the diagonal line required for a triangle (a good visualisation is to look at the corner of a picture frame, where the two borders meet and create triangles). It's important that one border is transparent and one coloured and that they are adjacent (i.e. left and top, not left and right). You can adjust the size, orientation and the lengths of the sides by playing with the border sizes.
For your button, we also use floats and negative margins to pull them outside of the element and line them up right. Position absolute and negative left and right values would also be a good solution to positioning
You can also do :hover states
.is-skewed:hover {
background-color: #40f;
}
.is-skewed:hover:after {
border-top-color: #40f;
}
.is-skewed:hover:before {
border-bottom-color: #40f;
}
It's important to note the use of background-color and border-color and also that the :hover comes first in all the relevant selectors. If the hover came second this would happen

Put a border on an image with css and inset it [duplicate]

I need to create a solid color inset border. This is the bit of CSS I'm using:
border: 10px inset rgba(51,153,0,0.65);
Unfortunately that creates a 3D ridged border (ignore the squares and dark description box)
You could use box-shadow, possibly:
#something {
background: transparent url(https://i.stack.imgur.com/RL5UH.png) 50% 50% no-repeat;
min-width: 300px;
min-height: 300px;
box-shadow: inset 0 0 10px #0f0;
}
#something {
background: transparent url(https://i.stack.imgur.com/RL5UH.png) 50% 50% no-repeat;
min-width: 300px;
min-height: 300px;
box-shadow: inset 0 0 10px #0f0;
}
<div id="something"></div>
This has the advantage that it will overlay the background-image of the div, but it is, of course, blurred (as you'd expect from the box-shadow property). To build up the density of the shadow you can add additional shadows of course:
#something {
background: transparent url(https://i.stack.imgur.com/RL5UH.png) 50% 50% no-repeat;
min-width: 300px;
min-height: 300px;
box-shadow: inset 0 0 20px #0f0, inset 0 0 20px #0f0, inset 0 0 20px #0f0;
}
#something {
background: transparent url(https://i.stack.imgur.com/RL5UH.png) 50% 50% no-repeat;
min-width: 300px;
min-height: 300px;
box-shadow: inset 0 0 20px #0f0, inset 0 0 20px #0f0, inset 0 0 20px #0f0;
}
<div id="something"></div>
Edited because I realised that I'm an idiot, and forgot to offer the simplest solution first, which is using an otherwise-empty child element to apply the borders over the background:
#something {
background: transparent url(https://i.stack.imgur.com/RL5UH.png) 50% 50% no-repeat;
min-width: 300px;
min-height: 300px;
padding: 0;
position: relative;
}
#something div {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
border: 10px solid rgba(0, 255, 0, 0.6);
}
<div id="something">
<div></div>
</div>
Edited after #CoryDanielson's comment, below:
jsfiddle.net/dPcDu/2 you can add a 4th px parameter for the box-shadow that does the spread and will more easily reflect his images.
#something {
background: transparent url(https://i.stack.imgur.com/RL5UH.png) 50% 50% no-repeat;
min-width: 300px;
min-height: 300px;
box-shadow: inset 0 0 0 10px rgba(0, 255, 0, 0.5);
}
<div id="something"></div>
I would recomnend using box-sizing.
*{
-webkit-box-sizing:border-box;
-moz-box-sizing:border-box;
-ms-box-sizing:border-box;
box-sizing:border-box;
}
#bar{
border: 10px solid green;
}
To produce a border inset within an element the only solution I've found (and I've tried all the suggestions in this thread to no avail) is to use a pseudo-element such as :before
E.g.
.has-inset-border:before {
content: " "; /* to ensure it displays */
position: absolute;
left: 10px;
right: 10px;
top: 10px;
bottom: 10px;
border: 4px dashed red;
pointer-events: none; /* user can't click on it */
}
The box-sizing property won't work, as the border always ends up outside everything.
The box-shadow options has the dual disadvantages of not really working and not being supported as widely (and costing more CPU cycles to render, if you care).
It's an old trick, but I still find the easiest way to do this is to use outline-offset with a negative value (example below uses -6px). Here's a fiddle of it—I've made the outer border red and the outline white to differentiate the two:
.outline-offset {
width:300px;
height:200px;
background:#333c4b;
border:2px solid red;
outline:2px #fff solid;
outline-offset:-6px;
}
<div class="outline-offset"></div>
If you want to make sure the border is on the inside of your element, you can use
box-sizing:border-box;
this will place the following border on the inside of the element:
border: 10px solid black;
(similar result you'd get using the additonal parameter inset on box-shadow, but instead this one is for the real border and you can still use your shadow for something else.)
Note to another answer above: as soon as you use any inset on box-shadow of a certain element, you are limited to a maximum of 2 box-shadows on that element and would require a wrapper div for further shadowing.
Both solutions should as well get you rid of the undesired 3D effects.
Also note both solutions are stackable (see the example I've added in 2018)
.example-border {
width:100px;
height:100px;
border:40px solid blue;
box-sizing:border-box;
float:left;
}
.example-shadow {
width:100px;
height:100px;
float:left;
margin-left:20px;
box-shadow:0 0 0 40px green inset;
}
.example-combined {
width:100px;
height:100px;
float:left;
margin-left:20px;
border:20px solid orange;
box-sizing:border-box;
box-shadow:0 0 0 20px red inset;
}
<div class="example-border"></div>
<div class="example-shadow"></div>
<div class="example-combined"></div>
I don't know what you are comparing to.
But a super simple way to have a border look inset when compared to other non-bordered items is to add a border: ?px solid transparent; to whatever items do not have a border.
It will make the bordered item look inset.
http://jsfiddle.net/cmunns/cgrtd/
Simple SCSS solution with pseudo-elements
Live demo: https://codepen.io/vlasterx/pen/xaMgag
// Change border size here
$border-width: 5px;
.element-with-border {
display: flex;
height: 100px;
width: 100%;
position: relative;
background-color: #f2f2f2;
box-sizing: border-box;
// Use pseudo-element to create inset border
&:before {
position: absolute;
content: ' ';
display: flex;
border: $border-width solid black;
left: 0;
right: 0;
top: 0;
bottom: 0;
border: $border-width solid black;
// Important: We must deduct border size from width and height
width: calc(100% - $border-width);
height: calc(100% - $border-width);
}
}
<div class="element-with-border">
Lorem ipsum dolor sit amet
</div>
You can do this:
.thing {
border: 2px solid transparent;
}
.thing:hover {
border: 2px solid green;
}
If box-sizing is not an option, another way to do this is just to make it a child of the sized element.
Demo
CSS
.box {
width: 100px;
height: 100px;
display: inline-block;
margin-right: 5px;
}
.border {
border: 1px solid;
display: block;
}
.medium { border-width: 10px; }
.large { border-width: 25px; }
HTML
<div class="box">
<div class="border small">A</div>
</div>
<div class="box">
<div class="border medium">B</div>
</div>
<div class="box">
<div class="border large">C</div>
</div>
I know this is three years old, but thought it might be helpful to someone.
The concept is to use the :after (or :before) selector to position a border within the parent element.
.container{
position:relative; /*Position must be set to something*/
}
.container:after{
position:relative;
top: 0;
content:"";
left:0;
height: 100%; /*Set pixel height and width if not defined in parent element*/
width: 100%;
-webkit-box-sizing:border-box;
-moz-box-sizing:border-box;
-ms-box-sizing:border-box;
box-sizing:border-box;
border:1px solid #000; /*set your border style*/
}
You may use background-clip: border-box;
Example:
.example {
padding: 2em;
border: 10px solid rgba(51,153,0,0.65);
background-clip: border-box;
background-color: yellow;
}
<div class="example">Example with background-clip: border-box;</div>
So I was trying to have a border appear on hover but it moved the entire bottom bar of the main menu which didn't look all that good I fixed it with the following:
#top-menu .menu-item a:hover {
border-bottom:4px solid #ec1c24;
padding-bottom:14px !important;
}
#top-menu .menu-item a {
padding-bottom:18px !important;
}
I hope this will help someone out there.
Simpler + better | img tag | z-index | link image | "alt" attribute
I figured out a method where you do not need to use the image as a background image but use the img HTML tag inside the div, and using z-index of the div as a negative value.
Advantages:
The image can now become a link to a lightbox or to another page
The img:hover style can now change image itself, for example:
black/white to color, low to high opacity, and much more.
Animations of image are possible The image is more accessible because
of the alt tag you can use.
For SEO the alt tag is important for keywords
#borders {
margin: 10px auto;
width: 300px;
height: 300px;
position:relative;
box-shadow: inset 0 0 0 10px rgba(0, 255, 0, 0.5);
}
img {
position:absolute;
top:0;
bottom:0;
left:0;
right: 0;
z-index: -1;
}
<div id="borders">
<img src="https://i.stack.imgur.com/RL5UH.png">
</div>

CSS: Skew a buttons border, not the text

I'm looking for an easy way with a single tag (just <a>)to create a skew effect on the borders, but keep the text the way it is.
I would know how do with a span in- or outside, but I don't want to have additional, pretty much zero meaning HTML on the page.
Example below.
You can unskew the child element i.e. provide the opposite skew co-ordinates as you specified for the parent.
Here is a working example
Suppose you have below as you html,
<div class="btn">
<button><div class="btn-text">Click</div></button>
</div>
If we skew the parent element by 20deg then we should skew the child element by -20deg as,
.btn {
-ms-transform: skewX(20deg); /* IE 9 */
-webkit-transform: skewX(20deg); /* Safari */
transform: skewX(20deg);
}
.btn-text {
-ms-transform: skewX(-20deg); /* IE 9 */
-webkit-transform: skewX(-20deg); /* Safari */
transform: skewX(-20deg);
padding: 20px;
}
You can simply accompish desired effect using CSS triangle tricks.
Just add some styles for the ::before and :: after pseudo-classes.
.skewed_button {
background: #32CD32;
color: #000;
text-decoration: none;
font-size: 20px;
display: inline-block;
height: 30px;
margin-left: 15px;
padding: 6px 10px 0;
}
.skewed_button::before {
content: "";
float: left;
margin: -6px 0 0 -25px;
border-left: 15px solid transparent;
border-bottom: 36px solid #32CD32;
height: 0px;
}
.skewed_button::after {
content: "";
float: right;
margin: -6px -25px 0 0 ;
border-left: 15px solid #32CD32;
border-bottom: 36px solid transparent;
height: 0px;
}
Some Text
You can also use clip-path for this, eg:
clip-path: polygon(14px 0%, 100% 0%, calc(100% - 14px) 100%, 0% 100%);
.skewed_button {
background: yellow;
text-decoration: none;
display: inline-block;
padding: 10px 20px;
clip-path: polygon(14px 0%, 100% 0%, calc(100% - 14px) 100%, 0% 100%);
}
Some Text
One solution is to use css triangles on :before and :after. This solution leaves the cleanest HTML.
This jsfiddle demonstrates
.is-skewed {
width: 80px;
height: 40px;
background-color: #f07;
display: block;
color: #fff;
margin-left: 40px;
}
.is-skewed:before,
.is-skewed:after {
content: '';
width: 0;
height: 0;
}
.is-skewed:before {
border-bottom: 40px solid #f07;
border-left: 20px solid transparent;
float:left;
margin-left: -20px;
}
.is-skewed:after {
border-top: 40px solid #f07;
border-right: 20px solid transparent;
float:right;
margin-right: -20px;
}
CSS triangles use thick borders on elements with 0 dimensions with the points at which the borders meet providing the diagonal line required for a triangle (a good visualisation is to look at the corner of a picture frame, where the two borders meet and create triangles). It's important that one border is transparent and one coloured and that they are adjacent (i.e. left and top, not left and right). You can adjust the size, orientation and the lengths of the sides by playing with the border sizes.
For your button, we also use floats and negative margins to pull them outside of the element and line them up right. Position absolute and negative left and right values would also be a good solution to positioning
You can also do :hover states
.is-skewed:hover {
background-color: #40f;
}
.is-skewed:hover:after {
border-top-color: #40f;
}
.is-skewed:hover:before {
border-bottom-color: #40f;
}
It's important to note the use of background-color and border-color and also that the :hover comes first in all the relevant selectors. If the hover came second this would happen

relative css only speech bubble

I am using this code to generate a css only speech bubble :-
li.selected{
background-color: blue;
a{
color: white;
}
}
li.selected:after{
content: "";
position: absolute;
top: 33%;
left: 390px;
border-top: 10px solid transparent;
// border-top-color: inherit;
border-left: 10px solid blue;
border-right: 10px solid transparent;
border-bottom: 10px solid transparent;
}
While this works fine, the triangle gets left when I move to the next li item as it has got a fixed position, how do I move the triangle as well?
here is my html code :-
<ul>
<li class='selected'>
Credits
</li>
<div class='line-separator'></div>
<li>
Change Password
</li>
<div class='line-separator'></div>
<li>
Investor Status
</li>
</ul>
Instead of using position:absolute to the arrow, you need to change it to relative position so that the arrow would position itself relatively to the .selected menu item.
See the demo here.
Note: Replace the :hover selector with the .selected class.
you have useful this css
/* Bubble with an isoceles triangle
------------------------------------------ */
.triangle-isosceles {
position:relative;
padding:15px;
margin:1em 0 3em;
color:#000;
background:#f3961c;
/* css3 */
-moz-border-radius:10px;
-webkit-border-radius:10px;
border-radius:10px;
background:-moz-linear-gradient(top, #f9d835, #f3961c);
background:linear-gradient(top, #f9d835, #f3961c);
}
/* creates triangle */
.triangle-isosceles:after {
content:"";
display:block; /* reduce the damage in FF3.0 */
position:absolute;
bottom:-15px;
left:50px;
width:0;
border-width:15px 15px 0;
border-style:solid;
border-color:#f3961c transparent;
}

Use box-sizing: "border-box" and keep image dimensions

If I use box-sizing: "border-box" for images the images will get smaller, like on hover: Example JsFiddle
Is it possible to do the same effect without the image getting cropped?
Solution #1 Outline property. Try to use outline instead of border with negative outline-offset value equal to outline width:
img:hover {
box-sizing:border-box;
outline: solid 10px #f80;
outline-offset: -10px;
}
http://jsfiddle.net/dfsq/BPRyZ/2/
Also since IE does not understand this property you can leave box-sizing to be used by IE8+.
Solution #2 Using div as wrapper + :after:
<div class="img-wrap">
<img src="http://upload.wikimedia.org/wikipedia/commons/a/af/Bonsai_IMG_6426.jpg" class="img1" />
</div>
CSS:
.img-wrap:after {
border: 0;
}
.img-wrap:hover:after {
content: '';
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
border: solid 10px #f80;
}
http://jsfiddle.net/dfsq/BPRyZ/7/
The question you need to answer is, do you want the image itself to be 200px, or the entire box to be 200px. There are 4 different ways to code this depending on your answer to the previous question...
If you want the entire box to be 200px wide, then you can use border-box with the following code...
http://jsfiddle.net/BPRyZ/8/
img {
width:200px;
border: transparent 10px solid;
box-sizing:border-box;
}
img:hover{
box-sizing:border-box;
border:solid 10px #f80;
}
If you want the entire box to be 200px wide, then you could also use this code...
img {
width:180px;
border: transparent 10px solid;
}
img:hover{
border:solid 10px #f80;
}
If you want the image itself to be 200px, then you need this code... (this means your total box width is actually 220px)
img {
width:220px;
border: transparent 10px solid;
box-sizing:border-box;
}
img:hover{
box-sizing:border-box;
border:solid 10px #f80;
}
For the above you could also use...
img {
width:200px;
border: transparent 10px solid;
}
img:hover{
border:solid 10px #f80;
}
I updated your jsfiddle
CSS:
img {
width:200px;
border: transparent 10px solid;
}
img:hover{
box-sizing:border-box;
border:solid 10px #f80;
width:220px;
}

Resources