CSS filter making element dissapear - html

I haven't found any good answers for this so I'm asking here; I have buttons on my website that i'm trying to mimic an OS X Lion style with, and I'm using keyframes to make an active button have a sort-of glow effect. However, using filter: brightness(x) for some reason is making my element disappear. Could it be because I'm using pseudo elements for the border? Or something else.
I tried using CSS filters to brighten a background gradient (I tried an image as well with the same results) and it ended up making the element disappear and show me my pseudo element (also I can't find the code snippet button anymore, is it gone?)
button {
padding: 5px 16px;
border-radius: 4px;
outline: none;
background: linear-gradient(to bottom, #fff 0 30%, #e2e2e2 70% 100%);
color: black;
border: none;
position: relative;
transform-style: preserve-3d;
letter-spacing: -0.3px;
text-shadow: -0.5px -0.5px 1px rgba(0, 0, 0, 0.1);
transition: 0s;
font-family: "Lucida Grande", sans-serif;
transform: scale(4);
margin: 200px;
}
button::after {
content: '';
position: absolute;
background: rgb(120, 120, 120);
width: calc(100% + 2px);
height: calc(100% + 2px);
left: -1px;
top: -1px;
transform: translateZ(-1px);
border-radius: 5px;
opacity: 1;
z-index: -1;
}
button:active {
background: linear-gradient(to bottom, rgb(188, 206, 233) 0, rgb(115, 158, 227) 50%, rgb(92, 145, 226) 51%, rgb(174, 215, 231) 100%);
animation: glow 1s infinite;
}
button:active::after {
content: '';
position: absolute;
background: linear-gradient(to bottom, rgb(89, 92, 169) 0 40%, rgb(80, 89, 142) 60% 100%);
width: calc(100% + 2px);
height: calc(100% + 2px);
left: -1px;
top: -1px;
transform: translateZ(-1px);
border-radius: 5px;
opacity: 1;
}
#keyframes glow {
0% {
filter: brightness(1.1);
}
50% {
filter: brightness(1.2);
}
100% {
filter: brightness(1.1);
}
}
<button>Button</button>
JSFiddle if there isn't a run snippet button

According to this answer, it seems that this is because filter overrides transform-style: preserve-3d, which then causes translateZ(-1px) to have unexpected result in this use case.
This could be avoided by refactor the styles without 3D transforms such as translateZ(-1px). While it might not be perfect, here is a possible example with the workaround.
This example moved styles on the original ::after to a ::before, and moved the button background style to a new ::after, as an alternative approach to the use of translateZ(-1px) to display the button background.
Hope this will help.
Example:
button {
padding: 5px 16px;
border-radius: 4px;
outline: none;
color: black;
border: none;
position: relative;
letter-spacing: -0.3px;
text-shadow: -0.5px -0.5px 1px rgba(0, 0, 0, 0.1);
transition: 0s;
font-family: "Lucida Grande", sans-serif;
transform: scale(2);
margin: 50px 100px;
}
button:active {
animation: glow 1s infinite;
}
button::before {
content: '';
position: absolute;
background: rgb(120, 120, 120);
width: calc(100% + 2px);
height: calc(100% + 2px);
left: -0.625px;
top: -0.625px;
border-radius: 5px;
opacity: 1;
z-index: -1;
}
button:active::before {
content: '';
position: absolute;
background: linear-gradient(to bottom, rgb(89, 92, 169) 0 40%, rgb(80, 89, 142) 60% 100%);
width: calc(100% + 2px);
height: calc(100% + 2px);
left: -0.625px;
top: -0.625px;
border-radius: 5px;
opacity: 1;
}
button::after {
content: '';
position: absolute;
inset: 0;
border-radius: 4px;
outline: none;
background: linear-gradient(to bottom, #fff 0 30%, #e2e2e2 70% 100%);
border: none;
transition: 0s;
z-index: -1;
}
button:active::after {
background: linear-gradient(to bottom, rgb(188, 206, 233) 0, rgb(115, 158, 227) 50%, rgb(92, 145, 226) 51%, rgb(174, 215, 231) 100%);
}
#keyframes glow {
0% {
filter: brightness(1.1);
}
50% {
filter: brightness(1.2);
}
100% {
filter: brightness(1.1);
}
}
<button>Button</button>

Related

Data-text attribute on an h1 element doesn't show up when adding an animation to the element

I have an h1 element that I want to be invisible and then appear after a few seconds. The element has an ::after pseudo-element that displays a data-text attribute that shadows the h1 element. When I add the animation, I only see the h1 and not the pseudo-element as well. Here is my code
EDIT
adding the animation to the pseudo-element makes it appear, but now the data-text appears over the h1 element when originally it is supposed to go behind it. Here are some pic of what is happening. The first is what it is doing and the second is what I want.
EDIT 2
The problem can be recreated by removing the z-index on the pseudo-element.
<section class="wrapper">
<div class="content-wrapper">
<img class="flipInY" src="./img/neon-blue - flip.png" alt="logo-triangle">
<h1 class="name-ani" data-text="My Name">My Name</h1>
<h2 data-text="web-dev">Web Developer</h2>
</div>
</section>
.wrapper {
.content-wrapper {
z-index: 0;
position: relative;
display: grid;
justify-items: center;
margin-top: 20vh;
img {
width: 350px;
max-width: 100%;
padding: 0 32px;
// transform: rotate(180deg);
filter: brightness(85%);
position: relative;
}
h1 {
background: linear-gradient(
to bottom,
#ebf1f6 0%,
#abd3ee 50%,
#859ee2 51%,
#d5ebfb 100%
);
-webkit-background-clip: text;
background-clip: text;
-webkit-text-fill-color: transparent;
font-family: kimberly;
text-transform: uppercase;
font-size: 2.25rem;
transition: font-size 1s;
position: absolute;
top: 10%;
opacity: 0;
&::after {
background: none;
content: attr(data-text);
left: 0;
position: absolute;
text-shadow: 1px -1px 0 rgba(255, 255, 255, 0.5),
3px 1px 3px rgba(255, 0, 255, 0.85),
-3px -2px 3px rgba(0, 0, 255, 0.85),
1px -2px 0 rgba(255, 255, 255, 0.8);
z-index: -10;
opacity: 0;
}
}
.name-ani {
animation-name: name-ani;
animation-duration: 250ms;
animation-delay: 4.5s;
animation-fill-mode: forwards;
}
#keyframes name-ani {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
You need to apply the animation to the pseudo-element as well.
.name-ani,
.name-ani::after {
animation-name: name-ani;
animation-duration: 250ms;
animation-delay: 4.5s;
animation-fill-mode: forwards;
}
Edit: Getting rid of the position: absolute on the h1 by wrapping it and giving it an display: inline solved the stacking order for me as well.
<section class="wrapper">
<div class="content-wrapper">
<img class="flipInY" src="./img/neon-blue - flip.png" alt="logo-triangle">
<div class="h1-wrapper">
<h1 class="name-ani" data-text="My Name">My Name</h1>
</div>
<h2 data-text="web-dev">Web Developer</h2>
</div>
</section>
.wrapper {
.content-wrapper {
z-index: 0;
position: relative;
display: grid;
justify-items: center;
margin-top: 20vh;
img {
width: 350px;
max-width: 100%;
padding: 0 32px;
filter: brightness(85%);
position: relative;
}
.h1-wrapper {
position: absolute;
top: 10%;
}
h1 {
background: linear-gradient(to bottom,
#ebf1f6 0%,
#abd3ee 50%,
#859ee2 51%,
#d5ebfb 100%);
-webkit-background-clip: text;
background-clip: text;
-webkit-text-fill-color: transparent;
font-family: kimberly;
text-transform: uppercase;
font-size: 2.25rem;
transition: font-size 1s;
display: inline;
opacity: 0;
&::after {
background: none;
content: attr(data-text);
left: 0;
position: absolute;
text-shadow: 1px -1px 0 rgba(255, 255, 255, 0.5),
3px 1px 3px rgba(255, 0, 255, 0.85),
-3px -2px 3px rgba(0, 0, 255, 0.85),
1px -2px 0 rgba(255, 255, 255, 0.8);
z-index: -10;
opacity: 0;
}
}
.name-ani,
.name-ani::after {
animation-name: name-ani;
animation-duration: 250ms;
animation-delay: 4.5s;
animation-fill-mode: forwards;
}
#keyframes name-ani {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
}
}

CSS Circular Arrow [duplicate]

I'm trying to create a round directional arrow with CSS and HTML. Below are my attempts.
Attempt 1
In this I have rotated the <div> and an arrow, but both are in different positions.
This is the CSS:
#curves div {
width: 100px;
height: 100px;
border: 5px solid #999;
}
#curves.width div {
border-color: transparent transparent transparent #999;
}
#curve1 {
-moz-border-radius: 50px 0 0 50px;
border-radius: 50px 0 0 50px;
}
.arrow-right {
width: 0;
height: 0;
border-top: 10px solid transparent;
border-bottom: 10px solid transparent;
border-left: 27px solid #ccc;
float: right;
margin-top: -7px;
margin-right: -26px;
}
<div id="curves" class="width">
<div id="curve1"></div><span class="arrow-right"></span>
</div>
Attempt 2
In this the arrow I have created is straight.
.container {
width: 60%;
height: 9px;
background: #ccc;
margin: 100px auto;
-moz-border-radius: 50px 0 0 50px;
border-radius: 50px 0 0 50px;
}
.arrow-right {
width: 0;
height: 0;
border-top: 10px solid transparent;
border-bottom: 10px solid transparent;
border-left: 27px solid #ccc;
float: right;
margin-top: -7px;
margin-right: -26px;
}
<div class="container">
</span><span class="arrow-right"></span>
</div>
Update
I want it something like this
You could use a pseudo element to generate the triangle (using the famous border hack).
After that, you would be able to use a thick border on the actual element (with a border-radius of 50% to make it a circle). This allows you to rotate the arrow to your liking.
div {
border: 20px solid transparent;
border-top-color: black;
border-left-color: black;
height: 100px;
width: 100px;
border-radius: 50%;
position: relative;
-webkit-transform: rotate(-45deg);
-ms-transform: rotate(-45deg);
transform: rotate(-45deg);
margin:30px auto;
}
div:before {
content: "";
position: absolute;
top: -20px;
left: 80%;
height: 0;
width: 0;
border-left: 30px solid black;
border-top: 30px solid transparent;
border-bottom: 30px solid transparent;
-webkit-transform: rotate(45deg);
-ms-transform: rotate(45deg);
transform: rotate(45deg);
}
/*BELOW IS FOR DEMO ONLY*/
div:hover {
-webkit-transform: rotate(315deg);
-ms-transform: rotate(315deg);
transform: rotate(315deg);
transition: all 0.8s;
}
html {
text-align:center;
color:white;
font-size:30px;
height: 100%;
background: rgb(79, 79, 79);
/* Old browsers */
background: -moz-radial-gradient(center, ellipse cover, rgba(79, 79, 79, 1) 0%, rgba(34, 34, 34, 1) 100%);
/* FF3.6+ */
background: -webkit-gradient(radial, center center, 0px, center center, 100%, color-stop(0%, rgba(79, 79, 79, 1)), color-stop(100%, rgba(34, 34, 34, 1)));
/* Chrome,Safari4+ */
background: -webkit-radial-gradient(center, ellipse cover, rgba(79, 79, 79, 1) 0%, rgba(34, 34, 34, 1) 100%);
/* Chrome10+,Safari5.1+ */
background: -o-radial-gradient(center, ellipse cover, rgba(79, 79, 79, 1) 0%, rgba(34, 34, 34, 1) 100%);
/* Opera 12+ */
background: -ms-radial-gradient(center, ellipse cover, rgba(79, 79, 79, 1) 0%, rgba(34, 34, 34, 1) 100%);
/* IE10+ */
background: radial-gradient(ellipse at center, rgba(79, 79, 79, 1) 0%, rgba(34, 34, 34, 1) 100%);
/* W3C */
filter: progid: DXImageTransform.Microsoft.gradient(startColorstr='#4f4f4f', endColorstr='#222222', GradientType=1);
/* IE6-9 fallback on horizontal gradient */
}
HOVER ME
<div></div>
If you then wanted to lengthen the arrow, you could make the bottom border visible. For example;
div {
border: 20px solid transparent;
border-top-color: black;
border-left-color: black;
border-bottom-color: black;
height: 100px;
width: 100px;
border-radius: 50%;
position: relative;
transform: rotate(-45deg);
margin:30px auto;
}
div:before {
content: "";
position: absolute;
top: -20px;
left: 80%;
height: 0;
width: 0;
border-left: 30px solid black;
border-top: 30px solid transparent;
border-bottom: 30px solid transparent;
transform: rotate(45deg);
}
/*BELOW IS FOR DEMO ONLY*/
div:hover {
transform: rotate(315deg);
transition: all 0.8s;
}
html {
text-align:center;
color:white;
font-size:30px;
height: 100%;
background: rgb(79, 79, 79);
/* Old browsers */
background: -moz-radial-gradient(center, ellipse cover, rgba(79, 79, 79, 1) 0%, rgba(34, 34, 34, 1) 100%);
/* FF3.6+ */
background: -webkit-gradient(radial, center center, 0px, center center, 100%, color-stop(0%, rgba(79, 79, 79, 1)), color-stop(100%, rgba(34, 34, 34, 1)));
/* Chrome,Safari4+ */
background: -webkit-radial-gradient(center, ellipse cover, rgba(79, 79, 79, 1) 0%, rgba(34, 34, 34, 1) 100%);
/* Chrome10+,Safari5.1+ */
background: -o-radial-gradient(center, ellipse cover, rgba(79, 79, 79, 1) 0%, rgba(34, 34, 34, 1) 100%);
/* Opera 12+ */
background: -ms-radial-gradient(center, ellipse cover, rgba(79, 79, 79, 1) 0%, rgba(34, 34, 34, 1) 100%);
/* IE10+ */
background: radial-gradient(ellipse at center, rgba(79, 79, 79, 1) 0%, rgba(34, 34, 34, 1) 100%);
/* W3C */
filter: progid: DXImageTransform.Microsoft.gradient(startColorstr='#4f4f4f', endColorstr='#222222', GradientType=1);
/* IE6-9 fallback on horizontal gradient */
}
HOVER ME
<div></div>
SVG solution
The shape is really simple to create in SVG.
For the svg interested:
<svg width="200px" height="200px" viewbox="0 0 400 400">
<path stroke="#000" stroke-width="50" fill="none"
d="M200 350 A 100 100 0 0 1 200 150
M200 150 200 125 225 150 200 175Z"/>
</svg>
Can i use it?
I have created this little thing in CSS, you can look at the code to see how it works.
Note: this does need a solid background.
.arrow {
width: 200px;
height: 200px;
border: 6px solid;
border-radius: 50%;
position: relative;
}
.arrow:before {
content: "";
display: block;
width: 10px;
height: 50px;
background: #fff;
position: absolute;
bottom: 0;
top: 0;
right: -6px;
margin: auto;
}
.arrow:after {
content: "";
width: 0;
height: 0;
border-left: 20px solid transparent;
border-right: 20px solid transparent;
border-top: 20px solid #000;
position: absolute;
bottom: 106px;
right: -20px;
}
<div class="arrow"></div>
Here's another way to do it using clip-paths instead of messing around with borders.
Demo - http://jsfiddle.net/r8rd0yde/4/
.arrow {
position: relative;
padding: 20px;
width: 100px;
height: 100px;
}
.circle {
position: absolute;
box-sizing: border-box;
height: 100px;
width: 100px;
border: 15px solid #000;
border-radius: 50%;
-webkit-clip-path: inset(0 50% 0 0);
clip-path: inset(0 50% 0 0);
}
.triangle {
position: absolute;
width: 35px;
height: 30px;
background: #000;
margin-top: -6px;
margin-left: 38px;
-webkit-clip-path: polygon(50% 0, 0% 100%, 100% 100%);
clip-path: polygon(50% 0, 0% 100%, 100% 100%);
-moz-transform: rotate(90deg);
-webkit-transform: rotate(90deg);
-o-transform: rotate(90deg);
-ms-transform: rotate(90deg);
transform: rotate(90deg);
}
/* JUST FOR DEMO */
.arrow:hover {
-webkit-transform: rotate(720deg);
-ms-transform: rotate(720deg);
transform: rotate(720deg);
transition: all 1.2s;
}
<div class="arrow">
<div class="circle"></div>
<div class="triangle"></div>
</div>
You can use the Clockwise open circle arrow (U+21BB) character: ↻
.arrow {
display: inline-block;
font-size: 300px;
line-height: 200px;
font-weight: bold;
transform: rotate(90deg);
}
<span class="arrow">↻</span>
#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);
}
I found this in
https://css-tricks.com/examples/ShapesOfCSS/
It may not be the exact shape you want but it's definately a good starting point.

CSS button with folded corner effect and animations

I used the code below to create an effect on the folded corner button, but I can not avoid white background which is in the upper left corner of the button. That class could use to make this transparent part and thus show the yellow color, which is the background of the main DIV?
http://codepen.io/rsvaz83/pen/aORzBy
.back {
background: #fc0;
}
.button {
display: inline-block;
padding: 1em;
margin: 1em;
background-color: #007E9F;
text-decoration: none;
color: white;
}
.curl-top-left {
display: inline-block;
position: relative;
-webkit-transform: translateZ(0);
transform: translateZ(0);
box-shadow: 0 0 1px rgba(0, 0, 0, 0);
}
.curl-top-left:before {
pointer-events: none;
position: absolute;
content: '';
height: 0;
width: 0;
top: 0;
left: 0;
/* IE9 */
background: linear-gradient(135deg, white 45%, #aaaaaa 50%, #cccccc 56%, white 80%);
filter: progid: DXImageTransform.Microsoft.gradient(GradientType=0, startColorstr='#ffffff', endColorstr='#000000');
/*For IE7-8-9*/
z-index: 1000;
box-shadow: 1px 1px 1px rgba(0, 0, 0, 0.4);
-webkit-transition-duration: 0.3s;
transition-duration: 0.3s;
-webkit-transition-property: width, height;
transition-property: width, height;
}
.curl-top-left:hover:before,
.curl-top-left:focus:before,
.curl-top-left:active:before {
width: 40px;
height: 40px;
}
<div class="back">
BUTTON EFFECT
</div>
Just change the 1st white to #fc0 (the color of the background bar) in the line below.
background: linear-gradient(135deg, white 45%, #aaaaaa 50%, #cccccc 56%, white 80%);
^^^^^
I also simplified the CSS slightly, merged transition rules, and remove that filter hack, it won't be able to get the effect you want on outdated IEs anyway, updated code snippet follows.
.back {
background: #fc0;
}
.button {
display: inline-block;
padding: 1em;
margin: 1em;
background-color: #007E9F;
text-decoration: none;
color: white;
}
.curl-top-left {
display: inline-block;
position: relative;
-webkit-transform: translateZ(0);
transform: translateZ(0);
box-shadow: 0 0 1px rgba(0, 0, 0, 0);
}
.curl-top-left:before {
pointer-events: none;
position: absolute;
content: '';
height: 0;
width: 0;
top: 0;
left: 0;
z-index: 1000;
background: linear-gradient(135deg, #fc0 45%, #aaa 50%, #ccc 50%, #fff 80%);
box-shadow: 1px 1px 1px rgba(0, 0, 0, 0.4);
transition: 0.3s;
}
.curl-top-left:hover:before,
.curl-top-left:focus:before,
.curl-top-left:active:before {
width: 40px;
height: 40px;
}
<div class="back">
BUTTON EFFECT
</div>
Change the first value of the background to the yellow color.
background: transparent linear-gradient(135deg, #Fc0 45%, #AAA 50%, #CCC 56%, #FFF 80%) repeat scroll 0% 0%;
You can set the color of the folded corner in curl-top-left:before:
.curl-top-left:before {
[...]
background: linear-gradient(135deg, HERE 45%,
#aaaaaa 50%,
#cccccc 56%,
white 80%);
[...]
}
Just replace HERE with your desired color (such as #fc0 for example). You cannot use transparency here, since the folded corner is drawn on top of the button, so when you set it to transparent, you will always see the button under the folded corner.
You can change your background to a gradient.
and move it in sync with the efect of the pseudo element.
.back {
background: #fc0;
padding-left: 30px;
vertical-align: top;
padding-top: 20px;
padding-bottom: 20px;
}
.button {
display: inline-block;
padding: 1em;
margin: 0em -2em;
text-decoration: none;
color: white;
}
.curl-top-left {
display: inline-block;
position: relative;
-webkit-transform: translateZ(0);
transform: translateZ(0);
box-shadow: 0 0 1px rgba(0, 0, 0, 0);
background-image: linear-gradient(135deg, transparent 30px, #007E9F 30px);
background-position: -20px -20px;
background-size: 200% 200%;
-webkit-transition-duration: 0.3s;
transition-duration: 0.3s;
-webkit-transition-property: background-position;
transition-property: background-position;
}
.curl-top-left:before {
pointer-events: none;
position: absolute;
content: '';
height: 0;
width: 0;
top: 0;
left: 0;
/* IE9 */
background: linear-gradient(135deg, transparent 45%, #aaaaaa 50%, #cccccc 56%, white 80%);
filter: progid: DXImageTransform.Microsoft.gradient(GradientType=0, startColorstr='#ffffff', endColorstr='#000000');
/*For IE7-8-9*/
z-index: 1000;
box-shadow: 1px 1px 1px rgba(0, 0, 0, 0.4);
-webkit-transition-duration: inherit;
transition-duration: inherit;
-webkit-transition-property: width, height;
transition-property: width, height;
}
.curl-top-left:hover:before,
.curl-top-left:focus:before,
.curl-top-left:active:before {
width: 40px;
height: 40px;
}
.curl-top-left:hover,
.curl-top-left:focus,
.curl-top-left:active {
background-position: 0px 0px;
}
<div class="back">HI!
BUTTON EFFECT
</div>

Wrap icons around an extendable circle

I have a disc whose size can change, and some icons arranged around that disc. The icons should always be on the border of the disc, and the intervals between each icon should always stay the same.
Can this be done in pure css without having to compute each icon's position whenever the disc grows or shrinks?
Expected result:
.container:nth-child(1)
{
position: absolute;
top: 20px;
left: 30px;
height: 280px;
width: 280px;
}
.container:nth-child(2)
{
position: absolute;
top: 20px;
right: 30px;
height: 200px;
width: 200px;
}
.container > *
{
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
.circle
{
height: 90%;
width: 90%;
border-radius: 50%;
border: 1px solid blue;
z-index: 20;
}
.icons
{
height: 100%;
width: 100%;
border: 1px dashed gray;
box-sizing: border-box;
z-index: 10;
}
.icons > *
{
position: absolute;
top: 50%;
left: 50%;
height: 20px;
width: 20px;
margin-top: -10px;
margin-left: -10px;
border: 1px solid red;
}
.container:nth-child(1) span:nth-child(1)
{
transform: rotate(230deg) translate(150px) rotate(-230deg);
}
.container:nth-child(1) span:nth-child(2)
{
transform: rotate(217deg) translate(150px) rotate(-217deg);
}
.container:nth-child(1) span:nth-child(3)
{
transform: rotate(204deg) translate(150px) rotate(-204deg);
}
.container:nth-child(1) span:nth-child(4)
{
transform: rotate(191deg) translate(150px) rotate(-191deg);
}
.container:nth-child(2) span:nth-child(1)
{
transform: rotate(230deg) translate(110px) rotate(-230deg);
}
.container:nth-child(2) span:nth-child(2)
{
transform: rotate(212deg) translate(110px) rotate(-212deg);
}
.container:nth-child(2) span:nth-child(3)
{
transform: rotate(194deg) translate(110px) rotate(-194deg);
}
.container:nth-child(2) span:nth-child(4)
{
transform: rotate(176deg) translate(110px) rotate(-176deg);
}
<div class="container">
<div class="circle"></div>
<div class="icons">
<span>A</span>
<span>B</span>
<span>C</span>
<span>D</span>
</div>
</div>
<div class="container">
<div class="circle"></div>
<div class="icons">
<span>A</span>
<span>B</span>
<span>C</span>
<span>D</span>
</div>
</div>
Without a preprocessor, I believe you'll need a script to achieve this. Here I've used jQuery in order to compute the intervals on hover.
Note
this would also support a dynamic number of .circle elements
+ function() {
var to;
$(".wrap").on('mouseenter', function() {
var circles = $(this).find(".circle");
var degree = (2 * Math.PI) / circles.length; //calc delta angle
var transforms = [];
// Calculate the position for each circle
circles.each(function(index) {
var x = 100 * Math.cos(-0.5 * Math.PI + degree * (-1 * index - 0.5));
var y = 100 * Math.sin(-0.5 * Math.PI + degree * (-1 * index - 0.5));
transforms.push('translate(' + x + 'px,' + y + 'px)');
});
// Function to moves all the circles
// We'll pop a circle each time and than call this function recursively
function moveCircles() {
var transform = transforms.shift();
circles.css('transform', transform);
circles.splice(0, 1);
if (circles.length) to = setTimeout(moveCircles, 400);
}
moveCircles();
});
$(".wrap").on('mouseleave', function() {
var circles = $(this).children().css('transform', '');
clearTimeout(to);
});
}();
html {
height: 100%;
background: radial-gradient(ellipse at center, rgba(79, 79, 79, 1) 0%, rgba(34, 34, 34, 1) 100%);
}
.wrap {
height: 300px;
width: 300px;
position: relative;
transform-origin: center center;
transition: all 0.8s;
}
.circle {
transition: all 0.8s;
position: absolute;
height: 5px;
width: 5px;
text-align: center;
line-height: 15px;
top: calc(50% - 2px);
left: calc(50% - 2px);
border-radius: 50%;
overflow: hidden;
}
.parent {
transition: all 0.8s;
position: absolute;
background: gray;
height: 50px;
width: 50px;
text-align: center;
line-height: 25px;
top: calc(50% - 25px);
left: calc(50% - 25px);
border-radius: 50%;
z-index: 8;
box-shadow: inset 2px 2px 10px black, inset 0 0 15px black, 0 0 15px black;
}
.parent:before,
.parent:after {
content: "";
position: absolute;
transition: all 0.8s;
height: 5px;
width: 25px;
top: 22px;
left: 12px;
background: black;
opacity: 1;
}
.parent:before {
top: 15px;
box-shadow: 0 14px 0 black;
}
.parent:hover:before,
.parent:hover:after {
transform: translate(0, 20px);
color: gray;
opacity: 0;
box-shadow: 0 14px 0 none;
}
.wrap:hover .parent,
.wrap:hover .parent:before,
.wrap:hover .parent:after {
background: darkgray;
}
.wrap:hover .parent:before {
box-shadow: none;
}
.wrap:hover .circle {
height: 50px;
width: 50px;
line-height: 25px;
top: calc(50% - 25px);
left: calc(50% - 25px);
box-shadow: inset 2px 2px 10px black, inset 0 0 15px black, 0 0 15px black;
}
.circle img {
position: absolute;
height: 100%;
width: 100%;
left: 0;
top: 0;
}
.circle:before {
border-radius: 50%;
transition: all 0.8s;
content: "";
position: absolute;
height: 100%;
width: 100%;
top: 0;
left: 0;
z-index: 8;
}
.circle:after,
button:after {
transition: all 0.8s;
border-radius: 50%;
content: "";
position: absolute;
height: 200%;
width: 200%;
top: 50%;
left: 200%;
z-index: 8;
background: -moz-linear-gradient(left, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.4) 50%, rgba(255, 255, 255, 0) 100%);
background: -webkit-gradient(linear, left top, right top, color-stop(0%, rgba(255, 255, 255, 0)), color-stop(50%, rgba(255, 255, 255, 0.4)), color-stop(100%, rgba(255, 255, 255, 0)));
background: -webkit-linear-gradient(left, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.4) 50%, rgba(255, 255, 255, 0) 100%);
background: -o-linear-gradient(left, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.4) 50%, rgba(255, 255, 255, 0) 100%);
background: -ms-linear-gradient(left, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.4) 50%, rgba(255, 255, 255, 0) 100%);
background: linear-gradient(to right, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.4) 50%, rgba(255, 255, 255, 0) 100%);
filter: progid: DXImageTransform.Microsoft.gradient(startColorstr='#00ffffff', endColorstr='#00ffffff', GradientType=1);
}
.circle:hover:after,
button:hover:after {
left: -200%;
top: -50%;
}
.circle:hover:before {
box-shadow: inset 2px 2px 10px black, inset 0 0 15px black, 0 0 15px black;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="wrap">
<div class="parent"></div>
<div class="circle">
<img src="http://lorempixel.com/300/300" />
</div>
<div class="circle">
<img src="http://placekitten.com/g/200/300" />
</div>
<div class="circle">
<img src="http://cdn.flaticon.com/png/256/56729.png" />
</div>
<div class="circle">
<img src="http://cdn.flaticon.com/png/256/54976.png" />
</div>
<div class="circle">Just Text</div>
<div class="circle">
<img src="http://cdn.flaticon.com/png/256/56582.png" />
</div>
</div>
There is a way to do it programmatically, but only with CSS3. What you have to do is have an element inside it that takes the full width and can rotate, and then counterrotate the inner containers of those rotating elements.
So you would have to define the circles by using :nth-child. In order to achieve the correct effect and not apply a style twice, we will have to count down from our last element in order to only attract elements at a certain position. This is because :nth-child(2n) applies to :nth-child(4n) as well, which might create overlapping styles. Skip to the snippet if this seems a bit too complicated - it's actually quite simple.
So your basic HTML would be:
<wrapper> <!-- This is your disc -->
<rotation> <!-- A rotation element. -->
<counter> <!-- A counter-rotation element. This contains your content. -->
The first element has to have a position enabled. The second element needs to overlap with all the other secondary elements, so it needs a position of absolute, and the third element, well, that's up to you. It's just there to counter rotate it again.
Heres an implementation:
/*The following animation shows that the outer frame is resizeable.*/
#-webkit-keyframes sizeBounce { 0% {width: 50vw; height: 50vw; } 50% {width: 20vw; height: 20vw; } 100% {width: 50vw; height: 50vw; }}
#keyframes sizeBounce { 0% {width: 50vw; height: 50vw; } 50% {width: 20vw; height: 20vw; } 100% {width: 50vw; height: 50vw; }}
div {
position: relative;
/* Any height you want here */
width: 20vw;
height: 20vw;
border-radius: 50%;
border: 1px solid #000;
-webkit-animation: sizeBounce 2s infinite;
animation: sizeBounce 2s infinite;
/* You can do anything you want with this circle! */
position: absolute;
top: 50%;
left: 50%;
-webkit-transform: translate(-50%,-50%);
transform: translate(-50%,-50%);
}
div > span {
position: absolute;
display: block;
width: 100%;
height: 100%;
top: 0;
left: 0;
transform: rotateZ(0deg);
transform-origin: 50% 50%;
}
div > span > em {
display: block;
position: absolute;
left: 0;
top: 0;
width: 20%;
height: 20%;
border-radius: 50%;
border: 1px solid #dd0300;
text-align: center;
}
div > span:nth-child(6n-6) {
-webkit-transform: rotateZ(0deg);
transform: rotateZ(0deg);
}
div > span:nth-child(6n-6) > em {
-webkit-transform: rotateZ(0deg);
transform: rotateZ(0deg);
}
div > span:nth-child(6n-4) {
-webkit-transform: rotateZ(60deg);
transform: rotateZ(60deg);
}
div > span:nth-child(6n-4) > em {
-webkit-transform: rotateZ(-60deg);
transform: rotateZ(-60deg);
}
div > span:nth-child(6n-3) {
-webkit-transform: rotateZ(120deg);
transform: rotateZ(120deg);
}
div > span:nth-child(6n-3) > em {
-webkit-transform: rotateZ(-120deg);
transform: rotateZ(-120deg);
}
div > span:nth-child(6n-2) {
-webkit-transform: rotateZ(180deg);
transform: rotateZ(180deg);
}
div > span:nth-child(6n-2) > em {
-webkit-transform: rotateZ(-180deg);
transform: rotateZ(-180deg);
}
div > span:nth-child(6n-1) {
-webkit-transform: rotateZ(240deg);
transform: rotateZ(240deg);
}
div > span:nth-child(6n-1) > em {
-webkit-transform: rotateZ(-240deg);
transform: rotateZ(-240deg);
}
div > span:nth-child(6n) {
-webkit-transform: rotateZ(300deg);
transform: rotateZ(300deg);
}
div > span:nth-child(6n) > em {
-webkit-transform: rotateZ(-300deg);
transform: rotateZ(-300deg);
}
<div>
<span><em>1</em></span>
<span><em>2</em></span>
<span><em>3</em></span>
<span><em>4</em></span>
<span><em>5</em></span>
<span><em>6</em></span>
</div>
There is a way to automate this is SASS as well and it looks something like this:
#mixin rotatePiecemeally($pieces:6,$wrapper:span,$container:em){
/* First calculate the angle between each piece */
$degrees : 360 / $pieces;
/* We want to count back from the amount of pieces to 0
* The counting is because simple counting 2n, 3n, 4n, ...
* will result in 4n inheriting from 2n - to keep things clean,
* we want to avoid that. */
#for $i from 0 through ($pieces - 1){
& #{$wrapper}:nth-child(#{$pieces}n-#{$i}){
transform: rotateZ(#{$i * $degrees}deg);
}
& #{$wrapper}:nth-child(#{$pieces}n-#{$i}) > #{$container}{
transform: rotateZ(#{-$i * $degrees}deg);
}
}
}
You can call it by doing the following:
#mycircle {
#include rotatePiecemeally(6);
}
And you can optionally include which elements you want to use as the children. Don't forget they all need some absolute positioning for this to work. Don't forget to add any prefixes you need (I added them to the snippet because I am using Safari)

How can I create a round arrow with only HTML and CSS?

I'm trying to create a round directional arrow with CSS and HTML. Below are my attempts.
Attempt 1
In this I have rotated the <div> and an arrow, but both are in different positions.
This is the CSS:
#curves div {
width: 100px;
height: 100px;
border: 5px solid #999;
}
#curves.width div {
border-color: transparent transparent transparent #999;
}
#curve1 {
-moz-border-radius: 50px 0 0 50px;
border-radius: 50px 0 0 50px;
}
.arrow-right {
width: 0;
height: 0;
border-top: 10px solid transparent;
border-bottom: 10px solid transparent;
border-left: 27px solid #ccc;
float: right;
margin-top: -7px;
margin-right: -26px;
}
<div id="curves" class="width">
<div id="curve1"></div><span class="arrow-right"></span>
</div>
Attempt 2
In this the arrow I have created is straight.
.container {
width: 60%;
height: 9px;
background: #ccc;
margin: 100px auto;
-moz-border-radius: 50px 0 0 50px;
border-radius: 50px 0 0 50px;
}
.arrow-right {
width: 0;
height: 0;
border-top: 10px solid transparent;
border-bottom: 10px solid transparent;
border-left: 27px solid #ccc;
float: right;
margin-top: -7px;
margin-right: -26px;
}
<div class="container">
</span><span class="arrow-right"></span>
</div>
Update
I want it something like this
You could use a pseudo element to generate the triangle (using the famous border hack).
After that, you would be able to use a thick border on the actual element (with a border-radius of 50% to make it a circle). This allows you to rotate the arrow to your liking.
div {
border: 20px solid transparent;
border-top-color: black;
border-left-color: black;
height: 100px;
width: 100px;
border-radius: 50%;
position: relative;
-webkit-transform: rotate(-45deg);
-ms-transform: rotate(-45deg);
transform: rotate(-45deg);
margin:30px auto;
}
div:before {
content: "";
position: absolute;
top: -20px;
left: 80%;
height: 0;
width: 0;
border-left: 30px solid black;
border-top: 30px solid transparent;
border-bottom: 30px solid transparent;
-webkit-transform: rotate(45deg);
-ms-transform: rotate(45deg);
transform: rotate(45deg);
}
/*BELOW IS FOR DEMO ONLY*/
div:hover {
-webkit-transform: rotate(315deg);
-ms-transform: rotate(315deg);
transform: rotate(315deg);
transition: all 0.8s;
}
html {
text-align:center;
color:white;
font-size:30px;
height: 100%;
background: rgb(79, 79, 79);
/* Old browsers */
background: -moz-radial-gradient(center, ellipse cover, rgba(79, 79, 79, 1) 0%, rgba(34, 34, 34, 1) 100%);
/* FF3.6+ */
background: -webkit-gradient(radial, center center, 0px, center center, 100%, color-stop(0%, rgba(79, 79, 79, 1)), color-stop(100%, rgba(34, 34, 34, 1)));
/* Chrome,Safari4+ */
background: -webkit-radial-gradient(center, ellipse cover, rgba(79, 79, 79, 1) 0%, rgba(34, 34, 34, 1) 100%);
/* Chrome10+,Safari5.1+ */
background: -o-radial-gradient(center, ellipse cover, rgba(79, 79, 79, 1) 0%, rgba(34, 34, 34, 1) 100%);
/* Opera 12+ */
background: -ms-radial-gradient(center, ellipse cover, rgba(79, 79, 79, 1) 0%, rgba(34, 34, 34, 1) 100%);
/* IE10+ */
background: radial-gradient(ellipse at center, rgba(79, 79, 79, 1) 0%, rgba(34, 34, 34, 1) 100%);
/* W3C */
filter: progid: DXImageTransform.Microsoft.gradient(startColorstr='#4f4f4f', endColorstr='#222222', GradientType=1);
/* IE6-9 fallback on horizontal gradient */
}
HOVER ME
<div></div>
If you then wanted to lengthen the arrow, you could make the bottom border visible. For example;
div {
border: 20px solid transparent;
border-top-color: black;
border-left-color: black;
border-bottom-color: black;
height: 100px;
width: 100px;
border-radius: 50%;
position: relative;
transform: rotate(-45deg);
margin:30px auto;
}
div:before {
content: "";
position: absolute;
top: -20px;
left: 80%;
height: 0;
width: 0;
border-left: 30px solid black;
border-top: 30px solid transparent;
border-bottom: 30px solid transparent;
transform: rotate(45deg);
}
/*BELOW IS FOR DEMO ONLY*/
div:hover {
transform: rotate(315deg);
transition: all 0.8s;
}
html {
text-align:center;
color:white;
font-size:30px;
height: 100%;
background: rgb(79, 79, 79);
/* Old browsers */
background: -moz-radial-gradient(center, ellipse cover, rgba(79, 79, 79, 1) 0%, rgba(34, 34, 34, 1) 100%);
/* FF3.6+ */
background: -webkit-gradient(radial, center center, 0px, center center, 100%, color-stop(0%, rgba(79, 79, 79, 1)), color-stop(100%, rgba(34, 34, 34, 1)));
/* Chrome,Safari4+ */
background: -webkit-radial-gradient(center, ellipse cover, rgba(79, 79, 79, 1) 0%, rgba(34, 34, 34, 1) 100%);
/* Chrome10+,Safari5.1+ */
background: -o-radial-gradient(center, ellipse cover, rgba(79, 79, 79, 1) 0%, rgba(34, 34, 34, 1) 100%);
/* Opera 12+ */
background: -ms-radial-gradient(center, ellipse cover, rgba(79, 79, 79, 1) 0%, rgba(34, 34, 34, 1) 100%);
/* IE10+ */
background: radial-gradient(ellipse at center, rgba(79, 79, 79, 1) 0%, rgba(34, 34, 34, 1) 100%);
/* W3C */
filter: progid: DXImageTransform.Microsoft.gradient(startColorstr='#4f4f4f', endColorstr='#222222', GradientType=1);
/* IE6-9 fallback on horizontal gradient */
}
HOVER ME
<div></div>
SVG solution
The shape is really simple to create in SVG.
For the svg interested:
<svg width="200px" height="200px" viewbox="0 0 400 400">
<path stroke="#000" stroke-width="50" fill="none"
d="M200 350 A 100 100 0 0 1 200 150
M200 150 200 125 225 150 200 175Z"/>
</svg>
Can i use it?
I have created this little thing in CSS, you can look at the code to see how it works.
Note: this does need a solid background.
.arrow {
width: 200px;
height: 200px;
border: 6px solid;
border-radius: 50%;
position: relative;
}
.arrow:before {
content: "";
display: block;
width: 10px;
height: 50px;
background: #fff;
position: absolute;
bottom: 0;
top: 0;
right: -6px;
margin: auto;
}
.arrow:after {
content: "";
width: 0;
height: 0;
border-left: 20px solid transparent;
border-right: 20px solid transparent;
border-top: 20px solid #000;
position: absolute;
bottom: 106px;
right: -20px;
}
<div class="arrow"></div>
Here's another way to do it using clip-paths instead of messing around with borders.
Demo - http://jsfiddle.net/r8rd0yde/4/
.arrow {
position: relative;
padding: 20px;
width: 100px;
height: 100px;
}
.circle {
position: absolute;
box-sizing: border-box;
height: 100px;
width: 100px;
border: 15px solid #000;
border-radius: 50%;
-webkit-clip-path: inset(0 50% 0 0);
clip-path: inset(0 50% 0 0);
}
.triangle {
position: absolute;
width: 35px;
height: 30px;
background: #000;
margin-top: -6px;
margin-left: 38px;
-webkit-clip-path: polygon(50% 0, 0% 100%, 100% 100%);
clip-path: polygon(50% 0, 0% 100%, 100% 100%);
-moz-transform: rotate(90deg);
-webkit-transform: rotate(90deg);
-o-transform: rotate(90deg);
-ms-transform: rotate(90deg);
transform: rotate(90deg);
}
/* JUST FOR DEMO */
.arrow:hover {
-webkit-transform: rotate(720deg);
-ms-transform: rotate(720deg);
transform: rotate(720deg);
transition: all 1.2s;
}
<div class="arrow">
<div class="circle"></div>
<div class="triangle"></div>
</div>
You can use the Clockwise open circle arrow (U+21BB) character: ↻
.arrow {
display: inline-block;
font-size: 300px;
line-height: 200px;
font-weight: bold;
transform: rotate(90deg);
}
<span class="arrow">↻</span>
#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);
}
I found this in
https://css-tricks.com/examples/ShapesOfCSS/
It may not be the exact shape you want but it's definately a good starting point.