is there a way to get jquery masonry working with percentage width divs?
I'm trying to create a fluid layout with 25%, 50%, 75% and 100% widths. But as soon as i set the widths with % the automatic resizing stops working, and if I try to manually trigger mason onresize I get rounding errors that makes the divs jump around. Also it becomes quite buggy that it sometimes ignores the height, and sometimes just stops placing the divs and put them all on 0,0
HTML markup:
<div class="boxes">
<div class="box weight-1">
<div class="inner">
<p>lkaj dlksaj ldksjf lkdj flksd flkds flkds flksd jfakldsjf lkdsj flkjfd </p>
</div>
</div>
<div class="box weight-1">
<div class="inner">
<p>lkaj dlksaj ldksjf lkdj flksd flkds flkds flksd jfakldsjf lkdsj flkjfd </p>
</div>
</div>
<div class="box weight-2">
<div class="inner">
<p>lkaj dlksaj ldksjf lkdj flksd flkds flkds flksd jfakldsjf lkdsj flkjfd </p>
</div>
</div>
<div class="box weight-3">
<div class="inner">
<p>lkaj dlksaj ldksjf lkdj flksd flkds flkds flksd jfakldsjf lkdsj flkjfd </p>
</div>
</div>
</div>
CSS properties:
.weight-1 {
width:25%;
}
.weight-2 {
width:50%;
}
.weight-3 {
width:75%;
}
.weight-4 {
width:100%;
}
Muchos gracias for any input,
J
forget the .wight stuff add only this in css
.box {
width: 25%;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
masonry js
$(function(){
var container = $('#boxes');
container.imagesLoaded(function(){
container.masonry({
itemSelector: '.box',
columnWidth: function( containerWidth ) {
return containerWidth /4;// depends how many boxes per row
}(), // () to execute the anonymous function right away and use its result
isAnimated: true
});
});
});
change holder div to
<div id="boxes" class="masonry clearfix">
and boxes to
<div class="box">...</div>
( note that Firefox might cause bit issue with exact divider of 100 like 25% so set the boxes at 24.9 or 24% )outdated.
Use box-sizing to avoid drooping column issue.
i have same problem, try, try, and try, and this work for me.
.masonry-brick {
width:25%;/*or others percents*/
/*following properties, fix problem*/
margin-left:-1px;
transform:translateX(1px);
}
I had the same problem … solved it with css calc option. That works fine, but not on resizing the windows, then it gets a bit mad …
#media screen and (min-width:1020px){.brick { width: calc((100% - 40px) / 5); }}
#media screen and (min-width:800px) and (max-width:1019px){.brick { width: calc((100% - 30px) / 4); }}
#media screen and (max-width:799px){.brick { width: calc((100% - 10px) / 2); }}
If you want 25% width not 24.9% add margin-left:-1px!important; to your box
Related
I have two columns in a row with bootstrap 4. I want to use the whole screen to show the image. This is my code:
<div class="container-fluid" style="padding-left:0px;">
<div class="row">
<div class="col-md-6 ">
<img class="img-fluid" src="jumbo_background.jpg" />
</div>
<div class="col-md-6">
<div class="contact-wrapper">
<p>Test</p>
</div>
</div>
</div>
</div>
Everything is working good and responsive but this is the result I get from this code:
The preferred result I want is this:
The picture I use the dimension are 6000 X 4000
The solutions I have tried:
html, body {
height: 100%;
}
I have inspected the browser with the Google dev tool and I can see the the body is 100% but still not the result I want.
I have used h-100 from bootstrap and still get the same result.
I have used height: 100vh; but on smaller devices it's not responsive
I have checked this link:
Height not 100% on Container Fluid even though html and body are
Still don't get the result I want.
How can I give the image a full height in bootstrap 4?
UPDATE:
After nikolay solution on resolution: 1156 x 1013
You seem to want to use the image as a background. So my suggestion would be to do just that, as the cross-browser support is better (I'm not saying it can't be done with <img> alone, only that it's easier with background-image). Do note I'm leaving the <img> tag in for two reasons:
SEO indexing (if you need it)
sizing the column properly on mobile devices.
However, the <img> is not rendered. You're always looking at the background image of the <div>.
Here's a solution which grabs the src attribute of the first <img> element in each .column-image and uses it as <div>s backgroundImage. For it to work, make sure the <div> has the image-column class:
$(function() {
$('.image-column').each(function() {
const src = $('img', this).eq(0).attr('src');
if (src) {
$(this).css({ backgroundImage: `url(${src})` })
}
})
});
.image-column {
min-height: 100vh;
background: transparent no-repeat center /cover;
}
.image-column .img-responsive {
visibility: hidden;
}
#media(max-width: 767px) {
.image-column {
min-height: 0;
}
.image-column .img-responsive {
width: 100%;
height: auto;
}
}
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://code.jquery.com/jquery-3.4.1.slim.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js#1.16.0/dist/umd/popper.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js"></script>
<div class="container-fluid">
<div class="row">
<div class="col-md-6 image-column">
<img src="https://i.picsum.photos/id/237/600/400.jpg" class="img-responsive">
</div>
<div class="col-md-6">
<div class="contact-wrapper">
<p>Test</p>
</div>
</div>
</div>
</div>
Note: even though it's used as both src of the <img> and background-image of the <div>, the resource (image) is only loaded once.
Here's a solution:
html, body,
.container-fluid .row,
.container-fluid .row .col-md-6,
.container-fluid .row .col-md-6 img {
height: 100vh !important;
}
Add example for the responsive mobile view as you made above, so I can write a solution.
I'm using jQuery panzoom to zoom an image and some div elements. This works generally but the elements positioned on top of the image don't stay in their original locations. Is there anyway to keep the div elements where they were whilst being scaled?
JSFiddle: https://jsfiddle.net/828wu2dy/
HTML:
<section id="inverted-contain">
<div class="panzoom-elements">
<div class="item item1">ITEM 1</div>
<div class="item item2">ITEM 2</div>
<div class="panzoom">
<img src="http://www.hdwallpapers.in/walls/enchanted_forest-wide.jpg">
</div>
</div>
<div class="buttons">
<button class="zoom-in">Zoom In</button>
<button class="zoom-out">Zoom Out</button>
<input type="range" class="zoom-range">
<button class="reset">Reset</button>
</div>
</section>
JS:
(function() {
var $section = $('#inverted-contain');
$section.find('.panzoom').panzoom({
$zoomIn: $section.find(".zoom-in"),
$zoomOut: $section.find(".zoom-out"),
$zoomRange: $section.find(".zoom-range"),
$reset: $section.find(".reset"),
$set: $section.find('.panzoom-elements > div'),
startTransform: 'scale(0)',
increment: 0.1,
minScale: 1,
maxScale: 2,
contain: 'invert'
}).panzoom('zoom');
})();
CSS:
.panzoom-elements {
width: 50%;
height: 400px;
}
.item {
position: absolute;
z-index: 10;
}
.item.item1 {
color: white;
background: black;
width:50px;
height:50px;
top: 300px;
left: 100px;
}
.item.item2 {
color: white;
background: black;
width:50px;
height:50px;
top: 200px;
left: 150px;
}
The other problem is that it also doesn't drag horizontally.
I've tried everything I can think of.
Part 1:
To fix your 'item' problem - try putting 'item' elements on one level with 'img' - I mean put them inside div class='panzoom'.
Works for me. ^ ^
<section id="inverted-contain">
<div class="panzoom-elements">
<div class="panzoom">
<div class="item item1">ITEM 1</div>
<div class="item item2">ITEM 2</div>
<img src="http://www.hdwallpapers.in/walls/enchanted_forest-wide.jpg">
</div>
</div>
<div class="buttons">
<button class="zoom-in">Zoom In</button>
<button class="zoom-out">Zoom Out</button>
<input type="range" class="zoom-range">
<button class="reset">Reset</button>
</div>
</section>
The method of thought that led me to this answer: while learning panzoom documentation for API, and examining your fiddle, I found that 'img' or anything that could be seen as direct selector to it (I mean like $('.panzoom').child().first() is nowhere mentioned in your script. That means that most probably img is zooming in/out not by itself. What I thought next - it seem that it's parent is changing. That would mean that you need to put your items inside of that changing space - it is the most logical way to handle it... I tried to test that idea - and it worked.
Part 2:
The other problem is that it also doesn't drag horizontally.
Add this to your CSS
.panzoom{ width: 1920px;}
This is the size of the image. Works for me.
Perhaps you also could add to .panzoom height of image. It is not required in your case where image is horisontal but it could matter when image is vertical.
I dont know why but when I try to use hover event on CSS and Jquery .css for some reason it will not update the text. My plan is to make one of those slide show that you see text on the picture and on hover more text will show up.I need the background because of the pictures color and I dont want to make it big and on hover it will show text I want it to start from small. I dont care if its made by Jquery CSS or whatever.My end goal will be also to animate it as far as I know with Jquery it easiest but I can also do CSS
$("#ShortText").css({
fontSize:screen.height*.015,
//right: screen.width * .18,
//top: screen.height * .585,
width:screen.width * .6,
right: screen.width * .2,
top:screen.height*.65
});
#ShortText{
background-color: rgba(0, 0, 0,.6);
}
#Hide{
display:none
}
#ShortText:hover{
background:blue;
background-size:100% 100%;
position:absolute;
}
#First:hover + #Hovered1{
display:block
}
body{
color:white
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="ShortText">
<div>
<h1 id="First">1</h1>
<p id="Hovered1">Hoverd </p>
</div>
<div>
<h1 id="Second">2</h1>
<p id="Hovered2">Hoverd </p>
</div>
<div>
<h1 id="Third">3</h1>
<p id="Hovered3">Hoverd </p>
</div>
</div>
If you are using top and right you need position: absolute:
$("#ShortText").css({
fontSize:screen.height*.015,
right: screen.width * .18,
top: screen.height * .585,
width:screen.width * .6
});
#ShortText{
background-color: rgba(0, 0, 0,.6);
}
#Hide{
display:none
}
#ShortText:hover{
background:blue;
background-size:100% 100%;
position: absolute;
}
#First:hover + #Hovered1{
display:block
}
body{
color:white
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="ShortText">
<div >
<h1 id="First">1</h1>
</div>
<div>
<h1 id="Second">2</h1>
</div>
<div>
<h1 id="Third">3</h1>
</div>
</div>
<div id="Hide">
<p id="Hovered1">Hoverd </p>
<p id="Hovered2">Hoverd </p>
<p id="Hovered3">Hoverd </p>
</div>
Your Issue Updated
The #First:hover + #Hovered1 will select nothing because the #Hovered1 is not an immediate sibling of the #First.
#Hide is always hidden, so if you are trying to show something inside it, the parent is still hidden, so are the children.
Change your approach totally.
Does anyone know how to fix this problem. The only browser that works correctly is Firefox; in Chrome and Edge it doesn't work. When I resize the screen the box changes the position. Is there some solution?
Screenshot
HTML
<div class="box" style="background:#F00; height:200px;"></div>
<div class="box" style="background:#F0F; width:25%"></div>
<div class="box" style="background:#FF0; width:25%"></div>
<div class="box" style="background:#00F; width:25%"></div>
<div class="box" style="background:#55F; width:25%"></div>
CSS
.box {
width: 50%;
height: 100px;
float: left
}
JavaScript
$(window).resize(resize)
function resize() {
$(".box").each(function() {
$(this).height( $(this).width() * 0.5)
});
}
Here's the Codepen link:
http://codepen.io/Tufik/pen/rxyQmV
UPDATE---------
I modified the CodePen to show a more complex structure. The problem is when you resize the screen browser, the divs don't respect the correct position, some divs jump to the next line.
This is an old problem. I think it's because HTML is not pixel perfect. But I want to know if there is some easy solution different to use masonry.js or any plugins. Firefox work great, but Chrome or Edge not.
Problem: Unpredictable browser rounding of integers
Each browser calculates numbers differently. For widths and heights, the browser also rounds to the nearest integer for layout. So, the computed pixel-width of each floated box may have a different initial value after converting from percentage and filling out the container. Calculating on these numbers can lead to unpredictable results.
Here is an example of how the values are being calculated in your setup (resize the browser and watch the values change):
function resize() {
$(".box").each(function() {
var height = $(this).width() * 0.5;
$(this)
.height(height)
.html("<code>height: " + $(this).height() + "px (rounded from " + height + ")</code>");
});
}
$(window).resize(resize);
resize();
.box { float: left; }
.box-large {
width: 50%;
height: 200px;
}
.box-small {
width: 25%;
height: 100px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="box box-large" style="background:#F00;"></div>
<div class="box box-small" style="background:#F0F;"></div>
<div class="box box-small" style="background:#FF0;"></div>
<div class="box box-small" style="background:#00F;"></div>
<div class="box box-small" style="background:#55F;"></div>
Solution: uniformly apply your own rounded integer
One way to solve this is to create your own new height value, round it to a whole integer and apply it uniformly to each box instead of applying the decimal value and relying on the browser to do the rounding. The best way to do this is to calculate the new height value from one box and apply it to the others, instead of doing a calculation on each.
Because you have two different sized boxes, we do this calculation twice: once for the large box and once for the small box. The calculated large height value gets applied to all large boxes (only one in this case) and the calculated small height value gets applied to all small boxes.
Example:
function resize() {
var $larges = $('.box-large'), // Get all large boxes
$lgFirst = $($larges.get(0)), // Get first large box
lgHeight = Math.floor( // Round down before the browser screws it up
$lgFirst.width() / 2 // Calculate new height
),
$smalls = $('.box-small'), // Get all small boxes
$smFirst = $($smalls.get(0)), // Get first small box
smHeight = Math.floor( // Round down before the browser screws it up
$smFirst.width() / 2 // Calculate new height
),
// Function returns a function to keep things DRY
setHeight = function(height) {
// This function is returned to the .each() call later
return function () {
$(this)
.height(height)
.html("<code>height: " + height + "px</code>");
}
};
// Set height of all large boxes to new large height
$larges.each(setHeight(lgHeight));
// Set height of all small boxes to new small height
$smalls.each(setHeight(smHeight));
}
$(window).resize(resize);
resize();
.box { float: left; }
.box-large {
width: 50%;
height: 200px;
}
.box-small {
width: 25%;
height: 100px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="box box-large" style="background:#F00;"></div>
<div class="box box-small" style="background:#F0F;"></div>
<div class="box box-small" style="background:#FF0;"></div>
<div class="box box-small" style="background:#00F;"></div>
<div class="box box-small" style="background:#55F;"></div>
I'm not sure whether this answers your question, but I think css flex box is what you are looking for. you don't need javascript to do this.
The below code will align your divs all in one line and also provides responsiveness using flex box(Not exact layout you are looking but im sure you will be able to figure it out)
For more info please refer this article
<!DOCTYPE html>
<html>
<head>
<style>
.container {
display: flex;
flex-direction: row;
height: 200px;
flex-grow: 1
}
.column {
display: flex;
flex-direction: column;
flex-grow: 1
}
.big {
flex-grow: 1;
}
</style>
</head>
<body>
<div class="container">
<div class="column">
<div class="big" style="background:#F00;">
1
</div>
</div>
<div class="column">
<div class="big" style="background:#F0F;">
2
</div>
<div class="big" style="background:#00F;">
3
</div>
</div>
<div class="column">
<div class="big " style="background:#FF0; ">
4
</div>
<div class="big" style="background:#55F;">
5
</div>
</div>
</div>
</body>
</html>
This is driving me mad: I have a small bit jquery who slides three divs horizontally.
FIDDLE
Edit 3:
Live demo; complete website showing how I want it to work.. until I get to less than 775px. Please resize window to see what I mean.
EDIT, by popular demand. What I want:
In small screens, say from 700 and down. I want one panel to fill the screen. At a time.
2ND edit:
It works fine at above 700px. Below that; I would want the screen to show only one panel at a time, and when desired (a click on the current panel), the next panel will slide in sideways. I.e. No stacked columns, which is the classic responsive design. Please see Fiddle. It is all good until you minimize the browser window or use a mobile device.
I define panel1 and panel2 as fixed width, and use a css calc to keep the third panel at 100% minus panel1 (200px) and panel2 (200px): (calc 100% - 400px)
This works ok, until I get down into small screens. Then it goes haywire:
The panels stack on top of each other vertically (I want to hide the panels not active), and because of the fixed widths I "see" tiny bits of squished panels to the right. Ideally, I want each panel to fill small screens 100%.
What I need help with is this:
I must either
find a way to replace this JS defintion of the slide distance of pixels to %
var margins = {
panel1: 0,
panel2: -200,
panel3: -400,
}
..and therefore be able to do my css calc (100% - 20%) or something like that.
..or, at the very least, find a way to hide panels when in small screens.
All pointers greatly appreciated.
You can read more about the TB3 grid here: http://getbootstrap.com/css/#grid
Also read: Twitter's Bootstrap mobile: more columns and Twitter's Bootstrap 3 grid, changing breakpoint and removing padding
You will need something like:
<div class="row">
<div class="col-sm-4">
<div class="panel">Panel 1</div>
</div>
<div class="col-sm-4">
<div class="panel">Panel 2</div>
</div>
<div class="col-sm-4">
<div class="panel">Panel 3</div>
</div>
</div>
Below the 768 pixels your columns will stack (100% screen-width) caused by the col-sm-4. Above the 767 pixels you can use a media query to give your panels a fixed width:
#media (min-width: 768px)
{
.panel {width:200px}
}
update (based on the comment) below.
Try this: http://bootply.com/73541
CSS
#media (max-width: 767px)
{
#panel1 {visibility:visible}
#panel2 {visibility:hidden}
#panel3 {visibility:hidden}
}
#media (min-width: 768px)
{
#menu {visibility:hidden}
}
javascript
function showandhide(show)
{
$('.panel').hide();
$('#' + show).css('visibility','visible').slideDown("slow");
}
$('.panellink').click(function()
{
showandhide($(this).attr('rel'))
return false;
} );
html
<div id="menu" class="row">
<div class="col-12">
<a class="panellink" rel="panel1" href="">panel 1</a> |
<a class="panellink" rel="panel2" href="">panel 2</a> |
<a class="panellink" rel="panel3" href="">panel 3</a>
</div>
</div>
<div class="container">
<div class="row">
<div class="col-sm-4 col-lg-4">
<div id="panel1" class="panel">Panel 1</div>
</div>
<div class="col-sm-4 col-lg-4">
<div id="panel2" class="panel">Panel 2</div>
</div>
<div class="col-sm-4 col-lg-4">
<div id="panel3" class="panel">Panel 3</div>
</div>
</div>
</div>
Update 2 based on the response.
1) above the 767 pixels, all panel are shown in my example. You will have to reload the page when you resize from small to big.
To could also trigger this reload with $(window).resize() note some browser will fire this twice, see https://stackoverflow.com/a/4298653/1596547 for a solution
2) for "sliding in sideways" rewrite this: http://jsfiddle.net/ax4AC/2/:
$('.panel').css('margin-left','-260px').hide();
$('#' + show).css('visibility','visible');
$('#' + show).show();
$('#' + show).animate({
'margin-left': parseInt($('#' + show).css('margin-left'), 10) == 0 ? -$('#' + show).outerWidth() : 0,
opacity: "show"
});
html (new)
<div id="menu" class="row">
<div class="col-12">
<a class="panellink" rel="panel1" href="">panel 1</a> |
<a class="panellink" rel="panel2" href="">panel 2</a> |
<a class="panellink" rel="panel3" href="">panel 3</a>
</div>
</div>
<div class="container">
<div class="row">
<div class="col-sm-3 col-lg-3">
<div id="panel1" class="panel">Panel 1</div>
</div>
<div class="col-sm-3 col-lg-3">
<div id="panel2" class="panel">Panel 2</div>
</div>
<div class="col-sm-6 col-lg-6">
<div id="panel3" class="panel">Panel 3</div>
</div>
</div>
</div>
javascript (new)
function showandhide(show)
{
// source: http://jsfiddle.net/ax4AC/2/
$('.panel').css('margin-left','-260px').hide();
$('#' + show).css('visibility','visible');
$('#' + show).show();
$('#' + show).animate({
'margin-left': parseInt($('#' + show).css('margin-left'), 10) == 0 ? -$('#' + show).outerWidth() : 0,
opacity: "show"
});
//.slideDown("slow");
}
$('.panellink').click(function()
{
showandhide($(this).attr('rel'))
return false;
} );
//source timeout: https://stackoverflow.com/a/4298653/1596547
var id;
$(window).resize(function()
{
clearTimeout(id);
id = setTimeout(doneResizing, 500);
});
function doneResizing()
{
if($(window).width()>=768)
{
$('.panel').css('display','block');
$('.panel').css('visibility','visible');
$('.panel').css('margin-left',0);
}
}
css (new)
#media (max-width: 767px)
{
.panel{
margin-left: -260px;
}
#panel1 {visibility:visible; margin-left:0}
#panel2 {visibility:hidden}
#panel3 {visibility:hidden}
}
#media (min-width: 768px)
{
#menu {visibility:hidden}
.panel {display:block; visibility:visible; margin-left:0}
}
see: http://bootply.com/73715 (new!!)
From what I have understood from your question, you have the issue with panel3. You can use to avoid this type of annoyances.check live demo
.panel1, .panel2, .panel3
{
float: left;
height: 800px;
padding: 5px ;
overflow: none;
}