I need to do a triangular onfocus on button, like on this image
I looked at different examples like this, but the focus zone is rectangular.
Is it possible make triangular onfocus?
You could use clip-path to give a triangular shape to the button and apply the same shape to button::before pseudoelement slightly enlarged to mimic an outline, e.g.
Codepen Demo
Note: working only on browser supporting clip-path
Markup
<button><span>button</span></button>
CSS
button {
position: relative;
border: 0;
padding: 0;
cursor: pointer;
-webkit-clip-path: polygon(0 0, 0 100%, 100% 100%, 100% 50% 100% 0);
clip-path: polygon(0 0, 0 100%, 100% 100%, 100% 50% 100% 0);
}
button span {
position: relative;
z-index: 1;
display: block;
background: linear-gradient(#f4f4f4, #d4d4d4);
padding: 10px 20px;
}
button:focus {
outline: none;
-webkit-clip-path: polygon(0 0, 0 100%, 90% 100%, 100% 50%, 90% 0);
clip-path: polygon(0 0, 0 100%, 90% 100%, 100% 50%, 90% 0);
}
button::before,
button span {
-webkit-clip-path: inherit;
clip-path: inherit;
}
button:focus::before {
content: "";
position: absolute;
height: calc(100% + 4px);
width: calc(100% + 4px);
left: -2px;
top: -2px;
background: rgba(81,153,219, .7);
}
Maybe like this?
Adding an element after the button to provide the triangular shape...
Now it is 45° rotation, you could play by skewing to get another angle.
CodePen Sample
button:hover { border-color: blue; }
button:hover:after { border-color: blue;}
button {
font-size: 14px;
background: none;
border: 1px solid red;
border-right: 0;
position: relative;
height: 44px;
z-index: 1;
background-color: #FFF;
}
button::after {
content: "";
display: block;
position: absolute;
width: 30px; height: 30px;
background: #FFF;
right: -15px;
top: 5px;
transform: rotate(-45deg);
z-index:-1;
border-right: 1px solid Red;
border-bottom: 1px solid Red;
}
You could use the map tag : http://www.w3schools.com/tags/tag_map.asp
But in that case your button must be a picture.
little late,
but you can do for almost every browser with transform and a pseudo.
Eventually add background gradient and shadow : http://codepen.io/gc-nomade/pen/yOjOby
* {
box-sizing: border-box;
}
a {
display: inline-block;
padding: 0.5em 1em;
margin: 0 1.5em 0 0;
text-decoration: none;
color: #177EE5;
border: solid 3px;
border-radius: 5px;
border-right: none;
position: relative;
background: linear-gradient(to right, lightgray, white, lightgray);
box-shadow: 0 0 5px black;
}
a:after {
content: '';
position: absolute;
top: 3px;
bottom: 3px;
right: -.8em;
width: 1.75em;
border-radius: inherit;
border-top: solid;
border-right: solid;
border-color: inherit;
transform: rotate(45deg);
background: linear-gradient(45deg, transparent 45%, lightgray 60%);
box-shadow: 0px -5px 5px -5px black, 5px 0px 5px -5px black
}
arrow
longer arrow
#
you can use this site and make triangular, polygon: The Shapes of CSS - CSS-Tricks
https://css-tricks.com/examples/ShapesOfCSS
make a css class. add that class on focus.
http://www.w3schools.com/jquery/html_addclass.asp
Related
I have a div and I am trying to add a transparent border to it with a box-shadow such that the transparent border shows the box-shadow underneath and not the div's background color.
Here is a JSFiddle I created to showcase my problem: https://jsfiddle.net/143k7myj/.
body {
background-color: #f8f8f8;
}
div {
width: 489px;
height: 169px;
background-color: #46aae3;
box-shadow: 0px 4px 15px rgba(0, 0, 0, 0.15);
border-radius: 3px;
border: 10px solid transparent;
/* background-clip: content-box; */
}
div:hover {
border-color: white;
}
<div></div>
As you can see, when I hover over the div, the border shows with it's white color. If I don't hover over it, it show's the 'transparent' border. However, it show's the div's background colour underneath and not the box-shadow of the div that I want to achieve.
One of my attempts was to use background-clip: content-box, however, then the transparent border shows the solid background-colour of the body.
How can I have achieve a transparent border such that the box-shadow of the div is shown underneath the transparent border and not the background color of the div. Thank you.
You can achieve with Pseudo-element :before
body {
background-color: #eee;
}
div {
width: 489px;
height: 169px;
background-color: #46aae3;
box-shadow: 0px 4px 15px rgba(0, 0, 0, 0.10);
border-radius: 3px;
position: relative;
/* background-clip: content-box; */margin-top: 30px;margin-left: 30px;
}
div:before {
content: "";
border: 10px solid #fff;
position: absolute;
left: -10px;
top: -10px;
right: -10px;
bottom: -10px;
opacity: 0;
border-radius: 3px;
}
div:hover:before {
opacity: 1;
}
<div></div>
Edit:
You may achieve it with pseudo element using some workaround:
body {
background-color: #ddd;
margin: 0;
padding: 10px;
}
div {
/* change the border width here */
--border-width: 10px;
width: 489px;
height: 169px;
background-color: #46aae3;
box-shadow: 0px 4px 15px rgba(0, 0, 0, 0.15);
border-radius: 3px;
margin: var(--border-width);
position: relative;
}
div::before {
content: '';
display: block;
width: calc(100% + var(--border-width) * 2);
height: calc(100% + var(--border-width) * 2);
margin: calc(var(--border-width) * -1);
position: absolute;
border-radius: inherit;
}
div:hover {
box-shadow: 0px 4px 15px transparent;
}
div:hover::before {
background-color: white;
z-index: -1;
}
<div></div>
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 have a span which contains ellipses and i want to show the content through tooltip, but the position of the tooltip isn't seem to adjust as i can't apply position relative to the parent (due to ellipses). Here's the code i've tried
.data-tooltip:hover:before{
content: "";
width: 0;
height: 0;
border-top: 5px solid transparent;
border-bottom: 5px solid transparent;
border-bottom: 5px solid rgba(0, 0, 0, 0.6);
position: absolute;
bottom: 82%;
left: 25%;
-webkit-transform: translate(-58%, 41.5%);
transform: translate(-58%, 51.5%);
}
.data-tooltip:hover:after{
content: attr(data-title);
padding: 6px 8px;
color: #fff;
text-align: left;
text-decoration: none;
background-color: rgba(0, 0, 0, 0.6);
border-radius: 4px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
min-height: 32px;
word-wrap: break-word;
position: absolute;
top: unset;
bottom: 75%;
-webkit-transform: translate(-50%, 50%);
transform: translate(-50%, 50%);
}
<span class="data-tooltip" data-tooltip="my tooltip">
ellipsed content
</span>
Here i am using 'before' for tooltip arrow and 'after' for tooltip content, but their positions doesn't seem to adjust either.
i have tried positioning my data-tooltip content relative, but due to overflow:hidden, the tooltip cuts outside the box.
An example below...
This code quoted from Chris Bracco. Please look at this article for detail.
/* Add this attribute to the element that needs a tooltip */
[data-tooltip] {
position: relative;
z-index: 2;
cursor: pointer;
}
/* Hide the tooltip content by default */
[data-tooltip]:before,
[data-tooltip]:after {
visibility: hidden;
-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";
filter: progid: DXImageTransform.Microsoft.Alpha(Opacity=0);
opacity: 0;
pointer-events: none;
}
/* Position tooltip above the element */
[data-tooltip]:before {
position: absolute;
bottom: 150%;
left: 50%;
margin-bottom: 5px;
margin-left: -80px;
padding: 7px;
width: 160px;
-webkit-border-radius: 3px;
-moz-border-radius: 3px;
border-radius: 3px;
background-color: #000;
background-color: hsla(0, 0%, 20%, 0.9);
color: #fff;
content: attr(data-tooltip);
text-align: center;
font-size: 14px;
line-height: 1.2;
}
/* Triangle hack to make tooltip look like a speech bubble */
[data-tooltip]:after {
position: absolute;
bottom: 150%;
left: 50%;
margin-left: -5px;
width: 0;
border-top: 5px solid #000;
border-top: 5px solid hsla(0, 0%, 20%, 0.9);
border-right: 5px solid transparent;
border-left: 5px solid transparent;
content: " ";
font-size: 0;
line-height: 0;
}
/* Show tooltip content on hover */
[data-tooltip]:hover:before,
[data-tooltip]:hover:after {
visibility: visible;
-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=100)";
filter: progid: DXImageTransform.Microsoft.Alpha(Opacity=100);
opacity: 1;
}
<p style="margin-top:50px">
<span data-tooltip="I’m the tooltip text.">I’m a span with a tooltip.</span>
</p>
Instead of
data-tooltip="my tooltip"
Your data-tooltip attribute should be data-title
That should work now.
Is it possible to style(skew) triangle like on the picture on the right side?
http://s15.postimg.org/h2vruavmz/triangle.jpg
I want to skew it, make background transparency 0.5 and hide bottom border of the triangle.
body {
background-color: #ccc;
}
.arrow_box {
position: absolute;
top: 40px;
left: 40px;
background: #fff;
/*border: 1px solid #ffffff;*/
}
.arrow_box:after, .arrow_box:before {
bottom: 100%;
left: 50%;
border: solid transparent;
content: " ";
height: 0;
width: 0;
position: absolute;
pointer-events: none;
}
.arrow_box:after {
border-color: rgba(0, 0, 0, 0);
border-bottom-color: #fff;
border-width: 20px;
margin-left: -20px;
}
.arrow_box:before {
border-color: rgba(255, 255, 255, 0);
border-bottom-color: #000;
border-width: 21px;
margin-left: -21px;
}
<div class="arrow_box"></div>
The method you are currently using means that you will not be able to set a semi transparent "background" on the triangle. This is because the black borders of the triangle are actually a slightly larger separate triangle, it just happens that the smaller white triangle is overlaying its center. If you modify the white triangle's opacity then you will just peek through to the black triangle.
This can be avoided by using another method to create the triangle. The general principle is to create a box then turn it on its side using transform: rotate(45deg);. Using overflow: hidden; on the container you can cut off half of the box to leave you with a triangle without a bottom border.
You can then skew the container using transform: skewX(55deg); to push the triangle to one side.
body {
background-color: #ccc;
}
.arrow_box {
height: 17px;
left: 40px;
overflow: hidden;
position: absolute;
top: 40px;
transform: skewX(55deg);
width: 34px;
}
.arrow_box:after {
background-color: rgba(255, 255, 255, 0.5);
border: 2px solid rgba(0, 0, 0, 1);
content: " ";
height: 20px;
left: 5px;
position: absolute;
top: 5px;
transform: rotate(45deg);
width: 20px;
}
<div class="arrow_box"></div>
you can use transform: skew(60deg,0deg); on the :before and :after
body {
background-color: #ccc;
}
.arrow_box {
position: absolute;
top: 40px;
left: 40px;
background: #fff;
/*border: 1px solid #ffffff;*/
}
.arrow_box:after, .arrow_box:before {
bottom: 100%;
left: 50%;
border: solid transparent;
content: " ";
height: 0;
width: 0;
position: absolute;
pointer-events: none;
transform: skew(60deg,0deg);
}
.arrow_box:after {
border-color: rgba(0, 0, 0, 0);
border-bottom-color: #fff;
border-width: 20px;
margin-left: -12px;
}
.arrow_box:before {
border-color: rgba(255, 255, 255, 0);
border-bottom-color: #000;
border-width: 24px;
margin-left: -21px;
}
<div class="arrow_box"></div>
Fiddle
I don't think you'd be able to make that background transparent easily with the technique you have used to draw triangles. You should use png image if you can.
Is it possible to create two arrows like the photo below with css or I have to use a png or svg?
So far
HTML
a {
position: relative;
display: block;
padding-left: 30px;
line-height: 45px;
height: 45px;
}
a:after,
a:before {
right: 100%;
top: 26px;
border-left: 1px solid black;
content: " ";
height: 30px;
width: 25px;
position: absolute;
pointer-events: none;
left: 7px;
}
a:after {
-webkit-transform: rotate(135deg);
left: -11px;
}
a:before {
-webkit-transform: rotate(45deg);
top: 5px;
}
Next
jsfiddle
I can't figure how to put another pair of borders.
Thanks in advance
With a bit of tinkering of your example, it's possible, but you'd probably be better off using another method to draw it or using an icon or icon font.
Here's the fiddle
Achieved with
transform: skew();
rather than rotate.
It's possible, but I would just use a SVG in this case:
http://jsfiddle.net/6v7Np/
HTML
<div class="arrow_box"></div>
<div class="arrow_box alt"></div>
CSS
.arrow_box {
position: relative;
background: #fff;
top:50px;
left:60px;
}
.arrow_box.alt {
left:80px;
}
.arrow_box:after, .arrow_box:before {
right: 100%;
top: 50%;
border: solid transparent;
content:" ";
height: 0;
width: 0;
position: absolute;
pointer-events: none;
}
.arrow_box:after {
border-color: rgba(255, 255, 255, 0);
border-right-color: #fff;
border-width: 30px;
margin-top: -30px;
}
.arrow_box:before {
border-color: rgba(0, 0, 0, 0);
border-right-color: #000;
border-width: 31px;
margin-top: -31px;
}
With gradients:
a{
position: relative;
padding-left: 40px;
}
a::before{
content: '';
position: absolute;
width: 40px;
height: 40px;
left: 0;
top: 0;
background-image:
linear-gradient(135deg, transparent 0px, transparent 19px, black 20px, transparent 21px),
linear-gradient(45deg, transparent 0px, transparent 19px, black 20px, transparent 21px),
linear-gradient(135deg, transparent 0px, transparent 19px, black 20px, transparent 21px),
linear-gradient(45deg, transparent 0px, transparent 19px, black 20px, transparent 21px);
background-repeat: no-repeat;
background-size: 50% 50%;
background-position: 0% top, 0% bottom, 50% top, 50% bottom;
/* distance ^ ^ */
}
http://jsfiddle.net/E8sRw/