TLDR: How do get a container to wrap multiple superimposed fluid-height divs?
I have a div with some objects:
<div class="container">
<div class="a" style="height: 300px;">Tab page a</div>
<div class="b" style="height: 100px; display: none;">Tab page b</div>
<div class="c" style="height: 200px; display: none;">Tab page c</div>
...
</div>
Based on a user action, I want to fade b in as a fades out (i.e. crossfade them). This requires them both being aligned to the top-left corner of container. Normally, I'd just use position: absolute; with the defaults top: 0; and left: 0; to superimpose them. The problem with this is that then the container collapses to 0px tall (rather than the height of its contents, which I want), as a and b have been removed from the flow.
Ok, so I can't user absolute positioning on a and b. How else can I get them to overlap? A negative margin-top also won't work since I don't know the heights of the children (they can change dynamically based on their content), and there could be any number of them.
Is this even possible without JS? If it isn't, what's the least hacky way that doesn't assume A) a small number of children in container or B) the children are a fixed size (known ahead of time or otherwise).
If you know the dimensions of your cross-fading elements, your best bet is to set the height and width of your container element, either through CSS if you only need one width/height, or through javascript if you'd like the container to adapt to new dimensions on cross-fade.
The Javascript method I described can be seen in action here: http://jsfiddle.net/mkd9s/2/
The important part is:
// Get Heights
var aHeight = $('.a').height(),
bHeight = $('.b').height();
// Set Height on Load
$('.container').height( aHeight );
// Fade on Click
$('.fade').on('click', function(event) {
event.preventDefault();
$('.a').fadeOut("slow");
$('.b').fadeIn("slow");
$('.container').animate({ height: bHeight });
});
Which first sets the height of the container, then animates the height of the container to be the height of the second element when a button is clicked.
Note that this will rapidly become unwieldy if you've got more than 2 elements in the container.
Related
I have the below structure:
<div class="wrapper1">
<div class="left">some img here with 100% width and some text which dispaly on hovering over the image</div>
<div class="right">some content here</div>
</div>
<div class="items">
<ul><li></li></ul>
</div>
The above layout is used for a responsive site. so on resizing the window or on page load on different devices the content in the right div should always remain of the same height as that of the left div.
Also, I have to append a link "more >>" responsively where the last character of the content in the right div ends.
I have used overflow hidden property for the right div and I am trying to give some height to the right div based on the window width using media queries. Have tried different things but since the text amount changes responsively it is becoming difficult to append more link to the last character.
Also, i tried using jquery/jscript to detect the height of the left div on page load so as to set the height of the right div same as that using .outerheight() property but on initial load of the page I am not able to get the height in pixels since the width of the image inside the left div is set to 100%.
Also, there are 2 main issues here,
1)I set the height of the left div same as that of the right div responsively. Here the extra content to be displayes in the right div should always be hidden.
2) append more link just where last last charcter of the last visible line of the content on the left div is responsively.
Could anyone please suggest some solution.
With flexbox the columns share the same height automatically, without any javascript.
.wrapper {
display: flex;
}
.left {
background: yellow;
flex: 1;
}
.right {
background: red;
flex: 1;
}
<div class="wrapper">
<div class="left">some img here with 100% width and some text which dispaly on hovering over the image</div>
<div class="right">some content here</div>
</div>
I believe all your problem will be solved if and only if you use bootstrap css rules the grid system and furthermore make a class with specific height and assign it to the div . And more advice get familiar with media query in css3
Create a div with relative position for appending links and make it in the bottom of the container div
Assuming I have 2 elements on a responsive design like this:
<div id="container">
<div class="first"></div>
<div class="second"></div>
</div>
both of them with style contains:
width: auto;
display: inline-block;
float: left;
And because I'm expecting different screen sizes to view page, so, according to screen size, sometimes they will be rendered/displayed on the same row, and sometimes they will not!, the second DIV will be moved to a separate row.
So, I'm wondering, how can I check if they are on the same line with JavaScript?
Thank you
"on the same line" would require inline elements or floating block elements of the exact same height. DIVs are block elements by default. So either use <span> tags instead of <div>, or add display: inline-block;to the CSS rule of those DIVs
ADDITION after EDIT OF QUESTION:
width: auto for a <div> means 100% of the parent element (in this case full width). As I wrote: If you have blocks, use display: inline-block; in their CSS. If you want them to have the same height, put them into a common container DIV (which you already have) and apply the following CSS:
#container {
display: table;
}
.first, .second {
display: table-cell;
width: 50%;
}
Aha (edited question), Javascript: Well, read out the DIV widths, add them and compare the result to the (read-out) container width.
You can use the element bounding boxes and check for overlap:
var rect1 = $('.first')[0].getBoundingClientRect();
var rect2 = $('.second')[0].getBoundingClientRect();
var overlaps = rect1.top <= rect2.bottom && rect2.top <= rect1.bottom;
This checks for any overlap which will probably be sufficient for your use. I used jQuery to get the elements but you can use pure js in the same way, it would just be a bit more verbose.
There is no concept of line on a page. You can check the x and y position of any element in the window and then decide if that meets whatever criteria you have for "on the same line".
By default, a div is the full width of a window so the two divs inside your container in this HTML:
<div id="container">
<div class="first"></div>
<div class="second"></div>
</div>
will be one above the other unless there is some other CSS you have not disclosed that controls the layout to allow them to be in the same row. If they are indeed width: auto and don't have any other layout rules affecting this, then they will each be full width and thus first will be above second in the layout stream. They would never be "on the same line" by any typical definition of that phrase.
Feel free to try it out here: https://jsfiddle.net/jfriend00/y0k7hLr8/ by resizing the right pane to any width you want. In all cases, the first will stay on top of the second.
If, on the other hand, you allow the div elements to have a different type of layout such as let them be display: inline-block and define a width for them, then the layout engine will fit as many on a given row as possible like here: https://jsfiddle.net/jfriend00/229rs97p/
Something tells me display: flex might help you in this. Read https://css-tricks.com/snippets/css/a-guide-to-flexbox/ for more info.
I've been working on my new portfolio/website and decided to go for a design that is basically one big index page that scrolls horizontally to show the different sections and vertically to show the content of the sections. Both the container and the boxed inside have a fixed width. The container is positioned relative and the boxes inside are floated left and positioned relative.
My question now is - how do I make it so that, regardless of the size of the browser window the user has when opening the website and even when re-sizing, the first box appears centered horizontally in the browser window AND without revealing the content that is on its right (content to which the user can scroll horizontally using buttons)?
The inspiration for my website came from this website http://www.cosstores.com/
I've inspected the code and I believe they are doing it using JavaScript and negative margins; but my Javascript knowledge is quite basic and I don't really understand how these negative margins are implemented effectively.
Would appreciate it if someone could explain how it works for the COS website or even come up with an easier alternative a noobie like me could use.
Thank you and please feel free to ask me to post anything else you think could help understand the problem better!
This is really quite simple, don't you worry. See it in action!
You'll need to work on a grid system. (You can use different-sized columns, but it's simpler if everything's nice and square.) Create a container div and a bunch of child "box" divs in your HTML:
<div id="container">
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<br />
<div class="box"></div>
<div class="box "></div>
<div class="box"></div>
<div class="box"></div>
</div>
Use <br /> to start a new row. Otherwise, rows will extend infinitely. The container div is exactly the height and width of one box, so it will only show one box at a time. But you can scroll, obviously.
Annotated CSS below:
#container {
font-size: 0; /* remove gaps between boxes */
height: 400px; /* show one box at a time */
margin: 0 auto; /* center horizontally */
overflow: scroll; /* show scroll bars */
width: 400px; /* show one box at a time */
white-space: nowrap; /* let boxes continue horizontally until manually <br />'d */
}
.box {
display: inline-block; /* stack up left to right */
font-size: 14px; /* undo font-size from parent so you can actually see text */
height: 400px;
vertical-align: top; /* line up tops of boxes within row */
width: 400px;
}
Then, to scroll to a location with Javascript:
$("#container").animate({ scrollTop: 400, scrollLeft: 800 }, "slow"); //with animation
$("#container").scrollTop(400).scrollLeft(800); //without animation
You'll need jQuery to use that code. Well worth it, since it hides browser inconsistencies in scrolling with Javascript.
If you want to use the browser's scrollbars, you'll need to use the body as your container. It's trickier, because you don't have a specified width and height. There is no way to hide elements (for sure) from every user—some have truly massive screen resolutions.
Basically, add a margin on each box so you get some space around it. With some quick JS calculations, you can figure out the location of each box and center it on screen. See updated fiddle.
Here's the relevant JS for anyone interested:
$("#scroll").click(function() { scrollCenter("#target"); });
scrollCenter("#home", 0);
function scrollCenter(target, duration) {
if (duration == undefined) duration = "slow";
target = $(target);
var offset = target.offset();
var top = offset.top - ($(window).height() - target.height()) / 2;
var left = offset.left - ($(window).width() - target.width()) / 2;
$("html, body").animate({ scrollTop: top, scrollLeft: left }, duration);
}
Run that OnDOMReady. The call to scrollCenter("#home", 0) forces the page to center the first box on load. You shouldn't even notice the jump.
Happy coding!
you should use the jQuery plugin scrollTo
http://archive.plugins.jquery.com/project/ScrollTo
Centering a div tag on the screen is easy. Set the margin property in it's css class to this:
margin:0px auto;
As for the rest of your question, this is a case for jQuery (in my opinion). Take a look at this link:
http://addyosmani.com/blog/building-spas-jquerys-best-friends/
And also google jQuery tutorials (you need to learn the framework first) and then, more specifically, "single-page sites" and "jQuery Paralax".
Good Luck!
I've created an effect whereby an HTML element is initially hidden behind another HTML element, and the CSS 'top' value of the hidden element is animated to expose it from beneath the masking element in a smooth sliding motion.
Does anyone know if there is a way to recreate this effect without the masking element on top?
I want to avoid the jQuery'esque slideDown where the height of the element being shown is animated.
I have the feeling that this just isn't possible, but if someone is otherwise aware, your advise would be much appreciated.
You can easily do this with a wrapper that has overflow set to hidden
http://jsfiddle.net/xvNf6/1/
HTML
<div id="wrapper" style="height:0px;">
<div>content</div>
</div>
Sample CSS
#wrapper{width:300px;height:280px;margin:0 auto; overflow:hidden; background:#eee}
Javascript
//if you must not use jQuery
var animationTimer = setInterval(function(){
var wrapper = document.getElementById("wrapper");
wrapper.style.height = (parseInt(wrapper.style.height) + 1) + "px";
if(parseInt(wrapper.style.height) >= 280)
clearInterval(animationTimer)
},1);
//if you can use jQuery
$("#wrapper").animate({height:"280px"},1000);
Place your element within a parent div with overflow:hidden. Then, position your element beyond bounds of the parent div so that it is hidden.
#wrapper { overflow: hidden; }
#target { height: 100px; top: -100px; } /* shift element out of view */
You can then reveal it by animating to {"top":0} to get the slidedown effect that doesn't resize the height of the element.
Here's a rather crude demo: http://jsfiddle.net/7RSWZ/
Update: Here's another demo that attempts to deal better with different content sizes by dynamically setting the heights and top values. http://jsfiddle.net/7RSWZ/2/
I need to create a sort of cart, where I store elements created by the user.
I've created a simple scheme to help you understand my needs:
.buttons are two div containing an image (an arrow), where I'll bind an onclick event to scroll elements (#scroller). The layout has fixed sizes, thus the exact length of ul#scroller (the element that will contain items and that needs to be scrolled) is 900px.
I think the size of any #scroller child <li> will be ~100px.
There's a button (not present in the scheme) that allows the user to store in #scroller an item.
Actually when there are too many items the next will go on the bottom (beginning a new line). Instead I'd like that the new elements go ahead on the same line, but hidden (without hit #button_right).
I was thinking to do this with javascript, storing elements in an array, and keeping visible only the first 9 (x 100px), then by clicking on the arrow (let's say, the right one) hide the first item and show the 10th.
Do you think this is a good solution?
If not, what do you suggest? What CSS rules could help me to do it?
Thanks in advance.
you need to create an extra div with a very long width, and put it inside #scroller and make #scroller have an overflow: hidden so it doesn't show the scrollbar.
like this:
html:
<div id="scroller">
<div id="inner">
(your items)
</div>
</div>
css:
#scroller {
width: 900px;
overflow: hidden;
}
#inner {
width: 90000px;
}
P.S. now the items won't go to another line but you need to code the buttons so they scroll the content depending on the number of items, depending on their width behing the same it can be more simple or not.