Displaying images under slideshow - css

I find it quite hard to explain, but I have made a demo here:
http://plnkr.co/edit/X0X4RAFjnUX7LzBL1R6p?p=preview
Basically I have 2 columns that are side-by-side. When the page gets smaller, the columns go under each other. One of the columns has a slider plugin where the image change. The wrapper has a relative position so it changes size. The images inside use an absolute position for the slider to work.
Under those images I want 3 separate images that always stay under. Unfortunately, I can only get them to appear either on the main image, or under the layer (not positioned below).
Here's the entire code:
var timer = setInterval(nextImage, 4000);
var curImage = 0;
var numImages = 3;
function nextImage() {
var e;
// remove showMe class from current image
e = document.getElementById("slideimg" + curImage);
removeClass(e, "showMe");
// compute next image
curImage++;
if (curImage > numImages - 1) {
curImage = 0;
}
// add showMe class to next image
e = document.getElementById("slideimg" + curImage);
addClass(e, "showMe");
}
function addClass(elem, name) {
var c = elem.className;
if (c) c += " "; // if not blank, add a space separator
c += name;
elem.className = c;
}
function removeClass(elem, name) {
var c = elem.className;
elem.className = c.replace(name, "").replace(/ /g, " ").replace(/^ | $/g, ""); // remove name and extra blanks
}
body,
html {
height: 100%
}
body {
min-height: 100%;
background-position: center;
background-size: cover;
font-family: 'Lato', sans-serif;
font-weight: 400;
margin: 0;
}
#content {
max-width: 1750px;
margin-left: auto;
margin-right: auto;
}
* {
box-sizing: border-box;
}
/* Create two equal columns that floats next to each other */
.column {
float: left;
width: 50%;
padding-top: 20px;
padding-bottom: 20px;
padding-left: 30px;
padding-right: 30px;
}
/* Clear floats after the columns */
.row:after {
content: "";
display: table;
clear: both;
}
/* Responsive layout - makes the two columns stack on top of each other instead of next to each other */
#media screen and (max-width: 900px) {
.column {
width: 100%;
}
}
.homepage-main-img-wrapper {
position: relative;
right: 0;
left: 0;
margin: auto;
height: 100%;
}
.homepage-main-img {
width: 100%;
border: 2px solid #194d98;
outline: 2px solid #0c7d5f;
}
.slide {
border: none;
opacity: 0;
position: absolute;
top: 0;
left: 0;
-webkit-transition: opacity 2s linear;
-moz-transition: opacity 2s linear;
-o-transition: opacity 2s linear;
transition: opacity 2s linear;
}
.showMe {
opacity: 1;
}
<html lang="et" xml:lang="et">
<body>
<div id="container">
<div id="content">
<div class="row">
<div class="column" style="background-color:#aaa;">
<div>stuff</div>
</div>
<div class="column container2">
<div class="homepage-main-img-wrapper">
<img id="slideimg0" class="slide homepage-main-img showMe" src="https://i.imgur.com/n3oGBvR.jpg">
<img id="slideimg1" class="slide homepage-main-img" src="https://i.imgur.com/Ak7Ykl8.jpg">
<img id="slideimg2" class="slide homepage-main-img" src="https://i.imgur.com/tSmA8zP.jpg">
</div>
<div id="test" style="
position: relative;
">
<div id="instagram-feed" class="instagram_feed">
<div class="instagram_gallery">
<img src="https://i.imgur.com/aoaWgFY.jpg" style="margin:0.5% 0.5%;width:32.333333333333336%;float:left;">
<img src="https://i.imgur.com/41i7fue.jpg" style="margin:0.5% 0.5%;width:32.333333333333336%;float:left;">
<img src="https://i.imgur.com/ITSAyjN.jpg" style="margin:0.5% 0.5%;width:32.333333333333336%;float:left;">
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</body>
</html>

Since the height of the images change when the browser is resized, you can take an existing image or transparent image with the same "homepage-main-img" class so that the scale is the same on browser resize.
I also removed the position:relative from your id test div.
Change your HTML to be the following in the HTML block. JS and CSS remains untouched. Just added for the snippit to work.
var timer = setInterval(nextImage, 4000);
var curImage = 0;
var numImages = 3;
function nextImage() {
var e;
// remove showMe class from current image
e = document.getElementById("slideimg" + curImage);
removeClass(e, "showMe");
// compute next image
curImage++;
if (curImage > numImages - 1) {
curImage = 0;
}
// add showMe class to next image
e = document.getElementById("slideimg" + curImage);
addClass(e, "showMe");
}
function addClass(elem, name) {
var c = elem.className;
if (c) c += " "; // if not blank, add a space separator
c += name;
elem.className = c;
}
function removeClass(elem, name) {
var c = elem.className;
elem.className = c.replace(name, "").replace(/ /g, " ").replace(/^ | $/g, ""); // remove name and extra blanks
}
body,
html {
height: 100%
}
body {
min-height: 100%;
background-position: center;
background-size: cover;
font-family: 'Lato', sans-serif;
font-weight: 400;
margin: 0;
}
#content {
max-width: 1750px;
margin-left: auto;
margin-right: auto;
}
* {
box-sizing: border-box;
}
/* Create two equal columns that floats next to each other */
.column {
float: left;
width: 50%;
padding-top: 20px;
padding-bottom: 20px;
padding-left: 30px;
padding-right: 30px;
}
/* Clear floats after the columns */
.row:after {
content: "";
display: table;
clear: both;
}
/* Responsive layout - makes the two columns stack on top of each other instead of next to each other */
#media screen and (max-width: 900px) {
.column {
width: 100%;
}
}
.homepage-main-img-wrapper {
position: relative;
right: 0;
left: 0;
margin: auto;
height: 100%;
}
.homepage-main-img {
width: 100%;
border: 2px solid #194d98;
outline: 2px solid #0c7d5f;
}
.slide {
border: none;
opacity: 0;
position: absolute;
top: 0;
left: 0;
-webkit-transition: opacity 2s linear;
-moz-transition: opacity 2s linear;
-o-transition: opacity 2s linear;
transition: opacity 2s linear;
}
.showMe {
opacity: 1;
}
<div id="container">
<div id="content">
<div class="row">
<div class="column" style="background-color:#aaa;">
<div>stuff</div>
</div>
<div class="column container2">
<div class="homepage-main-img-wrapper">
<img id="slideimg0" class="slide homepage-main-img showMe" src="https://i.imgur.com/n3oGBvR.jpg">
<img id="slideimg1" class="slide homepage-main-img" src="https://i.imgur.com/Ak7Ykl8.jpg">
<img id="slideimg2" class="slide homepage-main-img" src="https://i.imgur.com/tSmA8zP.jpg">
</div>
<div id="test"><img id="fakeslide" class="homepage-main-img" src="https://i.imgur.com/n3oGBvR.jpg">
<div id="instagram-feed" class="instagram_feed">
<div class="instagram_gallery">
<img src="https://i.imgur.com/aoaWgFY.jpg" style="margin:0.5% 0.5%;width:32.333333333333336%;float:left;">
<img src="https://i.imgur.com/41i7fue.jpg" style="margin:0.5% 0.5%;width:32.333333333333336%;float:left;">
<img src="https://i.imgur.com/ITSAyjN.jpg" style="margin:0.5% 0.5%;width:32.333333333333336%;float:left;">
</div>
</div>
</div>
</div>
</div>
</div>
</div>

Related

clip-path not working as expected in Chrome (works in Firefox and Safari)

I have been trying to find a workaround to overflow:hidden not applying to fixed elements, and I came across clip and clip-path. As clip is deprecated, I am trying to use clip-path to create the desired effect. I have successfully created the effect I am looking for in both Firefox and Safari, but the clip-path function does not appear to be working in Chrome.
I've included the current HTML and CSS below; the desired effect is for each title and subtitle to only be visible when their respective parent element is in view. If you are viewing on Firefox or Safari this should be working appropriately. However, if viewing on Chrome you should see that the clip-path function is not applying and therefore you can see both titles and subtitles at the same time when viewing the first parent element (the turquoise rectangle).
As you can see in the code, I am using clip-path: fill-box which works in both Firefox and Safari, but not Chrome. I've also tried inset(0), which still works in FF/Safari but it too fails in Chrome.
* {
padding: 0;
margin: 0;
border: none;
}
html {
background-color: black;
}
.info {
list-style-type: none;
margin-left: 13vw;
padding: 0;
overflow: hidden;
position: fixed;
color: white;
z-index: -1;
top: 80vh;
}
.container {
width: 100%;
height: 110vh;
}
.parent {
position: absolute;
width: 100%;
height: 110vh;
background-repeat: no-repeat;
background-position: center;
background-size: cover;
pointer-events: none;
clip-path: fill-box;
}
.parent_1 {
background-color: turquoise;
}
.parent_2 {
background-color: tomato;
}
.parent_3 {
background-color: purple;
}
.subchild {
position: fixed;
color: white;
width: 60vw;
left: 14vw;
}
.p1, .p3 {
top: 40vh;
}
.p2 {
top: 45vh;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Test</title>
<link href="css/clip.css" rel="stylesheet" type="text/css">
</head>
<body>
<section class="container container_1">
<Div class="parent parent_1">
<Div class="child child_1">
<p class="subchild p1">
First Title
</p>
<p class="subchild p2">
First Subtitle
</p>
</Div>
</Div>
</section>
<section class="container container_2">
<Div class="parent parent_2">
<Div class="child child_2">
<p class="subchild p3">
Second Title
</p>
<p class="subchild p2">
Second Subtitle
</p>
</Div>
</Div>
</section>
</body>
</html>
I decided to play a little with Javascript. I've changed a little the HTML and the CSS. The subchilds are positioned top: 150px;.
function getY(element) {
var rect = element.getBoundingClientRect();
return rect.bottom;
}
let container1 = document.querySelector(".container_1");
let container2 = document.querySelector(".container_2");
let container3 = document.querySelector(".container_3");
let subchild1 = document.querySelector(".container_1 .subchild");
let subchild2 = document.querySelector(".container_2 .subchild");
let subchild3 = document.querySelector(".container_3 .subchild");
document.addEventListener('scroll', function() {
let bottom1 = getY(container1);
let bottom2 = getY(container2);
let bottom3 = getY(container3);
if ((bottom1 > 166) && (bottom2 > 166) && (bottom3 > 166)) {
subchild1.style.display = "block";
}
else {
subchild1.style.display = "none";
}
//
if ((bottom1 < 166) && (bottom2 > 166) && (bottom3 > 166)) {
subchild2.style.display = "block";
}
else {
subchild2.style.display = "none";
}
//
if ((bottom1 < 166) && (bottom2 < 166) && (bottom3 > 166)) {
subchild3.style.display = "block";
}
else {
subchild3.style.display = "none";
}
});
* {
padding: 0;
margin: 0;
border: none;
}
html {
background-color: black;
}
.info {
list-style-type: none;
margin-left: 13vw;
padding: 0;
overflow: hidden;
position: fixed;
color: white;
z-index: -1;
top: 80vh;
}
.container {
width: 100%;
height: 110vh;
}
.parent {
position: absolute;
width: 100%;
height: 110vh;
background-repeat: no-repeat;
background-position: center;
background-size: cover;
pointer-events: none;
}
.parent_1 {
background-color: turquoise;
}
.parent_2 {
background-color: tomato;
}
.parent_3 {
background-color: purple;
}
.subchild {
position: fixed;
color: white;
width: 60vw;
left: 14vw;
top: 150px;
}
.container_1 .subchild {
display: block;
}
.container_2 .subchild {
display: none;
}
.container_3 .subchild {
display: none;
}
<section class="container container_1">
<Div class="parent parent_1">
<Div class="child child_1">
<p class="subchild">
First Title
</p>
</Div>
</Div>
</section>
<section class="container container_2">
<Div class="parent parent_2">
<Div class="child child_2">
<p class="subchild">
Second Title
</p>
</Div>
</Div>
</section>
<section class="container container_3">
<Div class="parent parent_3">
<Div class="child child_3">
<p class="subchild">
Third Title
</p>
</Div>
</Div>
</section>

Materialize carousel onchange jquery change bg

$(document).ready(function() {
$('.carousel').carousel();
});
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
*:focus {
outline: 0;
}
html {
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
}
body {
background-color: #000000;
}
.carousel {
height: 700px;
-webkit-perspective: 600px;
perspective: 600px;
-webkit-transform: translateY(-100px);
transform: translateY(-100px);
position: absolute;
top: 0;
left: 0;
height: 100%;
width: 100%;
}
.carousel .carousel-item {
cursor: -webkit-grab;
cursor: grab;
width: 400px;
}
.carousel .carousel-item:active {
cursor: -webkit-grabbing;
cursor: grabbing;
}
.carousel .carousel-item img {
width: 100%;
}
.carousel .carousel-item h3 {
background-color: #ffffff;
color: #000000;
font-size: 2em;
font-weight: bold;
margin: -5px 0 0;
padding: 10px 5px;
text-align: center;
}
<div class="carousel">
<div class="carousel-item">
<img src="./img/gry1.png" alt="Dog" title="Dog" id="Dog">
</div>
<div class="carousel-item">
<img src="./img/img1.png" alt="Cat" title="Cat" id="Cat">
</div>
<div class="carousel-item">
<img src="./img/img1.png" alt="Wolf" title="Wolf" id="Wolf">
</div>
<div class="carousel-item">
<img src="./img/img1.png" alt="Tiger" title="Tiger" id="Tiger">
</div>
<script src='https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.min.js'></script>
<script src='https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/js/materialize.min.js'></script><script src="./script.js"></script>
I'd like to change background for each item in my carousel, materialize adding "active" class for selected item in carousel but I cant figure out how to change bg (for whole page), I was trying to add background image to css for each item but it didnt cover whole page bg.
I think it will be good to solve it by jquery (check which item is "active" and select background for that item, adding it to body class)
The same script available on codepen:
https://codepen.io/crianbluff/details/PMZBVJ
You can do it like that.
I added the dummy data that contains image-url and I added carousel-item--* classes in HTML.
const setBackground = () => {
const number = document.querySelector('.carousel-item.active').classList[1].split('--')[1];
document.body.setAttribute('style', `background-image: url("${dummy[number]}")`);
}
in number variable, I am getting the carousel-item--* number and get the image-url of dummy data through index and add background-image through javascript
Codepen: https://codepen.io/NishargShah/pen/oNzwGwx?editors=1010

How to recreate specific animation

I'm trying to make an image slideshow that has a transition effect like seen here. I unfortunately only have this gif to go by and I have not been able to locate live web example. The slideshow should show 3 images at a time, then slide to the next 3, and so on. I started with using the slick slider to do most of the slideshow work for me (this is not a requirement). But I'm having difficulty recreating a transition that looks like the effect in the sample. I tried animating padding between the images but that causes the images to change size and causing the images to go off center. Using box-sizing: border-box did not help in this case. Any help on how to create this transition would be greatly appreciated. Here's my code:
$(document).ready(function(){
$('.slider').slick({
infinite: true,
arrows: true,
slidesToShow: 3,
slidesToScroll: 3,
speed: 500
});
});
.wrapper{
position: relative;
box-sizing: border-box;
}
.slick-slide img{
width:100%;
box-sizing:border-box;
}
.slick-slide{
padding: 0;
box-sizing: border-box;
}
.slick-active{
animation: slidetransition;
animation-duration: 3s;
}
#keyframes slidetransition {
0% {
padding: 0px;
}
50% {
padding: 0px 25px;
}
100% {
padding:0;
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/slick-carousel/1.8.1/slick.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/slick-carousel/1.8.1/slick.min.js"></script>
<div class="wrapper">
<div class="slider">
<div class="group1">
<img src="http://placehold.it/350x150/292929/dd0909&text=Slide_1">
</div>
<div class="group1">
<img src="http://placehold.it/350x150/292929/dd6809&text=Slide_2">
</div>
<div class="group1">
<img src="http://placehold.it/350x150/292929/fdff3b&text=Slide_3">
</div>
<div class="group2">
<img src="http://placehold.it/350x150/292929/3bff3b&text=Slide_4">
</div>
<div class="group2">
<img src="http://placehold.it/350x150/292929/5d87ff&text=Slide_5">
</div>
<div class="group2">
<img src="http://placehold.it/350x150/292929/ab8df8&text=Slide_6">
</div>
</div>
</div>
If you can group your items in groups of 3, this solution can work for you.
I am setting different delays to achieve the effect of the items moving separately and the grouping again
var page = 1;
window.onload = function() {
setInterval(changePage, 4000);
}
function changePage() {
var previous = document.querySelector(".previous");
if (previous) {
previous.classList.remove("previous");
}
var active = document.querySelector(".active");
active.classList.remove("active");
active.classList.add("previous");
page++;
if (page > 3) {
page = 1;
}
var id = "page" + page;
var newActive = document.getElementById(id);
newActive.classList.add("active");
}
.carousel {
height: 150px;
width: 500px;
position: relative;
}
.page {
width: 100%;
height: 100%;
display: flex;
position: absolute;
overflow: hidden;
}
.elem {
height: 98%;
width: 33%;
font-size: 100px;
border: solid 1px black;
transition: transform 1s;
transform: translateX(300%);
opacity: 0;
}
.active .elem {
transform: translateX(0%);
opacity: 1;
}
.previous .elem {
transform: translateX(-300%);
opacity: 1;
}
.elem:nth-child(1) {
background-color: tomato;
transition-delay: 0s;
}
.elem:nth-child(2) {
background-color: yellow;
transition-delay: 0.1s;
}
.elem:nth-child(3) {
background-color: lightblue;
transition-delay: 0.2s;
}
.active .elem:nth-child(1) {
transition-delay: 0.3s;
}
.active .elem:nth-child(2) {
transition-delay: 0.4s;
}
.active .elem:nth-child(3) {
transition-delay: 0.5s;
}
<div class="carousel">
<div class="page active" id="page1">
<div class="elem">1</div>
<div class="elem">1</div>
<div class="elem">1</div>
</div>
<div class="page" id="page2">
<div class="elem">2</div>
<div class="elem">2</div>
<div class="elem">2</div>
</div>
<div class="page" id="page3">
<div class="elem">3</div>
<div class="elem">3</div>
<div class="elem">3</div>
</div>
</div>
Here another snippet, working with nbuttons, and responsive
var page = 1;
var numPages = 4;
function forward() {
changePage(1);
}
function back() {
changePage(-1);
}
function changePage (inc) {
var ele = document.querySelector(".carousel");
if (inc > 0) {
ele.className = "carousel forward";
} else {
ele.className = "carousel back";
}
page += inc;
if (page > numPages) {
page = 1;
}
if (page < 1) {
page = numPages;
}
var id = page - 3;
if (id < 0) {
id += numPages;
}
document.getElementById("page" + (id % numPages)).className = "page";
id ++;
document.getElementById("page" + (id % numPages)).className = "page left";
id ++;
document.getElementById("page" + id % numPages).className = "page active";
id ++;
document.getElementById("page" + id % numPages).className = "page right";
id ++;
document.getElementById("page" + id % numPages).className = "page";
}
.carousel {
height: 200px;
width: 98%;
border: solid 3px black;
position: relative;
margin-left: 1%;
}
.page {
eft: 300px;
width: 100%;
height: 100%;
display: flex;
flex-direction: row;
position: absolute;
overflow: hidden;
}
.page:nth-child(2) {
op: 100px;
}
.page:nth-child(3) {
op: 200px;
}
.elem {
height: 100%;
width: 33.33%;
font-size: 100px;
transition: transform 1s;
transform: translateX(300%);
z-index: 1;
opacity: 0;
}
.active .elem {
transform: translateX(0%);
z-index: 2;
opacity: 1;
}
.left .elem {
transform: translateX(-300%);
}
.forward .left .elem {
z-index: 2;
opacity: 1;
}
.right .elem {
transform: translateX(300%);
}
.back .right .elem {
z-index: 2;
opacity: 1;
}
.elem:nth-child(1) {
background-color: tomato;
}
.elem:nth-child(2) {
background-color: yellow;
}
.elem:nth-child(3) {
background-color: lightblue;;
}
.back .right .elem:nth-child(3) {
transition-delay: 0s;
}
.back .right .elem:nth-child(2) {
transition-delay: 0.1s;
}
.back .right .elem:nth-child(1) {
transition-delay: 0.2s;
}
.back .active .elem:nth-child(3) {
transition-delay: 0.3s;
}
.back .active .elem:nth-child(2) {
transition-delay: 0.4s;
}
.back .active .elem:nth-child(1) {
transition-delay: 0.5s;
}
.forward .left .elem:nth-child(1) {
transition-delay: 0s;
}
.forward .left .elem:nth-child(2) {
transition-delay: 0.1s;
}
.forward .left .elem:nth-child(3) {
transition-delay: 0.2s;
}
.forward .active .elem:nth-child(1) {
transition-delay: 0.3s;
}
.forward .active .elem:nth-child(2) {
transition-delay: 0.4s;
}
.forward .active .elem:nth-child(3) {
transition-delay: 0.5s;
}
button {
font-size: 20px;
margin: 20px;
}
<div class="carousel forward">
<div class="page active" id="page0">
<div class="elem">1</div>
<div class="elem">1</div>
<div class="elem">1</div>
</div>
<div class="page right" id="page1">
<div class="elem">2</div>
<div class="elem">2</div>
<div class="elem">2</div>
</div>
<div class="page" id="page2">
<div class="elem">3</div>
<div class="elem">3</div>
<div class="elem">3</div>
</div>
<div class="page left" id="page3">
<div class="elem">4</div>
<div class="elem">4</div>
<div class="elem">4</div>
</div>
</div>
<button onclick="back()">back</button>
<button onclick="forward()">forward</button>
For performance, a simple transform:translate with pure CSS is much better. If you just need 2 groups of 3 images, the following will do
/*just toggles the "toggle" class on the "slider" element
/* when clicking the toggle button*/
document.getElementById("toggle").addEventListener("click", function(){
document.getElementById("slider").classList.toggle("toggle");
});
.wrapper{
/*hides the 3 overflowing imgs, preventing scrollbars*/
width:100%; overflow:hidden;
}
.slider{
/*classic inline-block whitespace hack*/
font-size:0;
/* so the 2 "groups" are side by side */
width:200%;
/*sets the transition between groups with some delay*/
transition: transform 1.2s;
}
.slider img{
/*sizes the imgs acording to the fixed quantity*/
width:calc(100% / 6);
/*set the transition for the imgs separation*/
transition: transform 1s;
/*sets the default value for transform*/
transform:translateX(0);
}
/*when "toggle" is not active, last images move to the right*/
.slider img:nth-child(4){transform:translateX(40px);}
.slider img:nth-child(5){transform:translateX(80px);}
.slider img:nth-child(6){transform:translateX(120px);}
/*when active, the slide moves 50% left so the second group shows*/
.slider.toggle{transform:translateX(-50%)}
/*when active, first two images move displaces to the left*/
.slider.toggle img:nth-child(1){transform:translateX(-80px);}
.slider.toggle img:nth-child(2){transform:translateX(-40px);}
/*when active, last two images reset to regular position*/
.slider.toggle img:nth-child(4){transform:translateX(0);}
.slider.toggle img:nth-child(5){transform:translateX(0);}
.slider.toggle img:nth-child(6){transform:translateX(0);}
<div class="wrapper">
<div class="slider" id="slider">
<img src="http://placehold.it/350x150/292929/dd0909&text=Slide_1">
<img src="http://placehold.it/350x150/292929/dd6809&text=Slide_2">
<img src="http://placehold.it/350x150/292929/fdff3b&text=Slide_3">
<img src="http://placehold.it/350x150/292929/3bff3b&text=Slide_4">
<img src="http://placehold.it/350x150/292929/5d87ff&text=Slide_5">
<img src="http://placehold.it/350x150/292929/ab8df8&text=Slide_6">
</div>
</div>
<button id="toggle">toggle slides</button>
Feel free to use javascript to automatically switch the groups, it's just a matter of toggling the "toggle" class list.
I've used a button toggle just for testing purposes.

How to make a button with an image background?

I am using bootstrap 3 and I want to make an image button i.e. the button should have:
an image background
The button should have a custom translucent dark overlay that lightens on hover and becomes even darker on click.
fixed height (of 300px), and width 100% (so that it occupies the entire parent div class="col-md-4").
The image should be cropped i.e. overflow: hidden
I tried to achieve this by setting the image as background to my parent <div> and used a child <div> for the translucent overlays. But I had to write a lot of jquery to change the states onhover, onclick, etc.
I realized I should be using a button, and not a div but I could not style it and make it overlay the parent div.
Current code:
HTML element:
<div class="col-md-4" style="background-image: url('...'); overflow: hidden; height: 200px; margin-bottom: 24px">
<div class="img-panel translucent-overlay-light"> <!-- Should be a button or a tag -->
<div>
Hello
</div>
</div>
</div>
javascript: (ideally there should be no js, all this should be done in CSS)
$('.img-panel').click(function() {
// do something
});
$('.img-panel').mouseenter(function() {
var elm = $(this);
elm.removeClass('translucent-overlay-light');
elm.addClass('translucent-overlay-dark')
}).mouseleave(function() {
var elm = $(this);
elm.removeClass('translucent-overlay-dark');
elm.addClass('translucent-overlay-light')
});
Also, I am using SCSS anyway so both SCSS and CSS answers are fine.
Not hard, just using css:
.my-button {
display: block;
position: relative;
height: 300px;
line-height: 300px;
overflow: hidden;
text-overflow: ellipsis;
padding: 0 10px;
text-align: center;
box-shadow: 0 0 2px rgba(0, 0, 0, .2);
cursor: pointer;
font-size: 18px;
font-weight: bold;
font-family: sans-serif;
text-transform: uppercase;
background: url('https://placeholdit.imgix.net/~text?txtsize=23&bg=22ffdd&txtclr=000000&txt=&w=250&h=250');
}
.my-button::after {
content: '';
display: block;
position: absolute;
left: 0;
top: 0;
right: 0;
bottom: 0;
width: 100%;
background: rgba(0, 0, 0, .4);
}
.my-button:hover::after {
background: rgba(0, 0, 0, .2);
}
.my-button:active::after {
background: rgba(0, 0, 0, .8);
}
<div class="my-button">
Click me
</div>
You just may need to adjust background image size and position, read more.
CSS only with pseudo-elements. Hope that works for you.
.col{
width:50%;
display:block;
}
.img-panel{
position:relative;
height: 200px;
background-image: url('https://placeimg.com/640/480/any');
background-size:cover;
color:white;
}
.img-panel:after{
content:"";
width:100%;
height:100%;
top:0;
left:0;
position:absolute;
transition:0.2s;
}
.img-panel:hover:after{
background:rgba(0,0,0,0.5) ;
}
.img-panel:active:after{
background:rgba(0,0,0,0.8) ;
}
<div class="col col-md-4">
<div class="img-panel translucent-overlay-light">
Hello
</div>
</div>
As I understood, you need something like that, please check this. It's pure CSS solution.
.btn-wrap {
.btn-wrap__input {
width: 100%;
height: 300px;
position: absolute;
z-index: 3;
margin: 0;
opacity: 0;
&:checked {
+ .btn-wrap__overlay {
opacity: .7;
}
&:hover {
+ .btn-wrap__overlay {
opacity: .7;
}
}
}
&:hover {
+ .btn-wrap__overlay {
opacity: .5;
}
}
}
.btn-wrap__button {
height: 300px;
width: 100%;
}
.btn-wrap__back {
position: absolute;
height: 300px;
width: 100%;
z-index: 1;
color: white;
background-image: url('https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcT7ixV_dB22rsPTNwbph6uHl62bSSNHK_TQLw1gMOPmoWErkRdK');
}
.btn-wrap__overlay {
background: black;
opacity: 0;
height: 300px;
position: absolute;
z-index: 2;
width: 100%;
}
}
<div class="col-md-4 btn-wrap">
<div class='btn-wrap__button'>
<input type='checkbox' class='btn-wrap__input'>
<div class="btn-wrap__overlay"></div>
<div class="btn-wrap__back"></div>
</div>
</div>

Text on Image Mouseover - CSS Positioning

I am using this fork code to display text on mouseover of an image.
http://codepen.io/anon/pen/hxqoe
HTML
<img src="http://placekitten.com/150" alt="some text" />
<img src="http://placekitten.com/150" alt="more text" />
<img src="http://placekitten.com/150" alt="third text" />
<div id="text"></div>
CSS
div {
display: none;
position: absolute;
}
img:hover + div {
display: block;
}
JQUERY
$('img').hover(function() {
$('div').html($(this).attr('alt')).fadeIn(200);
}, function() {
$('div').html('');
});
I am looking for the div text to be displayed inside each image instead of a stationary div.
Any ideas?
You actually don't need jQuery for this. It can easily be achieved with pure CSS.
In this example, I use the :after pseudo element to add the content from the alt attribute of the parent div. You can add whatever styling you want..
jsFiddle here - Updated to include a fade
HTML - pretty simple
<div alt="...">
<img src="..."/>
</div>
CSS
div {
position: relative;
display: inline-block;
}
div:after {
content: attr(alt);
height: 100%;
background: rgba(0, 0, 0, .5);
border: 10px solid red;
position: absolute;
top: 0px;
left: 0px;
display: inline-block;
box-sizing: border-box;
text-align: center;
color: white;
padding: 12px;
font-size: 20px;
opacity: 0;
transition: 1s all;
-webkit-transition: 1s all;
-moz-transition: 1s all;
}
div:hover:after {
opacity: 1;
}
Change your javascript to this:
$('img').hover(function() {
$('div').html($(this).attr('alt')).fadeIn(200);
$('div').css('left',$(this).offset().left + 'px');
$('div').css('top',$(this).offset().top + $(this).height() - 20 + 'px');
}, function() {
$('div').html('');
});
And that should do the trick.
I would wrap your images in some kind of wrapper and then use CSS for the hover effect (DEMO).
HTML:
<div class="img-wrapper">
<img src="http://placekitten.com/150" alt="some text 1" />
<div class="img-desc">some text 1</div>
</div>
CSS:
.img-wrapper {
position: relative;
display: inline;
}
.img-desc {
display: none;
position: absolute;
bottom: 0px;
left: 0px;
width: 100%;
background: #FFF;
opacity: 0.6;
padding: 5px;
}
.img-wrapper:hover .img-desc{
display: block;
}
I added an alternative solution with additional css transition to the demo.
To get a transition just control the visibility with opacity:
.img-desc {
/*...*/
opacity: 0;
/*...*/
}
.img-wrapper:hover .img-desc{
opacity: 0.6;
transition: opacity 0.4s ease-in;
}

Resources