How do I stop an pseudo element from being affected by parents hover?
.list-item {
position: absolute;
background: black;
color: white;
padding: 10px 20px;
transition: all 250ms ease-in-out;
}
.list-item:hover {
transform: scale(1.5);
}
.list-item:after {
content: '';
position: absolute;
width: 20px;
height: 20px;
background: orange;
z-index: 10;
border-radius: 100%;
}
<div class="list-item">
test
</div>
When hovering it applies all hover effects to :after pseudo element
One method can be to apply an opposing transition to the ::after pseudo element:
.list-item:hover {
transform: scale(1.5);
}
.list-item:hover::after {
/* transform: scale(calc(1 - (your main scale amount - 1) / 2)); */
transform: scale(0.75);
}
Related
Here is the html:
<div class="card">
<!-- First child -->
<div class="card__side">
Front
</div>
<!-- Last child -->
<div class="card__side--back-1">
Back
</div>
</div>
and here is the scss code:
.card {
perspective: 150rem;
position: relative;
height: 50rem;
&:hover &__side {
&:first-child {
transform: rotateY(180deg);
}
&:last-child {
transform: rotateY(0deg);
}
}
[class*="card__side"] {
font-size: 2rem;
height: 50rem;
transition: all .8s ease;
position: absolute;
width: 100%;
backface-visibility: hidden;
&:first-child {
background-color: $color-white;
}
&:last-child {
background-color: $color-white;
transform: rotateY(180deg);
}
}
}
when I use the class name card__side--back-1, the selector [class*="card__side"] is working but the selector :last-child is not working,
however when I change the class name to card__side for both of the divs, it works.
I know I can give different classes for the task but asking to learn the main reason behind this. This is my first post so I hope I am making it right. Thanks in advance.
when I change the class name to card__side for both of the divs, it works.
I've solved it, the selectors work fine now.
the problem was at the &:hover &__sideselector at line 5.
I've changed the 5th line of the scss code to &:hover [class*="card__side"] now it selects.
.card {
perspective: 150rem;
position: relative;
height: 50rem;
&:hover [class*="card__side"] {
&:first-child {
transform: rotateY(180deg);
}
&:last-child {
transform: rotateY(0deg);
}
}
[class*="card__side"] {
font-size: 2rem;
height: 50rem;
transition: all .8s ease;
position: absolute;
width: 100%;
backface-visibility: hidden;
&:first-child {
background-color: $color-white;
}
&:last-child {
background-color: $color-white;
transform: rotateY(180deg);
}
}
}
I'm trying to make line moving infinitely but the problem that the line back for another loop late.. I want it to be in the left immediately when the line off screen
*{
margin: 0;
padding: 0;
box-sizing: border-box;
}
body{
background-color: #222;
color: #fff;
}
.navbar{
padding: 2rem;
position: relative;
}
.navbar span{
position: absolute;
bottom: 0;
left: 0;
height: 2px;
width: 100px;
background-color: #fff;
animation: animate 6s linear infinite;
}
#keyframes animate {
0%{
left: -100%;
}
50%,100%{
left: 100%;
}
}
<nav class="navbar">
<span></span>
</nav>
You can use a combination of positioning in relation to the parent - left property - and relative positioning (relative to the width of the line itself) - transform: translateX property.
So the line starts at minus its own width and ends at the width of the parent (as you have now) with no translation.
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
background-color: #222;
color: #fff;
}
.navbar {
padding: 2rem;
position: relative;
overflow: hidden;
}
.navbar span {
position: absolute;
bottom: 0;
left: 0;
height: 2px;
width: 100px;
background-color: #fff;
animation: animate 6s linear infinite;
}
#keyframes animate {
0% {
left: 0;
transform: translate(-100%);
}
100% {
left: 100%;
transform: translate(0);
}
}
<nav class="navbar">
<span></span>
</nav>
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<style>
*{
margin: 0;
padding: 0;
box-sizing: border-box;
}
body{
background-color: #222;
color: #fff;
}
.navbar{
padding: 2rem;
position: relative;
width: 100%;
animation: animate 6s linear infinite;
}
.navbar span{
position: absolute;
bottom: 0;
left: 0;
height: 2px;
width: 100px;
background-color: #fff;
}
#keyframes animate {
0% {
transform: translateX(0%);
}
100% {
transform: translateX(100%);
}
}
</style>
</head>
<body>
<nav class="navbar">
<span></span>
</nav>
</body>
</html>
So I'm going to explain what I did here. It's a combination of Keyframes and the transform - translate in CSS. Now, if you used animation alone to try to move from left to left, you'll notice a default delay from the end of one keyframe to the other, especially since you're not moving along the corners of the .navbar box (topleft-topright-bottomright-bottom-left and repeat). Using the animation-delay property will not solve it either. There are two options, using CSS Flex-box property and using Transforms. Since you are working with keyframes, I made use of the transforms-translate property.
The issue with transform - translate, is that translate will move the element with respect to the width of itself. Hence, having the animation within .navbar span and setting translate for keyframe 100% will only move the element to the end of the width of the element which in this case is 100px. To go around this, we will set the animation property to the parent box itself and translate the child from 0% to 100%.
I'm stuck on :hover doesn't work. I suspect the absolute and float position but don't have any clear idea. I'm a beginner user of Sass and the css animation. Any help ?
.menus {
cursor: pointer;
&:hover >.box {
transform: scale(0) translateX(300px);
.check {
transform: rotate(0deg);
}
}
}
.box {
float: right;
position: absolute;
top: 0;
right: 0;
width: 20%;
height: 100%;
background-color: yellow;
border-radius: 4px;
color: green;
transform: scale(1) translateX(0);
transition: transform 330ms ease-in-out;
.check {
display: block;
float: right;
position: absolute;
right: 30%;
top: 35%;
transform: rotate(-360deg);
transition: transform 500ms ease-in-out;
}
}
<div class="restaurants menus">
<div class="box"><img class="check" src="img/check24.png" alt="#"></div>
<h3>Citrus Squid Carpaccio</h3>
<p>with orange zest</p>
<img class="heart " src="img/heart-30.png" alt="#">
</div>
The problem lies here :
.menus {
cursor: pointer;
&:hover + .box {
Your selector &:hover + .box selects the .box elements that are siblings of .menus, and not children. You can use &:hover .box if you want to select all boxes children and grand children of .menus, or &:hover>.box to select direct .box children.
Here's a link with all the css selector that might be useful in the future: https://www.w3schools.com/cssref/css_selectors.asp
I have been looking for a slide in the menu for mobile in bootstrap, the closest that I could get is this one https://codepen.io/erikterwan/pen/EVzeRP , But I can't make it open from right to left and have the hamburger in the bottom right, any ideas?.
This will be little tricky because the creator writes:
Too bad the menu has to be inside of the button
but hey, it's pure CSS magic.
The code to add is
/*
* This move all the navbar to right because the ul is inside the button
*/
#menuToggle{
position:fixed;
left: calc(100vw - 70px);
top:calc(100vh - 50px);
}
/*
* This will position the menu
*/
#menu{
top: calc(-100vh + 50px);
left: 70px;
margin: 0;
margin-top: -100px;
height: 100vh;
}
/*
* Fade menu from the right
*/
#menuToggle input:checked ~ ul
{
transform: translate(-100%, 0);
opacity: 1;
}
/*
* Correct the overflow
*/
html{
max-width: 100vw;
overflow-x: hidden;
}
/*
* Made by Erik Terwan
* 24th of November 2015
* All rights reserved
*
* Modified by Alessandro Lodi
* 5th of August 2017
*
* If you are thinking of using this in
* production code, beware of the browser
* prefixes.
*/
body
{
margin: 0;
padding: 0;
/* make it look decent enough */
background: #232323;
color: #cdcdcd;
font-family: "Avenir Next", "Avenir", sans-serif;
}
a
{
text-decoration: none;
color: #232323;
transition: color 0.3s ease;
}
a:hover
{
color: tomato;
}
#menuToggle
{
display: block;
position: relative;
top: 50px;
left: 50px;
z-index: 1;
-webkit-user-select: none;
user-select: none;
}
#menuToggle input
{
display: block;
width: 40px;
height: 32px;
position: absolute;
top: -7px;
left: -5px;
cursor: pointer;
opacity: 0; /* hide this */
z-index: 2; /* and place it over the hamburger */
-webkit-touch-callout: none;
}
/*
* Just a quick hamburger
*/
#menuToggle span
{
display: block;
width: 33px;
height: 4px;
margin-bottom: 5px;
position: relative;
background: #cdcdcd;
border-radius: 3px;
z-index: 1;
transform-origin: 4px 0px;
transition: transform 0.5s cubic-bezier(0.77,0.2,0.05,1.0),
background 0.5s cubic-bezier(0.77,0.2,0.05,1.0),
opacity 0.55s ease;
}
#menuToggle span:first-child
{
transform-origin: 0% 0%;
}
#menuToggle span:nth-last-child(2)
{
transform-origin: 0% 100%;
}
/*
* Transform all the slices of hamburger
* into a crossmark.
*/
#menuToggle input:checked ~ span
{
opacity: 1;
transform: rotate(45deg) translate(-2px, -1px);
background: #232323;
}
/*
* But let's hide the middle one.
*/
#menuToggle input:checked ~ span:nth-last-child(3)
{
opacity: 0;
transform: rotate(0deg) scale(0.2, 0.2);
}
/*
* Ohyeah and the last one should go the other direction
*/
#menuToggle input:checked ~ span:nth-last-child(2)
{
opacity: 1;
transform: rotate(-45deg) translate(0, -1px);
}
/*
* Make this absolute positioned
* at the top left of the screen
*/
#menu
{
position: absolute;
width: 250px;
margin: -100px 0 0 -50px;
padding: 50px;
padding-top: 125px;
background: #ededed;
list-style-type: none;
-webkit-font-smoothing: antialiased;
/* to stop flickering of text in safari */
transform-origin: 0% 0%;
//transform: translate(-100%, 0);
transition: transform 0.5s cubic-bezier(0.77,0.2,0.05,1.0);
}
#menu li
{
padding: 10px 0;
font-size: 22px;
}
/*
* And let's fade it in from the left
*/
#menuToggle input:checked ~ ul
{
transform: translate(-100%, 0);
opacity: 1;
}
#menuToggle{
position:fixed;
left: calc(100vw - 70px);
top:calc(100vh - 50px);
}
#menu{
top: calc(-100vh + 50px);
left: 70px;
margin: 0;
margin-top: -100px;
height: 100vh;
}
html{
max-width: 100vw;
overflow-x: hidden;
}
<nav role="navigation">
<div id="menuToggle">
<!--
A fake / hidden checkbox is used as click reciever,
so you can use the :checked selector on it.
-->
<input type="checkbox" />
<!--
Some spans to act as a hamburger.
They are acting like a real hamburger,
not that McDonalds stuff.
-->
<span></span>
<span></span>
<span></span>
<!--
Too bad the menu has to be inside of the button
but hey, it's pure CSS magic.
-->
<ul id="menu">
<li>Home</li>
<li>About</li>
<li>Info</li>
<li>Contact</li>
<li>Show me more</li>
</ul>
</div>
</nav>
I got a pseudo-element that marks the user's current choice in a navigation bar. It's a small upward triangle, an icon font from Font-Awesome. here's a jsFiddle DEMO of it (you need to stretch the result panel so everything will be lined).
.subnav > ul > li.active > a:after {
position: relative;
text-align: center;
font-family: FontAwesome;
top: 25px;
right: 50%;
content: "\f0de";
color: #c1c1c1;
}
I've added some basic jQuery function that switches the .active class, and I'm wondering if there's a way to animate the transition of the pseudo element so it'll move horizontally to the new position.
I know pseudo-elements transition are a thing, but searching and googling around I couldn't find anything similar to what I'm looking for. Is this even possible?
In this solution I used the :target pseudo class to switch states, but I recommend you stick with the jQuery function that switches the .active class.
FIDDLE
Markup
<div class="page" id="one">page one</div>
<div class="page" id="two">page two</div>
<div class="page" id="three">page three</div>
<div class="top">
<div class="arrow"></div>
<ul>
<li>One</li>
<li>Two</li>
<li>Three</li>
</ul>
</div>
CSS
.top
{
background: #eee;
position:relative;
overflow: hidden;
}
.arrow
{
border-bottom: 1px solid #c2c2c2;
height: 50px;
}
.arrow:before
{
content: '';
display: block;
width: 14px;
height: 14px;
border: 1px solid #c2c2c2;
border-radius: 3px;
position:absolute;
bottom:-9px;
left: 30px;
background: #fff;
-webkit-transform: rotate(45deg);
-moz-transform: rotate(45deg);
-ms-transform: rotate(45deg);
-o-transform: rotate(45deg);
transform: rotate(45deg);
-webkit-transition: left, 0.5s;
-moz-transition: left, 0.5s;
-o-transition: left, 0.5s;
transition: left, 0.5s;
}
ul
{
position: absolute;
top: 0;
list-style: none;
padding-left: 20px;
margin-top: 15px;
}
li
{
display: inline-block;
text-decoration: none;
font-size: 18px;
color: #676767;
margin-right: 40px;
}
.page
{
width: 100%;
height: 200px;
position: absolute;
top: 80px;
opacity: 0;
background: yellow;
-webkit-transition: opacity, 0.5s;
-moz-transition: opacity, 0.5s;
-o-transition: opacity, 0.5s;
transition: opacity, 0.5s;
}
.page:target
{
opacity: 1;
}
#two
{
background: pink;
}
#three
{
background: brown;
}
#one:target ~ .top .arrow:before
{
left: 30px;
}
#two:target ~ .top .arrow:before
{
left: 105px;
}
#three:target ~ .top .arrow:before
{
left: 189px;
}