how to make the expand slide always under a div - javascript

How can I make the outside div always underneath the current item div. the code works fine but if it has two lines, like the image below.
The outside div would be on the top if I click box6 or box7. If there is a way I could make outside div change the position dynamically?
<div class="container">
<div class="item" data-content="1">1
</div>
<div class="item" data-content="2">2
</div>
<div class="item" data-content="3">3
</div>
<div class="outside">
</div>
</div>
.outside {
background:yellow;
background: #222222;
float: left;
display: none;
position: absolute;
top:80px;
width:100%;
color:white;
font-size:20px;
height: 300px;
}
Sample online http://jsfiddle.net/nm3Y4/
Thanks a lot for the answers and your time. I think I didn't make it clear, so what I wanted to achieve is that, if you click box1, should looks like the image below
and when click on box6 or box7 should show like below
so which means that outside below current item div
Thanks again

You could change the value of top property of the absolutely positioned .outside element according to the height of the .item box and the top offset of the current clicked item:
$('.item').click(function(event) {
var $this = $(this);
var contentNumber = $this.data("content");
$('.active').removeClass('active');
$this.addClass("active");
$('.content').hide();
$('.content'+contentNumber).show();
$('.outside')
.css('top', $(this).offset().top + $(this).height() + 'px')
.slideDown();
});
UPDATED DEMO.
As a side-note: It's better to position the .outside element relative to the .container rather than the initial containing block.
.container {
/* Create a containing block for the absolutely positioned elements */
position: relative;
}
Also float: left; declaration is redundant for the .outside as it's positioned absolutely.
As per your update, you could relative positioning and add top property in order to position the items (which their top offset is higher than the current clicked item) when the click event is triggered:
.item {
/* other styles here... */
float:left;
position: relative; /* Position the items relatively */
}
$('.item').click(function(event) {
var $this = $(this);
// ...
$('.item').filter(function() {
return $(this).offset().top > $this.offset().top;
}).css('top', $('.outside').height() + 'px');
// ...
});
Then reset their position when the .outside is closed:
$('.close').click(function(){
$('.item').css('top', '0'); // reset the top property/value
$('.outside').slideUp();
$('.active').removeClass('active');
});
UPDATED DEMO.

remove position:absolute and top:80px and add clear:both;
.outside {
background:yellow;
background: #222222;
clear:both;
display: none;
width:100%;
color:white;
font-size:20px;
height: 300px;
}
DEMO

since question is updated, this answer doesnt fit the need,
i leave it here just because it shows behavior of absolute element if no coordonates are given ...
you could reset white-space and not float the divs to keep them on 1 line.
http://jsfiddle.net/nm3Y4/7/
.slider {
margin: 10px 0;
width: 580px;
height: 250px;
position: relative;
overflow: hidden;
}
.slider li {
display: none;
position: absolute;
top: 0;
left: 0;
}
.item {
width: 60px;
height: 60px;
display:inline-block;
background:red;
margin:10px;
cursor: pointer;
}
.content {
display:none;
}
.active {
background:blue;
}
.outside {
background:yellow;
background: #222222;
float: left;
display: none;
position: absolute;
top:80px;
width:100%;
color:white;
font-size:20px;
height: 300px;
}
.close {
float:right;
cursor: pointer;
margin-right:10px;
}
.container {
white-space:nowrap;
}
.outside {
white-space:normal;
}
or do not let your box float, inline-block is just fine, and remove the top coordonates, see : http://jsfiddle.net/nm3Y4/9/

Related

Overflow scrolling on dynamically moving elements

var block = document.getElementById('block')
function myFunct() {
block.style.transform = 'translateX(-400px)'
}
.container {
position:relative;
width:400px;
height:150px;
margin:auto;
background-color: blue;
overflow:scroll;
}
#block {
position:absolute;
height:25px;
width:100%;
left:50%;
bottom:50%;
overflow: scroll;
background-color: yellow;
border:1px solid black;
align-self: flex-end;
}
<div class="container">
<div id="block"></div>
<button onclick='myFunct()'>CLICK</button>
</div>
In my example the block overflows the right side of the container and overflow is set to scroll. So you can scroll the right side and see the rest of the block. Then when I run the function, the block moves so it's overflowing the left side of the container. However it does not adjust to allow for scrolling left to see the rest of the block. What is the solution to allow for scrolling of other sides after functions are ran and blocks are moved to overflow those different sides.
Based on this, a the solution can be sort of 'hack' like this:
var block = document.getElementById('block')
function myFunct() {
document.getElementsByClassName('container')[0].dir = 'rtl';
block.style.transform = 'translateX(-400px)'
}
.container {
position:relative;
width:400px;
height:150px;
margin:auto;
background-color: blue;
overflow:scroll;
}
#block {
position:absolute;
height:25px;
width:100%;
left:50%;
bottom:50%;
overflow: scroll;
background-color: yellow;
border:1px solid black;
align-self: flex-end;
}
<div class="container">
<div id="block"></div>
<button onclick='myFunct()'>CLICK</button>
</div>
Thanks to #TemaniAfif that point me.
The real problem at hand is that the css property transform will only trigger a repaint on the Composite Layer, this was an optimization decision made to facilitate animations without triggering repaints on the Layout Layer . To trigger an entire layout repaint you should use a layout property like left or right:
Example:
function myFunct() {
block.style.left = '0px'
}
Also the reason you are getting the scrollbar on initial load is because you have:
#block {
...
left: 50%
...
}
More here on Compositor-Only Properties
Edit:
Although the above is true, switching to 'style.left' will still not cut it
because block level elements have a default content flow direction of left to right or in css direction: ltr so this means you'll need to modify the content direction as well which should cancel out the need to use style.left. See below:
var block = document.getElementById('block')
var container = document.querySelector('.container')
function myFunct() {
block.style.transform = 'translateX(-400px)'
container.style.direction = 'rtl'
}
.container {
position:relative;
width:400px;
height:150px;
margin:auto;
background-color: blue;
overflow:scroll;
}
#block {
position:absolute;
height:25px;
width:100%;
left:50%;
bottom:50%;
overflow: scroll;
background-color: yellow;
border:1px solid black;
}
<div class="container">
<div id="block"></div>
<button onclick='myFunct()'>CLICK</button>
</div>
Is it important where the yellow block shifts and gets positioned? if you just set the #block width to allow for the extra 400px with width: calc(100% + 400px) then you can see it with overflow after calling the function.
var block = document.getElementById('block')
function myFunct() {
block.style.transform = 'translateX(-400px)'
}
.container {
position: relative;
width: 400px;
height: 150px;
margin: auto;
background-color: blue;
overflow: scroll;
}
#block {
position: absolute;
height: 25px;
width: calc(100% + 400px);
left: 50%;
bottom: 50%;
overflow: scroll;
background-color: yellow;
border: 1px solid black;
align-self: flex-end;
}
<div class="container">
<div id="block"></div>
<button onclick='myFunct()'>CLICK</button>
</div>
This is what I came up with. My solution applies to my use which is to have a have a line of text run across the page right to left and being able to scroll left to see the parts of the sentence that eventually overflow. The #fill div lets the entire wrapper be scrollable rather than just the span. There's a way to do it with two divs using "line-height = (size of container)" but I figured that would lead to future problems so I avoided. The key to my way was the "outer.scrollLeft += outer.scrollWidth" within the function. There's a more fluid way of doing this as my way is choppy by moving the entire span element left which is what my original question was pointed towards but ultimately not how I did it. Meshu's solution also worked in application to the question I asked. "Direction:rtl" also allows for a solution.
var inset = document.getElementById('inset')
var fill = document.getElementById('fill')
var text = 'There was a lamb who had a cow and a farmer was involved and then you make a moo sound and yell BINGO and that is how the song goes.'; /*Obviously you can change this jibberish */
var words = text.split(" ") /* breaking the text into an array of each word */
var i = 0
var timer = 5; /*How long the text will take to run through in seconds*/
var wordTime = (timer / words.length) * 1000; /* Time before the next word takes to the screen. As of this code, all words have equal time */
var myVar = setInterval(myFunct, wordTime);
function myFunct() {
if (i == words.length) {
clearInterval(myVar); /* Stops running when all words are passed through */
} else {
inset.innerHTML += " " + words[i];
}
i++
let outer = fill
outer.scrollLeft += outer.scrollWidth; /*important */
}
#wrapper {
position: absolute;
display: flex;
height: 100px;
width: 100%;
min-width: 100%;
max-width: 100%;
left: 0;
right: 0;
bottom: 0;
align-items: center;
text-align: right;
color: whitesmoke;
font-family: sans-serif;
font-size: 200%;
background-color: rgba(0, 0, 0, 0.7);
}
#fill {
display: flex;
width: 100%; /*You can change this to change how much of container the text overtakes */
height: 100%;
max-width: 100%;
align-items: center;
overflow: auto;
}
#inset {
padding-left:5px;
white-space: nowrap;
margin-left:auto;
}
<div id='wrapper'>
<div id='fill'>
<span id='inset'></span>
</div>
</div>
.

how to show full image with overlay in jquery?

Could you please tell me how to show big or large image on button click with overlay. I am making a image slider in which user click on image and it shows the full image with overlay. I tried like this
https://plnkr.co/edit/7AqAHSSPwZyj7cipXMrq?p=preview
.overlay {
position:absolute;
top:0;
left:0;
right:0;
bottom:0;
width:100%;
height:100%;
background-color:black;
z-index:9999;
color:white;
}
$(function() {
var counter = 0;
$('#next').click(function() {
if (counter < $('.imageBlock').length-1) {
counter++;
$('.imageBlock').hide();
$('.imageBlock').eq(counter).show();
}
})
$('#pre').click(function() {
if (counter > 0) {
counter--;
$('.imageBlock').hide();
$('.imageBlock').eq(counter).show();
}
})
$('.imageBlock').click(function(){
$('body html').addClass('overlay')
})
})
Here's an example where clicking the image - we take the src, and add it to a hidden div (.overlay img) and then show the div.
clicking the overlay hides it again.
Hope this is helpful
$('.thumb').on('click', function(){
$('.overlay img').attr('src', $(this).attr('src'));
$('.overlay').show();
});
$('.overlay').on('click', function(){
$('.overlay').hide();
});
.thumb {
width: 250px;
}
.overlay {
display: none;
position: absolute;
top:0px;
background: #000;
width: 100%;
height: 100vh;
white-space: nowrap;
text-align: center;
}
.overlay img {
width: 100%;
border:5px solid #000;
vertical-align: middle;
}
.helper {
display: inline-block;
height: 100%;
vertical-align: middle;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<img class="thumb" src="https://images.unsplash.com/photo-1428094479093-8973a318bd76?dpr=1&auto=format&fit=crop&w=1500&h=1001&q=80&cs=tinysrgb&crop=">
<div class="overlay"><span class="helper"></span><img src=""></div>
Here's a fiddle: https://jsfiddle.net/BradChelly/kbode1cx/
For starters $('body html').addClass('overlay') doesn't work, because that selects an html element inside a body element.. which doesn't exist.
I think you meant to target either class (to make it cross-browser):
$('body,html')
You could toggle the class:
$('body,html').toggleClass('overlay')
Then adjust your css. Probably something like this:
.overlay .imageBlock .small img {
display: none;
}
.overlay .imageBlock .large img {
display: block;
}
BTW, if you only need the .small and .large wrappers with img just for the overlay feature, then you're making things harder than needed...
If you want to use a library, you can use prettyPhoto that does everything you need.
If you don't want to use a library, you can do that in your code (last jQuery event of your JS file) :
$('.imageBlock').click(function(){
$('body').toggleClass('overlay');
$('.imageBlock').eq(counter).find('.large img').toggle();
})

Resize child div element to fit in parent div on window resize

I have a div element (shown with red border in the image below), which I want to be able to fit in its parent div when the window is resized and not fall into the next line (the parent is the one with the green border).
I want the red div to have a starting width: 949px (in my current screen) in order to fit the entire space available as shown in the image, but be resizable, so that it doesn't fall into the next line if width: 949px is to much to fit.
In essence, I want it at all costs to cover the area it covers in the image even if in a narrower screen that means it will be like 10px wide.
How can I achieve this? Any solution using CSS, JavaScript or jQuery will be gladly accepted.
The image:
CSS:
#parent {
text-align: center;
width: 90%;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
display: inline-block;
}
#child1-row2 {
text-align: left;
vertical-align: middle;
width: 288px;
display: inline-block;
}
#child2-row2 {
text-align: left;
vertical-align: middle;
width: 288px;
position: relative;
margin: 0 25px 0 25px;
display: inline-block;
}
#child3-row2 {/* The one with the red border */
vertical-align: middle;
height: 452px;
width: 949px;
overflow: hidden;
position: relative;
display: inline-block;
}
You can use flexbox to do this by using the flex-grow property.
HTML :
<div id="main">
<div id="box1">1</div>
<div id="box2">2</div>
<div id="box3">3</div>
</div>
CSS :
#main {
display: flex;
flex-flow: row;
width:100%;
min-height:50px;
}
#box1{
background-color:red;
width:100px;
}
#box2{
background-color:blue;
width:100px;
}
#box3{
background-color:green;
flex-grow: 1;
}
Here is a working JSFiddle
You can use css calc function for this. Support for calc seems to be quite good now.
As you have mentioned, the left side divs are of fixed width, say 120px each. Also suppose the margin between them is 30px. So, the total width left for your red div is 100% - (2*120 + 2*30)px i.e. (100% - 300px ).
#red-div
{
width: calc(100% - 300px);
}
Add % width or you can do following :
$(window).resize(function() {
var window_width = $(window).width();
var w1_width = $('.div1').width(); // The first element width
var w2_width = $('.div2').width(); // The second element width
var main_div_width = window_width - (w1_width+w2_width+gutter[i.e margin between all 3 elements]);
$('.main_div_width').css('width', main_div_width);
});

Keep width of container that of the longest child

In short: When I have a container and some inline-block divs, the container's width shrinks around the divs. But when the divs are too-long and therefore one of them goes to another line, the container width is rendered as 100%.
In the picture the default behavior is the first one, whereas the desired behavior is the second one.
Here is a fiddle with the example:
http://jsfiddle.net/gzbx4upq/
See fiddle for desired results
Either use
display:block;
or
display:inline;
or
max-width:250px ;
That seems possible using pseudo classes.
CSS
div {
display: inline;
position: relative;
}
div:before {
content:"";
position: absolute;
left: 0px;
right: 0px;
bottom: -5px;
top: -5px;
background-color: blue;
z-index:-1;
}
div:after {
content:"";
display: block;
}
p {
display: inline-block;
background-color: red;
}
Working Fiddle

Description div overlay not showing on li image

I am using the slider http://marktyrrell.com/labs/blueberry/ and am trying to add description boxes that overlay the images and change with each div. I added a div class, but it is not showing up. Not sure if I also need to alter javascript?
css
.blueberry {
margin: 0 auto;
max-width:1280px;
position:relative;
z-index:1;
margin-top:-25px;
}
.blueberry .slides {
display: block;
position: relative;
overflow: hidden;
margin:0;
padding:0;
list-style:none;
}
.blueberry .slides li {
position: absolute;
top: 0;
left: 0;
overflow: hidden;
}
.blueberry .slides li img {
display: block;
width: 100%;
max-width: none;
}
.blueberry .slides li.active { display: block; position: relative; }
.blueberry .crop li img { width: auto; }
.slides .description {
z-index:100;
position:absolute;
left: 0px;
background:#000;
color:#1d1d1d;
}
HTML
<div class="blueberry shadow">
<ul class="slides">
<li><img src="images/slide1.jpg" />
<div class="description">
<p>Kick off 2013 by starting a fundraising campaign to help people get access to clean water. It’s fun, it’s easy and it’s the best way we can think to start the new year.</p></div></li>
js
<script>
$(window).load(function() {
$('.blueberry').blueberry();
});
</script>
Thanks for any help in advance
You need to define css top property, see it works fine:
Note: Using div or p inside ul li is agaisnt to the web standarts. I suggest to use tags like span, em, s, i.

Categories

Resources