Follow Mouse on Hover in SCSS with Responsive. No JS!
So Let's create hover follow mouse using scss without using JavaScript. Below is the gif image for final output. Its also responsive.
Let's create list elements in html like below code. Also add <span class="item"></span>
at the bottom of last <li>
. This item span
will follow the mouseover.
<ul id="list">
<li class="box"><img src="img/1.jpg" alt=""><span>caption</span></li>
<li class="box"><img src="img/2.jpg" alt=""><span>caption</span></li>
<li class="box"><img src="img/3.jpg" alt=""><span>caption</span></li>
<li class="box"><img src="img/4.jpg" alt=""><span>caption</span></li>
<li class="box"><img src="img/5.jpg" alt=""><span>caption</span></li>
<li class="box"><img src="img/6.jpg" alt=""><span>caption</span></li>
<li class="box"><img src="img/7.jpg" alt=""><span>caption</span></li>
<li class="box"><img src="img/8.jpg" alt=""><span>caption</span></li>
<li class="box"><img src="img/9.jpg" alt=""><span>caption</span></li>
<li class="box"><img src="img/10.jpg" alt=""><span>caption</span></li>
<li class="box"><img src="img/11.jpg" alt=""><span>caption</span></li>
<li class="box"><img src="img/12.jpg" alt=""><span>caption</span></li>
<li class="box"><img src="img/13.jpg" alt=""><span>caption</span></li>
<li class="box"><img src="img/14.jpg" alt=""><span>caption</span></li>
<li class="box"><img src="img/15.jpg" alt=""><span>caption</span></li>
<span class="item"></span>
</ul>
Let's create scss variables $w, $h for width and height of <li>
. Assign width, height to 100% to img and span(which has text: caption) tags which are inside <li>
like below code. span will appear on hover of <li>
and also <span class="item"></span>
will follow on hover with our for loop logic.
$w: 150px;
$h: 100px;
body {
margin: 0;
padding: 0;
background: #5b5b5b;
font-family: monospace;
}
#list {
display: flex;
flex-wrap: wrap;
margin: 50px auto;
// width:750px;
padding: 0;
list-style-type: none;
position: relative;
li {
&.box {
box-sizing: border-box;
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
width: $w;
height: $h;
position: relative;
overflow: hidden;
border: 1px solid rgb(255, 255, 255);
z-index: 1;
margin: 0;
padding: 0;
cursor: pointer;
img {
width: 100%;
height: 100%;
opacity: 0.5;
}
span {
font-size: 15px;
opacity: 0;
z-index: 2;
position: absolute;
color: white;
width: 100%;
height: 100%;
left: 0;
top: 0;
z-index: 2;
text-shadow: none;
display: flex;
align-items: center;
justify-content: center;
}
&:hover {
img {
opacity: 0.15;
}
span {
opacity: 1;
animation: fade 0.5s;
}
}
}
}
.item {
position: absolute;
width: $w;
height: $h;
left: unset;
top: unset;
background: rgb(0, 0, 0);
opacity: 0;
z-index: 0;
transition: 0s ease;
pointer-events: none;
}
}
@keyframes fade {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
Output:
Now, I have two methods to do this. First lets go with first method. Please comment which method is better. Feedback is much appreciated.
Method 1:
@mixin responsive-styles($width, $col, $multiplier, $max-nth-child) {
#list {
width: $width;
// Calculate the maximum range for the loop
$limit: min($col * $multiplier, $max-nth-child);
@for $i from 1 through $limit {
li:nth-child(#{$i}):hover~.item {
$row: ceil($i / $col); // determine the row number
$rowOffset: ($row - 1) * $col * $w; // adjust based on row
left: #{$i * $w - $rowOffset - ($w)};
top: #{($row - 1) * $h};
transition: 0.25s ease;
opacity: 0.7;
}
}
}
}
// media queries
@media only screen and (max-width: 1920px) {
@include responsive-styles(750px, 5, 3, 15);
}
@media only screen and (max-width: 768px) {
@include responsive-styles(600px, 4, 4, 15);
}
@media only screen and (max-width: 600px) {
@include responsive-styles(450px, 3, 5, 15);
}
@media only screen and (max-width: 450px) {
@include responsive-styles(300px, 2, 8, 15);
}
Output:
$max-nth-child: 15;
$breakpoints: (1920px:(col: 5, numOfRows: 3, width: 750px),
768px: (col: 4, numOfRows: 4, width: 600px),
600px: (col: 3, numOfRows: 5, width: 450px),
450px: (col: 2, numOfRows: 8, width: 300px));
#list {
@each $breakpoint,
$settings in $breakpoints {
@media only screen and (max-width: $breakpoint) {
width: map-get($settings, width);
$col: map-get($settings, col);
$numOfRows: map-get($settings, numOfRows);
$limit: min($col * $numOfRows, $max-nth-child);
@for $i from 1 through $limit {
li:nth-child(#{$i}):hover~.item {
$row: ceil($i / $col);
$rowOffset: ($row - 1) * $col * $w;
left: #{$i * $w - $rowOffset - ($w)};
top: #{($row - 1) * $h};
transition: 0.25s ease;
opacity: 0.7;
}
}
}
}
}
Thank you for watching...Please subscribe to my youtube channel
Click here for demo
Top comments (0)