How to center images while keeping them responsive? - javascript

Hi please take a look at my site, below is the code snippet in question i have to center my images since ive never had any luck with the css-html methods. The problem is because its set to wait for document.ready() sometimes it will place all my images to the right. Ive tried window.load() but the images center offscreen at smaller window sizes. It was also suggested i try
<div style="
background: url('Assets/image.png') center center no-repeat;
width: 100%;
height: 500px;
">
</div>
but this causes it to lose responsiveness. Ive searched around and i cant find a solution, i just need my images (and the one form) to stay centered and for the images to scale down with the window size.
site: http://bit.ly/11nAQJK
<script type="text/javascript"> //Centering Script
$(document).ready(function () {
updateContainer();
$(window).resize(function() {
updateContainer();
});
});
function updateContainer() {
(function ($) {
$.fn.vAlign = function() {
return this.each(function(i){
var h = $(this).height();
var oh = $(this).outerHeight();
var mt = (h + (oh - h)) / 2;
$(this).css("margin-top", "-" + mt + "px");
$(this).css("top", "50%");
$(this).css("position", "absolute");
});
};
})(jQuery);
(function ($) {
$.fn.hAlign = function() {
return this.each(function(i){
var w = $(this).width();
var ow = $(this).outerWidth();
var ml = (w + (ow - w)) / 2;
$(this).css("margin-left", "-" + ml + "px");
$(this).css("left", "50%");
$(this).css("position", "absolute");
});
};
})(jQuery);

Remove that whole script. Place this in your CSS.
img{
display: block;
margin: 0 auto;
}

just do
<style>
a{
display:block;
text-align:center;
}
</style>
<a href="Assets/OrderSheet.xls">
<img src="Assets/OrderSheet.png" class="image">
</a>
no need for repositioning
fiddle

No need for js, CSS alone is fine. Set your image to display block, set a width and Max width plus margin auto.
img {
display: block;
width: 300px;
max-width: 100%;
margin: 0 auto;
}

If you won't accept the method suggested by others, I would suggest using em's. Best to use them everywhere, but you could just apply them to your images.
Then use media queries to scale up/down all elements with values specified in em's, by changing the base font-size for different screen sizes.

center a responsive sized element
/* element/id/class */
/* margin is 100 - width / 2 */
img {
width:34%;
margin: 0 33%;
}

Related

Making a container grow on hover using jQuery

I'm trying to make a jQuery function that takes the current height and width of a link then makes it grow by whatever amount of px I set. I don't have much so far and I'm completely lost.
$('.absolute_img_links').hover(function(){
var link_height = $('.absolute_img_links').outerHeight();
var link_width = $('.absolute_img_links').width();
});
I know how to get the current height and width but I don't know how to basically say height of .absolute_img_links = link_height + 10px in jQuery
same functions do the job:
$('.absolute_img_links').hover(function(){
var link_height = $('.absolute_img_links').outerHeight();
$('.absolute_img_links').outerHeight(link_height + 10);
var link_width = $('.absolute_img_links').width();
$('.absolute_img_links').width(link_width + 10);
});
To achieve what you need you can pass a function to the height() and width() functions. In these functions you receive the current value, to which you can just add the 10px as required.
Note that hover() fires twice, once for mouseenter and once for mouseleave. Also, you don't reset the size of the element, so it just gets larger and larger on successive hovering. To fix this, amend your logic so that you attach the event handlers separately instead of one hover() call so you can increase/decrease the size as needed. Try this:
$('.absolute_img_links').on('mouseenter', function(){
$(this)
.height(function(i, height) { return height + 10; })
.width(function(i, width) { return width + 10; });
}).on('mouseleave', function() {
$(this)
.height(function(i, height) { return height - 10; })
.width(function(i, width) { return width - 10; });
});
.absolute_img_links {
position: absolute;
background-color: #C00;
color: #FFF;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="absolute_img_links">
Hover me!
</div>
Also note that you can implement a pure CSS version of this which has the exact same effect, although simply adds padding to the right and bottom of the element, instead of changing the width/height. Try this:
.absolute_img_links {
position: absolute;
background-color: #C00;
color: #FFF;
}
.absolute_img_links:hover {
padding: 0 10px 10px 0;
}
<div class="absolute_img_links">
Hover me!
</div>
Using the above method you could even keep the text centralised too, by adding a consistent 5px padding around the entire element.
Using height() and width() you can simply add 10 to the values you have found to increase the height/width of the container.
$('.absolute_img_links').hover(function() {
//var link_height = $('.absolute_img_links').outerHeight();
//var link_width = $('.absolute_img_links').width();
//Changed to $(this)
var link_height = $(this).outerHeight();
var link_width = $(this).width();
$(this).height(link_height + 10);
$(this).width(link_width + 10);
});
.absolute_img_links {
width: 300px;
height: 300px;
background-color: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="absolute_img_links"></div>
I know you asked for jQuery but...
This is trivial (and more flexible) in CSS:
.absolute_img_links img { transition: all .2s ease-in-out; }
.absolute_img_links:hover img { transform: scale(1.1); }
<img src="https://placeimg.com/100/100/any" />
<img src="https://placeimg.com/100/100/any" />

Responsive Masonry layout without predefined widths

I'm creating a 2 column masonry layout using images of different sizes. The images can be any size as long as they have the greatest common divisor (as required by the Masonry plugin).
In order to make the layout responsive I'm converting the width of the masonry items into percent (or I can use min-width and width 100%).
Update: I noticed that many who answer make both columns 50% as a solution. That works but is not the goal. Images have to retain their original image size. They can shrink but keep the same ratio.
$(function () {
var container = $('#container');
// Convert .box width from pixels to percent
$('.box').find('img').each(function () {
var percent = ($(this).width()) / container.width() * 100 //convert to percent;
$(this).closest('.box').css('max-width', percent + '%');
});
// Trigger masonry
container.masonry({
itemSelector: '.box',
columnWidth: 1 //widths dividable by 1
});
});
jsfiffle: http://jsfiddle.net/AMLqg/278/
This seems to work. The items are fluid when you resize the window. However if you load the script in a small window size (smaller than the 2 column width) the items collapse. How can I keep the masonry items responsive on window load even when the window is smaller?
Update: Here is more info for a better understanding. I'm trying to keep 2 responsive columns regardless of the window size. The columns can't have equal widths because the images have different widths. For this reason I'm using columnWidth: 1 because all widths are dividable by 1.
Please see images below for examples.
Problem: When you open the page in a small window the elements are collapsed. When you resize the window to be larger the elements remain collapsed until the window width is larger than the width of both elements.
Goal: I'm trying to keep the elements in 2 responsive columns on load like in the image below. Currently they remain responsive if on load the window is large and you resize it to be smaller but not vice verse when window is small on load and you make it larger.
You can try overflow:hidden on the surrounding box.
Using imagesloaded.js and columnwidth set using css like so:
jsFiddle
<div id="container">
<div class="grid-sizer"></div>
<div class="box">
<img src="http://images.huffingtonpost.com/2007-11-01-ice.jpg" />
</div>
<div class="box">
<img src="http://www.wwalls.ru/mini/201211/57608.jpg" />
</div>
<div class="box">
<img src="http://artistsandwriters.com/site/wp-content/uploads/2014/09/IMG_7303LR-390x150-1412284267.jpg" />
</div>
</div>
Script
$(document).ready(function () {
var container = $('#container');
$('.box').find('img').each(function () {
var percent = $(this).width() / container.width() * 50;
$(this).closest('.box').css('max-width', percent + '%');
});
// Trigger masonry
container.imagesLoaded(function () {
container.masonry({
itemSelector: '.box',
columnWidth: '.grid-sizer'
});
});
});
CSS
#container {
max-width:580px;
}
.box {
float: left;
margin-bottom: 5px;
}
.box img {
width: 100%;
}
.grid-sizer {
width: 50%;
}
Are you looking for something like this?
Fiddle
So, all we're doing here is getting rid of your percentage calculation (of which I really don't understand the necessity), and setting a min-width on the .box class. Just like this:
.box {
float: left;
min-width: 100px;
}
I was able to reproduce your problem. This is how it looks for those curious:
The problem is your float: left rule in the CSS, which is collapsing the box when Masonry is doing its positioning calculations after adding the image. You can do a simple clear-fix to keep this if you really need to keep that clunky percentage calculation, like so:
.container:after {
content: '';
display: table;
clear: both;
}
Hope that helps!
Edit – Based on your comments:
Okay, if you always want there to be two columns, it's an even simpler change:
Get rid of this Javascript
// Convert .box width from pixels to percent
$('.box').find('img').each(function () {
var percent = $(this).width() / container.width() * 100;
$(this).closest('.box').css('max-width', percent + '%');
});
Add this CSS
.box {
max-width: 50%;
}
Fairly straightforward, I think.
Here's a fiddle, just for giggles
EDIT
Check this http://jsfiddle.net/gk3t009j/2/
CSS
#wrapper
{
background-color: red;
margin: 0 auto; max-width:580px;
}
#container,
{
overflow: hidden;
width: 100%;
}
.box
{
max-width: 290px!important; width: 50%;
}
.box img{width: 100%;}
JS
$( window ).load( function()
{
var wc=$( '#container').width();
wc=parseInt(wc);
if( wc % 2)
{
var wb=$('.box').width();
wb--;
$('.box').width(wb)
}
$( '#container').masonry(
{
itemSelector: '.box',
columnWidth: function( containerWidth ) {
return parseInt(containerWidth / 2);
}
});
});
HTML
<div id="wrapper">
<div id="container">
<div class="box">
<img src="http://images.huffingtonpost.com/2007-11-01-ice.jpg" />
</div>
<div class="box">
<img src="http://www.wwalls.ru/mini/201211/57608.jpg" />
</div>
<div class="box">
<img src="http://artistsandwriters.com/site/wp-content/uploads/2014/09/IMG_7303LR-390x150-1412284267.jpg" />
</div>
</div>
</div>
I removed the JS code and some of the HTML markup and updated the styling:
#container {
width: 100%;
}
img {
display: inline;
vertical-align: top;
float: left;
min-width: 50%;
width: 50%;
}
http://jsfiddle.net/org6nsr8/8/
I agree with Josh Burgess on that Masonry is not needed to accomplish this, take a look and see if this is what you're after.
I'd be happy to elaborate if something is unclear or you want anything explained.
You don't need the JavaScript; just change the css for .box to:
.box {
float: left;
max-width: 50%;
}
I am not sure if this is what you need. If I understood the problem correctly may be you need to use max-width instead of width.
Here is example fiddle :
http://jsfiddle.net/AMLqg/304/
My JS code :
$(function () {
var container = $('#container');
var maxWidth = container.css("maxWidth");
maxWidth = parseInt(maxWidth.substring(0,maxWidth.indexOf("px")));
// Convert .box width from pixels to percent
$('.box').find('img').each(function () {
var percent = ($(this).width()) / maxWidth * 100;
console.log(percent);
$(this).closest('.box').css('max-width', percent + '%');
});
// Trigger masonry
container.masonry({
itemSelector: '.box',
columnWidth: 1 //widths dividable by 1
});
});
After trying several library to make a masonry layout , I prefer salvattor.js
Very easy to use. the size of the columns you can configure css.
#media screen and (max-width: 480px){
#grid[data-columns]::before {
content: '1 .column.size-1of1';
}
}
What i understand you want to keep Layout 2 Column with Images on aspect ratio on all screen sizes ,
Check
http://jsfiddle.net/tasaeed/k40cgfye/
CSS
#container {
max-width: 580px;
}
.box {
float: left;
width:50%;
}
.box img {
width: 100%;
height:auto;
}
Script
$(function () {
var container = $('#container');
// Trigger masonry
container.masonry({
itemSelector: '.box',
});
});

overflow-y:scroll in bxSlider (horizontal slider) Part 2

As a newbie, I realized too late that it is not possible to add code in comments.
So I opened a new question and asking again for your help.
For reasons of space I'm using bxSlider with fixed width and height (width 500px + height 300px). All images have the same width, but some of the images have a greater height than 300px.
As I mentioned - for reasons of space - I don't want to use adaptiveHeight, but (vertical) overflow:auto, but the result is always unsatisfactory, because now a scrollbar appears at each image - in the length of the image with the greatest height.
I just want to have a vertical scrollbar, when the height of an image is more than 300px.
Is this possible?
I tried this in query.bxslider.js:
.bx-wrapper {
position: relative;
padding: 0;
*zoom: 1;
width:500px;
height:300px;
overflow:auto;
}
.bx-wrapper img {
max-width: 100%;
display: block;
}
Because my query knowledge is still low, I also tried to use overflow:auto in the
.bx-wrapper img, but it didn't work, too.
I had to use javascript. And if you're so inclined, you can adapt this FIDDLE for your purposes.
Just click on the radio buttons to see different sized pictures.
JS
$('input:radio[name=photoradio]').change(function(){
pnum = $('input:radio[name=photoradio]:checked').val();
changethepicture(pnum);
});
function changethepicture(pnum)
{
var photonum = $('.photo img:nth-child('+ pnum +')');
$('.putmehere').html( photonum.height() );
if( photonum.height() > 350 )
{
$('img').css('display', 'none');
photonum.css('display', 'block');
$('.photo').css('height', '350px');
$('.photo').css('overflow-y', 'scroll');
}
else
{
$('img').css('display', 'none');
photonum.css('display', 'block');
$('.photo').css('height', 'auto');
$('.photo').css('overflow-y', 'hidden');
}
}

jQuery sticky header jumps at specific height

I'm trying to create a basic sticky header.
The header contains 2 parts: top and main. When page is scrolled down, i want to keep only the .main sticky (so that the .top becomes invisible).
I'm trying following code, but it is jerky and if the content has a specific height, it does not let scroll, starts jumping. I have captured video to illustrate the problem. Please see:
http://www.screenr.com/Z89H
Here's the demo:
http://jsfiddle.net/M33g4/
(you might not see the issue because of different screen height, in that case drag the results window to set its height about 535px).
HTML:
<header>
<div class="top"></div>
<div class="main"></div>
</header>
<section>
</section>
jQuery:
$(window).scroll(function () {
var height = $('header').outerHeight();
if($(this).scrollTop() > height){
$('header').addClass('sticky');
}else{
$('header').removeClass('sticky');
}
});
I'm sure you will have fixed this by now but after encountering the same issue I came up with a solution:
The issue was caused by the document size not having enough leeway beneath the fold to fit the height of the overall header. This meant that if a visitor tried to scroll down, the sticky part of the header will become fixed, but immediately unfix itself.I believe it may be the bounce-back effect that causes the problem but I haven't tested to verify this.
In short, I fixed it by adding simple check to ensure that there is more than enough space beneath the fold by comparing the height of the body and the height of the window. i.e body height minus window height must be greater than the total header height. Here's the code that worked in my instance:
// Sticky sub navbar
var sub_nav_height = $('#sub-nav').outerHeight();
var total_height = $('#main-head').outerHeight();
var header_height = total_height - sub_nav_height;
var content_height;
var y;
$(window).scroll(function() {
// Only make sticky if window is large enough not to cause jumping issue
content_height = $('body').height() - $(window).height();
if(content_height > total_height) {
y = $(this).scrollTop();
if($(this).scrollTop() > header_height) {
$('#sub-nav').addClass('fixed');
} else {
$('#sub-nav').removeClass('fixed');
}
}
});
There are two caveats which I decided were absolutely fine for my scenario. The first is that an extra calculation has been added every time the scroll event is triggered, but this hasn't caused me any performance issues. The second is that the sticky header functionality is simply disabled when a vistor's window is a problematic size, but again I had no qualms with this as the navbar could still just about be seen.
Check this
http://jsfiddle.net/M33g4/3/
JS
$(window).scroll(function () {
var height = $('.top').height();
if($(this).scrollTop() > height){
$('.top').hide();
$('header').addClass('sticky');
}else{
$('.top').show();
$('header').removeClass('sticky');
}
});
CSS
*{
margin: 0;
padding: 0;
}
header{
width: 100%;
}
.top{
height: 50px;
background: blue;
}
.main{
height: 70px;
background: green;
}
section{
height: 560px;
background: yellow;
}
.sticky{
position: fixed;
width: 100%;
}
You should target to the top but not to whole header demo
$(window).scroll(function () {
var height = $('header .top').outerHeight();
if($(this).scrollTop() > height){
$('header').addClass('sticky');
}else{
$('header').removeClass('sticky');
}
});
http://jsfiddle.net/M33g4/1/
$(window).scroll(function () {
var height = $('.top').outerHeight();
if($(this).scrollTop() > height){
$('header').addClass('sticky');
}else{
$('header').removeClass('sticky');
}
});
guess you got the wrong height.
Updated:
The blinking issue is caused by height changing (due to position: fixed)
check this one: http://jsfiddle.net/M33g4/6/
$(window).scroll(function () {
var height = $('.top').outerHeight();
if($(this).scrollTop() > height){
if($('.main.sticky').length == 0) {
$('header').append(
$('.main').clone().addClass('sticky'));
}
}else{
$('.main.sticky').remove();
}
});
and stick .main only:
.sticky{
position: fixed;
width: 100%;
top: 0;
}
This works for me:
Set the height variable to 30:
$(window).scroll(function () {
var height = 30;
if($(this).scrollTop() >= height){
$('header').addClass('sticky');
}else{
$('header').removeClass('sticky');
}
});
and change the css for the sticky class to the following:
.sticky{
position: fixed;
width: 100%;
top: -30px;
left: 0;
}
Top is -30 instead of -40. Works for me!
Check how the content in this demo snaps to the top, under the header, but not visible. You might want to resize the Results window to about 500px. Is there a solution to this please?
$(window).scroll(function () {
var height = $('.top').outerHeight();
if($(this).scrollTop() > height){
$('header').addClass('sticky');
}else{
$('header').removeClass('sticky');
}
});

Absolute position after zooming

I have divs with class="myDiv". I need to do this logic: on mouse over, I want to show a popup in the middle of the div.
For that I have the following:
$(".myDiv").mouseover(function () {
positionDiv($(this).position().left + $(this).width() / 2, $(this).position().top + $(this).height() / 2);
});
function positionDiv(xPosition ,yPosition ) {
$("#popupWindow").css("left", xPosition + "px");
$("#popupWindow").css("top", yPosition + "px");
$("#popupWindow").show();
}
The CSS:
.popupWindow{
position:absolute;
width:313px;
height:383px;
display:none;
}
This will position the popup window in the middle of the div on mouse over. Everything works great at this point.
However, if the website is zoomed in (using the browser zoom functionality), tHe position will get messed up. The popup window no longer appears in the middle of myDiv.
Any idea what might be the problem?
Edit:
For more info, if it is created and I zoom it, it is fine. But when I move my mouse to another myDiv and the new popup appears in a weird position. The left and top attribute of the Div are messing up.
You don't need JS for this:
http://jsfiddle.net/coma/6VUpS/1/
The key is to play with CSS and avoid JS calculations. The container div (myDiv) should be position: relative, the popup must be inside and position: absolute, top and left to 50% and using negative margins to center it (http://www.css-101.org/negative-margin/06.php).
Try avoiding JS for visual fanciness, only CSS ensures the correct position even on zoom since it's rendered by the browser.
HTML
<div class="myDiv">
Hi!
<div class="popupWindow">you are welcome!</div>
</div>
CSS
div.myDiv {
padding: 10px;
background-color: #eee;
margin: 50px 0;
position: relative;
}
div.popupWindow {
position: absolute;
top: 50%;
left: 50%;
margin: -50px 0 0 -100px;
width: 200px;
line-height: 100px;
background-color: #111;
color: #fff;
text-align: center;
display: none;
pointer-events: none;
}
div.myDiv:hover > div.popupWindow {
display: block;
}
Bonus track using a checkbox to click/tap/toggle popup and some fade in:
http://jsfiddle.net/coma/6VUpS/3/
More hacky:
http://jsfiddle.net/coma/6VUpS/
More complex example:
http://jsfiddle.net/coma/dHTHG/
I understand your problem and my solution is to put every object containing a pop up in pos relative and then set your pop up with those CSS :
.myPopUp{
position:absolute;
display : none;
width:400px;
height : 100px;
margin-top : -50px;
margin-left:-200px;
background-color: red;
top : 50%;
left: 50%;
}
It will alway be centered.
Now i understand you have only 1 pop up for all your hoverable div. My trick is to save the pop up in a var and remove it from its parent container to append it in the hovered div like this :
var popUp = $('.myPopUp');
$('.myDiv').mouseover(appendPopUp);
$('.myDiv').mouseout(function(){popUp.css('display', 'none')});
function appendPopUp(){
console.log(popUp.parent(), $(this))
if(popUp.parent()[0] != $(this)[0]){
popUp.remove();
$(this).append(popUp);
}
popUp.css('display', 'block')
}
That should work, here's my fiddle : http://jsfiddle.net/7EEZT/
$(window).on('resize', function(){
var $md = $('.myDiv');
positionDiv($md.position().left + $md.width() / 2, $md.position().top + $(this).height() / 2);
});
I have a simple css solution if you have a div with known height and width you can do same task with help of css only
.popupWindow {
position:absolute;
width:313px;
height:383px;
left:50%;
top:50%;
margin-left:-156px;/*half of width*/
margin-top:-191px;/*half of height*/
display:none;
}
Go with position:relative and try this. It will solved your problem relate to position.
$(".myDiv").mouseover(function () {
positionDiv( $(this).width() / 2, $(this).height() / 2);
});
function positionDiv(xPosition ,yPosition ) {
$("#popupWindow").css("left","-" + xPosition + "px");
$("#popupWindow").css("top", "-" + yPosition + "px");
$("#popupWindow").show();
}
The CSS:
.popupWindow{
position:relative;
width:313px;
height:383px;
display:none;
}
http://jsfiddle.net/kishan6446/PdNkg/13/

Categories