Image as a toggle hide/reveal button - javascript

Hello Stack Overflow,
I am a photographer building an html website, so excuse my ignorance. I am looking to use an image as a button that reveals a set of text on click. I can't seem to find a way to do this without having a button over the image. Is there an easier way? or perhaps is there another word other than "button" that I am lacking in searching for this?
Update:
I again apologize for my ignorance, I feel I lacked clarity in my question. I used a toggle/reveal button on my page and I want the text to start hidden so that the photograph reveals the text,rather than removes it.
See site:
http://lyonswork.com/

You can use several options, 1 option is to use the css :hover state. This allows the user to hover over the image and then reveal a text.

Have you tried onclick attribute on img tag. If it works then you just have to write your javascript code.

I suppose you are looking for something like that ?
(just click on figure element to show / hide text over image)
const myImage = document.querySelector('#my-image')
;
myImage.onclick =()=>
{
myImage.classList.toggle('noCaption')
}
figure#my-image {
position: relative
}
figure#my-image img {
width: 500px;
height: 300px;
border: 1px solid grey;
padding: 2px;
}
figure#my-image figcaption {
position: absolute;
bottom: 3px;
left: 3px;
display: block;
width: 492px; /* 500 - (2*4) */
padding: 4px;
color: white;
background-color: rgba(0, 0, 0, 0.5);
}
q {
display: block;
text-align: center;
}
cite {
float: right;
}
figure#my-image.noCaption figcaption {
display: none !important;
}
<figure id="my-image" class="noCaption">
<img src="https://picsum.photos/500/300" alt="something revelant" />
<figcaption>
<q>A people who do not read is a risk for democracy</q>
<cite>Fréderic Paulin</cite>
</figcaption>
</figure>
OR
const myImage = document.querySelector('#my-image');
myImage.onclick=()=>
{
myImage.classList.toggle('noCaption')
}
figure#my-image {
width: 506px;
}
figure#my-image * {
display: inline-block;
box-sizing: border-box;
width: 100%;
}
figure#my-image img {
border: 1px solid grey;
padding: 2px;
margin: 0;
}
figure#my-image figcaption {
padding: .4em 0 .3em 0;
color: white;
background-color: rgba(0, 0, 0, 0.5);
}
q {
text-align: center;
}
cite {
width: 100%;
padding : .7em .5em 0 0;
text-align: right;
}
figure#my-image.noCaption figcaption {
display: none !important;
}
<figure id="my-image" class="noCaption">
<img src="https://picsum.photos/500/300" alt="something revelant" />
<figcaption>
<q>A people who do not read is a risk for democracy</q>
<cite>Fréderic Paulin</cite>
</figcaption>
</figure>

Related

How can i get 2 classes by id inside the same function

I need to target two div elements and toggle their classes simultanouesly.
I understand that I can get multiple divs "by ID" by using .querySelectorAll
but when I get to .classlist.toggle ("NewClassName"); how can I target two classes??
So here's some code:
#small-div{
background-color:#aaaaaa;
border: 3px solid #aaaaaa;
padding: 0px 0px 0px 0px;
margin: auto 10px auto auto;
border-radius: 10px;
overflow: auto;
}
.tobetoggled{
width: 45%;
float: left;
}
#small-div2{
background-color:#aaaaaa;
border: 3px solid #aaaaaa;
padding: 0px 0px 0px 0px;
margin: auto 10px auto auto;
border-radius: 10px;
overflow: auto;
}
.tobetoggled2{
width: 45%;
float: right;
}
.toggletothis{
width: 100%;
float: left;
position: fixed;
display: block;
z-index: 100;
}
.toggletothis2{
width: 100%;
float: left;
position: fixed;
display: block;
z-index: 100;
}
.whensmalldivistoggled{
display: none;
}/* when small-div is clicked, small-div toggles to class "tobetoggled" while small-div 2 simultaneously toggles to class "whensmalldivistoggled" (the display none class) */
<div id="container">
<div class="tobetoggled" onclick="function()" id="small-div">
</div>
<div class="tobetoggled2" onclick="separatefunction()" id="small-div2">
</div>
</div> <!-- end container -->
<script>
function picClicktwo() {
document.querySelectorAll("small-div, small-div2").classList.toggle("toggletothis, whensmalldivistoggled");
}
</script>
So as you can see one div is on the right, the other is on the left, each set to 45% width. So if I toggle one div to 100% width the browser still respects the other divs space instead of taking the whole 100%.
So I'm thinking if I can get the div on the right ,for example, to not display when the div on the left is toggled, it will be out of the way so the left div can take all 100%
Maybe im going about this the wrong way. Any help is welcome. Thanks.
You can create a single javascript function that sets appropriate classes on each element. Since you have only two elements it is not too complex.
HTML
<div id="container">
<div id="lefty" onclick="toggle('lefty', 'righty')">Lefty</div>
<div id="righty" onclick="toggle('righty', 'lefty')">Righty</div>
</div>
JS
function toggle(target, other)
{
var t = document.getElementById(target);
var o = document.getElementById(other);
if (!t.className || t.className == "inative")
{
t.className = "active";
o.className = "inactive";
}
else
{
t.className = "";
o.className = "";
}
}
CSS
#container {
background-color: lightgreen;
padding: 15px 0;
}
#container div {
color: white;
width: 45%;
display: inline-block;
}
#lefty {
background-color: blue;
}
#righty {
background-color: purple;
}
#container div.active {
width: 90%;
}
#container div.inactive {
display:none;
}
https://jsfiddle.net/dLbu9odf/1/
This could be made more elegant or capable of handling more elements with something like toggle(this) and then some DOM traversal and iteration in javascript, but that's a bit beyond scope. If that were the case I would recommend jQuery.

JS newsticker issues

I have a site that wanted a TV credits-style ticker & I just went back to revisit & check up on them & noticed that the display was starting to break down. I'm hoping that those of you more experienced JS veterans can help me figure out where I've gone wrong, here.
My JS is as follows:
$('.sidescroll').totemticker({
row_height : '120px',
next : '#ticker-next',
previous : '#ticker-previous',
stop : '#stop',
start : '#start',
mousestop : true
});
jQuery(".sidescroll li").append("<hr />");
and the my CSS for it is as follows:
.sidescroll {
height: 100% !important;
display: block;
}
.sidescroll li {
margin: 10px;
text-align: left;
height: 120px;
}
.sidescroll hr {
height: 3px;
border: 0;
box-shadow: inset 0 3px 3px -3px rgba(92, 71, 112, 0.75);
}
.sidescroll li a {
font-family: 'lulo' !important;
}
.sidescroll li a:hover {
text-decoration: none;
color: #5c4770;
}
The ticker is for their blog posts, sort of a running list of posts, which is being pulled by the list category plugin & is limited to 20 characters for the excerpt. The issue that I noticed was that the horizontal row is starting to interact with a couple of the posts, which was not the case when the site was set up.
Turns out it's fairly simple. There is sometimes too much content in the boxes and they overflow into the one below. Either too much text or the word wrapping is splitting over too many lines.
Bonus (completely optional)
We can elegantly suppress this behavior (assuming the use of CSS3 to generate a gradient).
First we modify the javascript to insert the horizontal line as first child, then we insert a div with a class as a last child:
jQuery(".sidescroll li").prepend('<hr />');
jQuery(".sidescroll li").append('<div class="fadeToWhite"></div>');
Then we modify the css:
.sidescroll {
height: 100% !important;
display: block;
}
.sidescroll li {
margin: 10px;
text-align: left;
height: 120px;
/* additions: */
position: relative;
overflow: hidden;
}
.sidescroll hr {
height: 3px;
border: 0;
box-shadow: inset 0 3px 3px -3px rgba(92, 71, 112, 0.75);
}
.sidescroll li a {
font-family: 'lulo' !important;
}
.sidescroll li a:hover {
text-decoration: none;
color: #5c4770;
}
/* additions */
.sidescroll li div.fadeToWhite {
width: 100%;
height: 20px;
position: absolute;
bottom: 0;
background: linear-gradient(transparent, white);
}
This will hide any overflowing text while turning the additional div into a fade-to-white bar at the bottom of each list element to avoid a hard text-cut.

Adding A Div Caption To Divs Containing Sliders (Follow Up On Previous Q)

I currently have a grid layout made up of image sliders and text slider with square divs. I have just asked a question of how to add captions to these squares within the grid. Now I can do this nicely when the div contains a text slider. However when I try to apply the same caption to divs containing the image slider it does not work, could somebody please show me how I can do this.
CSS FOR DIVS
.slider2 { position: relative; }
.caption-box {
position: absolute;
right: 0;
height: 20px;
width:100px;
background-color: red; // change to suit
color: #fff; // change to suit
}
.trigger {
width: 200px;
height: 200px;
}
.static {
position: relative;
width: 200px;
height: 200px;
text-align: center;
font-size: 0;
border-style: solid;
border-width: 1px;
border-color: #CCCCB2;
border-radius: 5px;
}
BELOW IS THE HTML CODE OF THE TEXT SLIDER DIV WHERE THE CAPTION DIV WORKS WELL
<div class="trigger">
<div class="slider2">
<div style="border-style: solid; border-width: 1px; border-color: #CCCCB2; border-radius: 5px; height: 200px; width: 200px; color: #CCC;" class="just_text"><div class="caption-box">Monthly Plan</div>As part of our budget graphic design service we also offer a money saving monthly advertising schedule option. Whether it be for 6, 9 or 12 months we will remove all stress of advertising from your office leaving you to concentrate on your customers. </div>
<div style="border-style: solid; border-width: 1px; border-color: #CCCCB2; border-radius: 5px; height: 200px; width: 200px; color: #CCC;" class="just_text"><div class="caption-box">Web Updates</div>Our website design service also includes a money saving update scheme. For a monthly fee you can have updates to keep your website fresh and dynamic. No other company can offer this service.</div>
</div>
</div>
BELOW IS THE HTML CODE OF THE IMAGE SLIDER WHERE I CAN NOT GET THE CAPTION DIV TO WORK
<div class="trigger">
<div tabindex="0" class="maincontent static"><div class="slider2">
<img src="client9.jpg" height="200" width="200" />
<img src="client10.jpg" height="200" width="200" />
<img src="client11.jpg" height="200" width="200" />
<img src="client2.jpg" height="200" width="200" />
</div></div>
</div>
JAVASCRIPT
<script>
$(function(){
$('.slider').sss({
slideShow : true, // Set to false to prevent SSS from automatically animating.
startOn : 0, // Slide to display first. Uses array notation (0 = first slide).
transition : 400, // Length (in milliseconds) of the fade transition.
speed : 20000, // Slideshow speed in milliseconds.
showNav : true // Set to false to hide navigation arrows.
});
$('.slider2').sss({
slideShow : true, // Set to false to prevent SSS from automatically animating.
startOn : 0, // Slide to display first. Uses array notation (0 = first slide).
transition : 400, // Length (in milliseconds) of the fade transition.
speed : 10000, // Slideshow speed in milliseconds.
arrows : false // Set to false to hide navigation arrows.
});
});
</script>
CSS THAT JAVASCRIPT LINKS TO CALLED SSS.CSS
.sss {
height: 0;
margin: 0;
padding: 0;
position: relative;
display: block;
overflow: hidden;
}
.ssslide {
width: 100%;
margin: 0;
padding: 0;
position: absolute;
top: 0;
left: 0;
display: none;
overflow: hidden;
}
.ssslide img {
max-width: 100%;
height: auto;
margin: 0;
padding: 0;
position: relative;
display: block;
}
.sssnext, .sssprev {
width: 25px;
height: 100%;
margin: 0;
position: absolute;
top: 0;
background: url('images/arr.png') no-repeat;
}
.sssprev {
left: 3%;
background-position: 0 50%;
}
.sssnext {
right: 3%;
background-position: -26px 50%;
}
.sssprev:hover, .sssnext:hover {
cursor: pointer;
}.row .col .trigger .slider2 .just_text {
color: #CCC;
}
The code for the images is incomplete, and had to create my own version to be able to replicate the issue. But once that was done, the problem was easy to find. You can see it working on this JSFiddle: http://jsfiddle.net/Lbrcbhxw/2/ (I took the liberty of cleaning it a bit so it was easier to read).
The problem is that .static has a font-size:0 that makes the text invisible. Remove it (or don't wrap the div with the images with it), and the problem will be solved.
.static {
position: relative;
width: 200px;
height: 200px;
text-align: center;
/* font-size: 0; */
border-style: solid;
border-width: 1px;
border-color: #CCCCB2;
border-radius: 5px;
}
The text version isn't wrapped around that .static, so that's why it was displayed correctly and didn't have the problem.

Show one element if another is above a certain height

I have a following HTML:
<span class="day-number">{{day-number}}</span>
<div class="event-box">
<div class="event-container">
</div>
<div class="more-events">more ...</div>
</div>
Event-container is filled with an unknown number of .event elements like the following:
<div class="event">{{event-name}}</div>
I want to show or hide the .more element based on if the .event-container has a height of over 76px (equal to the height of four .event elements stacked).
The styling for the above elements:
.event {
text-align: left;
font-size: .85em;
line-height: 1.3;
border-radius: 3px;
border: 1px solid #3a87ad;
background-color: #3a87ad;
font-weight: normal;
color: whitesmoke;
padding: 0 1px;
overflow: hidden;
margin-bottom: 2px;
cursor: pointer;
}
.event-box {
max-height: 76px;
overflow: hidden;
position:relative;
}
.event-box .more-events {
height: 10px;
position: absolute;
right: 0;
bottom: 10px;
display: none;
z-index: 5;
}
No styling for .event-container
I can do what I want with Javascript (jQuery):
$(".event-box").each(function(){
var $this = $(this);
if($this.children(".event-container").height() > 76){
$this.children(".more-events").css("display", "block");
} else {
$this.children(".more-events").css("display", "");
}
});
And run that every time a make a change, but I'd rather do it with CSS.
Is this possible? Maybe with pseudo elements or media queries or something?
JSFIDDLE: http://jsfiddle.net/pitaj/LjLxuhx2/
If changing the markup is acceptable there is a possibility to achieve a somewhat similarly looking page without using JavaScript to show or hide, here is the Fiddle
I have removed <div class="more-events">more ...</div> line and made elements of event class to get hide when it is necessary I also made them to appear when hovering over more ... .
The CSS I have added:
.event:nth-child(n){
display: none;
}
.event:nth-child(1),.event:nth-child(2),.event:nth-child(3),.event:nth-child(4){
display: block;
}
.event:nth-child(5){
text-indent: -9999px;
position: relative;
display: block;
color: black;
border: none;
background-color: #FFF;
}
.event:nth-child(5)::before{
position: absolute;
text-indent: 0px;
content: "more ...";
display: block;
}
.event:nth-child(5):hover{
position: static;
text-indent: 0;
border: 1px solid #3a87ad;
background-color: #3a87ad;
color: whitesmoke;
}
.event:nth-child(5):hover::before{
display:none;
}
.event:nth-child(5):hover ~ .event:nth-child(n){
display: block;
}
And for .event-box class I have commented out max-height: 76px; because in my browser 76px was not equal to the height of four .event elements stacked. Also removed update function.
I dont think it's possible using css only. but for better approach in what you are trying to do.instead of using max-height for .event-box I use this css which is add display:none to +4.event on your event container:
.event-box .event-container .event:nth-child(n+5){
display: none;
}
and now when it's more than 4 .event your more text appears. FIDDLE
UPDATE:
HERE I make little change in you js as well and make it more professional,
while you are using template to render the page, maybe you can do it as follow
<div class="event-container">
{{#each events}}
<div class="event">{{event-name}}</div>
{{/each}}
</div>
{{#if canshowmore}}
<div class="more-events">more ...</div>
{{/if}}
and
function canshowmore() {
return events.length >= 4;
}

How can I use CSS or Javascript to switch images on mouseover as simple and lightweight as possible?

I'm trying to change one image to another on mouseover. Specifically, when the visitor hovers over this:
The image will change to this:
The Current Code
I'd like to do this as lightweight as possible. But the image-background CSS thing doesn't work for me. My code is as follows:
<div id="featured-box-right"><a href="/videos/"
target="_self"><img src="../images/box-featured-home-right.png" title="videos"
alt="videos" width="300" height="150"></a></div>
But when I do this to the CSS:
#featured-box-right a:hover
{
background-image: url(../images/box-featured-home-right-hover.png);
}
The effect doesn't turn out right; it's not a background. It's an actual image. Any guidance as to how I can achieve this as lightweight as possible would be greatly appreciated!
The lightweight method is to use CSS, and use the property background-image of the div:
jsFiddle
<div id="featured-box-right"></div>
CSS:
#featured-box-right {
width: 300px;
height: 150px;
background-image: url('http://i.stack.imgur.com/OywDf.png');
}
#featured-box-right:hover {
background-image: url('http://i.stack.imgur.com/aRJOk.png');
}
You should use css image sprites techniques and do not use img tag here use css background property. You should try something below. you can use cllass or id or parent child relationship that is totally up to you.
<div id="featured-box-right">
</div>
css:
#img1
{
background: url(../images/box-featured-home-right.png);
}
#img1:hover
{
background: url(../images/box-featured-home-right-hover.png);
}
Remove the <img/> tag altogether and try this css.
#featured-box-right a {
background-image: url(../images/box-featured-home-right.png);
}
#featured-box-right a:hover {
background-image: url(../images/box-featured-home-right-hover.png);
}
CSS Sprites is a technique where you use a background-image, a set width and height, and adjust the background-position to display only the portion you need to show. This way you can use a single image and display lots of different graphics with it, saving server requests and speeding up page load times:
HTML:
<img src="images/arrow-sprite.png" alt="arrow" class="clip pos-1" />
CSS:
.clip { position: absolute; top: 0; left: 0; }
.pos-1 { clip:rect(0 48px 48px 0); }
.pos-2 { clip:rect(0 96px 48px 48px); left: -48px; }
.pos-3 { clip:rect(48px 48px 96px 0); top: -48px; }
.pos-4 { clip:rect(48px 96px 96px 48px); top: -48px;
left: -48px; }
Took from here
You can delete the <img> tag and use CSS background iamge method, but you need to combine the 2 pic into one (one on top and one on bottom)
next, you need to use this code:
#featured-box-right {
width: 300px;
height: 150px;
background-image: url(image url here) center top;
}
#featured-box-right:hover {
background-image: url(image url here) center bottom;
}
Using this method makes you need only 1 image
No images (background or otherwise) are required.
This comes out to only 3.84% the size of your two images combined:http://fiddle.jshell.net/gWytK/show/:
<!doctype html>
<html>
<head>
<title></title>
<style>
body {
margin: 8px;
}
#links {
list-style: none;
margin: 0;
padding: 0;
display: block !important;
display: inline-block;
overflow: hidden;
}
#links li {
float: left;
width: 300px;
height: 150px;
overflow: hidden;
background: #000000;
border-radius: 20px;
}
#links a {
display: block;
font: bold 30px/30px 'comic sans ms', sans-serif;
padding: 40px 66px 100px;
color: #5496ff;
text-decoration: none;
text-transform: capitalize;
text-shadow: 0 0 100px #ffffff, 0 0 100px #ffffff;
}
#links a:after {
content: ' >>';
}
#links a:hover,
#links a:focus {
color: #1b1b1b;
background: #5496ff;
text-shadow: none;
}
</style>
</head>
<body>
<ul id="links">
<li>
Our video collection
</li>
</ul>
</body>
</html>
No image property in CSS. In order to get the desired effect you should replace it with background-image and delete the img tag from your HTML code.
#featured-box-right
{
background-image: url(../images/box-featured-home-right.png);
}
#featured-box-right:hover
{
background-image: url(../images/box-featured-home-right-hover.png);
}

Categories

Resources