I know how to answer my question, I'm just posting to see if there's a better way to do what I'm already doing.
Let's say I'm making a website that sells 4 different types of posters. I want the user to see each of the posters in a row. and when they hover over each picture the image will change to show the price, and measurements of the poster.
How I achieved this:
<ul>
<li> image link here using onmouseover and onmouseout for hover over effects </li>
<li> same as above </li>
<li> same as above </li>
<li> same as above </li>
</ul
Then I just styled the list to remove bullets and aligned it horizontally. Now here's my question... I am currently using onmouseover and onmouseout for hover over effects Because you need 2 images in order to achieve this you need a lot of data, especially if you're going to do this for, say, a grid of 25 images for an art portfolio.
Is this a bad way to get a hover over effect? I'm assuming because I'm new at web-development anything I can throw onto a webpage is going to be somewhat crude and not efficient.
You could have another div within the <li> containing the info you wanted. Have this absolutely positioned over the image and then show it on hover using opacity.
Demo
HTML
<ul>
<li><img src="http://placehold.it/350x150" alt="" /><div class="info">Info here</div></li>
<li><img src="http://placehold.it/350x150" alt="" /><div class="info">Info here</div></li>
<li><img src="http://placehold.it/350x150" alt="" /><div class="info">Info here</div></li>
</ul>
CSS
ul,li {
list-style: none;
}
li {
display: inline-block;
position: relative;
z-index: 1;
}
img {
display: block;
}
.info {
opacity: 0;
color: white;
position: absolute;
top: 0;
bottom: 0;
width: 100%;
z-index: 2;
background: red;
.transition(opacity 0.5s ease);
}
li:hover .info {
opacity: 1;
}
I made an example for you :)
You can line .image next to each other with display: inline-block;
Have a fiddle!
HTML
<div class="image">
<img src="http://www.placehold.it/200X200" />
<div class="text">Hello</div>
</div>
CSS
.image {
position: relative;
width: 200px;
height: 200px;
}
.text {
display: none;
}
img {
cursor: pointer;
}
img:hover + .text, .text:hover {
position: absolute;
bottom: 0;
height: 50px;
background: rgba(0, 0, 0, 0.5);
display: block;
padding: 10px;
width: 180px;
cursor: pointer;
}
Related
I have been trying to develop a product page for my website and I have three angles for my product images so I wanted to create a image gallery when you go to the page. The layout I am going with and the code I have so far is at this link https://jsfiddle.net/b1g2f8dh/ . My issue is I want this to be responsive so I want the .main-image img width to shrink with the page as it collapses until it gets to a min-width in which case the .angle-images div i want to shift below the main-image div and with the thumbnails laid out horizontally. My first issue is I cannot get the main image to resize despite i have width 100%. I would have thought it would scale it down as the parent container gets smaller. The second issue is I cannot figure out how to shift the second images beneath. I am getting my positions all mixed up that nothing seems to work! I plan to figure out some javascript so when you click the thumbnail it makes it the main image but thats a problem for another day ha! Any help would be appreciated. The full implementation of my code can be found here in case that helps https://www.printperry.com/home/product-page/index.php
<div class="product-images">
<div class="angle-images">
<li>
<img data-image="White" src="https://cdn.ssactivewear.com/Images/Color/17130_f_fl.jpg" alt="">
</li>
<li>
<img data-image="White" src="https://cdn.ssactivewear.com/Images/Color/17130_f_fl.jpg" alt="">
</li>
<li>
<img data-image="White" src="https://cdn.ssactivewear.com/Images/Color/17130_f_fl.jpg" alt="">
</li>
</div>
<div class="main-image">
<img data-image="White" src="https://cdn.ssactivewear.com/Images/Color/17130_f_fl.jpg" alt="">
</div>
</div>
.product-images{
max-height: 700px;
max-width: 700px;
width: 100%;
display: block;
}
.angle-images{
padding:5px 0px;
width: 120px;
display: inline-block;
float:left;
max-height: 700px;
}
.main-image{
width: 80%;
height: 600px;
float: left;
margin: 10px;
}
.angle-images li{
list-style: none;
padding-top: 50px;
}
.angle-images img {
width: 100px;
float: right;
margin:5px 10px;
}
.main-image img {
width: auto;
height:700px;
}
There a couple of issues with your CSS preventing it from working as you desire. The height, width, max-width, values you have are working against each other in ways that aren't immediately apparent.
It works after making the modifications below.
Using flexbox for the layout mode makes it easy to switch between column and row layouts based on a media query.
.product-images{
max-height: 700px;
max-width: 700px;
width: 100%;
display: flex;
flex-flow: column nowrap;
flex-direction: column-reverse;
}
#media (min-width: 768px) {
.product-images {
flex-flow: row nowrap;
}
}
.angle-images{
padding:5px 0px;
width: 120px;
max-height: 700px;
display: flex;
}
#media (min-width: 768px) {
.angle-images {
flex-flow: column nowrap;
}
}
.main-image{
width: 80%;
height: 600px;
margin: 10px;
}
.angle-images li{
list-style: none;
padding-top: 50px;
}
.angle-images img {
width: 100px;
margin:5px 10px;
}
.main-image img {
max-width: 100%;
}
Like Dan mentioned in his post, there were conflicting values. One of the issue I saw, was the size of the parent container, and the child container.
I am also learning as well, and one tip I would give you is try to use border-style to help you see visually, it makes problem solving more direct and easy.It really helps when you're working with multiple div container. Then play around with what you know, and try to see how to make it fit. I decided to give a stab at this, and came up with this version. You would have to use Flex unfortunately, it just made problem solving easier. The angle and main are responsive together for now unless you were trying to make just the main responsive only, please let me know so I can take some more time later and see if I further assist you, but for now this is what I have. I hope this leads you to the right path of whatever it is you're trying to achieve.
<div class="product-images">
<div class="angle-images">
<ul class="angle-ul">
<li class="angle-li angle-li-1">
<img data-image="White" src="https://cdn.ssactivewear.com/Images/Color/17130_f_fl.jpg" alt="">
</li>
<li class="angle-li angle-li-2">
<img data-image="White" src="https://cdn.ssactivewear.com/Images/Color/17130_f_fl.jpg" alt="">
</li>
<li class=" angle-li angle-li-3">
<img data-image="White" src="https://cdn.ssactivewear.com/Images/Color/17130_f_fl.jpg" alt="">
</li>
</ul>
</div>
<div class="main-Image">
<img data-image="White" src="https://cdn.ssactivewear.com/Images/Color/17130_f_fl.jpg" alt="">
</div>
</div>
* {
margin: 0;
padding: 0;
}
.product-images {
height: 700px;
max-width: 700px;
width: 100%;
display: flex;
flex-direction: row;
flex-wrap: warp;
border-style: dotted;
}
.angle-images {
width: 100px;
border-style: dotted;
}
.angle-ul {
}
.angle-li img {
width: 100%;
}
.main-Image img {
height: 100%;
width: 100%;
}
How to apply a transform to element without affecting position: absolute sibling. Been playing with this for a few hours to no avail. I think the code will explain clearer than I can put into words.
The below works as intented, until transform: translateX(10px) is applied to the ul. I need the transform to move the ul based on screen size, it's a longer list in reality. Can the hover state be preserved? Thanks, webstudent
.relative {
position: relative;
}
nav {
min-width: 100vw;
height: fit-content;
overflow: hidden;
}
ul {
display: block;
min-width: 100vw;
list-style-type: none;
margin: 0;
padding: 0;
/* breaks stacking order */
/* transform: translateX(10px); */
}
li {
display: inline-block;
}
li a {
display: block;
padding: 4px 8px;
font-size: 1rem;
max-height: 1rem;
}
li a:hover {
background-color: red;
}
.absolute-sibling {
position: absolute;
left: 0;
top: calc(1rem + 8px);
width: 100vw;
height: fit-content;
display: none;
}
li a:hover + .absolute-sibling,
.absolute-sibling:hover {
background-color: red;
display: block;
}
<div class="relative">
<nav>
<ul>
<li>
<a>text one</a>
<!-- absolute child of .relative -->
<div class="absolute-sibling">content one</div>
</li>
<li>
<a>text two</a>
<!-- absolute child of .relative -->
<div class="absolute-sibling">content two</div>
</li>
<li>
<a>text three</a>
<!-- absolute child of .relative -->
<div class="absolute-sibling">content three</div>
</li>
</ul>
</nav>
</div>
Broken version with transform included, jsfiddle to reduce wall of code. Same code, apart from transform: translate(10px);
Update:
This describes the issue I'm trying to counter CSS stacking contexts
Also, for instance if I replace the transform: translateX(10px); with margin-left: 10px; everything is as intended. Just I'd like to use the transform for animation smoothness.
Heres one more solution, set the transform on your parent component div.relative and remove it from the ul. (you could also wrap that div and transform that if it works better for your layout)
Change this line in your css
.relative {
position: relative;
transform: translateX(10px)
}
If this still breaks your design then you need to rethink your HTML. As per your article setting a transform creates a new stacking context causing these weird effects. By setting the transform on a parent or wrapper element then you are moving that context up the chain and the child elements should behave like normal.
friends there is something that I want to do for a week with cycle 2 slideshow plugin but I failed every time let me tell you What I want to do I'm trying to do categorized slideshow.I have filters on my cycle2 carousel (you will see on example)
I have 3 categories (or more than 3)
<ul class="filter">
<li id="sports">Sports</li>
<li id="naturel">Naturel</li>
<li id="animals">Animals</li>
</ul>
and my each li has an id
id#sports,id#naturel,id#animals,id#blabla..
at the same time my image has data-id attribute
data-id="sports",data-id="naturel",data-id="animals",data-id="blabla.."
and at this point I can not do what I want to do.
if I click li#sports than only data-id="sports" img must be appear on slideshow with thumbnail
or if I click li#animals than only data-id="animals" img must be appear on slideshow with thumbnail
I try with jquery but nothing happend
and please click to see my little project on codepen
$(document).ready(function() {
$(".filter li").on("click", function() {
var activeId = $(this).attr("id");
$("img[data-id]").hide();
$("img[data-id = '" + activeId + "']").show();
});
});
.single-gallery{
width:800px;
overflow:hidden;
position:relative;
}
.cycle-slideshow img {
width:100%;
height:234px;
max-width:100%;
}
#single-pager a img {
width: 49.3px !important;
height:49.3px !important;
border: 1px solid #fff;
}
#single-pager a.cycle-pager-active img {
opacity: 0.4;
}
#single-left,
#single-right {
position: absolute;
top: 50%;
z-index: 1000;
background: rgba(255, 255, 255, .8);
padding: 12px;
cursor: pointer;
}
#single-left {
left: 0;
}
#single-right {
right: 0;
}
.filter {
position: absolute;
z-index: 1000;
right: 0;
top:0;
padding: 0;
color: #FFF;
background: rgba(255, 255, 255, 0.6);
padding: 10px 30px;
}
.filter li {
list-style-type:none;
cursor: pointer;
display: inline-block;
background: rgba(0, 0, 0, .6);
padding: 5px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery.cycle2/2.1.6/jquery.cycle2.min.js"></script>
<div class="single-gallery">
<div class="cycle-slideshow" data-cycle-pager="#single-pager" data-cycle-pager-template="<a href='#'><img src='{{src}}' width=48 height=48></a>" data-cycle-prev="#single-left" data-cycle-next="#single-right" data-cycle-pause-on-hover="true">
<img src="https://amazingcarousel.com/wp-content/uploads/amazingcarousel/7/images/lightbox/golden-wheat-field-lightbox.jpg" data-id="sports">
<img src="https://amazingcarousel.com/wp-content/uploads/amazingcarousel/7/images/lightbox/sunny-day-lightbox.jpg" data-id="naturel">
<img src="https://amazingcarousel.com/wp-content/uploads/amazingcarousel/7/images/lightbox/night-in-the-city-lightbox.jpg" data-id="animals">
<img src="https://amazingcarousel.com/wp-content/uploads/amazingcarousel/7/images/lightbox/sakura%20trees-lightbox.jpg" data-id="animals" />
<img src="https://amazingcarousel.com/wp-content/uploads/amazingcarousel/7/images/lightbox/daffodil-flowers-lightbox.jpg" data-id="animals" />
<img src="https://amazingcarousel.com/wp-content/uploads/amazingcarousel/7/images/lightbox/dandelion-lightbox.jpg" data-id="animals" />
<img src="https://amazingcarousel.com/wp-content/uploads/amazingcarousel/7/images/lightbox/tulips-lightbox.jpg" data-id="sports" />
<div id="single-pager" class="center external"></div>
<div id="single-next-prev">
<span id="single-left">Prev</span>
<span id="single-right">Next</span>
</div>
</div>
<ul class="filter">
<li id="sports">Sports</li>
<li id="naturel">Naturel</li>
<li id="animals">Animals</li>
</ul>
</div>
Even though you are setting display: none on the elements you want hidden (using .hide()) the plugin is still setting them to display: block because when you initialize the slider they are all eligible slides.
There doesn't seem to be a very easy way of dynamically removing/adding slides on the fly.
The approach I took was setting data-hidden="true" on the slides you want hidden, then re-initializing the slider to only use images that match img[data-hidden="false"] as slides.
I added the code below to your css so that the hidden slides don't show up below the slideshow.
img[data-hidden="true"]{
display: none;
}
I also took all the other data- attributes in the cycle div, and renamed its class to mySlideShow so I could render the cycle when I needed using the $('.mySlideShow').cycle({...}) method.
Here should be a working example: http://codepen.io/anon/pen/dvoLeE
I've been asked at a job application to make jQuery slider plugin from scratch.
I just graduated as a Computer Science Engineer and to be honest, I've never been taught in college about jQuery. At all.
The little I know about it, is because I've read docs and experimented a little.
But a jQuery slider is very very far away from my current abilities.
I was reading this article on github http://rafbm.github.io/howtomakeaslider/ which is quite illustrative, but still it would be worthless to just copy the code (which by the way I do not understand fully), because what I need/want is to understand how to do one.
On the small free-lance jobs I've done, it's been easy because I just look for plugins, but now I realize that I need to start learning how to make these by myself, and it would be good to start by doing a slider.
What are the things I need? Like I was reading I should create a slider class and create methods for next(), prev() and goTo() sliding-methods. The problem is that for what I hear javascript/jQuery is not a pure OOP language, and it is done differently.
What are the basic things I need to store the images inside an array, know the current position and slide to the next/previous one?
Help would be much appreciated. My HTML and CSS markup is the following:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Slider Plugin</title>
<style type="text/css">
a{
text-decoration: none;
color: black;
text-align: center;
}
.slider{
width: 300px;
height: 200px;
overflow: hidden;
float: left;
}
.slider > ul{
position: relative;
list-style: none;
margin: 0;
padding: 0;
-webkit-transition: 0.5s left;
-moz-transition: 0.5s left;
-ms-transition: 0.5s left;
-o-transition: 0.5s left;
}
.slider > ul li img{
width: 300px;
height: 200px;
overflow: hidden;
}
.img-thumb-container > ul{
list-style: none;
margin: 0;
padding: 0;
}
.thumb{
width: 50px;
height: 50px;
display: inline-block;
text-align: center;
}
.img-thumb-container{
float: left;
height: 150px;
width: 200px;
}
</style>
<script src="js/jquery.js"></script>
<script src="js/slider.js"></script>
</head>
<body>
<div class="img-thumb-container">
<ul>
<li><button type="button">↑</button></li>
<a href="#"><li>
<img src="images/s1.jpg" class="thumb">
</li></a>
<a href="#"><li>
<img src="images/s2.jpg" class="thumb">
</li></a>
<a href="#"><li>
<img src="images/s3.jpg" class="thumb">
</li></a>
<li><button type="button">↓</button></li>
</ul>
</div>
<div class="slider">
<ul>
<li><img src="images/s1.jpg"></li>
<li><img src="images/s2.jpg"></li>
<li><img src="images/s3.jpg"></li>
</ul>
</div>
</body>
</html>
This is the basic markup I need for what I understand.
I was also asked the same thing in a Job interview and here is the code that I used to passed the interview:
HTML CODE:
<div id="background-slideshow">
<img id="home-image" class="slides" src="img/home-image.jpg" />
<img id="shop-image" class="slides" src="img/shop-image.jpg" />
<img id="dine-image" class="slides" src="img/dine-image.jpg" />
<img id="watch-image" class="slides" src="img/watch-image.jpg" />
</div>
CSS CODE:
div#background-slideshow{
position: relative;
height: 745px;
width: 1440px;
position: absolute;
top: 0px;
right: -10px;
}
img.slides{
position: absolute;
width: 100%;
top: 0px;
right: 0px;
height: 745px;
}
img#home-image{
z-index: -666;
}
img#shop-image{
z-index: -777;
}
img#dine-image{
z-index: -888;
}
img#watch-image{
z-index: -999;
}
JQUERY CODE:
var indexer = 0;
var animateInterval;
function animate(){
if(indexer == 0){
$("#background-slideshow > #watch-image").fadeOut(2000);
$("#background-slideshow > #home-image").fadeIn(2000);
}
else if(indexer == 1){
$("#background-slideshow > #home-image").fadeOut(2000);
$("#background-slideshow > #shop-image").fadeIn(2000);
}
else if(indexer == 2){
$("#background-slideshow > #shop-image").fadeOut(2000);
$("#background-slideshow > #dine-image").fadeIn(2000);
}
else if(indexer == 3){
$("#background-slideshow > #dine-image").fadeOut(2000);
$("#background-slideshow > #watch-image").fadeIn(2000);
}
if(indexer == 3) indexer = 0;
else indexer++;
}
animateInterval = setInterval(animate, 10000);
animate();
Give it a try and good luck, I also never learned it from school too.
You should check out this free course:
30 Days to Learn jQuery
After going through the basics of jQuery in the first chapter, you'll be learning how to build a slider from scratch.
The main video is in the chapter about Effects - The Obligatory Slider (First Stab).
Don't feel bad man. I am a Software Engineer. So far I have 5 years experience as a PHP Developer. 5 years experience as a SEO Engineer, and I am a Senior UI Developer and none of that was taught to me in school either! lol. My best advice to you is:
Find the easiest smallest Jquery Slider
Break it down and re-verse engineer it
Then start adding your own flavor.
I've taught myself a lot this way. Tutorials take a long time and it looks like you need a quick solution.
Do take the tutorial eventually tho.
Good luck
HTML:
<div id="background-slideshow" class="background-slideshow">
<img class="current" src="img/1.jpg" />
<img src="img/2.jpg" />
<img src="img/3.jpg" />
<img src="img/4.jpg" />
<img src="img/5.jpg" />
</div>
CSS:
div.background-slideshow img {
display: none;
z-index: 1;
width: 100%;
vertical-align: middle;
}
div.background-slideshow img.current {
display: inline;
z-index: 2;
}
div.background-slideshow img.previous {
z-index: 1;
}
jQuery:
var animateInterval;
function rotateImagesForward(){
var oCurrentPhoto = $("#background-slideshow img.current");
var oNextPhoto = oCurrentPhoto.next();
if (oNextPhoto.length == 0) {
oNextPhoto = $("#background-slideshow img:first");
}
oCurrentPhoto.removeClass("current").addClass("previous");
oNextPhoto.css({opacity:0.0}).addClass("current")
.animate({opacity:1.0}, 500, function(){
oCurrentPhoto.removeClass("previous");
});
}
animateInterval = setInterval(rotateImagesForward, 4000);
I'm using bootstrap's carousel ( http://twitter.github.com/bootstrap/javascript.html#carousel ) to show a user submited gallery. Because it's user submited, it doesnt look very good with the rest of my website design thats why i want to add a layer mask on top off everything
Here is the mask : http://img52.imageshack.us/img52/2659/degrade.png
Unfortunatly, I'm unable to show that particular div...
It has to be non clickable because when a user click on a picture of the carousel, it opens modal popup with the full sized picture.
My css (its using less but you get the idea):
.carousel {
width: 292px;
height: 163px;
.carousel-inner {
width: 292px;
height: 163px;
img {
width: 100%;
height: 100%;
}
}
}
.carousel-control {
margin-top: 0;
top: 0;
right: 0;
background: none;
border: 0;
width: 60px;
height: 163px;
opacity: 0.65;
background-repeat: no-repeat;
&:hover.right {
background-image: url('/assets/index/r_arrow.png');
}
&:hover.left {
background-image: url('/assets/index/l_arrow.png');
}
}
heres is my html:
<div class="carousel slide">
<div class="carousel-inner">
<div class="item active">
<img src="thumbnail1.jpg" />
</div>
<div class="item">
<img src="thumbnail2.jpg" />
</div>
<div class="item">
<img src="thumbnail3.jpg" />
</div>
</div>
<a class="carousel-control left" href=".carousel" data-slide="prev"> </a>
<a class="carousel-control right" href=".carousel" data-slide="next"> </a>
</div>
Depending on your cross-browser support needs, you could try giving the overlay pointer-events: none. Here's an example of that.
If you insert <div class="overlay"></div> into .carousel-inner, give .carousel-inner {position: relative;} and
.overlay {
background: url(http://img52.imageshack.us/img52/2659/degrade.png) top left no-repeat;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 10;
pointer-events: none;
}
There's an answer here that gives information and links to solutions using javascript. Unfortunately, the resources for the accepted answer to the linked question have gone offline, but there is a fairly simple demonstration here: http://jsbin.com/uhuto