On my website, I would like to add a grid consisting of square images (album covers). I also want to add this hover effect to said images: https://codepen.io/jarvis-ai/pen/GRJpQWO. How would I do this?
I have already tried a couple of things I found while researching my question but I never got the result I wanted. I have always had issues with the sizing of the images and making the sizes responsive. Here is a visualization of what I want it to look like and what I to happen:
Grid on a normal-sized monitor:
Grid on a smaller monitor or window:
Image on hover:
Pretty much: If the page is viewed on a normal-sized monitor, there should be 4 images in one row. If the page is viewed on a phone or if the window is resized, the images split into more rows with one row containing less than 4 now. If the mouse is being hovered over an image, the image should do the effect thing.
Notice: I should be able to do the hover effect by myself since there is already a working demo. I am just mentioning that I want the effect so that you can give me a solution that works with the effect.
Here is the last thing I have tried:
:root {
--grey: grey;
--white: white;
}
#music {
width: 100%;
min-height: 100vh;
background-color: var(--grey);
display: flex;
color: var(--white);
justify-content: center;
align-items: center;
text-align: center;
flex-direction: column;
}
#cover-section {
display: flex;
align-items: center;
vertical-align: middle;
justify-content: center;
flex-direction: row;
}
.cover {
flex: 1 0 21%;
width: 100%;
height: auto;
background-image: url(https://commons.wikimedia.org/wiki/File:Stack_Overflow_icon.svg);
}
<div id="music">
<div id="cover-section">
<div class="cover"></div>
<div class="cover"></div>
<div class="cover"></div>
<div class="cover"></div>
<div class="cover"></div>
<div class="cover"></div>
<div class="cover"></div>
<div class="cover"></div>
<div class="cover"></div>
</div>
</div>
Thanks in advance for your help!
By the way: If I need JavaScript to achieve this, please do not tell me to just use JavaScript but give me some code I could use, as I have done next to nothing with JavaScript before.
Something that works is that.
I cant implement all the part you want, but for use this example in a mobile view use the media-query css.
Something to start, not a definitive solution! It would be expensive to do it all here.
This is the code:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<title>Document</title>
<style>
#music {
width: 100%;
height: 100vh;
text-align: center;
margin-top: 60px;
}
#cover-section {
width: 100%;
height: 100vh;
}
.b-game-card {
width: 20%;
height: 30%;
float: left;
}
.cover {
width: 90%;
height: 90%;
background: url('https://m.media-amazon.com/images/I/81aTawcGdmL._AC_SL1500_.jpg');
background-size: cover;
background-position: center;
float: left;
}
</style>
</head>
<body>
<div id="music">
<div id="cover-section">
<div class="b-game-card">
<div class="cover">
</div>
</div>
<div class="b-game-card">
<div class="cover">
</div>
</div>
<div class="b-game-card">
<div class="cover">
</div>
</div>
<div class="b-game-card">
<div class="cover">
</div>
</div>
</div>
</body>
<script>
const maxTilt = 50; // Max card tilt (deg).
$(".b-game-card")
.mousemove(function (evt) {
let bounding = mouseOverBoundingElem(evt);
let posX = bounding.width / 2 - bounding.x;
let posY = bounding.height / 2 - bounding.y;
let hypotenuseCursor = Math.sqrt(Math.pow(posX, 2) + Math.pow(posY, 2));
let hypotenuseMax = Math.sqrt(Math.pow(bounding.width / 3, 2) + Math.pow(bounding.height / 3, 2));
let ratio = hypotenuseCursor / hypotenuseMax;
$(".cover", this).css({
transform: `rotate3d(${posY / hypotenuseCursor}, ${-posX / hypotenuseCursor}, 0, ${ratio * maxTilt}deg)`,
filter: `brightness(${2 - bounding.y / bounding.height})`
});
$(".gloss", this).css({
transform: `translateX(${posX * ratio * 1}px) translateY(${posY * ratio}px)`
});
})
.mouseleave(function () {
let css = {
transform: "",
filter: ""
};
$(".cover, .gloss", this).css(css);
});
function mouseOverBoundingElem(evt) {
let bounding = evt.target.getBoundingClientRect();
let x = evt.originalEvent.pageX - Math.round(bounding.left);
let y = evt.originalEvent.pageY - Math.round(bounding.top);
return {
x: Math.max(0, x),
y: Math.max(0, y),
width: Math.round(bounding.width),
height: Math.round(bounding.height)
};
}
</script>
</html>
I managed to figure out a solution by myself. Here is the code:
HTML:
<div id="music">
<div id="cover-section">
<div class="cover">
<!--Cover-->
</div>
<div class="cover">
<!--Cover-->
</div>
<div class="cover">
<!--Cover-->
</div>
<div class="cover">
<!--Cover-->
</div>
<div class="cover">
<!--Cover-->
</div>
<div class="cover">
<!--Cover-->
</div>
<div class="cover">
<!--Cover-->
</div>
<div class="cover">
<!--Cover-->
</div>
<div class="cover" id="tablet-cover">
<!--Cover-->
</div>
</div>
</div>
The tablet cover does not actually exist and is just a placeholder in case there are an uneven amount of squares in one row. As you can see in the...
CSS:
#music {
width: 100%;
min-height: 100vh;
background-color: var(--grey);
display: flex;
color: var(--white);
justify-content: center;
align-items: center;
text-align: center;
flex-direction: column;
}
#cover-section {
display: flex;
flex-wrap: wrap;
width: 80%;
}
.cover {
margin: 0px;
flex: 1 0 21%;
background-color: blue;
border: 2px solid black;
}
#tablet-cover {
display: none;
}
#media only screen and (max-width: 768px) {
/* For phones: */
.cover {
flex: 1 0 41%;
}
#waving-hand span {
font-size: 30pt;
}
}
#media only screen and (min-width: 600px) and (max-width: 800px) {
/* For tablets: */
.cover {
flex: 1 0 31%;
}
#tablet-cover {
display: block;
}
#waving-hand span {
font-size: 70pt;
}
}
The tablet cover is being removed on smaller or larger screens, where there would be an even number of squares in one row. It gets added once there is an uneven amount of covers in a row so that the last row has two squares instead of two rectangles.
Now for the self-engineered JavaScript code:
let coverWidth = document.querySelector('.cover').offsetWidth;
const allCovers = document.getElementsByClassName('cover')
for (var i = 0; i < allCovers.length ; i++){
allCovers[i].style.height= coverWidth + "px";
}
function coverheight(){
let coverWidth = document.querySelector('.cover').offsetWidth;
const allCovers = document.getElementsByClassName('cover')
for (var i = 0; i < allCovers.length ; i++){
allCovers[i].style.height= coverWidth + "px";
}
}
window.onresize = coverheight;
This is what the code basically does:
Check the width of the divs and then apply the value of the div-width to the height attribute of the divs
Every time the screen is resized, it re-checks the values and sets the new values accordingly
I do not know if this code is the "cleanest" code, but as long as it works, I am happy. What sucks to me is that I had to work with media queries, because the flex layout is usually used for when you want a layout that is responsible by default, AFAIK.
Thanks to everyone who tried helping me out though! I hope I can help someone else with my spaghetti code.
Related
I have a UI that involves (on wider devices) a 2 column layout that scroll in opposite directions in an infinite loop. On page load the UI seems to work pretty well but I really need some help improving some aspects of it.
The key things I want to work on are:
Order of items (projects) matches HTML structure. Currently they're reversed
Improve how the UI reacts and displays on browser resize
Fix ESLint undefined errors for "Map" and Weakmap"
1. Order of Items (projects)
You can see I've number each .project and on load the one that appears last in the HTML is first when viewing the webpage. It would make more sense the 'top' item is visible in the viewport before revealing the others in cascading order on scroll.
2. UI on Browser Resize
Though the UI seems to work well on page load, I think due to the positional values set on each .project this seems to lead to content overlapping or getting cropped on resize. I've tried matchMedia to see if I can run/recalculate once the viewport has 'stopped' resizing but doesn't seem to work.
It doesn't seem as bad going from desktop to mobile size screens. But vice versa, if you open on a narrow viewport and enlarge no content is visible and the UI appears empty until you scroll ...and then the left column doesn't loop (it stops) until you refresh the page.
On the mid-point #media when each .project has 50vh and not 100vh on scroll the items appear to flicker. Again, until you refresh.
It seems like maybe I need to run the script again after each resize? This is for a 'fun' portfolio style project so I appreciate that's a bit heavy on the resource but maybe acceptable in this instance, as it's not a commercial or D2C site?
3. ESLint Errors
Lastly, I get 2 errors saying Map and Weakmap are undefined when I compile using CodeKit and ESLint. That is in relation to these 2 lines...
const lastScrollPos = new WeakMap();
const linkedLoops = new Map([
I know there's a couple of issues but I wanted to break them down to try and be as clear as possible.
const leftLoop = document.querySelector(".split-loop__left");
const rightLoop = document.querySelector(".split-loop__right");
const scrollHeight = leftLoop.scrollHeight;
const offsetBoundary = 200; //the offset from the borders at which the element reordering event is triggered
const lastScrollPos = new WeakMap();
const linkedLoops = new Map([
[leftLoop, rightLoop],
[rightLoop, leftLoop]
]);
let scrollLockElement = null;
let scrollLockTimeout = null;
// the function sets handlers to scrolling for infinite scrolling
function infiniteScrollHandler(loop) {
const virtualLoop = Array.from(loop.children);
virtualLoop.forEach(
(el) => (el.style.top = scrollHeight / 2 + el.offsetHeight + "px")
);
loop.addEventListener("scroll", () => {
if (virtualLoop.length < 2) return; // not enough items to scroll
const topBound = loop.scrollTop;
const bottomBound = loop.scrollTop + loop.offsetHeight;
const firstEl = virtualLoop[0];
const lastEl = virtualLoop[virtualLoop.length - 1];
if (firstEl.offsetTop >= topBound - offsetBoundary) {
lastEl.style.top = firstEl.offsetTop - lastEl.offsetHeight + "px";
virtualLoop.unshift(lastEl);
virtualLoop.pop();
} else if (
lastEl.offsetTop + lastEl.offsetHeight <
bottomBound + offsetBoundary
) {
firstEl.style.top = lastEl.offsetTop + lastEl.offsetHeight + "px";
virtualLoop.push(firstEl);
virtualLoop.shift();
}
});
}
// the function sets handlers to scrolling for reverse interaction with the linked loop
function reverseLinkLoopHandler(loop) {
loop.addEventListener("scroll", () => {
const delta = lastScrollPos.get(loop) - loop.scrollTop;
lastScrollPos.set(loop, loop.scrollTop);
// this is blocked to prevent deadlock when events of two blocks are called each other.
{
if (scrollLockElement !== null && scrollLockElement !== loop)
return;
scrollLockElement = loop;
clearTimeout(scrollLockTimeout);
scrollLockTimeout = setTimeout(
() => (scrollLockElement = null),
300
);
}
linkedLoops
.get(loop)
.scrollTo(0, linkedLoops.get(loop).scrollTop + delta);
});
}
// set scroll handlers on all loops
linkedLoops.forEach((loop) => {
infiniteScrollHandler(loop);
loop.scrollTo(0, scrollHeight / 2);
lastScrollPos.set(loop, scrollHeight / 2);
reverseLinkLoopHandler(loop);
});
/* Hide Scroll Bars */
::-webkit-scrollbar {
display: none;
}
html,
body {
margin: 0;
padding: 0;
-ms-overflow-style: none;
scrollbar-width: none;
}
/* Content will be in these eventually */
.bar-left,
.bar-right {
border-right: 2px solid black;
box-sizing: border-box;
height: 100vh;
position: fixed;
top: 0;
left: 0;
width: 48px;
z-index: 10000;
}
.bar-right {
border: none;
border-left: 2px solid black;
left: auto;
right: 0;
}
/* Split Loop */
.split-loop {
margin-left: 24px;
}
.split-loop__item {
background: white;
overflow: hidden;
}
.project {
box-sizing: border-box;
border-bottom: 2px solid black;
padding: 24px 24px 0;
width: 100%;
}
.project__media {
margin-bottom: 24px;
}
.project__img {
border: 2px solid black;
width: 100%;
max-width: 100%;
}
.project__title {
font-family: Arial;
font-size: 12px;
margin-bottom: 24px;
}
/* Tablet View */
#media screen and (min-width: 400px) {
.split-loop {
height: 100vh;
position: relative;
margin: 0 48px;
}
.split-loop__left {
border-right: 2px solid black;
box-sizing: border-box;
width: 50%;
}
.split-loop__right {
position: fixed;
right: 24px;
bottom: 0;
width: calc(50% - 48px);
}
.split-loop__item {
display: flex;
flex-flow: column;
height: 50vh;
}
.project__media {
display: flex;
flex-grow: 1;
align-items: center;
justify-content: center;
overflow: hidden;
margin-bottom: 24px;
}
.project__img {
box-sizing: border-box;
display: block;
margin-bottom: 0;
width: auto;
max-width: 100%;
height: 100%;
max-height: 100%;
object-fit: contain;
overflow: hidden;
}
/* Split Loop */
.split-loop {
position: relative;
margin: 0 48px;
}
.split-loop__left {
width: 50%;
overflow: auto;
position: relative;
max-height: 100vh;
}
.split-loop__right:before,
.split-loop__left:before {
display: block;
content: "";
z-index: -1;
height: 9999999px;
}
.split-loop__right {
box-sizing: border-box;
position: fixed;
right: 48px;
bottom: 0;
z-index: 5;
width: calc(50% - 48px);
overflow: auto;
max-height: 100vh;
}
.project {
box-sizing: border-box;
border-bottom: 2px solid black;
padding: 24px 24px 0;
position: absolute;
}
}
#media screen and (min-width: 600px) {
.split-loop__item {
height: 100vh;
}
}
<header class="bar-left"></header>
<div class="bar-right"></div>
<div class="split-loop" role="main">
<div class="split-loop__left">
<div class="split-loop__item project">
<div class="project__media">
<img src="https://www.fillmurray.com/g/600/800" alt="" class="project__img" />
</div>
<div class="project__copy">
<h2 class="project__title">Project Left #1</h2>
</div>
</div>
<div class="split-loop__item project">
<div class="project__media">
<img src="https://www.fillmurray.com/600/800" alt="" class="project__img" />
</div>
<div class="project__copy">
<h2 class="project__title">Project Left #2</h2>
</div>
</div>
<div class="split-loop__item project">
<div class="project__media">
<img src="https://www.fillmurray.com/g/600/800" alt="" class="project__img" />
</div>
<div class="project__copy">
<h2 class="project__title">Project Left #3</h2>
</div>
</div>
<div class="split-loop__item project">
<div class="project__media">
<img src="https://www.fillmurray.com/600/800" alt="" class="project__img" />
</div>
<div class="project__copy">
<h2 class="project__title">Project Left #4</h2>
</div>
</div>
</div>
<div class="split-loop__right">
<div class="split-loop__item project">
<div class="project__media">
<img src="https://www.fillmurray.com/600/800" alt="" class="project__img" />
</div>
<div class="project__copy">
<h2 class="project__title">Project Right #1</h2>
</div>
</div>
<div class="split-loop__item project">
<div class="project__media">
<img src="https://www.fillmurray.com/g/600/800" alt="" class="project__img" />
</div>
<div class="project__copy">
<h2 class="project__title">Project Right #2</h2>
</div>
</div>
<div class="split-loop__item project">
<div class="project__media">
<img src="https://www.fillmurray.com/600/800" alt="" class="project__img" />
</div>
<div class="project__copy">
<h2 class="project__title">Project Right #3</h2>
</div>
</div>
<div class="split-loop__item project">
<div class="project__media">
<img src="https://www.fillmurray.com/g/600/800" alt="" class="project__img" />
</div>
<div class="project__copy">
<h2 class="project__title">Project Right #4</h2>
</div>
</div>
</div>
</div>
I'm making an HTML based game. In this game, 5 words are chosen at complete randomness. Everything's fine, the code picks 5 words at random, and displays it on the screen, right?
Well I don't like the way the words end up getting styled, and it pretty much looks like this:
So the goal is to end up making the text look like this.
So far, I haven't tried anything because I didn't really know what to do, however the only one attempted using was inline-block, and it somewhat helped, but not to the full extent of how I want it. Here is the current source code:
<body>
<div class="content" id="content">
<div class="wordBank" id="wordBank">
</div>
</div>
<script src="script.js"></script>
</body>
var wordBank = document.getElementById("wordBank")
// sparing you some of the unneeded stuff, this is just the word array
for (let i = 0; i < 5; i++) {
wordBank.innerHTML += "<p>" + words[Math.floor(Math.random()*words.length)] + "</p>"
}
body {
margin: 0px;
}
.content {
width: 512px;
height: 512px;
margin-left: auto;
margin-right: auto;
font-family: Arial;
}
.wordBank {
border: 2.5px solid black;
border-radius: 5px;
font-size: 24px;
}
How can I achieve my goal effectively?
Try something like this: https://codepen.io/c_sharp_/pen/ZEvjvqg
HTML
<div class="wrapper">
<span class="item">multiply</span>
<span class="item even">step</span>
<span class="item">kiss</span>
<span class="item even">force</span>
<span class="item">ago</span>
</div>
CSS
.wrapper {
display: flex;
width: 100%;
justify-content: space-between;
height: 500px;
}
.even {
align-self: flex-end;
}
alternatively,
.wrapper {
display: flex;
width: 100%;
justify-content: space-between;
height: 500px;
}
.wrapper > :nth-of-type(even) {
align-self: flex-end;
}
The numbers are (obviously) placeholders and fit them as you like.
Right now my webpage has vertical snap to scroll to each of the three 100vh sections.
In the second section, I have 3 100vw divs lined up horizontally with { overflow-x: scroll }. So I went ahead and try to link the my button that would help translate x using the following code:
const button = document.getElementById('slide');
button.onclick = function () {
document.getElementById('wrapper').scrollLeft += 20;
};
I guess right now the numbers doesn't matter. I just want to see it moving, but I can't get it to move on-click. Any ideas?
codepen.io/brandoniscool/pen/vYBMZyM
300% width is set on the wrapper, so it is the wrapper parent (id special) which needs to scroll.
Setting scrollLeft on the special element works as expected. document.getElementById('special').scrollLeft += 20;
const button = document.getElementById('slide');
button.onclick = function () {
document.getElementById('special').scrollLeft += 20;
};
* {
margin: 0;
font-family: 'Montserrat', sans-serif;}
body {
scroll-snap-type: y mandatory;
overflow-x: hidden;
width: 100vw;
height: 100%;
}
section {
scroll-snap-align: start;
height: 100vh;
outline: 1px dashed lightgray;
background-color: #c1d37f;
overflow-x: scroll;
}
.verticalSection {
display: flex;
justify-content: center;
flex-direction: row;
height: inherit;
border: 0.5px dashed #664e4c;
box-sizing: border-box;
/* so the border doesnt increase over the 100% width and heights */
}
#wrapper {
height: 100%;
width: 300%;
display: flex;
}
.horizontalSection {
background-color: #f9d4bb;
height: 100%;
width: 100%;
display: flex;
justify-content: center;
flex-direction: row;
border: 0.5px dashed #664e4c;
box-sizing: border-box; /* so the border doesnt increase over the 100% width and heights */
}
h1 {
color: #664e4c;
font-size: 3em;
margin: auto;
}
<!DOCTYPE html>
<html>
<head>
<title>vertical snap and horizontal snap integration</title>
<link rel="stylesheet" type="text/css" href="styles.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<script type="text/javascript" src="scripts.js"></script>
</head>
<body>
<section>
<div class="verticalSection"> <h1> BOX 1</h1> </div>
</section>
<section id="special">
<div id="wrapper">
<div class="horizontalSection"> <h1> BOX 2.1</h1> <button id="slide" type="button">Next</button></div>
<div class="horizontalSection"> <h1> BOX 2.2</h1> </div>
<div class="horizontalSection"> <h1> BOX 2.3</h1> </div>
</div>
</section>
<section>
<div class="verticalSection"> <h1> BOX 3</h1> </div>
</section>
</body>
</html>
I need to get rid of gaps between elements in my column layout. I can use the latest css3 as the site is targeted at modern browsers/devices but I need to avoid a javascript solution such that the page as delivered from the server doesn't need to be re-rendered based on the width of the client.
Using flexbox, css columns, and other tricks I need to coax a pinterest-like layout. (Pinterest uses javascript and absolute positioning for their layout, it doesn't even render with js turned off.) The site has boxes with a known width but variable height. The number of columns needs to vary based on browser width. (I can do this via media queries if I know what css attribute to change.) Here's what this looks like: via
Also note that I can't just increase the height of the containers to fill the empty space. I want to bring the item below it UP, not make all the heights match. (So stretching items 1, 3, and 4 in the picture above is NOT what I want.)
Things I've tried:
CSS 3 columns. This looks great, but the items are in the wrong order, with the second item being under the first. If this can be changed to a different order such that they go left-to-right, great!
Flexbox various flexbox configurations, I've tried just about every setting that I was able to change.
Javascript. Yes, I know I can manually create columns and re-render them on resize. I'm looking to avoid an expensive re-render operation that requires a manual balancing of columns and display. I can resort to this for older browsers that don't support a css3 solution. I'm also wanting to avoid manually positioning all of the items. Gross.
I've put a comment link to JSFiddle because I can't put it in here as "links to jsfiddle require code".
check this demo. This is pure css3 masonry effect.
http://w3bits.com/labs/css-masonry/
spinet from above link
body {
font: 1em/1.67 'Open Sans', Arial, Sans-serif;
margin: 0;
background: #e9e9e9;
}
.wrapper {
width: 95%;
margin: 3em auto;
}
.masonry {
margin: 1.5em 0;
padding: 0;
-moz-column-gap: 1.5em;
-webkit-column-gap: 1.5em;
column-gap: 1.5em;
font-size: .85em;
}
.item {
display: inline-block;
background: #fff;
padding: 1em;
margin: 0 0 1.5em;
width: 100%;
height: 150px;
box-sizing: border-box;
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
box-shadow: 2px 2px 4px 0 #ccc;
}
.item.black{
background-color: #000; height:200px;}
.item.blue{
background-color:blue; height:250px;}
.item.green{
background-color:green; height:300px;}
#media only screen and (min-width: 400px) {
.masonry {
-moz-column-count: 2;
-webkit-column-count: 2;
column-count: 2;
}
}
#media only screen and (min-width: 700px) {
.masonry {
-moz-column-count: 3;
-webkit-column-count: 3;
column-count: 3;
}
}
#media only screen and (min-width: 900px) {
.masonry {
-moz-column-count: 4;
-webkit-column-count: 4;
column-count: 4;
}
}
#media only screen and (min-width: 1100px) {
.masonry {
-moz-column-count: 5;
-webkit-column-count: 5;
column-count: 5;
}
}
#media only screen and (min-width: 1280px) {
.wrapper {
width: 1260px;
}
}
<div class="masonry">
<div class="item">Lorem ipsum dolor sit amet, consectetur adipisicing elit.</div>
<div class="item black">...</div>
<div class="item blue">...</div>
<div class="item green">...</div>
<div class="item black">...</div>
<div class="item blue">...</div>
<div class="item green">...</div>
<div class="item black">...</div>
<div class="item blue">...</div>
<div class="item green">...</div>
</div>
Hope this is helpful to you.
You can achieve it by flexbox:
HTML:
<div class="container">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
<div class="item">4</div>
<div class="item">5</div>
<div class="item">6</div>
</div>
CSS:
.container {
max-width: 900px;
height: 470px;
display: flex;
flex-flow: column wrap;
align-items: flex-start;
}
.item {
height: 150px;
}
http://codepen.io/asim-coder/pen/vXzKgg
CSS3: Set the main ul li that holds all 8 drop-down panels to margin: 0 auto;
mainList li {
margin: 0 auto; /*0 giving no margins on the top and bottom of the panels, and auto making the panels use all of the space within the parent, mainList. I hope this helps.*/
}
Well, a little bit late, may be this could be a solution.
I am using flex as it is the only system that can change the order as you want.
The drawbacks of this method is that I need to use some artificial elements to act as separators, and that I need to set a predetermined height on the container
.container {
border: 1px solid black;
width: 90%;
height: 700px;
display: flex;
flex-flow: column wrap;
align-items: flex-start;
}
.item {
height: 150px;
width: 24%;
margin: 2px;
}
.item:nth-child(3n + 1) {
height: 200px;
}
.item:nth-child(3n + 2) {
height: 250px;
}
.item:nth-child(4n) {
background-color: orange;
order: 40;
}
.item:nth-child(4n + 1) {
background-color: green;
order: 10;
}
.item:nth-child(4n + 2) {
background-color: lightblue;
order: 20;
}
.item:nth-child(4n + 3) {
background-color: yellow;
order: 30;
}
.divider {
width: 1px;
background-color: red;
height: 100%;
}
.divider:nth-last-child(3) {
order: 15;
}
.divider:nth-last-child(2) {
order: 25;
}
.divider:nth-last-child(1) {
order: 35;
}
<div class="container">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
<div class="item">4</div>
<div class="item">5</div>
<div class="item">6</div>
<div class="item">7</div>
<div class="item">8</div>
<div class="item">9</div>
<div class="divider"></div>
<div class="divider"></div>
<div class="divider"></div>
</div>
Use http://desandro.github.io/masonry/ Masonry will help to solve your issue, it is what Pinterest uses. My company is currently using it to develope a program, it is very easy and user friendly.
I have a problem to get exact width of flexbox after rendering contents.
I am working on a Windows 8 application (mean ie10 specific).
Here is the code:
[HTML]
<html>
<head>
<title>flexbox test</title>
</head>
<body>
<div class='container'>
<div class='viewport'>
<div class='canvas'>
<div class="item"> A </div>
<div class="item"> B </div>
<div class="item"> C </div>
<div class="item"> D </div>
<div class="item"> E </div>
<div class="item"> F </div>
<div class="item"> G </div>
<div class="item"> H </div>
<div class="item"> I </div>
<div class="item"> J </div>
</div>
</div>
</div>
<hr style="width: 600px; text-align: left;">
<div class="outbox"></div>
<script>tester();</script>
</body>
</html>
[CSS]
.container {
width: 400px;
height: 200px;
border: 1px solid black;
}
.container .viewport {
width: inherit;
height: inherit;
position: absolute;
overflow: auto;
}
.container .viewport .canvas{
display: -ms-flexbox;
-ms-flex: 0 0 auto;
-ms-flex-pack: start;
-ms-flex-flow: row none;
-ms-flex-align: start;
-ms-flex-item-align: start;
-ms-flex-line-pack: start;
position: relative;
}
.container .viewport .canvas .item {
width: 100px; height: 100px;color: #fff;
background-color: black;
margin: 10px;
}
[JAVASCRIPT]
(function tester(){
var canvas = document.querySelector('.canvas');
var style = document.defaultView.getComputedStyle(canvas, null);
function addToOutbox(str){
var outbox = document.querySelector('.outbox');
outbox.innerText = 'Width: ' + str;
}
addToOutbox(style.width);
})();
I was expecting width to be something else as there is a scroll bar.
Outer container width is 400px, middle one is inheriting width and height with overflow: auto and inner most is expandable.
There are eight items in flexbox with width and height 100px each. So I was expecting the flexbox width abot 900px (i.e. 100px*8 + margin-left and margin-right for each item) but still getting 400px only which is parent dimensions. Am I missing something?
Here is the link to JS Fiddle: http://jsfiddle.net/pdMSR/ [Open with ie10 only]
The element really is 400px. The flex items that are positioned past 400px are actually overflowing.
It sounds like what you are really trying to get is the scrollWidth. If you pass in canvas.scrollWidth to your addToOutbox function you'll get what you are looking for.