FlexSlider : get the caption vertically on right side - javascript

I'm using the cool Felxslider to display a slideshow on a sharepoint installation.
it works quite well, but i still have two questions :
1- How to display the caption (you know, the little transparent background with title/description of the picture) not on the bottom of the image, but on the right side?
And not hover the picture, if possible.
2- I have N images to whos, but the slider always shows N+N images, the first extra ones are clones of the images, but the last is always just blank.
For example, i have 3 pictures to show, but the slider generates 6 slides : Number 4 and number 5 are clones of number 1 and number2, and number 6 is totally blank.
It displays such extra pictures no matter how many pictures I have (if i have 2 pictures to display, it will display 4).
Do you have any idea on how to get rid off all these clones?
Thanks a lot to answer, and have a nice day!

in order to have the caption appear on the right side I added some css rules and a specific HTML caption format.
Here's a jfiddle of the right caption display: http://jsfiddle.net/tyuth1sr/23/
Use the following css on your website's custom stylesheet, then use the HTML format for the captions:
CSS
/*
* flexslider slide styling
*/
.slides {
overflow: hidden !important;
}
.slides div .flex-caption {
overflow: scroll !important;
}
/*
* flexslider caption styling
*/
.flex-caption {
position: absolute;
text-align: left;
font-size: 11px;
background:rgba(255, 255, 255, 0.7);
z-index: 100;
padding: 20px 10px 35px 30px;
width: 287px;
padding-top: 100%;
bottom: 0px;
color: #000;
}
.right {
right: 0;
margin-bottom: 0px;
}
.show-caption {
position: absolute;
top: 48%;
right: 240px;
z-index: 99;
opacity: 0.7;
filter: alpha(opacity=70); /* For IE8 and earlier */
pointer-events: none;
}
And format your flexslider captions like so:
HTML
<ul class="slides" id="slideshow" ondragstart="return false;">
<li>
<img src="https://iluvmafuckinglife.files.wordpress.com/2012/04/256989-a-sphere-sculpture-made-from-easter-eggs-is-on-display-on-the-day-of-i.jpg" />
<div class="flex-caption right">
<div class="caption-content">
<p><span class="hcaption">Caption 1</span></p>
<br /><br />
<p class="hcap">Caption 1 text goes here.</p>
</div>
</div>
</li>
<li>
<img src="http://s3-ec.buzzfed.com/static/enhanced/web05/2012/2/8/11/enhanced-buzz-wide-29760-1328717305-32.jpg" />
<div class="flex-caption right">
<div class="caption-content">
<p><span class="hcaption">Caption 2</span></p>
<br /><br />
<p class="hcap">Caption 2 text goes here.</p>
</div>
</div>
</li>
Please note that you can make the caption appear on over any side of the flexslider slide by removing the .right css position specification of "right: 0px" and adding "left: 0px", "top: 0px;" or "bottom: 0px;" depending on where you want it to appear. You would also have to tweak the text formatting/background padding CSS to make it appear properly in one of those other positions.

Related

How can I make a general JavaScript function to toggle the visibility of a div on click?

I have a webpage with a layout of multiple divs in a gridlike arrangement that all are going to contain separate text. When clicked, I want the grid to expand into a div that is z-indexed above the other elements. on click of this div, it will close.
The thing is, I do not want to make a separate function for each one of the divs, instead I want to make a generic function that will recognize which div is being clicked, and then access the divs child paragraph element and toggle that. (There is also an img within the div).
here is a cut of the HTML with the overall format that the other sections follow.
<div id="Section" onclick="portfolio()">
<h6 class="number">2. Stand Up Jetski</h6>
<img src="../resources/images/icons8-paper-ship-100.png"
alt="Brake Disc"
id="click-image">
<p class="popuptext" id="jetski-text"> random </p>
</div>
<div id="Section" onclick="portfolio()">
<h6 class="number">3. PC build</h6>
<img src="../resources/images/icons8-workstation-100.png"
alt="Brake Disc"
id="click-image">
<p class="popuptext" id="pc-text"> random </p>
</div>
Here is the javascript I came up with from internet searches.
//Portfolio Pop ups//
function portfolio() {
parent = document.getElementById('Section');
children = parent.children[0];
children.classlist.toggle('show')
}
Here is the CSS I have for these popup texts
.popuptext {
border : 1px solid var(--black);
z-index : 100;
position : absolute;
left : 50%;
top : 50%;
margin-left : -500px;
margin-top : -50px;
height : 1000px;
width : 1000px;
visibility : hidden;
}
.popuptext .show {
visibility : visible;
}
As explained earlier, when I click the div, I want the child element to toggle visibility. So far, when I click, nothing happens.
You have an issue with some of your js and your CSS. You want to pass the clicked element into your event using this. Then use querySelector() to drill down to the popup text and toggle it. Finally in your CSS, use 100vw and 100vh to make the text fill the page, and use flex to center the text in the div.
I also just changed your ids to classes for the sections, you can only have one id of the same name per webpage.
function portfolio(el) {
const textEl = el.querySelector('.popuptext')
textEl.classList.toggle('show')
}
.popuptext {
border: 1px solid #000;
z-index: 100;
visibility: hidden;
display: flex;
height: 100vh;
width: 100vw;
margin: 0;
position: absolute;
top: 0;
left: 0;
justify-content: center;
align-items: center;
background: #fff;
}
.popuptext.show {
visibility: visible;
}
<div class="section" onclick="portfolio(this)">
<h6 class="number">2. Stand Up Jetski</h6>
<img src="../resources/images/icons8-paper-ship-100.png" alt="Brake Disc" id="click-image">
<p class="popuptext" id="jetski-text"> random 1 </p>
</div>
<div class="section" onclick="portfolio(this)">
<h6 class="number">3. PC build</h6>
<img src="../resources/images/icons8-workstation-100.png" alt="Brake Disc" id="click-image">
<p class="popuptext" id="pc-text"> random 2 </p>
</div>

Can this be achieved without js?

I have this image gallery which I want to do without the javascript. Can this be done without using the javascript ?? Just need the big picture to change when mouseover or something similar.
function myFunction(imgs) {
var expandImg = document.getElementById('expandedImg')
var imgText = document.getElementById('imgtext')
expandImg.src = imgs.src
imgText.innerHTML = imgs.alt
expandImg.parentElement.style.display = 'block'
}
* {
box-sizing: border-box;
}
body {
margin: 0;
font-family: Arial;
}
/* The grid: Four equal columns that floats next to each other */
.column {
float: left;
width: 25%;
padding: 10px;
}
/* Style the images inside the grid */
.column img {
opacity: 0.8;
cursor: pointer;
}
.column img:hover {
opacity: 1;
}
/* Clear floats after the columns */
.row:after {
content: '';
display: table;
clear: both;
}
/* The expanding image container */
.container {
position: relative;
display: none;
}
/* Expanding image text */
#imgtext {
position: absolute;
bottom: 15px;
left: 15px;
color: white;
font-size: 20px;
}
/* Closable button inside the expanded image */
.closebtn {
position: absolute;
top: 10px;
right: 15px;
color: white;
font-size: 35px;
cursor: pointer;
}
<div style="text-align: center">
<h2>Tabbed Image Gallery</h2>
<p>Click on the images below:</p>
</div>
<!-- The four columns -->
<div class="row">
<div class="column">
<img src="img_nature.jpg" alt="Nature" style="width: 100%" onclick="myFunction(this);" />
</div>
<div class="column">
<img src="img_snow.jpg" alt="Snow" style="width: 100%" onclick="myFunction(this);" />
</div>
<div class="column">
<img src="img_mountains.jpg" alt="Mountains" style="width: 100%" onclick="myFunction(this);" />
</div>
<div class="column">
<img src="img_lights.jpg" alt="Lights" style="width: 100%" onclick="myFunction(this);" />
</div>
</div>
<div class="container">
<span onclick="this.parentElement.style.display='none'" class="closebtn">×</span
>
<img id="expandedImg" style="width: 100%" />
<div id="imgtext"></div>
</div>
Any help is appreciated. Sorry for adding this text as StackOverflow won't let me post this without adding more text.
Thanks in advance.
Preface
Though not impossible, I nonetheless highly recommend using JavaScript instead of CSS for this task. You should not see the following content of this answer as an alternative to JavaScript's intended purpose, but see this as a playful "solution".
Another big point to use JavaScript instead of CSS is: Using CSS for this task is not accessible at all. You should always strive to make good, easy-to-use and accessible websites.
You should especially refrain from using this in a business environment for the aforementioned reason.
CSS-only solution
Necessary HTML changes
Since CSS is cascading, the image-previews need to come before either the big image itself or its ancestor. You can imagine this like this: The HTML is a tree, and effects are only carried through down to the leaves, but cannot affect neighbouring branches as that would require backtracking at some point.
In code, this could look like this:
<!-- Either this (case 1): -->
<img class="img-preview">
<img class="big-img">
<!-- Or this (case 2): -->
<img class="img-preview">
<div>
<img class="big-img"> <!-- May be nested deeper -->
</div>
The CSS
The CSS should be relatively simple. The only issue is, that for each image-preview, a new CSS-rule needs to be added. This makes adding a new image-preview a bit more work in the future, but more importantly: It crams your CSS full with unnecessary rules! This will probably result in unused CSS-rules in case you'll rewrite some, and will hinder maintenance and readability heavily.
Friendly reminder: This should better be done by using JavaScript!
CSS' :hover-pseudo-class is effectively the same as JS' mouseover. Using this and the general sibling-combinator ~ (and potentially the descendant combinator ), we can override the big image's background-image-property depending on the image-preview that is hovered:
/* Either this (case 1): */
.img-preview:hover~.big-img {/* ... */}
/* Or this (case 2): */
.img-preview:hover~* .big-img {/* ... */}
As I have already mentioned, every image-preview requires its own CSS-rule. This is because CSS cannot use HTML-attributes for its properties (except for pseudo-elements and their content-property, I think).
This means, the CSS could look like this for the current HTML:
/* The CSS */
.img-preview[data-src="https://picsum.photos/id/10/64/64"]:hover~.big-img {
background-image: url("https://picsum.photos/id/10/64/64");
}
.img-preview[data-src="https://picsum.photos/id/1002/64/64"]:hover~.big-img {
background-image: url("https://picsum.photos/id/1002/64/64");
}
/* etc. */
/* Ignore; for styling only */
img {border: 1px solid black}
.img-preview {
width: 2rem;
height: 2rem;
}
.big-img {
width: 4rem;
height: 4rem;
}
<img class="img-preview"
src="https://picsum.photos/id/10/32/32"
data-src="https://picsum.photos/id/10/64/64">
<img class="img-preview"
src="https://picsum.photos/id/1002/32/32"
data-src="https://picsum.photos/id/1002/64/64">
<!-- etc. -->
<img class="big-img">
(Sidenote: I used attribute-selectors here, but the same thing could be done using IDs or similar, as long as every image-preview can be selected individually.)
Endnote
Adding text-descriptions while hovering may be solved in a similar fashion, but is left as a task.
Unfortunately, the big image won't stay when using this approach. If you want it to stay, you should take a look at Abd Elbeltaji's answer. They use <input>- and <label>-tags to accomplish that, together with CSS' :checked-pseudo-class.
Despite looking so, changing the HTML as shown does not restrict you in how you can style your elements, especially when using FlexBox or CSS Grid. Not only do they make styling easier, they are also meant to easily make a website responsive.
Accessibility
Again: This is not an accessible solution! This whole task should certainly be handled by JavaScript.
Should this be a public website, then I advise adding alt-descriptions for every image, even the previews. Unfortunately updating the big image's alt-attribute via CSS is impossible, making it inaccessible, which in turn harms your SEO. This being said, I commend your effort in displaying the image's alt-attribute in your original code, though not perfect. You might want to take a look at <figure>.
While we're at it: I'd also advise learning some semantic HTML-tags for the purpose of accessibility.
Pseudo-elements (::after, ::before, etc.) are also inaccessible. You should not use them to contain any relevant information/text. Though they may be used for styling-purposes in every imaginable way.
Yes, you can achieve the same behavior without the use of javascript, you may use the concept of input elements (checkbox for single toggle value, radio for multiple select values) as adjacent siblings to your elements that they should be affected of the input, and by utilizing the :checked pseudo selector for inputs in css, in a compination with the adjacent sibling selector ~ you can affect the desired elements when the input is checked. You can also use labels which will allow you to hide your inputs and trigger their values with whatever is inside your label.
// No JS!
* {
box-sizing: border-box;
}
body {
margin: 0;
font-family: Arial;
}
/* The grid: Four equal columns that floats next to each other */
.column {
float: left;
width: 25%;
padding: 10px;
}
/* Style the images inside the grid */
.column img {
opacity: 0.8;
cursor: pointer;
}
.column img:hover {
opacity: 1;
}
/* Clear floats after the columns */
.row:after {
content: "";
display: table;
clear: both;
}
/* The expanding image container */
.container {
position: relative;
}
/* Expanding image text */
#imgtext::after {
position: absolute;
bottom: 15px;
left: 15px;
color: white;
font-size: 20px;
}
/* Closable button inside the expanded image */
.closebtn {
position: absolute;
top: 10px;
right: 15px;
color: white;
font-size: 35px;
cursor: pointer;
}
.container .img {
height: 500px;
width: 100%;
background-image: url(https://images.pexels.com/photos/15286/pexels-photo.jpg?auto=compress&cs=tinysrgb&dpr=2&h=650&w=940);
background-size: cover;
}
/* Tab select */
input[name=tabSelect],
#hideImage {
display: none;
}
#tabSelect1:checked~div.container .img {
background-image: url(https://images.pexels.com/photos/15286/pexels-photo.jpg?auto=compress&cs=tinysrgb&dpr=2&h=650&w=940);
}
#tabSelect2:checked~div.container .img {
background-image: url(https://images.pexels.com/photos/869258/pexels-photo-869258.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=650&w=940);
}
#tabSelect3:checked~div.container .img {
background-image: url(https://images.pexels.com/photos/1183021/pexels-photo-1183021.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=650&w=940);
}
#tabSelect4:checked~div.container .img {
background-image: url(https://images.pexels.com/photos/1124960/pexels-photo-1124960.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=650&w=940);
}
#tabSelect1:checked~div.container #imgtext::after {
content: "Nature";
}
#tabSelect2:checked~div.container #imgtext::after {
content: "Snow";
}
#tabSelect3:checked~div.container #imgtext::after {
content: "Mountains";
}
#tabSelect4:checked~div.container #imgtext::after {
content: "Lights";
}
/* image hide btn */
#hideImage:checked~div.container {
display: none;
}
<div style="text-align:center">
<h2>Tabbed Image Gallery</h2>
<p>Click on the images below:</p>
</div>
<input type="radio" name="tabSelect" id="tabSelect1">
<input type="radio" name="tabSelect" id="tabSelect2">
<input type="radio" name="tabSelect" id="tabSelect3">
<input type="radio" name="tabSelect" id="tabSelect4">
<!-- The four columns -->
<div class="row">
<div class="column">
<label for="tabSelect1">
<img src="https://images.pexels.com/photos/15286/pexels-photo.jpg?auto=compress&cs=tinysrgb&dpr=2&h=650&w=940" alt="Nature" style="width:100%">
</label>
</div>
<div class="column">
<label for="tabSelect2">
<img src="https://images.pexels.com/photos/869258/pexels-photo-869258.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=650&w=940" alt="Snow" style="width:100%">
</label>
</div>
<div class="column">
<label for="tabSelect3">
<img src="https://images.pexels.com/photos/1183021/pexels-photo-1183021.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=650&w=940" alt="Mountains" style="width:100%">
</label>
</div>
<div class="column">
<label for="tabSelect4">
<img src="https://images.pexels.com/photos/1124960/pexels-photo-1124960.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=650&w=940" alt="Lights" style="width:100%">
</label>
</div>
</div>
<input type="checkbox" id="hideImage">
<div class="container">
<label for="hideImage" class="closebtn">×</label>
<div class="img"></div>
<div id="imgtext"></div>
</div>
Here is a working example in: JSFiddle
Note! this approach is not optimal and would be tricky to expand in case you need to add more values.
PS: I had to change the images since the ones provided in your code do not exist.

How to position a div above another div?

My code is:
HTML:
<section>
<div id="banner">
<div class="container">
<p class="para">hello world</p>
</div>
<div class="container banner-bottom">
<div class="card card-primary text-center z-depth-2 contact-main-text">
<div class="card-block">
<p class="white-text">Please fill out the form below and ESC
staff will be in contact with you shortly.</p>
</div>
</div>
</div>
</div>
</section>
CSS:
.para{
color:white;
background: red;
padding:70px;
text-align:center;}
.white-text{
background:green;
padding:20px;}
Output is: Bootply
And i want:
Could anyone help me with that?
You can set negative top margin to overlay the second div, see the live example:
<div class="container banner-bottom" style="margin-top:-5%;padding:2%">
http://www.bootply.com/MorC45NB4V
PS: I have used inline css just to show, avoid inline css.
My solution uses jQuery and some calculations. My calculation works even if you move the elements around the document. I also used CSS for the margins you wanted.
jQuery
//location of bottom of the red container
var bottomOfContainer = $('#onTopOfMe').offset().top + $('#onTopOfMe').height();
//gets the bottom 4th of the red container
var placement = bottomOfContainer - ($('#onTopOfMe').height() / 4);
//setter of top for green container
$('#placeMe').offset({"top": placement});
CSS
p.white-text{
margin-left:5%;
margin-right:5%;
}
Output
bootply
1) In case you want your lower banner to have a full width:
You could add position: relative; to the lower banner and position it adding a bottom value and use margin to create the same visual effect asked in the question.
.banner-bottom {
position: relative;
bottom: 45px;
margin: 0 40px;
}
2) In case you don't need to have a banner with full width and just center it, then no need to use margins. Remember to set one parent as position: relative;:
#banner { position:relative;}
.banner-bottom {
position: absolute;
top:75%;
right:0;
bottom:auto;
left:0;
}
CODEPEN
http://codepen.io/alexincarnati/pen/PWOPjY
Here's my solution for this.
Basically just make the position of the card block "relative", position the "top" position accordingly, then set the margin to "auto" to center it.
.card-block {
position: relative;
top: -50px;
margin: auto;
width: 80%;
}
A bit of position could help you, here's a rough version that will hopefully get you thinking what you need to do:
#banner { position:relative;}
.banner-bottom { position: absolute; top:75%;right:0;bottom:auto;left:0; }
Heres a forked bootply: http://www.bootply.com/Imuh4wUj50

CSS position change on image next to it

So, I have the same image that I need to overlap each other. The first one as you can see has an z-index:1 and the others of 0. But, as the images keep repeating I have to keep creating a new style to make the next one 115px to the right. Is there a css pseudo method to automate this or do I have to revert to using jquery or js to bump it to the right?
<style>
img.overlap{z-index:1;position:absolute;left:670px;}
img.underlap{z-index:0;position:absolute; left:785px;}
</style>
<div class="span12">
<img src="img/blue_btn.png" alt="Home" class="overlap"/>
<img src="img/blue_btn.png" alt="About" class="underlap"/>
<img src="img/blue_btn.png" alt="Services" class="underlap"/>
<img src="img/blue_btn.png" alt="Portfolio" class="underlap"/>
<img src="img/blue_btn.png" alt="Blog" class="underlap"/>
<img src="img/blue_btn.png" alt="Contact" class="underlap"/>
</div>
UPDATE: I was cropping the image as I read this post as I knew that it would be hard to visualize. Here is the nav area. I have cropped the first one and I will repeat them and later change the alpha with jquery.
http://weslice.com/images/nav_complete.jpg
You should try using float and margins instead of absolute positioning.
http://www.w3schools.com/css/css_float.asp
How about using display : inline-block to get your elements to sit next to each-other, then use margin : -*px to overlap the elements:
.span12 a {
display : inline-block;
margin : 0 0 0 -20px;/*this margin is responsible for the overlap between elements*/
/*IE 6&7 Compatibility*/
*display : inline;/*only read by IE7*/
zoom : 1;/*give the element the `hasLayout` property since you can't give it to an element directly*/
_height : 50px;/*only read by IE6, but is necessary to specify a height for IE6*/
}
Here is a demo: http://jsfiddle.net/WJKS5/2/
Update
To stack the element from left to right instead of right to left:
.span12 a {
float : right;
margin : 0 -10px 0 0;/*this margin is responsible for the overlap between elements*/
}
Here is a demo: http://jsfiddle.net/WJKS5/4/
I think this fiddle http://jsfiddle.net/2vUzp/9/ achieves the effect without the need for classes (though it does reverse the order of the menu in the html, but not in what is displayed to the average user). After looking at your sample image, you may not want the "hover" effect in my example, but that can be removed.
CSS
.span12 {
float: left;
}
.span12 a {
position: relative;
margin-right: -30px;
display: block;
float: right;
}
.span12 a:first-child {
margin-right: 0;
}
.span12 a:hover {
z-index: 1;
}
.span12 img { /*for demo*/
display: block;
width: 100px;
height: 20px;
border: 1px solid blue;
background-color: cyan;
}
HTML
<div class="span12">
<img src="img/blue_btn.png" alt="Contact"/>
<img src="img/blue_btn.png" alt="Blog"/>
<img src="img/blue_btn.png" alt="Portfolio"/>
<img src="img/blue_btn.png" alt="Services"/>
<img src="img/blue_btn.png" alt="About" />
<img src="img/blue_btn.png" alt="Home" />
</div>
Since you are trying to accomplish an overlap, floating's probably not going to work. I would recommend you use CSS sibling selectors and write rules specifically for 'img', 'img + img', 'img + img + img', etc. that would increase incrementally. I think that should be the only pure CSS way around it. Doing this with JavaScript would be a breeze.

Problem with PNG image on top of an image in CSS?

I am using a jQuery content rotator and I want to place a
PNG image on top of a image and on top of that text.
This is how my rotator looks like in HTML:
<div id="testimonials">
<div class="slides">
<div class = "testimonialContainer">
<div class ="leesmeer"> <img src ="http://site/afbeeldingen/test.jpg" ><div class="caption">LORUM IPSUM DOLOR SIT AMET </div></div>
</div>
<div class = "testimonialContainer">
<p class = "testimonial"> 2 </p>
<div class ="leesmeer"> <img src ="http://site/afbeeldingen/test.jpg" ></div>
</div>
</div>
</div>
Here is the CSS:
.testimonialContainer {height: 123px}
#testimonials{
width: 210px;
height: 125px;
}
.slides div{
width: 210px;
xheight: 25px;
xpadding: 5px;
.slides div.caption{
background-image: url(../images/h_contentrotator_zwart.png);
/*background-color:#000000;
filter:alpha(opacity=60);
-moz-opacity: 0.6;
opacity: 0.6;*/
color: #fff;
width: 210px;
height: 41px;
position: relative;
top: -24px;
padding: 2px 20px 2px 10px;
zbehavior: url("iepngfix.htc")
}
The problem is that the PNG image doesn't appear and also the text doesn't appear.
Can someone help me out?
You need to add a dot (.) at last selector:
.slides div.caption{
Right now it's not there, but should be.
If the problem is not solved after adding a dot
then be more specific. Change
.slides div.caption
to this:
#testimonials a div.caption
And remove Z from behaviour.
And even if it is not solved then give me a link of jQuery script homepage.
Make sure that you have the right path to the background image. If the style is in the <head> of the HTML page, then the path will be relative to the HTML page. If the style is within an external stylesheet, then the path will be relative to the file location of the stylesheet.
You also might want to get it working without the Internet Explorer 6 PNG fixes first, and then add the fixes back in after you know the rest of the code is correct.

Categories