I want to set equal heights to my columns in Bootstrap 3. I CAN'T set the rows to 'display: table;' or anything like that cause it screws up the layout of everything.
<article>
<div id="post-<?php the_ID(); ?>"> <!-- just gets the post's id -->
<div class="row">
<div class="col-md-8 indx-img" style="background-image:url('...');">
</div>
<div class="col-md-4 text-cell">
<h1>title</h1>
<h3>category</h3>
</div>
</div><!-- /#row -->
</div><!-- /#post -->
</article>
The content is on the right, a column with a background image is on the left. That column needs a height so that the background image is shown, I want that height applied to the column with the text.
I want it to be responsive height, what I used so far for that is
CSS
indx-img {
padding: 16% 0;
}
problem is that height doesn't apply the the column with the text. The ultimate goal is to have the two columns the same height, with the text vertically centred in the 'text-cell' column
If you can't use any css solutions because they will break your layout, you can use javascript.
Here we define a function named resize which will loop through the posts.
If the page is larger than the break point, set the height of the post container to the height of the image.
Then set the height of the text container to 100% once.
If the page is smaller than the break point, check to see if the height is set.
If it is we remove the height setting to allow natural expansion and contraction.
We call the resize function once on page load, then assign it to the window resize handler
(Demo)
<script type="text/javascript">
window.onload = function() {
(function () {
"use strict";
var resize = function () {
var posts = document.querySelectorAll('[id^="post"] .row'), post;
for (var i = 0; post = posts[i]; i++) {
if (window.innerWidth > 768) {
post.style.height = post.firstElementChild.offsetHeight + 'px';
if(post.lastElementChild.style.height !== '100%') {
post.lastElementChild.style.height = '100%';
}
} else {
if(post.style.height !== '')
post.style.height = '';
}
}
};
window.onresize = resize;
resize();
})();
}
</script>
I use the matchHeight plugin for this kind of issue all the time and it works perfectly with Bootstrap.
Just install the plugin, add a class of matchHeight to your col-md-8 and col-md-4 columns:
<div class="matchHeight col-md-8 indx-img" style="background-image:url('...');">
</div>
<div class="matchHeight col-md-4 text-cell">
<h1>title</h1>
<h3>category</h3>
</div>
And add the following to your javascript:
$('.matchHeight').matchHeight();
You can then use this fix throughout your site by simply repeating the above steps, even several times on the same page (it automatically scopes to within the current "row" element so if you have 3 rows with 6 elements then only those elements in any given row are matched in size).
Related
I have the following HTML:
<div class="page">
<div class="somecontent_1">...</div>
<div class="somecontent_2">...</div>
<div class="somecontent_3">...</div>
<div class="somecontent_4">...</div>
</div>
Now I'd like to separate the content with a separate page so it looks something like this:
<div class="page">
<div class="somecontent">...</div>
<div class="somecontent">...</div>
</div>
<div class="newpage">
<div class="somecontent">...</div>
<div class="somecontent">...</div>
</div>
The function checks the height of each class somecontent and if it's larger than a certain amount, I need to move the content to a new page.
My guess is that I would need to create an empty div (newpage) and then fetch the elements after the height is exceeded and move them to the empty newpage and continue iterate like that.
My question would be how I would get all content that are after the last element that reached the height so I can move it to the new empty page that I would create. Other solutions are most welcome if there is a better way of doing it!
The code I came up with looks like this:
var page = $('.page');
var pageHeight = 0;
$.each(page.find('.somecontent'), function() {
if (pageHeight > 1000) {
page.next('<div class="newpage"></div>');
/* Somehow get all elements to add to the newly created page */
page.next('.newpage').append(<NEXT_ELEMENTS>);
pageHeight = 0;
}
pageHeight = pageHeight + $(this).height();
});
When you reach the page which answers the height criterion use the .nextAll function to get all the next siblings of it, then use .wrapAll to wrap them with your newpage div.
Here is the corresponding documentation of nextAll and wrapAll, it has everything you need to cover your scenario.
See comments in line below.
// Instead of the $.each() utiility function
// Just loop over each content area that needs
// examination
$('.somecontent').each(function(index, item) {
// Check if the height of the item is greater than the target (20px for this example)
if (parseInt(getComputedStyle(item).height,10) > 20) {
// Make a new div after the div that the item is currently in
// if one doesn't already exist
if($(".newpage").length === 0){
$(item.closest(".page")).after('<div class="newpage"></div>');
}
// Move the item into the new div
$(item.closest(".page")).next('.newpage').append(item);
}
});
//console.log(document.body.innerHTML); // shows resulting HTML
div.page {border:1px solid red; }
div.newpage {border:1px solid green; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="page">
<div class="somecontent">This<br>is<br>some<br>content</div>
<div class="somecontent">This is some content</div>
<div class="somecontent">
<ul>
<li>This</li>
<li>is</li>
<li>some</li>
<li>content</li>
</ul>
</div>
<div class="somecontent">Other</div>
</div>
I've got a single page site with two div modules that expand when clicked.
The first is at the top, in the Hero section and with the current code works as desired. The second is much further down the page in another section. Currently this second module closes as soon as the scroll takes place.
What I need to do is get the documents scroll coordinates when the div is clicked. Then once the user scrolls 200px up or down the div closes back up. Regardless of where it (the div) is on the site.
All the questions I found here and elsewhere only refer to setting the scroll tolerance relative to the window position on page load. But for me that's no goon. This site is responsive, and as it changes the initial positions of the div's will / can be unknown. I need someway of dynamically storing the viewports scroll position when the div's are clicked and assigning the 200px tolerance then.
I hope that makes sense. I've been at this for like 12+hrs now. SOS :)
Here's the Fiddle
If you don't want to go over to Fiddle, Here's the requisite code
HTML:
<body>
<section id="hero">
<div>
<div class="module-cta hero-cta">
<a class="module-cta__button"><!-- Fallback location -->
<span class="module-cta__text">PRESS ME</span>
</a>
<div class="module-cta__open">
<div class="module-cta__open-inner">
<div class="hero-cta__contact-points">
<div class="phone">
<div class="hero-cta_contact_logo">
<span><!-- phone.svg" --></span>
</div><!-- .service-logo -->
<div class="contact_trigger">
<a>Scroll down to 200px to see</a>
</div><!-- .contact_trigger -->
</div><!-- .phone -->
<div class="email">
<div class="hero-cta_contact_logo">
<span><!-- email.svg --></span>
</div><!-- .service-logo -->
<div class="contact_trigger">
<a>this div fold back up</a>
</div><!-- .contact_trigger -->
</div><!-- .email -->
</div><!-- .hero-cta__contact-points -->
<button class="module-cta__close module-cta__cancel"><i class="icon"><span></span></i></button>
</div><!-- .hero-cta__open-inner -->
</div><!-- .hero-cta__open -->
</div><!-- .hero-cta -->
</div>
</section>
<section class="spacer"></section>
<section id="service_area">
<div class="area_input">
<div class="module-cta area-cta wow fadeInUp" id="form_module">
<a class="module-cta__button area-cta__button">
<span class="module-cta__text area-cta__text">NOW PRESS ME</span>
</a>
<div class="module-cta__open area-cta__open">
<div class="module-cta__open-inner area-cta__open-inner">
<div class="area-cta__search">
<form class="postcode_form" id="postcode_form" name="postcode_form" action="#">
<input type="number" id="your_postcode" class="your_postcode" name="postcode" placeholder="3???">
<button type="button" class="area-btn"><span></span></button>
<a class="call-now">##########</a>
</form>
</div><!-- .area-cta__search -->
<button class="module-cta__close module-cta__cancel"><i class="icon"><span></span></i></button>
</div><!-- .area-cta__open-inner -->
</div><!-- .area-cta__open -->
</div><!-- .area-cta -->
</div><!-- .area_input -->
</section>
<section class="spacer"></section>
</body>
Script:
I'm sure a lot of this can be cleaned up and shrunk, but for now I'm just trying to get it all going.
// opens & closes modules by clicking module name
$('.module-cta__button').on('click', function(){
if($(this).parent().hasClass('hero-cta')){
$(this).parent().toggleClass('module-cta--active');
} else {
if($(this).parent().hasClass('area-cta')){
$(this).parent().toggleClass('module-cta--active');
}
}
});
// closes modules with .module-cta__close btn
$('.module-cta__close').on('click', function(){
if($(this).closest('div .module-cta').hasClass('module-cta--active')){
$(this).closest('div .module-cta').removeClass('module-cta--active');
}
});
// closes modules on scroll.
// * works but doesn't apply scroll tolerance of 200px for #area
$(window).scroll(function(){
var currentPos = $(window).scrollTop();
var module = $('div .module-cta');
if(module.hasClass('module-cta--active') && module.position().top <= currentPos+200){
$('div .module-cta--active').removeClass('module-cta--active');
}
});
// closes modules when escape key is pressed
$(window).keydown(function(escape){
var key = escape.which;
if(key == 27){
$('div .module-cta--active').removeClass('module-cta--active');
}
});
see Fiddle for css
Thanks for any help or useful suggestions in advanced.
I've put together a much smaller and simpler demonstration, just to show you what variables you need to accomplish this. Essentially, when a div is clicked, capture the current document scroll position using $(document).scrollTop(). Also store a refference to the current div that has been clicked.
When scrolling, check the difference between the current scroll and the new scroll, and using your clicked div reference, shrink the div when the difference is 200 or greater. JS fiddle below;
https://jsfiddle.net/jLqu4pas/
Code from Fiddle;
var currentScroll;
var lastClickedDiv;
$('section').click(function(){
$(this).css({'height' : '400'})
currentScroll = $(document).scrollTop();
lastClickedDiv = $(this);
console.log(currentScroll);
})
$(window).scroll(function(){
if($(document).scrollTop() > currentScroll + 200){
lastClickedDiv.css({'height' : 0})
}
})
So I've put together a script that will potentially help you.
I've done some basic testing on it, but if you come across any problems make a comment.
// Generate offsets and return them as an object
function generateOffsets($element, tolerance)
{
var offsets = $element.offset(),
offsetTop = offsets.top;
return {
scrollPos: offsetTop,
toleranceTop: offsetTop - tolerance,
toleranceBottom: offsetTop + tolerance
};
}
// Run a callback when the user leaves the scroll tolerance of a set of elements
function closeOnScroll($elements, tolerance, callback)
{
$elements.each(function() {
var $element = $(this),
offsets = generateOffsets($element, tolerance),
resizeEvent;
// On resize, regenerate the offsets so they stay up to date
$(window).on('resize', function(e) {
resizeEvent = e;
offsets = generateOffsets($element, tolerance);
});
// On scroll check if we've left the tolerance area, if so run the event and unbind
$(window).on('scroll', function(e) {
var windowPos = $(this).scrollTop();
if (windowPos < offsets.toleranceTop || windowPos > offsets.toleranceBottom) {
callback($element);
$(this).unbind(e);
$(this).unbind(resizeEvent);
}
});
});
}
// Example: Apply the event to a set of elements
$('.btn').click(function() {
closeOnScroll($('div .module-cta'), 200, function($element) {
$element.removeClass('module-cta--active');
});
});
The thing to remember with thie script is that it needs to be applied EVERY time the user clicks your button. You may say, WHY WOULD YOU DO THAT - but it actually has some serious performance implications.
The events rely on both scroll and resize, both of which are very slow, especially if not debounced like in this script. However, what I do in the script is unbind the events once it has occured. Otherwise, the resize and scroll would keep happening for each and every one of your buttons until the end of time. By 'unbinding' the event, you ensure long running performance of your page.
Wouldn't want to ruin those pretty animations would we?
Sticky Sidebar that only sticks when sidebar bottom is at window bottom
i get this site ( got to bootstrap sticky example)
javascript
$(function() {
var win = $(window);
var doc = $(document);
var wh = win.height();
var dh = doc.height();
var sidebar = $('.rightside .stickybar');
var sot = sidebar.offset().top;
var sh = sidebar.height();
var elementToBottom = dh - sot - sh;
// reset the sidebar width
var wt = sidebar.width();
sidebar.width(wt);
win.scroll(function(){
var dst = doc.scrollTop();
var scrollBottom = dh - dst - wh;
if(scrollBottom <= elementToBottom) {
sidebar.addClass('fixToBottom');
} else {
sidebar.removeClass('fixToBottom');
}
});
});
css
.fixToTop {
position: fixed;
top: 50px;
}
.fixToBottom {
bottom: 60px;
position: fixed;
}
html
<header> </header>
<div class="contents">
<div class = "leftside"> left</div>
< div class="righside">
<div class="stickybar">
// when move scrolling up and down
</div>
</div>
</div>
<footer> footer </div>
I have a 2 column layout. The left column is way longer than the sidebar. I want the sidebar only to stick when its bottom reaches the bottom of the browser window. So the user can continue to scroll down the left column content while the right sidebar sticks. I've seen a lot of sticky questions here, however this particular situation still stumps me. I also have a sticking headline bar on the left column that i've successfully gotten to stick.
Check out this example, I whipped up.
http://www.bootply.com/hVx29SmQ4g
If you or anyone has any questions, just send me a message and I'll try to explain. I commented the code however, so it should be quite straightforward. I hope its what you needed though!
:::CODE:::
/*
=== JS ===
============
Author: Kevin Leegsma
Updated: Feb 10, 2015
Notes: Coded for Stack Overflow - re: Sticky Sidebar
*/
/* Base function that waits till rest of site loads and then executes */
$(document).ready(function () {
"use strict";
/* activate sidebar, this can also be done as in-line HTML using the following line, instead of the Javascript below */
/* <div class = "col-xs-4" id = "rightColumn" data-spy = "affix" data-offset-bottom = "200"> */
$('#sidebar').affix({
offset: {
top: 400 /* both TOP and BOTTOM can be used here, tweek to your own needs */
}
});
/*This function gets the WIDTH of the wrapper and maintains it for the SIDEBAR*/
/*It does this by setting the WRAPPER as the PARENT, it then calls a function to resize the child (SIDEBAR)
in this case equal to the parent size.*/
/*NOTE: Without this function, the AFFIX still works, just doesn't function as nicely as it doesn't follow
standard Bootstrap grid CSS rules. */
$('#sidebar').each(function () {
var elem = $(this);
var parentWrapper = $('#sidebarWrapper');
var childToParentResize = function () {
var sidebarWidth = $(parentWrapper).width();
elem.width(sidebarWidth);
};
childToParentResize();
$(window).resize(childToParentResize);
});
/* Alert to inform you the SIDEBAR has become fixed, can be removed/commented, just for testing, but helpful for those new to AFFIX */
$('#sidebar').on('affixed.bs.affix', function(){
alert("The left navigation menu has been affixed. Now it doesn't scroll with the page.");
});
});
/* CSS used here will be applied after bootstrap.css
=== CSS ===
=============
Author: Kevin Leegsma
Updated: Feb 10, 2015
Notes: Coded for Stack Overflow - re: Sticky Sidebar
--------------------------------------
Layout
-------------------------------------- */
/* Targets the SIDEBAR once the affix has become active */
/* Adjust these to cater to your layout settings */
#sidebar.affix{
top: 10px;
right: 8.5%;
}
/*
==============
=== HTML ===
==============
Author: Kevin Leegsma
Updated: February 10, 2015
Notes: Coded for Stack Overflow - re: how-use-sticky-sidebar-move-up-when-window-scroll-top
*/
<!-- Main Code -->
<div class="container" id="main">
<!-- Left column with dummy text -->
<div class="col-xs-8" id="leftColumn">
<h1> LEFT COLUMN</h1>
<h3>With Even More Filler Text!</h3>
<p>...a bunch of text...</p>
</div><!--end leftColumn-->
<!-- Right column/sidebar that affixes itself as the window is scrolled -->
<!-- Stuck within a col-xs-4 parent element, this is because the AFFIX
has wonky width controls, they ignore Bootstrap grids and aren't responsive
with this wrapper and the JS however, it resizes well. -->
<div class="col-xs-4" id="sidebarWrapper">
<div id="sidebar" data-spy="affix">
<h1> SIDEBAR</h1>
<h3>With Filler!</h3>
<small>
<p>...sidebar text/links...</p>
</small>
</div><!--end sidebar-->
</div><!--end sidebarWrapper-->
</div><!--end container-->
I'm not at my computer at home right now, if it still isn't answered by tonight I'll whip up an example.
However if I'm reading what you need correctly, all you need to do is give the one element, that's to be fixed, the AFFIX property either through HTML/CSS
<div id="sidebar" data-spy="affix" data-affix-bottom="50">
NOTE -> the data-affix-bottom is an offset number, so tweak it to suit your needs
Or through JavaScript
$("#sidebar").affix({
offset: {
bottom: someValue
}
}
});
Some useful links that explain it more in depth:
http://getbootstrap.com/javascript/#affix
And
http://goo.gl/8knwd4 (With a scrolling sidebar example)
I have a slider that's in place on my website.
The basic way that it works is depicted in this jsfiddle -
http://jsfiddle.net/6h7q9/15/
I've written code to set the parent's height to the height of the content div. This worked fine, until I introduced some content that did not have a fixed height and whose height might increase while it was being shown on the page. Is there a way, I can dynamically change the height of this parent div whenever content inside it increases or decreases it's height.
HTML -
<div id="slider_container">
<div id="slider">
<div id="slide1">
Has content that might increase the height of the div....
</div>
<div id="slide2">
Has content that might increase the height of the div....
</div>
<div id="slide3">
Has content that might increase the height of the div....
</div>
</div>
</div>
<input type="button" value="Next" id="btnNext">
<input type="button" value="Previous" id="btnPrev">
<input type="button" value="Add text" id="btnAddText">
<div class="footer">
I appear after the largest container, irrespective of which one is present....
</div>
JavaScript -
var currSlider = 1;
$('#btnNext').click(function(){
debugger;
var margin = $('#slider').css('margin-left');
if(parseInt(margin) <= -400) {
return;
}
currSlider++;
// Moving the slider
$('#slider').css('margin-left', parseInt(margin) - 200 + 'px');
// Resetting the height...
$('#slider').height($('#slide' + currSlider).height());
});
$('#btnPrev').click(function(){
debugger;
var margin = $('#slider').css('margin-left');
if(parseInt(margin) >= 0) {
return;
}
currSlider--;
// Moving to the previous slider
$('#slider').css('margin-left', parseInt(margin) + 200 + 'px');
// Resetting the height...
$('#slider').height($('#slide' + currSlider).height());
});
$('#btnAddText').click(function() {
$('#slide' + currSlider).text('Hello World'.repeat(100));
});
String.prototype.repeat = function(times) {
return (new Array(times + 1)).join(this);
};
I hope this "answer" gets you going in the right direction. Since i don't have the time to fully look this up right now, i hope to send you in the right direction. if you do find out how to do this properly, please shoot me a message, since i would really like to know ^_^
http://www.w3.org/TR/DOM-Level-3-Events/#legacy-event-types
An example on how to use: (DOMSubtreeModified didn't work in IE from what i read. Therefor the propertchange event)
$('#slide1').on('DOMSubtreeModified propertychange', function() {
console.log('test',this);
});
Another option is by using the MutationObserver:
http://updates.html5rocks.com/2012/02/Detect-DOM-changes-with-Mutation-Observers
https://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#mutation-observers
Updated 6-8-2014 15:00 CET
Since i totally misread the original post, this answer was useless to say the best. But since the problem is actually really easy to solve (or... at least i hope i understand the problem this time), i thought i'd post an answer that worked for the situation: a slider with content of different heights.
What was the problem with the original slider? You moved the content out of the container, which made it hidden. However, the container would still pick up the height of it, since it only had a fixed width. The fixed height on the '#slider' did not prevent the container of picking up the height from the '#slide-*'. Had you set the height for the container... all would be fine :-)
Here's the outline of the hidden slide, moved 'off canvas': http://i.gyazo.com/f2404e85263a7209907fdbc8f9d8e34e.png
I did not fix your fiddle by completing your code. I just rewrote it to provide you with an easier to maintain slider. Here's a fiddle with a working slider where you can add and remove stuff in the slides: http://jsfiddle.net/3JL2x/3/
Just remove the height properties in the .slide1, 2 and 3 and add min-height instead.
Like that :
#slider > div {
min-height:200px;
float:left;
width : 200px;
}
#slide1 {
background-color : red;
}
#slide2 {
background-color: green;
}
#slide3 {
background-color: blue;
}
Live example
http://jsfiddle.net/6h7q9/27/
I've seen the same question over and over here, but no solution worked for me.
I am applying the jScrollPane() method on a <div> element with settled height and width, the content is cut by the overflow jScrollPane() inserts, but the scroll bar is not appearing.
My JavaScript code:
function openSubs(cont){
var width = 500;
var height = 500;
var mtop = ((height+65)/2)*(-1);
$('#lightbox .content').width(width).height(height).css('margin-top', mtop).load('content/'+cont+'.php', function(){
$('#sub-content').width(width).height(height);
$('#sub-content').jScrollPane();
});
openLightBox();
}
(on the openLightBox(); function are the fadeIns for the Lightbox divs below)
And the HTML before the Scroll Pane method is called:
<div id="lightbox">
<div class="fade"></div>
<div class="content">
A HUGE TEXT GOES HERE
</div>
<div class="fechar" onClick="resetLightBox();"></div>
</div>