Binding a wrapper's height to height of specific child element - javascript

I have a setup where a double-wrapper contains several elements of varying height. They're all arranged next to each other via display: inline-block and vertical-align: top with one of them being considered 'active'.
<section class="gallery">
<div class="gallery__content">
<img class="gallery__item gallery__item--img" src="assets/GIRM/1.png" width="350" heigth="197">
<img class="gallery__item gallery__item--img" src="assets/GIRM/2.png" width="1280" heigth="800">
<img class="gallery__item gallery__item--img" src="assets/GIRM/3.png" width="1280" heigth="511">
<img class="gallery__item gallery__item--img" src="assets/GIRM/4.png" width="1135" heigth="742">
</div>
</section>
I want to limit the height of the wrapper (at either level) to the height of the active child, with overflow: hidden cutting off anything that's higher. Right now, I achieve this by using js to set outerWrapper.maxHeight = activeChild.height.
However, the children can be arbitrary elements, not just imgs and it's not unlikely that they will change their height. With the current js, I have to catch those occurances and reapply the max-height for the new value, if the height changes with a transition it gets even worse.
Is there a way to bind the height of either of the wrappers to the height of a specific child element in css, maybe by making it ignore all other elements for height-computation? If not, is there a better way to do this with js?

Does this work?
Code for the lazy:
HTML
<section>
<div id="under-wrapper">
<img class="child" id="child1" src="https://pro.buysellads.com/p/manage/asset/id/28341" height="150">
<img class="child active" id="child2" src="https://pro.buysellads.com/p/manage/asset/id/28341" height="300">
<img class="child" id="child3" src="https://pro.buysellads.com/p/manage/asset/id/28341" height="350">
<img class="child" id="child4" src="https://pro.buysellads.com/p/manage/asset/id/28341" height="200">
</div>
<div id="over-wrapper">
<img class="child" name="child1" src="https://pro.buysellads.com/p/manage/asset/id/28341" height="150">
<img class="child active" name="child2" src="https://pro.buysellads.com/p/manage/asset/id/28341" height="300">
<img class="child" name="child3" src="https://pro.buysellads.com/p/manage/asset/id/28341" height="350">
<img class="child" name="child4" src="https://pro.buysellads.com/p/manage/asset/id/28341" height="200">
</div>
</section>
CSS (minus the aesthetics)
section {
position: relative;
overflow: hidden;
}
#over-wrapper {
position: absolute;
top: 0;
left: 0;
}
img {
vertical-align: top;
width: 120px;
opacity: 0.3;
}
img.active {
opacity: 1;
display: inline-block;
}
#under-wrapper img {
visibility: hidden;
}
#under-wrapper img:not(.active) {
display: none;
}
JS (well, jQuery)
$('img').click(function() {
$('img').removeClass('active');
$(this).addClass('active');
var child = $(this).attr('name');
$('#'+child).addClass('active');
});
How did I do it?
I added a section wrapper with overflow:hidden (to cut off the extra) and position:relative (to contain the absolutely-positioned child elements).
I created two inner wrappers with the exact same contents, except that the latter has its id attributes replaced with name, for ease of access later on.
I left the first inner wrapper (under-wrapper) alone (it can just behave normally), but the second (over-wrapper) I made absolutely positioned. This is so the contents of this wrapper don't effect the height of the section.
I created a rule for the active class, so while inactive images in the under-wrapper are display:none, active ones are display:inline-block and visibility:hidden. This means only the active image will be influencing the height of the section, and the rest will be hidden. Meanwhile, all the upper images have to do are sit there and look nice.
The javascript is simple; just a click handler on the images which gives it the active class and takes away everybody else's. Clicking an upper image takes the name of it ('child1', 'child2', etc.) and selects the corresponding lower image with the matching id, and gives it the active class.
If this doesn't completely answer your question or I broke a rule, I'd be glad to change my solution. Maybe someone else can use it to find a more convenient/efficient solution that doesn't involve two sets of the same elements.

Related

Using addEventListener

I'm trying to toggle a second element by clicking on the first, and not having the second as interactive but it's not working. What am I doing wrong? The element.timage should change itself and the element . rimage when selected, but only the element.timage should be clickable.
function myFunction(x) {
if (x.target.matches('.timage'))
this.classList.toggle('change');
}
document.querySelector('.container4').addEventListener('click', myFunction);
.container4 {
cursor: pointer;
display: inline- block;
}
.timage {
position: relative;
left: 50px;
}
.change .timage {
left: 200px;
}
.rimage {
position: relative;
left: 200px;
}
.change .rimage {
position: relative;
left 500px;
}
<a id="mobile-nav" href="#">
<div class="container4" onclick="myFunction
(this,event)">
<div class="container4">
<div class="timage"><img class="size-medium wp-
image-13846" src="http://4309.co.uk/wp-
content/uploads/2020/05/
IMG_20200509_104613-
288x300.jpg" alt="" width="70" height="300" />.
</div>
<div class="rimage">
<img class="size-medium wp-
image-13669" src="http://4309.co.uk/
wp-content/uploads
/2020/05/IMG_20200508_1
30758-287x300.jpg" alt="" width="90" height="300" />.
</div>
</div>
</a>
You're probably clicking the img, not the div that the image is in, so event.target is the img.
To find the nearest ancestor (starting with the current element) that matches a selector, use closest.
You're also using myFunction both in onclick="myFunction(this,event)" and in an addEventListener call. Those will provide different arguments to the function. Remove the onclick and just use addEventListener.
Here's the updated function:
function myFunction(x) {
const timage = x.target.closest(".timage");
if (timage && this.contains(timage)) {
this.classList.toggle('change');
}
}
The reason for the contains is just completeness and in many cases you can leave it off: It's to defend against closest having gone past the container element and found the match in the container's ancestors. That won't happen with your layout because timage is only used with the container, but for more general situations, I include that check. For instance:
<div class="x">
<div id="container">
<div class="x">xxx</div>
<div class="y">yyy</div>
</div>
</div>
There, if I have click hooked on #container and the user clicks yyy and I'm doing const x = event.target.closest(".x"), I'll get the .x that's the parent of the container. So this.contains(x) weeds those out.

CSS height 100% percent not working [duplicate]

This question already has answers here:
Why doesn't height: 100% work to expand divs to the screen height?
(12 answers)
Closed 8 years ago.
I have a div with height: 100%; but it's not working. When I declare a fixed height (for example height: 600px;) it is working, but I would like a responsive design.
html:
<blink><div class="row-fluid split-pane fixed-left" style="position: relative; height: 78%;">
<div class="split-pane-component" style="position: relative; width: 50em;">
<div style="">
<ul class="nav nav-tabs">
<li class="active">Html</li>
<li>Helpers</li>
</ul>
<div class="tab-content">
<div class="tab-pane active" id="html" style="height: 100%;">
<textarea id="htmlArea" style="height: 100%;">{{:html}}</textarea>
</div>
<div class="tab-pane" id="helpers" style="height: 100%;">
<textarea id="helpersArea">{{:helpers}}</textarea>
</div>
</div>
</div>
</div>
<div class="split-pane-divider" id="my-divider" style="left: 50em; width: 5px;"></div>
<div class="split-pane-component" style="left: 50em; margin-left: 5px;">
<div style="">
<ul class="nav nav-tabs">
<li>
<a href="#" class="active">Preview
<img width="22px" height="16px" class="preview-loader" src="img/spinner-green2.gif" style="display: none" />
</a>
</li>
</ul>
<div class="tab-content">
<div class="tab-pane active" style="height: 100%;">
<iframe name="previewFrame" frameborder="0" allowtransparency="true" allowfullscreen="true" style="width: 100%; height: 100%;"></iframe>
</div>
</div>
</div>
</div>
</div>
</blink>
You probably need to declare the code below for height:100% to work for your divs
html, body {margin:0;padding:0;height:100%;}
fiddle: http://jsfiddle.net/5KYC3/
You aren't specifying the "height" of your html. When you're assigning a percentage in an element (i.e. divs) the css compiler needs to know the size of the parent element. If you don't assign that, you should see divs without height.
The most common solution is to set the following property in css:
html{
height: 100%;
margin: 0;
padding: 0;
}
You are saying to the html tag (html is the parent of all the html elements) "Take all the height in the HTML document"
I hope I helped you. Cheers
I would say you have two options:
to get all parent divs styled with 100% height (including body and html)
to use absolute positioning for one of the parent divs (for example #content) and then all child divs set to height 100%
Set the containing element/div to a height. Otherwise your asking the browser to set the height to 100% of an unknown value and it can't.
More info here: http://webdesign.about.com/od/csstutorials/f/set-css-height-100-percent.htm
I believe you need to make sure that all the container div tags above the 100% height div also has 100% height set on them including the body tag and html.
For code mirror divs refer to the manual, these sections might be useful to you:
http://codemirror.net/demo/fullscreen.html
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
lineNumbers: true,
theme: "night",
extraKeys: {
"F11": function(cm) {
cm.setOption("fullScreen", !cm.getOption("fullScreen"));
},
"Esc": function(cm) {
if (cm.getOption("fullScreen")) cm.setOption("fullScreen", false);
}
}
});
And also take a look at:
http://codemirror.net/demo/resize.html
Also a comment:
Inline styling is horrible you should avoid this at all costs, not only will it confuse you, it's poor practice.
Night's answer is correct
html, body {margin:0;padding:0;height:100%;}
Also check that your div or element is NOT inside another one (with height less than 100%)
Hope this helps someone else.

Show only content inside div's background image

A div in which I would be sliding in images , I want the images to appear in only a certain area of the div, say a triangle shaped area. The rest of the div should just show whatever is underneath the div.
CSS:
#overlay {
width: 700px ;
height: 300px ;
position: absolute;
top: 50px;
left: 50px;
z-index: 100;
background: url("img/overlay.png");
background-repeat: no-repeat;
}
HTML:
<div class="boxcat" id="websitesbox">
<div id="overlay"></div>
<div id="websitesSlider">
<img src="img/seanswers.PNG" alt="Seanswers screenshot">
<img src="img/stories.png" alt="Seanswers screenshot">
<img src="img/PerfectUpload_1.png" alt="Seanswers screenshot">
</div>
</div>
Here I would be sliding in the images into overlay, BUT I don't want the images to show up completely , instead just a part of the overlay div should be covered in the image.
Not sure If I am making any sense. If I am is this possible ?
Thanks
You want to use mask-image however it isn't widely supported by the browsers.
Here you can read about the spec: http://www.w3.org/TR/css-masking/
And here you can see the support: http://caniuse.com/#search=mask
you can next websitesSlider into overlay:
<div class="boxcat" id="websitesbox">
<div id="overlay">
<div id="websitesSlider">
<img src="img/seanswers.PNG" alt="Seanswers screenshot">
<img src="img/stories.png" alt="Seanswers screenshot">
<img src="img/PerfectUpload_1.png" alt="Seanswers screenshot">
</div>
</div>
</div>

Scroll horizontally across image thumbnails and have images pop up on mouse hover

I have written some code in html and css to scroll horizontally across image thumbnails and have them pop up on mouse hover. The problem is that when I can scroll horizontally, then the popped up (enlarged) image on mouse hover is only visible within the div that it is contained in. I would like for it to be visible on top of everything else on the page. But since I created the scroll bar by making the property of the div overflow-x:scroll,you would have to scroll to see the enlarged image if it is larger than the div. When I don't see the overflow-x property to scroll, I can view the enlarged image on top of everything else like I want to but all the other thumbnails are also visible. Here is a code snippet to show what I've done.
HTML
<div id="example1">
<h1>This is an example</h1>
<h2>Car 1</h2>
<div class="scroll">
<div id="example1_car1">
<a class="thumb" href="#"><img src="car1.jpg" alt="car1" height="200" width="251"><span> <img src="car1.jpg" alt="car1"></span></a>
<a class="thumb" href="#"><img src="car2.jpg" alt="car2" height="200" width="251"><span><img src="car2.jpg" alt="car2"></span></a>
<a class="thumb" href="#"><img src="car3.jpg" alt="car3" height="200" width="251"><span><img src="car3.jpg" alt="car3"></span></a>
</div><!--example1_car1-->
</div><!--example1_scroll-->
<h2>Car 2</h2>
<div class="scroll">
<div id="example1_car2">
<a class="thumb" href="#"><img src="car1.jpg" alt="car1" height="200" width="251"><span><img src="car1.jpg" alt="car1"></span></a>
<a class="thumb" href="#"><img src="car2.jpg" alt="car2" height="200" width="251"><span><img src="car2.jpg" alt="car2"></span></a>
<a class="thumb" href="#"><img src="car3.jpg" alt="car3" height="200" width="251"><span> <img src="car3.jpg" alt="car3"></span></a>
</div><!--example1_car2-->
</div><!--example2_scroll-->
</div><!--example1-->
CSS
#example1_car1,#example1_car2,.scroll{
position:relative;
}
#example1_car1, #example1_car2
{
width:2400px;
height:200px;
z-index:0
}
.scroll
{
width:800px;
height:210px;
overflow-x:scroll;
z-index:0;
}
.thumb img {
border:1px solid #000;
margin:3px;
float:left;
zindex:-1;
}
.thumb span {
position: relative;/*absolute;*/
display:none;
}
.thumb:hover, .thumb:hover span {
display:inline;
top:0; left: 0px;
/*z-index:1;*/
z-index:10;
}
Any help would be much appreciated.
To make the enlarged image appear on top of/outside of the scrollable region, it will have to actually be outside of it.
To make the enlarged image appear outside, when hovering over a thumbnail that is inside of the scrollable region, you will need to use JavaScript on top of your HTML and CSS.
Here's an example on jsfiddle, in which I haven't changed your HTML structure. Instead I used jQuery to clone the enlarged image outside of the scrollable region and append it to the #example1 div, when you hover over a thumbnail.
JavaScript portion:
$('.thumb').hover(
function(){
var thumb = $(this).children('img');
var large = $(this).find('span>img').clone();
$('#example1').append(large);
large.addClass('enlargedImg');
large.css({
'top': thumb.offset().top,
'left': thumb.offset().left
});
},
function(){
$('.enlargedImg').remove();
}
);
I used the thumb image's offset() values to position the enlarged image directly on top of it. You'll probably want to move it a bit but hopefully this is enough to get you started.

New DIV to appear on hover / mouseover of another Div

I have a number of DIVs currently laid out in an oval shape. Each div represents a "service" and is ID'd accordingly, all are set with an absolute position.
What I am wanting to do is on mouseover of a div, I want to have a new DIV with relevant information appear in the middle. This should happen for each "service" so each "descriptive" div will be hidden until mouseover but all appear in the same space.
The website in question is the home page of www.faa.net.au.
How do I go about making this new descriptive DIV appear on mouseover and hide on mouseout?
What you can do is position all of those divs in that spot in the middle with CSS. They can stack and the z-index doesn't matter since all you'll only see one at a time. Then hide them with "display:none" in your CSS.
Then use jQuery's .hover() method to show those the appropriate div on mouseover
$("#idOftheDivYouHoverOn").hover(function (e) {
//This funciton defines what happens on mouse-in or hover.
$("#idOfTheDefaultCenterDiv").hide();
$("#idOfTheDivYouWantedToShow").show();
}, function (e) {
//This function defines what happens on mouse-out or when the hover is over.
$("#idOfTheDefaultCenterDiv").show();
$("#idOfTheDivYouWantedToShow").hide();
});
You'll have to do this for each one you hover on. There is a "smarter" way but it would be a very long answer to explain it.
That is if you want to do this using JavaScript/jQuery instead of just plain CSS similar to the ones you see in other answers. With this method you can add fading effects - take a look at jQuery's hover - http://api.jquery.com/hover/
Edit: Here's a working example: http://jsfiddle.net/6dMDS/
Hope that helps.
A friend in another forum just posted another way of doing this. Be warned it's CSS3 only so some browsers (and definitely older IE's) won't support it.
<div class="container">
<img class="one" src="http://placehold.it/100x100" />
<img class="two" src="http://placehold.it/100x100" /><br>
<img class="three" src="http://placehold.it/100x100" />
<img class="four" src="http://placehold.it/100x100" /><br>
<img class="five" src="http://placehold.it/100x100" />
<img class="six" src="http://placehold.it/100x100" />
<div class="hidden-one">hidden-one</div>
<div class="hidden-two">hidden-two</div>
<div class="hidden-three">hidden-three</div>
<div class="hidden-four">hidden-four</div>
<div class="hidden-five">hidden-five</div>
<div class="hidden-six">hidden-six</div>
</div>
* {margin: 0; padding: 0;}
.container {width: 400px;}
.one:hover ~ .hidden-one,
.two:hover ~ .hidden-two,
.three:hover ~ .hidden-three,
.four:hover ~ .hidden-four,
.five:hover ~ .hidden-five,
.six:hover ~ .hidden-six
{display: block;}
.hidden-one,
.hidden-two,
.hidden-three,
.hidden-four,
.hidden-five,
.hidden-six
{
width: 200px;
height: 300px;
border: 1px solid red;
display:none;
float: right;
position: relative;
top:-305px;
left: 10px;
}
http://codepen.io/anon/pen/LbfCl
So if I got it right, you got a "service" DIV and a "descriptive" DIV. Try some CSS to make it happen.
HTML:
<div id="service"></div>
<div id="descriptive"></div>
And CSS:
#descriptive
{
visibility:hidden;
}
#service:hover #descriptive
{
visibility:visible;
}
Basically this will make the DIV with id="descriptive" be shown when id="service" is hovered.

Categories

Resources