These plugins only depend on JQuery (and your own code) - super lightweight but really useful. Remember to combine plugins into a single file for quicker downloads... minify too if you wish.
I wrote these simple plugins as I found myself reusing the same code over and over... I'm sure someone out there will find them useful / time saving!
The div below is 100% wide (with a cover-sized background image), it has no height set in CSS and as the window resizes it will maintain it's aspect ratio:
$('.photo-square').maintainRatio({ ratio: 1 });
<div class="photo-square" style='background-image:url(sample.jpg);'></div>
/*! MaintainRatio for JQuery v1.00 BETA * http://www.davidjohnfarmer.co.uk/jquery-plugins/maintainratio/ * Do not remove any of this notice (you're welcome to use this code in commercial projects) * Copyright (c) 2016 David John Farmer www.davidjohnfarmer.co.uk * Licensed under the MIT license */ (function ( $ ) { $.fn.maintainRatio = function(options) { // DEFAULT OPTIONS var settings = $.extend({ ratio: 1, pixelmod: 0 }, options ); var $this = $(this); $this.css('min-height',0); var calculateSize = function(obj) { var thiswidth = $(obj).width(); var newheight = thiswidth*settings.ratio; if (settings.pixelmod != 0) { newheight = newheight + settings.pixelmod; } return newheight; } return this.each(function(i,obj) { var newheight = calculateSize(obj); $(obj).css('min-height',newheight); $(window).resize(function() { var $newheight = calculateSize(obj); $(obj).css('min-height',$newheight); }); }); }; }( jQuery ));
When using MaintainRatio you don't have to set it to be a square (you set a ratio), you can also set an offset.
The example below also shows use of AbsoluteMiddle - this sets an absolutely positioned element vertically to the middle, regardless of its parent size or how big it is (responsive too).
Note: Your 'in the middle' element must be absolutely positioned, and the parent item must be relative.
$('.photo-rect').maintainRatio({ ratio: 1.5, pixelmod: -20 }); $('.in-the-middle').absoluteMiddle({ pixelmod: 0 });
<div class="photo-rect" style='background-image:url(sample.jpg);'> <div class="in-the-middle">Im Rectange on Resize and my label is slightly longer</div> </div>
.photo-rect { background-size: cover; position: relative; } .in-the-middle { position: absolute; width: 100%; background-color: rgba(0,0,0,0.4); color: #fff; text-align: center; padding: 10px; }
/*! AbsoluteMiddle for JQuery v1.00 BETA * http://www.davidjohnfarmer.co.uk/jquery-plugins/absolutemiddle/ * Do not remove any of this notice (you're welcome to use this code in commercial projects) * Copyright (c) 2016 David John Farmer www.davidjohnfarmer.co.uk * Licensed under the MIT license */ (function ( $ ) { $.fn.absoluteMiddle = function(options) { // DEFAULT OPTIONS var settings = $.extend({ pixelmod: 0 }, options ); var gettop = function(obj) { var myheight = $(obj).outerHeight(); var parentheight = $(obj).parent().innerHeight(); var settop = (parentheight/2)-(myheight/2); if (settings.pixelmod != 0) { settop += settings.pixelmod; } return settop; } return this.each(function(i,obj) { var settop = gettop(obj); $(obj).css('top',settop); $(window).resize(function() { var settop = gettop(obj); $(obj).css('top',settop); }); }); }; }( jQuery ));
Works when you have multiple rows (like a product grid):
Accounts for some items having padding, others without:
And you can set extra padding (e.g. min-height + some pixels):
In this example, the child elements are run through the SyncHeights sizing before the parent items (so it works on complicated product panels for example):
At the moment SyncHeights works as shown below (there is no specific CSS or HTML):
$( document ).ready(function() { // Set up all of the SyncHeights rules... $('.example-one').prep_syncHeights(); $('.example-two').prep_syncHeights({ hook: "example-two", // Optional mode: "innerHeight", // Default pad: "200" // Adds extra height (pixels) }); $('.example-three').prep_syncHeights(); // Using borders? Use outerHeight $('.special-offer-text').prep_syncHeights({mode:"outerHeight"}); $('.example-product-image').prep_syncHeights({mode:"outerHeight"}); $('.example-product-notes').prep_syncHeights({mode:"outerHeight"}); $('.example-product-name').prep_syncHeights({mode:"outerHeight"}); $('.example-wrapper').prep_syncHeights({mode:"outerHeight"}); // Run your SyncHeights rules... $.fn.do_syncHeights({ resizedelay: 500 }); });
/*! SyncHeights for JQuery v1.00 BETA * http://www.davidjohnfarmer.co.uk/jquery-plugins/syncheights/ * Do not remove any of this notice (you're welcome to use this code in commercial projects) * Copyright (c) 2016 David John Farmer www.davidjohnfarmer.co.uk * Licensed under the MIT license */ (function ( $ ) { var sequence = 0; var delayed = 0; var delay = (function(){ var timer = 0; return function(callback, ms){ clearTimeout (timer); timer = setTimeout(callback, ms); }; })(); $.fn.prep_syncHeights = function(options) { // DEFAULT OPTIONS var settings = $.extend({ mode: "innerHeight", hook: "", pad: "0" }, options ); // COUNTS FROM 1 sequence++; if (settings.hook == "") { settings.hook = sequence; } var uniquehook = settings.hook+"-syncHeights"; var $this = $(this); return this.each(function() { $this.attr('data-syncheights',uniquehook); $this.attr('data-syncheights-mode',settings.mode); $this.attr('data-syncheights-pad',settings.pad); $this.attr('data-syncHeights-sequence',sequence); }); }; $.fn.do_syncHeights= function(options) { // DEFAULT OPTIONS var settings = $.extend({ resizedelay: 500 }, options ); $.fn.syncHeights(); $(window).load(function() { $.fn.syncHeights(); }); $( window ).resize(function() { delay(function(){ $.fn.syncHeights(); }, settings.resizedelay); }); }; $.fn.syncHeights = function() { var seq = 1; var rels = {}; var all_attr = "*[data-syncHeights-sequence]"; $(all_attr).css('min-height','0'); while (seq <= sequence) { var seq_attr = "*[data-syncHeights-sequence='"+seq+"']"; $(seq_attr).each(function(i, obj) { // FOR ALL ITEMS IN THIS SEQUENCE var pad = parseInt($(this).attr('data-syncheights-pad')); var mode = $(this).attr('data-syncheights-mode'); var hook = $(this).attr('data-syncheights'); if (mode == "innerHeight") { var thisheight = $(this).innerHeight(); } if (mode == "outerHeight") { var thisheight = $(this).outerHeight(); } if (mode == "height") { var thisheight = $(this).height(); } theheight = Math.ceil(thisheight); if (!rels[hook]) { rels[hook] = 1; } if (thisheight > rels[hook]) { rels[hook] = thisheight+pad; $("*[data-syncheights='"+hook+"']").css('min-height',rels[hook]); } }); seq++; } }; }( jQuery ));
My demo pages use this (the tabs below are the demo). These are great for SEO as the content renders prior to being shifted into tabs.
$('.list-to-tabs').listtoTabs();
<ul class="list-to-tabs"> <li> <h6>Tab Link 1</h6> <p>The tab content</p> </li> <li> <h6>Tab Link 2</h6> <p>The tab content</p> </li> </ul>
ul.list-to-tabs { margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px; list-style: none; } ul.list-to-tabs li { margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px; } ul.list-to-tabs li h6 { font-size: 18px; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px; } .list-to-tabs-trigger { display: inline-block; background-color: #90708C; color: #fff; text-decoration: none; padding: 2px 10px 2px 10px; margin-right: 10px; -webkit-box-shadow: 4px 4px 5px -4px rgba(0,0,0,0.75); -moz-box-shadow: 4px 4px 5px -4px rgba(0,0,0,0.75); box-shadow: 4px 4px 5px -4px rgba(0,0,0,0.75); } .list-to-tabs-trigger.active { background-color: #666; }
/*! ListToTabs for JQuery v1.00 BETA * http://www.davidjohnfarmer.co.uk/jquery-plugins/listtotabs/ * Do not remove any of this notice (you're welcome to use this code in commercial projects) * Copyright (c) 2016 David John Farmer www.davidjohnfarmer.co.uk * Licensed under the MIT license */ (function ( $ ) { var tabset = 0; $.fn.listtoTabs = function(options) { // DEFAULT OPTIONS var settings = $.extend({ }, options ); var $this = $(this); $(document).on("click", ".list-to-tabs-trigger", function(event) { event.preventDefault(); $(this).parent().parent().find('li.list-to-tabs-list-item').hide(); $(this).parent().find('.list-to-tabs-trigger').removeClass('active'); var tabid = $(this).attr('href'); $(tabid).show(); $(this).addClass('active'); }); var addLabels = function(obj,tabset) { var itemid = 0; var tabcontrolshtml = ""; $(obj).children('li').each(function(i,listobj) { var label = $(listobj).find('h6').html(); $(listobj).find('h6').hide(); var linkclass = 'listtotabs-'+tabset+'-li-'+itemid; $(listobj).addClass('list-to-tabs-list-item'); $(listobj).attr('id',linkclass); $(listobj).hide(); tabcontrolshtml += "<a href='#"+linkclass+"' class='list-to-tabs-trigger'>"+label+"</a>"; itemid++; }); return tabcontrolshtml; } return this.each(function(i,obj) { tabset++; var tabcontrolshtml = addLabels(obj,tabset); $(obj).wrap("<div class='list-to-tabs-wrap'></div>"); $('<div>'+tabcontrolshtml+'</div>').insertBefore(obj); $(obj).parent().find('.list-to-tabs-trigger:first').trigger('click'); }); }; }( jQuery ));