I have square navigation buttons where I want to visually show which are active, for example using:
At the moment I use background: linear-gradient for this purpose. This however is hard to animate and I therefore am looking for alternatives. The HTML structures looks like:
<div class='navigation-button'>
<div class='navigation-button-container'>
<i class='fa fa-bars'></i>
</div>
</div>
with corresponding CSS:
.navigation-button {
width: 50px;
height: 50px;
background: purple;
}
.navigation-button-container {
width: 100%;
height: 100%;
text-align: center;
}
.navigation-button-container i {
margin-top: 25%;
margin-bottom: 25%;
color: white;
}
.active {
background: linear-gradient(right, blue 0%, blue 10%, rgba(0,0,0,0) 10%);
}
The active class can be applied to the navigation-button-container to get the desired effect. I want to however fade this in and out and as I understand linear-gradients cannot be animated.
I have looked in adding a element before the navigation-button-container and animate it's width and using the CSS ::before syntax but neither seemed to be of help. Is there an efficient CSS way to get the desired effect using #keyframes or transition?
Is this what you needed? There is a ::before pseudo-element on .nb-container which has a width transition.
.nb {
background-color: #f00;
display: block;
height: 50px;
width: 50px;
}
.nb-container {
width: 100%;
height: 100%;
position: relative;
text-align: center;
}
.nb-container i {
color: white;
display: inline-block;
margin: 25% 0 25%;
}
.nb-container ::before {
background-color: #00f;
content: "";
display: block;
height: 100%;
left: 0;
position: absolute;
top: 0;
transition: width .2s;
width: 0;
}
.nb-container:hover ::before, .nb-container:focus ::before {
width: 20%;
}
Mouse over the elements to see the effect:
<div class="nb">
<div class="nb-container">
<i class="fa fa-bars">∆</i>
</div>
</div>
<div class="nb">
<div class="nb-container">
<i class="fa fa-bars">®</i>
</div>
</div>
<div class="nb">
<div class="nb-container">
<i class="fa fa-bars">©</i>
</div>
</div>
The ::before element is very versatile in the way it can be animated. So if you wanted a fade-in instead of a slide-in:
.nb {
background-color: #f00;
display: block;
height: 50px;
width: 50px;
}
.nb-container {
width: 100%;
height: 100%;
position: relative;
text-align: center;
}
.nb-container i {
color: white;
display: inline-block;
margin: 25% 0 25%;
}
.nb-container ::before {
background-color: #00f;
content: "";
display: block;
height: 100%;
left: 0;
opacity: 0;
position: absolute;
top: 0;
transition: opacity .2s;
width: 20%;
}
.nb-container:hover ::before, .nb-container:focus ::before {
opacity: 1;
}
Mouse over the elements to see the effect:
<div class="nb">
<div class="nb-container">
<i class="fa fa-bars">∆</i>
</div>
</div>
<div class="nb">
<div class="nb-container">
<i class="fa fa-bars">®</i>
</div>
</div>
<div class="nb">
<div class="nb-container">
<i class="fa fa-bars">©</i>
</div>
</div>
Related
I've been trying to make a square image that is layered behind a <div>. For my website, I'm trying to make it look similar to an album with a CD popping out from the slip, but every attempt I've done to make the image square, layered behind and the same size as the <div> seems to not work. It's either on top, or it's overflowing to the bottom of the page.
Here's the HTML I did:
<div class="container">
<div id="navbar">
<div id="nav">
<div>
<i class="fa fa-home" aria-hidden="true"></i>Home
</div>
<div>
<i class="fa fa-address-book" aria-hidden="true"></i>About
</div>
<div>
<i class="fa fa-book" aria-hidden="true"></i>Work
</div>
<div>
<i class="fa fa-question-circle" aria-hidden="true"></i>Extras
</div>
</div>
</div>
<iframe src="home.html" title="Webpage" id="content" name="content"></iframe>
</div>
</div>
<div class="disk">
<img src="/images/cd.svg">
</div>
And the CSS:
:root { /* to get the color just type var(--color) */
--color1:#150F0F; /*DARKEST*/
--color2:#221918;
--color3:#2C221F;
--color4:#423229;
--color5:#58493D;
--color6:#8D7357;
--color7:#BCAA9B;
--color8:#BCAA9B;
--color9:#F5DEAD;
--color10:#FFF9BC; /*BRIGHTEST*/
--border-size:3px;
}
.container {
min-height: 50vh;
width: 70%;
margin: auto;
margin-left:10%;
display: grid;
grid-template-columns: minmax(2vw, 260px) auto;
background-color: var(--color9);
border: 0px;
border-style: solid;
border-top-width: var(--border-size);
border-bottom-width: var(--border-size);
border-color: var(--color10);
z-index: 69;
}
#navbar {
height: auto;
width: auto;
padding: 10%;
float: left;
background-color: var(--color7);
font-family: PopMagic;
font-size: clamp(15px, 4vw, 30px);
}
#content {
height: 100%;
width: 100%;
border:none;
}
.disk {
min-height: 50vh;
max-width: 85%;
margin: auto;
margin-left:10%;
margin-top: -50vh;
position:relative;
overflow:hidden;
padding-bottom:100%;
}
.disk img {
min-height: 50vh;
position: absolute;
}
The site I'm using this on can be found here.
As you may expect there are as many approaches as developers.
You should consider how your layout is constructed at the moment because there is simply not enough space for your disc element.
If I were you I would get rid the following div
<div class="disk">
<img src="/images/cd.svg">
</div>
and try to use ::after psuedo-element instead.
...
.container {
border: none;
position: relative;
padding: 0 160px 0 0;
background-color: #0000;
::after {
right: 0;
content: '';
width: 160px;
height: 100%;
position: absolute;
background-size: cover;
background-position: right;
background-repeat: no-repeat;
background-image: url(/images/cd.svg);
}
}
...
Please don't expect the final solution here but take above code as a bunch of clues which may help to solve your problem.
How can I recreate GitHub's repositories language list using CSS only? Something like this, for example:
I started with a list of divs but I cannot figure out how to draw the dots using CSS...
<div>
<div>C 90%</div>
<div>Assembly 5.8%</div>
<div>Makefile 2.9%</div>
<div>C++ 0.5%</div>
</div>
You can use ::before pseudo element to add the dots before each item.
https://developer.mozilla.org/en-US/docs/Web/CSS/::before
Something like this:
div > div {
position: relative;
margin-left: 10px;
}
div > div:before {
content: '';
position: absolute;
height: 5px;
width: 5px;
right: 100%;
margin-right: 5px;
top: calc(50% - 2.5px);
border-radius: 2px;
background: red;
}
<div>
<div>C 90%</div>
<div>Assembly 5.8%</div>
<div>Makefile 2.9%</div>
<div>C++ 0.5%</div>
</div>
Okay I managed to do something similar:
<div class="rows">
<div class="dot" style="color: #555555;"></div>
<div class="child">C 90%</div>
</div>
<div class="rows">
<div class="dot" style="color: #6E4C13;"></div>
<div class="child">Assembly 5.8%</div>
</div>
<div class="rows">
<div class="dot" style="color: #427819;"></div>
<div class="child">Makefile 2.9%</div>
</div>
.rows {
text-align: center;
display: inline-block;
vertical-align: middle;
margin-right: 10px;
}
.dot, .child {
vertical-align: middle;
display: inline-block;
}
.rows > .dot {
position: relative;
margin-left: 10px;
margin-bottom: 10px;
}
.rows > .dot:before {
content: '';
position: absolute;
height: 10px;
width: 10px;
right: 100%;
margin-right: 5px;
top: 20%;
border-radius: 10px;
background-color: currentColor;
}
The dot colour is managed from the style attribute. The last thing left to do is to change the font of the language name(e.g. Assembly) and of the percentage(e.g. 5.8%), after that result is very similar to GitHub's.
I am trying to bring some hidden text into view when a radio checkbox is checked. I cant quite work out why the :checked styling is not applying once the label is checked. I think i am being really daft but just cant work out what is going on.
Could anyone lend some advice?
.wrap__wrapper {
width: 400px;
margin: 0 auto;
}
.wrap {
position: relative;
overflow: hidden;
}
.wrap__radio--input {
display: none;
}
.wrap__inner {
width: 300%;
left: 0;
transition: all 1s;
}
.wrap__slides {
float: left;
width: 33.333%;
}
.wrap__text {
font-size: 16px;
text-align: center;
}
.wrap__button {
font-size: 1.8rem;
cursor: pointer;
text-align: center;
display: block;
}
.wrap__radio--input:checked~.wrap__inner {
transition: all 1s;
background: red;
left: -100%;
}
<div class="wrap__wrapper">
<div class="wrap">
<input type="radio" class="wrap__radio--input" id="slide--1">
<label for="slide--1" class="wrap__button">next slide</label>
<div class="wrap__inner">
<div class="wrap__slides">
<p class="wrap__text">slide1</p>
</div>
<div class="wrap__slides">
<p class="wrap__text">slide2</p>
</div>
</div>
</div>
</div>
Your element need to be positionned so you have to set position property to relative, absolute or fixed on .wrap__inner to be able to use left property. You cannot update position of static element.
.wrap__wrapper {
width: 400px;
margin: 0 auto;
}
.wrap {
position: relative;
overflow: hidden;
}
.wrap__radio--input {
display: none;
}
.wrap__inner {
position:relative;
width: 300%;
left: 0;
transition: all 1s;
}
.wrap__slides {
float: left;
width: 33.333%;
}
.wrap__text {
font-size: 16px;
text-align: center;
}
.wrap__button {
font-size: 1.8rem;
cursor: pointer;
text-align: center;
display: block;
}
.wrap__radio--input:checked~.wrap__inner {
transition: all 1s;
background: red;
left: -100%;
}
<div class="wrap__wrapper">
<div class="wrap">
<input type="radio" class="wrap__radio--input" id="slide--1">
<label for="slide--1" class="wrap__button">next slide</label>
<div class="wrap__inner">
<div class="wrap__slides">
<p class="wrap__text">slide1</p>
</div>
<div class="wrap__slides">
<p class="wrap__text">slide2</p>
</div>
<div class="wrap__slides">
<p class="wrap__text">slide3</p>
</div>
</div>
</div>
</div>
You can use the :before or :after pseudo-elements to toggle the previous and next text, apply the position property different from the default value of static to the .wrap__inner div and most importantly change the input type="radio" to input type="checkbox" to be able to toggle the checkbox state:
.wrap__wrapper {
width: 400px;
margin: 0 auto;
}
.wrap {
position: relative;
overflow: hidden;
}
.wrap__radio--input {
display: none;
}
.wrap__inner {
position: relative; /* any value other than default */
width: 300%;
left: 0;
transition: all 1s;
}
.wrap__slides {
float: left;
width: 33.333%;
}
.wrap__text {
font-size: 16px;
text-align: center;
}
.wrap__button {
font-size: 1.8rem;
cursor: pointer;
text-align: center;
display: block;
}
/* added */
.wrap__button:after {
content: "next";
}
.wrap__radio--input:checked + .wrap__button:after {
content: "previous";
}
/***/
.wrap__radio--input:checked ~ .wrap__inner {
transition: all 1s;
background: red;
left: -100%;
}
<div class="wrap__wrapper">
<div class="wrap">
<input type="checkbox" class="wrap__radio--input" id="slide--1">
<label for="slide--1" class="wrap__button"></label>
<div class="wrap__inner">
<div class="wrap__slides">
<p class="wrap__text">slide1</p>
</div>
<div class="wrap__slides">
<p class="wrap__text">slide2</p>
</div>
</div>
</div>
</div>
Note: Like I wrote in the comment, this only works for two slides.
I've 2 problems with the following snippet, I would like that on hover all the circles stay on the same line, they are "simply" pushed on the side.
But I'm struggling, it only seems they are going to the bottom when one of the circle is scaling..
Then, I'm trying to have them as close as possible, maybe because it's not aline, but they don't stick together on resize. And the text move too far away :O
I've seen the scaling option but I can't make it work here. So I'm only using the font-size.
I'm really not good with animations, if someone could give me clues or help me with that I would be grateful!
.bubble {
display: inline-block;
position: relative;
margin-right: -17px;
}
.bubble p {
font-size: 12px;
text-align: center;
color: rgba(100, 110, 115, 0.6);
}
.circle:before {
content: ' \25CF';
font-size: 80px;
transition: font 0.5s ease;
transform-origin: 0 0
}
.label-top {
position: absolute;
top: 10px;
left: 0;
right: 0;
}
.label-bottom {
position: absolute;
bottom: 3px;
left: 0;
right: 0;
}
.circle.blue:before {
color: #306BCE;
}
.circle.azure:before {
color: #05CDF9;
}
.circle.yellow:before {
color: #EEFB11;
}
.circle.red:before {
color: red;
}
.circle.bordeau:before {
color: #C90035;
}
.circle.purple:before {
color: #832A50;
}
.circle.brown:before {
color: #6C000C;
}
.circle:hover:before {
font-size: 200px;
}
<div>
<div class="bubble">
<span class="circle blue"></span>
<p class="label-bottom">Honesty</p>
</div>
<div class="bubble">
<p class="label-top">Confidence</p>
<span class="circle azure"></span>
</div>
<div class="bubble">
<span class="circle yellow"></span>
<p class="label-bottom">Curiosity</p>
</div>
<div class="bubble">
<p class="label-top">Passion</p>
<span class="circle red"></span>
</div>
<div class="bubble">
<span class="circle bordeau"></span>
<p class="label-bottom">Judging</p>
</div>
<div class="bubble">
<p class="label-top">Disagree</p>
<span class="circle purple"></span>
</div>
<div class="bubble">
<span class="circle brown"></span>
<p class="label-bottom">Nervousness</p>
</div>
</div>
As what #CBroe has pointed out, you are using a font glyph as the circle. By changing its font size, you are changing the line-height and that will mess up the vertical positioning of all elements in the row. The trick is to use pseudo-elements to create the circles instead, and position the circles absolutely. Once that is done, you can use transform: scale(...) to scale up the circles, without affecting the layout of surrounding elements.
I have also made some changes to your code:
Using display: flex to align your bubble elements. You may also use float: left on the bubble elements, but flexbox is quite widely supported today.
Do not set the transform origin, because it defaults to center center anyway :)
.bubble-wrapper {
display: flex;
}
.bubble {
position: relative;
width: 40px;
height: 90px;
}
.bubble p {
font-size: 12px;
text-align: center;
color: rgba(100, 110, 115, 0.6);
}
.circle {
display: block;
width: 40px;
height: 40px;
}
.circle:before {
display: block;
width: 40px;
height: 40px;
border-radius: 50%;
content: ' ';
transition: all 0.5s ease;
position: absolute;
top: 25px;
}
.label-top {
position: absolute;
top: 0px;
left: 0;
right: 0;
}
.label-bottom {
position: absolute;
bottom: 0;
left: 0;
right: 0;
}
.circle.blue:before {
background-color: #306BCE;
}
.circle.azure:before {
background-color: #05CDF9;
}
.circle.yellow:before {
background-color: #EEFB11;
}
.circle.red:before {
background-color: red;
}
.circle.bordeau:before {
background-color: #C90035;
}
.circle.purple:before {
background-color: #832A50;
}
.circle.brown:before {
background-color: #6C000C;
}
.circle:hover:before {
transform: scale(2.5);
}
<div class="bubble-wrapper">
<div class="bubble">
<span class="circle blue"></span>
<p class="label-bottom">Honesty</p>
</div>
<div class="bubble">
<p class="label-top">Confidence</p>
<span class="circle azure"></span>
</div>
<div class="bubble">
<span class="circle yellow"></span>
<p class="label-bottom">Curiosity</p>
</div>
<div class="bubble">
<p class="label-top">Passion</p>
<span class="circle red"></span>
</div>
<div class="bubble">
<span class="circle bordeau"></span>
<p class="label-bottom">Judging</p>
</div>
<div class="bubble">
<p class="label-top">Disagree</p>
<span class="circle purple"></span>
</div>
<div class="bubble">
<span class="circle brown"></span>
<p class="label-bottom">Nervousness</p>
</div>
</div>
Update: If you want the width of the element to expand on hover, that is also possible. However, I also suggest that you can simplify your markup: basically we can make do without the circle div:
.bubble-wrapper {
display: flex;
}
.bubble {
position: relative;
width: 40px;
height: 90px;
transition: all 0.5s ease;
}
.bubble p {
font-size: 12px;
text-align: center;
color: rgba(100, 110, 115, 0.6);
}
.bubble:before {
display: block;
width: 40px;
height: 40px;
border-radius: 50%;
content: ' ';
transition: all 0.5s ease;
position: absolute;
top: 25px;
left: 50%;
transform: translateX(-50%);
}
.label-top {
position: absolute;
top: 0px;
left: 0;
right: 0;
}
.label-bottom {
position: absolute;
bottom: 0;
left: 0;
right: 0;
}
.bubble.blue:before {
background-color: #306BCE;
}
.bubble.azure:before {
background-color: #05CDF9;
}
.bubble.yellow:before {
background-color: #EEFB11;
}
.bubble.red:before {
background-color: red;
}
.bubble.bordeau:before {
background-color: #C90035;
}
.bubble.purple:before {
background-color: #832A50;
}
.bubble.brown:before {
background-color: #6C000C;
}
.bubble:hover {
width: calc(40px * 2.5);
}
.bubble:hover:before {
transform: translateX(-50%) scale(2.5);
}
<div class="bubble-wrapper">
<div class="bubble blue">
<p class="label-bottom">Honesty</p>
</div>
<div class="bubble azure">
<p class="label-top">Confidence</p>
</div>
<div class="bubble yellow">
<p class="label-bottom">Curiosity</p>
</div>
<div class="bubble red">
<p class="label-top">Passion</p>
</div>
<div class="bubble bordeau">
<p class="label-bottom">Judging</p>
</div>
<div class="bubble purple">
<p class="label-top">Disagree</p>
</div>
<div class="bubble brown">
<p class="label-bottom">Nervousness</p>
</div>
</div>
I've used #Terry's excellent answer as the base to mine.
The main difference is that you don't need the pseudo elements. Just transform: scale() (transforms don't effect the layout) the hovered elements, and give it z-index: 1 if you want to bring them to the top.
.bubble-wrapper {
display: flex;
}
.bubble {
position: relative;
width: 40px;
height: 90px;
}
.bubble p {
font-size: 12px;
text-align: center;
color: rgba(100, 110, 115, 0.6);
}
.circle {
display: block;
position: relative;
width: 40x;
height: 40px;
border-radius: 50%;
content: ' ';
transition: all 0.5s ease;
}
.label-top {
position: absolute;
top: -40px;
left: 0;
right: 0;
}
.label-bottom {
position: absolute;
bottom: 0;
left: 0;
right: 0;
}
.circle.blue {
background-color: #306BCE;
}
.circle.azure {
background-color: #05CDF9;
}
.circle.yellow {
background-color: #EEFB11;
}
.circle.red {
background-color: red;
}
.circle.bordeau {
background-color: #C90035;
}
.circle.purple {
background-color: #832A50;
}
.circle.brown {
background-color: #6C000C;
}
.circle:hover {
z-index: 1;
transform: scale(2.5);
}
body {
padding: 40px;
}
<div class="bubble-wrapper">
<div class="bubble">
<span class="circle blue"></span>
<p class="label-bottom">Honesty</p>
</div>
<div class="bubble">
<p class="label-top">Confidence</p>
<span class="circle azure"></span>
</div>
<div class="bubble">
<span class="circle yellow"></span>
<p class="label-bottom">Curiosity</p>
</div>
<div class="bubble">
<p class="label-top">Passion</p>
<span class="circle red"></span>
</div>
<div class="bubble">
<span class="circle bordeau"></span>
<p class="label-bottom">Judging</p>
</div>
<div class="bubble">
<p class="label-top">Disagree</p>
<span class="circle purple"></span>
</div>
<div class="bubble">
<span class="circle brown"></span>
<p class="label-bottom">Nervousness</p>
</div>
</div>
.bubble {
display: inline-block;
position: relative;
/* margin-right: -17px; */
vertical-align: middle;
}
.circle:hover:before {
/* font-size: 200px; */
width: 100px;
height: 100px;
}
.circle.blue:before {
background: #306BCE;
/* width: 50px; */
/* height: 50px; */
/* display: block; */
}
.circle:before {
content: '';
font-size: 80px;
transition: font 0.5s ease;
transform-origin: 0 0;
width: 50px;
height: 50px;
display: block;
border-radius: 50%;
background: red;
}
I have a small bug that I can't seem to locate. In my snippet you can see how whenever you hover over the image, opactiy and an image scale takes place, as well as a box comes over the image. That is perfect, but my issue is whenever you hover over the text below it, the hover effect takes place over the image.
I can't seem to figure out how for the hover effect to only take place when the mouse is hovering over the image.
Any suggestions would be appreciated.
$('.home-img-block img').addClass(function() {
return (this.width / this.height > 1) ? 'wide' : 'tall';
});
#home-img-block-section {
width: 100%;
height: 900px;
}
#home-img-blocks {
width: 100%;
height: 750px;
}
.home-img-block {
width: 33.33%;
float: left;
display: block;
overflow: hidden;
position: relative;
}
.home-img-container {
position: relative;
overflow: hidden;
cursor: pointer;
}
.home-img-block:hover .overlay {
background: rgba(0, 0, 0, 0.6);
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
}
.home-img-container:after {
content: attr(data-content);
color: #fff;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
opacity: 0;
transition: all 0.5s;
border: 1px solid #fff;
padding: 20px 25px;
text-align: center;
}
.home-img-container:hover:after {
opacity: 1;
}
.home-img-block img {
display: block;
transition: all 1s ease;
}
.home-img-block:hover img {
transform: scale(1.25);
background: rgba(0, 0, 0, 0.3);
width: 33.33%;
max-height: 100%;
overflow: hidden;
}
.home-img-block img.wide {
max-width: 100%;
max-height: 100%;
height: auto;
width: 100%;
}
.home-img-block img.tall {
max-width: 100%;
max-height: 100%;
width: auto;
}
#home-img-block-wording-container {
width: 100%;
height: 300px;
}
.home-img-wording-blocks {
width: 100%;
height: 100%;
text-align: center;
display: inline-block;
vertical-align: top;
}
.home-img-wording-block-title {
padding-top: 30px;
font-size: 1.7em;
}
.home-img-wording-block-description {
padding: 25px 50px 0 50px;
font-size: 1.1em;
color: #5d5d5d;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="home-img-block-section">
<div id="home-img-blocks">
<div class="home-img-block fadeBlock1">
<div data-content="FIND OUT MORE" class='home-img-container'>
<img src="http://optimumwebdesigns.com/images/test1.jpg">
<div class="overlay"></div>
</div>
<div class="home-img-wording-blocks">
<div class="home-img-wording-block-title">WEB DESIGN</div>
<div class="home-img-wording-block-description">The OD team can see your web design visions brought
to life, creating a site that promotes your uniqueness through specific functionalities and features.</div>
</div>
</div>
<div class="home-img-block fadeBlock2">
<div data-content="FIND OUT MORE" class='home-img-container'>
<img src="http://optimumwebdesigns.com/images/test2new.jpg">
<div class="overlay"></div>
</div>
<div class="home-img-wording-blocks">
<div class="home-img-wording-block-title">ECOMMERCE</div>
<div class="home-img-wording-block-description">Custom built solutions catered towards you end goal.
gfdgfdsg greg reg regrfesg fdsg gretswtgy tgreswt treswt trgegfd gsvbd fbgre greasgv drfdg greaag gredr</div>
</div>
</div>
<div class="home-img-block fadeBlock3">
<div data-content="FIND OUT MORE" class='home-img-container'>
<img src="http://optimumwebdesigns.com/images/test3new.jpg">
<div class="overlay"></div>
</div>
<div class="home-img-wording-blocks">
<div class="home-img-wording-block-title">MARKETING STRATEGIES</div>
<div class="home-img-wording-block-description">MARKETING STRATEGIES gfdgf fdggs gfsg gfsg gf sgf g
gfdsg sdfggfs gfdsgssdfg fdggfds gfdsg gfds gfdgs gf dsgfdsgfgs gfdgfs gtrg resg reg rgesgresrgrg</div>
</div>
</div>
</div>
</div>
.home-img-block:hover .overlay
and
.home-img-block:hover img
replace them with
.home-img-container:hover .overlay
.home-img-container:hover img
otherwise you're triggering when you hover over the whole container instead of only wheen hovering the img one.