What I'd like to do:
I would like to create a radial menu as shown below, considering all elements in the picture interactive, i.e the image in centre as well as the four quarters around it.
It's important that the solution is cross-browser compatible.
This is just a simple example as the parts dont really have to be quarters, they can be any possible number of parts :
Solutions Tried So Far :
I have tried using CSS3 round div with border , where the border have these images as background, but doesnt really work well, as each element has to be a stand-alone element.
I heard about css-shapes, but I don't know how to use it to create the radial menu.
EDIT:
Maybe there is also a way to add a text caption to each of these images...
Thank you for help!
I made this pen with a css radial menu. The circular menu appears on hover :
Demo : CSS radial menu
The radial shape is made with border radius and the overflow property. The hover animation is handled with CSS transition (scale and oapcity).
For a version with menu titles, see this DEMO
Full Code for the radial menu :
HTML :
<span><span></span></span>
<div class="wrap">
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
</div>
CSS :
body,html{margin:0;padding:0;height:100%;}
body{background:#E3DFD2;box-shadow: inset 0 0 20vmin 0 #585247;}
.wrap{
position:relative;
width:80vmin; height:80vmin;
margin:0 auto;
background:inherit;
transform:scale(0.2) translatez(0px);
opacity:0;
transition:transform .5s, opacity .5s;
}
a{
position:absolute;
left:0; top:0;
width:47.5%; height:47.5%;
overflow:hidden;
transform:scale(.5) translateZ(0px);
background:#585247;
}
a div{
height:100%;
background-size:cover;
opacity:.5;
transition:opacity .5s;
border-radius:inherit;
}
a:nth-child(1){
border-radius:40vmin 0 0 0;
transform-origin: 110% 110%;
transition:transform .4s .15s;
}
a:nth-child(1) div{
background-image:url('https://farm3.staticflickr.com/2827/10384422264_d9c7299146.jpg');
}
a:nth-child(2){
border-radius:0 40vmin 0 0;
left:52.5%;
transform-origin: -10% 110%;
transition:transform .4s .2s;
}
a:nth-child(2) div{
background-image:url('https://farm7.staticflickr.com/6083/6055581292_d94c2d90e3.jpg');
}
a:nth-child(3){
border-radius:0 0 0 40vmin;
top:52.5%;
transform-origin: 110% -10%;
transition:transform .4s .25s;
}
a:nth-child(3) div{
background-image:url('https://farm7.staticflickr.com/6092/6227418584_d5883b0948.jpg');
}
a:nth-child(4){
border-radius:0 0 40vmin 0;
top:52.5%; left:52.5%;
transform-origin: -10% -10%;
transition:transform .4s .3s;
}
a:nth-child(4) div{
background-image: url('https://farm8.staticflickr.com/7187/6895047173_d4b1a0d798.jpg');
}
a:nth-child(5){
width:55%;height:55%;
left:22.5%; top:22.5%;
border-radius:50vmin;
box-shadow:0 0 0 5vmin #E3DFD2;
transform:scale(1);
}
a:nth-child(5) div{
background-image: url('https://farm4.staticflickr.com/3766/12953056854_b8cdf14f21.jpg');
}
span{
position:relative;
display:block;
margin:0 auto;
top:45vmin;
width:10vmin; height:10vmin;
border-radius:100%;
background:#585247;
transform:translateZ(0px);
}
span span{
position:absolute;
width:60%;height:3px;
background:#ACA696;
left:20%; top:50%;
border-radius:0;
}
span span:after, span span:before{
content:'';
position:absolute;
left:0; top:-1.5vmin;
width:100%; height:100%;
background:inherit;
}
span span:after{
top:1.5vmin;
}
span:hover + .wrap, .wrap:hover{
transform:scale(.8) translateZ(0px);
opacity:1;
}
span:hover + .wrap a, .wrap:hover a{
transform:scale(1) translatez(0px);
}
a:hover div{
opacity:1;
transform:translatez(0px);
}
Here's an alternative, less fancy, have to get clever with img opacity + div background-color to preserve the hover.
/* CSS */
* {
box-sizing: border-box;
}
div {
background: white;
}
img {
width: 100%;
-webkit-transition: opacity .2s;
}
div:hover > img {
opacity: .5;
}
.wrap,
.wrap div:first-child{
width: 500px;
height: 500px;
margin: auto;
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
}
.wrap div:first-child {
float: none;
z-index: 2;
width: 50%;
height: 50%;
border-radius: 100%;
border: 30px solid white;
}
div div {
float: left;
overflow: hidden;
width: 50%;
height: 50%;
border: 15px solid white;
}
div div:nth-child(2) img {
border-radius: 100% 0 0 0;
}
div div:nth-child(3) img {
border-radius: 0 100% 0 0;
}
div div:nth-child(4) img {
border-radius: 0 0 0 100%;
}
div div:nth-child(5) img{
border-radius: 0 0 100% 0;
}
<!-- HTML -->
<div class="wrap">
<div><img src="http://placehold.it/300x300&text=Center" /></div>
<div><img src="http://placehold.it/300x300&text=Top Left" /></div>
<div><img src="http://placehold.it/300x300&text=Top Right" /></div>
<div><img src="http://placehold.it/300x300&text=Bottom Left" /></div>
<div><img src="http://placehold.it/300x300&text=Bottom Right" /></div>
</div>
Here's a solution if you only needed 'four quarters', rather than an unknown amount:
.wrap {
position: relative;
height: 310px;
width: 310px;
}
.square {
display: inline-block;
height: 150px;
width: 150px;
}
.circle {
position: absolute;
height: 180px;
width: 180px;
top: 50%;
left: 50%;
background: gray;
border-radius: 50%;
transform: translate(-50%, -50%);
border: 10px solid white;
}
.wrap div:hover {
background: url(http://placekitten.com/g/300/300);
background-size: 100% 100%;
}
.square:nth-child(1) {
border-radius: 100% 0 0 0;
background: cornflowerblue;
}
.square:nth-child(2) {
border-radius: 0 100% 0 0;
background: tomato;
}
.square:nth-child(3) {
border-radius: 0 0 0 100%;
background: darkorange;
}
.square:nth-child(4) {
border-radius: 0 0 100% 0;
background: green;
}
<div class="wrap">
<div class="square"></div>
<div class="square"></div>
<div class="square"></div>
<div class="square"></div>
<div class="circle"></div>
</div>
I got confused by the other examples here so I tried to simplify them and use container divs that I can put anything into, rather than images. Here is the result if it helps anyone.
/* CSS */
* {
padding: 0;
margin: 0;
box-sizing: border-box;
}
body {
background-color: #272727;
}
.container { /* for the container */
width: 90vw;
height: 90vmin;
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
margin: auto;
display: flex;
flex-wrap: wrap;
} /* Basically just a responsive container that stays at the page's center */
.box { /* Applies to the four corner boxes within container */
width: 50%;
height: 50%;
border: 2.5vmin solid #272727; /* The 4 borders between the boxes */
}
.center { /* The fifth box at the center, we'll turn it into a circle */
width: 50vmin;
height: 50vmin;
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
margin: auto;
border-radius: 100%;
border: 5vmin solid #272727; /* The circular border in the center */
z-index: 2;
}
.inner { /* The content holding div inside each of the 5 blocks */
height: 100%; width: 100%; background-color: gold;
}
.center .inner {border-radius: 100%;}
.inner:hover {
background-color: yellow;
}
/* In case you want all buttons to have rounded corners, try: */
/*.top-left .inner {border-radius: 50vmin 0 0 0;}
.top-right .inner {border-radius: 0 50vmin 0 0;}
.bottom-left .inner {border-radius: 0 0 0 50vmin;}
.bottom-right .inner {border-radius: 0 0 50vmin 0;}
*/
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" type="text/css" href="style.css">
<title>Document</title>
</head>
<body>
<div class="container">
<div class="box top-left"><div class="inner"></div></div>
<div class="box top-right"><div class="inner"></div></div>
<div class="box bottom-left"><div class="inner"></div></div>
<div class="box bottom-right"><div class="inner"></div></div>
<div class="center"><div class="inner"></div></div>
</div>
</body>
</html>
Related
Here's my code:
HTML
<div id="featuredWrapper">
<div id="featuredContentWrapper">
<div class="ContentThumbnail">
<a>
<div class="ContentThumbnailCaption">
<h3>Lorem</h3>
<p>Ipsum</p>
</div>
<img src="https://i.picsum.photos/id/1/200/300.jpg" class="ContentThumbnailImage" />
</a>
</div>
</div>
</div>
CSS
#featuredWrapper
{
/*SETUP*/
display:inline-block;
margin-left:13.85%;
margin-right:13.85%;
width:72.3%;
/*BORDER*/
border-bottom: solid 1px gray;
/*ANIMATION*/
transition: 0.3s;
}
#featuredContentWrapper
{
/*SETUP*/
text-align:center;
}
.ContentThumbnail
{
/*SETUP*/
display:inline-block;
height: 30%;
width: 22.5%;
margin: 2% 4% 2% 4%;
/*VISUAL*/
background-color:aqua;
/*ANIMATION*/
transition: 0.3s;
}
.ContentThumbnail:hover .ContentThumbnailCaption
{
/*VISUAL*/
filter:opacity(100%);
}
.ContentThumbnail:hover .ContentThumbnailImage
{
/*VISUAL*/
filter:brightness(50%);
}
.ContentThumbnail a
{
/*SETUP*/
display:inline-block;
position:relative;
}
.ContentThumbnailImage
{
/*SETUP*/
display:inline-block;
height: 100%;
width: 100%;
}
.ContentThumbnailCaption
{
/*SETUP*/
position:absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
/*VISUAL*/
color:white;
filter:opacity(0);
/*ANIMATION*/
transition:0.3s;
}
I would like for the brightness and opacity changes to occur concurrently, so that the text would display over the darkened image.
As it stands now, I think either the brightness filter is somehow hiding the text or the effects are occurring one after another because when you stop hovering, the text will appear and play the fading out animation.
I have tried changing the mechanisms used to do both effects, like using visibility CSS instead of filters. I haven't tried JavaScript yet, but I would like to keep this effect within CSS.
Changed for below mentioned css
.ContentThumbnail:hover .ContentThumbnailCaption
{
/*VISUAL*/
filter:opacity(100%);z-index:1;
}
#featuredWrapper {
/*SETUP*/
display: inline-block;
margin-left: 13.85%;
margin-right: 13.85%;
width: 72.3%;
/*BORDER*/
border-bottom: solid 1px gray;
/*ANIMATION*/
transition: 0.3s;
}
#featuredContentWrapper {
/*SETUP*/
text-align: center;
}
.ContentThumbnail {
/*SETUP*/
display: inline-block;
height: 30%;
width: 22.5%;
margin: 2% 4% 2% 4%;
/*VISUAL*/
background-color: aqua;
/*ANIMATION*/
transition: 0.3s;
}
.ContentThumbnail:hover .ContentThumbnailCaption {
/*VISUAL*/
filter: opacity(100%);
z-index: 1;
}
.ContentThumbnail:hover .ContentThumbnailImage {
/*VISUAL*/
filter: brightness(50%);
}
.ContentThumbnail a {
/*SETUP*/
display: inline-block;
position: relative;
}
.ContentThumbnailImage {
/*SETUP*/
display: inline-block;
height: 100%;
width: 100%;
}
.ContentThumbnailCaption {
/*SETUP*/
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
/*VISUAL*/
color: white;
filter: opacity(0);
/*ANIMATION*/
transition: 0.3s;
}
<div id="featuredWrapper">
<div id="featuredContentWrapper">
<div class="ContentThumbnail">
<a>
<div class="ContentThumbnailCaption">
<h3>Lorem</h3>
<p>Ipsum</p>
</div>
<img src="https://i.picsum.photos/id/1/200/300.jpg" class="ContentThumbnailImage" />
</a>
</div>
</div>
</div>
i need to animate the border bottom of the div using keyframe animation without using :before or :after or modifying the current html structure
div{
padding:3px 6px;
display:inline-block;
position:relative;
border-bottom: 2px solid black;
}
<div><h1>Lorem Ipsum</h1></div>
You can simulate it like below. Hope that helps.
.container {
padding: 3px 6px;
display: inline-flex;
flex-direction: column;
}
.underline {
height: 2px;
max-width: 0%;
background-color: black;
animation: drawBorder 2s ease forwards;
}
#keyframes drawBorder {
from {
max-width: 0%;
}
to {
max-width: 100%;
}
}
<div class="container">
<h1>Lorem Ipsum</h1>
<div class="underline"></div>
</div>
Use gradient:
div.box {
padding: 3px 6px;
display: inline-block;
position: relative;
background: linear-gradient(#000, #000) bottom/0% 2px no-repeat;
transition:1s all;
}
div.box:hover {
background-size: 100% 2px;
}
<div class="box">
<h1>Lorem Ipsum</h1>
</div>
I have 3 boxes that in a normal desktop viewport they display in an inline fashion. My issue is when in a 640 viewport or less I cannot get the boxes to display: block; . I have tried putting the display: block in the .box class and the individual color ids. What happens is the boxes overlap and lay on each other.
Does anyone see what I am doing wrong in my attempt?
<section id="info">
<article>
<a href="projects"><div id="green" class="box">
<div class="info-box-title">PROJECTS</div>
<div class="info-box-description">Over 60 years of accumulated projects.</div>
</div></a>
<a href="about"><div id="yellow" class="box">
<div class="info-box-title">ABOUT US</div>
<div class="info-box-description">Find out about - The Eslich Wrecking Company.</div>
</div></a>
<a href="contact"><div id="red" class="box">
<div class="info-box-title">CONTACT US</div>
<div class="info-box-description">Contact us for more information.</div>
</div></a>
</article>
</section>
Default CSS
#info {
max-width: 80%;
height: auto;
padding: 100px 10%;
margin: 100px 10%;
}
.box {
width: 20%;
height: 300px;
opacity:0;
position: absolute;
line-height: 1.5em;
}
#green, #yellow, #red {
box-shadow: inset 0 0 0 0;
-webkit-transition: all ease 0.3s;
-moz-transition: all ease 0.3s;
transition: all ease 0.3s;
}
#green {
background: #3e745b;
left: 15%;
}
#yellow {
background: #6f9697;/*#f3db6d*/
left: 40%;
}
#red {
background: #3e745b;
left: 65%;
}
#green:hover, #yellow:hover, #red:hover {
/*box-shadow: inset 0 300px 0 0 #6f9697;*/
box-shadow: inset 0 300px 0 0 #303030;
}
#green.green{animation:slideinGreen .5s ease}
#yellow.yellow{animation:slideinYellow 1.3s ease}
#red.red{animation:slideinRed 2s ease}
#green.active,#red.active,#yellow.active{opacity: 1}
#keyframes slideinGreen {
from {
left: calc(25% - 250px);opacity:0;
}
}
#keyframes slideinYellow{
from {
left: calc(45% - 350px);opacity:0;
}
}
#keyframes slideinRed {
from {
left: calc(65% - 450px);opacity:0;
}
}
Media query of 640px or less
/*---Fade In Boxes---*/
#info {
max-width: 100%;
height: auto;
padding: 100px 0%;
margin: 0;
}
.box {
width: 100%;
height: 200px;
position: absolute;
line-height: 1.5em;
display: block;
}
#green {
left: 0%;
}
#yellow {
left: 0%;
}
#red {
left: 0%;
}
Your absolute positioning on the box class is causing the issue. The elements are overlapping one another because of this.
Change position of .box to relative:
#media screen and (max-width: 640px) {
.box {
width: 100%;
height: 200px;
position: relative;
line-height: 1.5em;
display: block;
}
Because #home-info-container have padding: 100px 15%, 3 boxes can full width. If you want full with for 3 boxes, and keep padding ofdescription:
#media screen and (max-width: 640px) {
#home-info-container {
padding-left: 0;
padding-right: 0;
}
#home-info-container-description {
padding-left: 15%;
padding-right: 15%;
}
}
On a webpage I am working on, I have a div which contains an image and another div. The inner div is initially set to
opacity: 0;
so that it's not visible. The inner div should appear over my image when hovered. I have achieved this, but now I want to improve upon it further by having the 'overlay' div (which appears with an opacity of 0.5) slide down gradually over the image. I could do it theoretically with JavaScript but on this occasion it must be a pure CSS solution. So far my solution just makes the overlay div appear gradually (it fades in) but does not slide down as I have never done this in CSS alone.
See the image below to understand further:
The HTML:
<div class="img"> <img class="squareImg" src="img1.jpg"/><div class="overlay"> tweet This <br> Buy This</div></div>
<div class="img"> <img class="squareImg" src="img3.jpg"/></div>
<div class="img"> </img></div>
CSS
.overlay{
position: absolute;
width: 200px;
overflow-y: hidden;
transition-property: all;
transition-duration: .5s;
transition-timing-function: cubic-bezier(0, 1, 0.5, 1);
height: 200px;
background-color: red;
border: 1px solid white;
top: 10px;
left: 10px;
opacity: 0;
} .overlay:hover{
cursor:pointer;
opacity: 0.5;
z-index: 1;
}
.img{
position: relative;
margin-bottom: 10px;
border: 2px solid yellow;
background-color: black;
width: 200px;
height: 200px;
left: 50%;
margin-left: -110px;
padding: 10px;
}
Here it is with a slide down thanks to a height transition.
Improvements:
Instead of opacity, use background: rgba(255,0,0,0.5) so that the contents of the overlay remain fully opaque.
The transition property has been simplified to transition: all .5s
The outside border is created with box-shadow and the black border is now created with the border property instead of padding.
.overlay has a height of 0 and on hover it is given a height of 100%. It is stretched accross the image with the combination of left: 0 and right: 0
There is no set image size, the size of the <img> now controls the size of the border and overlay, allowing different image sizes.
Complete Example
.img {
position: relative;
border: 10px solid black;
box-shadow: 0 0 0 2px yellow;
display: inline-block;
vertical-align: top;
cursor: pointer;
margin: 10px;
}
.overlay {
position: absolute;
top: 0;
left: 0;
right: 0;
transition: all .5s;
overflow: hidden;
height: 0;
background: rgba(255, 0, 0, 0);
}
.img:hover .overlay,
.overlay:hover {
height: 100%;
background: rgba(255, 0, 0, 0.5);
}
.img > img {
display: block;/* Prevent inline gap under image*/
}
<div class="img">
<img src="http://www.placehold.it/200" />
<div class="overlay">tweet This <br>Buy This</div>
</div>
<div class="img">
<img src="http://www.placehold.it/300" />
<div class="overlay">tweet This <br>Buy This</div>
</div>
You can just use simple transitions for this, rather than a keyframe animation
Example:
http://jsfiddle.net/realseanp/c4e08hy7/9/
HTML:
<div class="holder">
<div class="info">
<span>All your info</span>
<div class="overlay"></div>
</div>
</div>
CSS:
.holder{
position:relative;
height:200px;
width: 200px;
overflow: hidden;
border:1px solid #000;
z-index:3;
}
.info {
box-sizing: border-box;
height: 100%;
padding: 20px;
position: absolute;
top: -100%;
transition: top 0.5s ease 0s;
width: 100%;
z-index: 4;
}
.overlay {
background: none repeat scroll 0 0 #000;
height: 100%;
left: 0;
opacity: 0;
position: absolute;
top: 0;
width: 100%;
z-index: -1;
transition: 1s all;
}
.holder:hover .info{
top:0;
}
.holder:hover .overlay{
opacity: .85
}
Just a simple approach using the image as background:
.img{
position: relative;
background: none 50% / cover;
width: 200px;
height: 200px;
margin: 0 auto;
border: 10px solid #000;
box-shadow: 0 0 0 2px yellow;
}
.overlay{
position: absolute;
width: 100%;
height: 0%;
overflow: hidden;
transition: all .5s cubic-bezier(0, 1, 0.5, 1);
box-shadow: inset 0 0 0 1px white;
background: rgba(255,0,0,0.4); /* Don't use opacity but rgba on bg */
}
.img:hover .overlay{
height: 100%;
}
<div class="img" style="background-image:url(//placehold.it/300x300/aba)">
<div class="overlay">Tweet This <br> Buy This</div>
</div>
If you need to slide it down, you should use #keyframes:
.overlay:hover{
-webkit-animation: slide 5s; /* Chrome, Safari, Opera */
animation: slide 5s;
}
#keyframes slide {
from {height: 0px;}
to {height: 200px;}
}
/* Chrome, Safari, Opera */
#-webkit-keyframes slide {
from {height: 0px;}
to {height: 200px;}
}
You can achieve this by setting the .overlay with a negative top position and then you can target the sibling element with the + selector and change the top position to positive.
Also you can change the transition timing by setting the transition-duration: 2s; to 2 sec.
.overlay{
position: absolute;
width: 200px;
overflow-y: hidden;
transition-property: all;
transition-duration: 2s;
transition-timing-function: cubic-bezier(0, 1, 0.5, 1);
height: 200px;
background-color: red;
border: 1px solid white;
top: -200px;
left: 10px;
opacity: 0;
z-index:-1;
}
.squareImg:hover + .overlay, .overlay:hover {
cursor:pointer;
top:10px;
opacity: 0.5;
z-index: 1;
}
.img{
position:relative;
height:200px;
width: 200px;
overflow: hidden;
border:1px solid #000;
z-index:3;
margin-bottom: 10px;
border: 2px solid yellow;
background-color: black;
left: 50%;
margin-left: -110px;
padding: 10px;
}
DEMO http://jsfiddle.net/a_incarnati/c4e08hy7/8/
Does anybody know how to algin a line under my text automatically to all?
here is my animation
<div class="line"><div>behance.net</div>
</div>
<br>
<div class="line"><div>google.pl</div>
</div>
<br>
<div class="line"><div>twitter.com</div>
</div></br>
CSS
.line{
font-family:Tahoma;
width:0px;
position: absolute;
background:black;
transition:width 0.4s ease ;
}
div:hover{
position: absolute;
width:86px;
}
.line div{
background:#fff;
position:relative;
bottom:1px;
}
In the first example, everything works fine, the width of line is ok, but in other no.
You can try this - DEMO
HTML
<div class="line">behance.net <span></span></div> <br />
<div class="line">google.pl <span></span></div> <br />
<div class="line">twitter.com <span></span></div> <br />
CSS
.line {
font: 400 1em Tahoma;
margin: 5px;
display: inline-block;
overflow: hidden;
padding: 2px 0;
position: relative;
}
.line span {
display: block;
position: absolute;
left: -90px;
bottom: 1px;
height: 1px;
width: 100%;
background: #c00;
-webkit-transition: all .4s;
}
.line:hover span {
left: 0;
}
Another solution with less markup:
demo
<div class='line'>behance.net</div><br>
<div class='line'>google.pl</div><br>
<div class='line'>twitter.com</div><br>
CSS:
.line {
display: inline-block;
position: relative;
background-position: -85px 0;
transition: 1s;
cursor: pointer;
}
.line:before {
position: absolute;
right: 0; top: 0; bottom: 0; left: 0;
background: linear-gradient(0deg, crimson 1px, transparent 1px) no-repeat;
background-position: inherit;
background-size: 100% 100%;
color: transparent;
content: '';
}
.line:hover { background-position: 0 0; }
Note:
My demo uses -prefix-free which adds prefixes as needed. WebKit browsers still need prefixes for transitions and gradients. You'll have to add these yourself in your code. When you do, please remember to always put the unprefixed ones last!