Entrance Chat Gallery Guilds Search Everyone Wiki Login Register

Welcome, Guest. Please login or register. - Thinking of joining the forum??
March 18, 2026 - @549.13 (what is this?)
Activity rating: Four Stars Posts & Arts: 55/1k.beats Unread Topics | Unread Replies | My Stuff | Random Topic | Recent Posts Start New Topic  Submit Art
News: ozwomp is requesting your location :ozwomp: [Agree] Guild Events: Winter Bird Watch

+  MelonLand Forum
|-+  World Wild Web
| |-+  ✁ ∙ Web Crafting
| | |-+  ☔︎ ∙ I need Help!
| | | |-+  Tile gallery problem (Javascript)


« previous next »
Pages: [1] Print
Author Topic: Tile gallery problem (Javascript)  (Read 101 times)
Rubbereon
Jr. Member ⚓︎
**
View Profile WWWArt


⛺︎ My Room
SpaceHey: Friend Me!
Matrix: Chat!
XMPP: Chat!

Guild Memberships:
Artifacts:
Joined 2025!
« on: March 11, 2026 @543.38 »

I used some javascript I nabbed from another website because this stuff was hella complicated. (or at least I think that's what I did, this script was there since 2024, so my memory's getting fuzzy)

I had no idea how to make a minimalist gallery that didn't take too much space on the post, but now I want another gallery lower on my blog page and I just can't figure it out. I can't reuse the id because it's an id not a class, it's not reusable. I tried cloning the entire code inside the script brackets with a brand new "tileMe2" id completely separate from the first script and it breaks the gallery. What should I do?

Here's the code and it works perfectly when used alone, but when I need a secondary gallery on the same page it's unworkable.

Code
"use strict"
    window.onload = window.onresize = function() {
        resize("tileMe", 14)
    }
    var pixelsPerEm = function(element) {
        var width
        var div = document.createElement('div')
        div.style.width = "1000em"
        element.appendChild(div)
        width = div.offsetWidth
        element.removeChild(div)
        return width / 1000
    }
    var findAspectRatio = function(images, count) {
        var i
        var aspect = 0
        for (i=0; i<count; ++i)
            aspect += images[i].naturalWidth / images[i].naturalHeight
        return aspect
    }
    var makeDiv = function(container, aspect, images, count) {
        var i
        var div = document.createElement("div")
        div.style.height = (container.clientWidth / aspect) + "px"
        div.style.display = "flex"
        for (i=0; i<count; ++i)
            div.appendChild(images.shift())
        container.appendChild(div)
    }
    var resize = function(id, maxEms) {
        var aspect, count, i
        var container = document.getElementById(id)
        var maxHeight = pixelsPerEm(container) * maxEms
        var images = Array.from(container.getElementsByTagName("img"))
        while (container.lastChild) container.removeChild(container.lastChild)
        while (images.length) {
            for (i=1; i<=images.length; ++i) {
                count = i
                aspect = findAspectRatio(images, i)
                if (container.clientWidth / aspect < maxHeight)
                    break
                aspect = container.clientWidth / maxHeight
            }
            makeDiv(container, aspect, images, count)
        }
    }

The page affected by this problem: https://rubbereon.nekoweb.org/blog/My-thoughts-on-Palworld.html

Notice how 1 group of images correctly tile tightly packed together and the other takes 50% of the webpage.

This is what the script looks like duplicated in the head tag of my page.
Code
<script> "use strict"
    window.onload = window.onresize = function() {
        resize("tileMe", 14)
    }
    var pixelsPerEm = function(element) {
        var width
        var div = document.createElement('div')
        div.style.width = "1000em"
        element.appendChild(div)
        width = div.offsetWidth
        element.removeChild(div)
        return width / 1000
    }
    var findAspectRatio = function(images, count) {
        var i
        var aspect = 0
        for (i=0; i<count; ++i)
            aspect += images[i].naturalWidth / images[i].naturalHeight
        return aspect
    }
    var makeDiv = function(container, aspect, images, count) {
        var i
        var div = document.createElement("div")
        div.style.height = (container.clientWidth / aspect) + "px"
        div.style.display = "flex"
        for (i=0; i<count; ++i)
            div.appendChild(images.shift())
        container.appendChild(div)
    }
    var resize = function(id, maxEms) {
        var aspect, count, i
        var container = document.getElementById(id)
        var maxHeight = pixelsPerEm(container) * maxEms
        var images = Array.from(container.getElementsByTagName("img"))
        while (container.lastChild) container.removeChild(container.lastChild)
        while (images.length) {
            for (i=1; i<=images.length; ++i) {
                count = i
                aspect = findAspectRatio(images, i)
                if (container.clientWidth / aspect < maxHeight)
                    break
                aspect = container.clientWidth / maxHeight
            }
            makeDiv(container, aspect, images, count)
        }
    }
    </script>
    <script> "use strict"
    window.onload = window.onresize = function() {
        resize("tileMe2", 14)
    }
    var pixelsPerEm = function(element) {
        var width
        var div = document.createElement('div')
        div.style.width = "1000em"
        element.appendChild(div)
        width = div.offsetWidth
        element.removeChild(div)
        return width / 1000
    }
    var findAspectRatio = function(images, count) {
        var i
        var aspect = 0
        for (i=0; i<count; ++i)
            aspect += images[i].naturalWidth / images[i].naturalHeight
        return aspect
    }
    var makeDiv = function(container, aspect, images, count) {
        var i
        var div = document.createElement("div")
        div.style.height = (container.clientWidth / aspect) + "px"
        div.style.display = "flex"
        for (i=0; i<count; ++i)
            div.appendChild(images.shift())
        container.appendChild(div)
    }
    var resize = function(id, maxEms) {
        var aspect, count, i
        var container = document.getElementById(id)
        var maxHeight = pixelsPerEm(container) * maxEms
        var images = Array.from(container.getElementsByTagName("img"))
        while (container.lastChild) container.removeChild(container.lastChild)
        while (images.length) {
            for (i=1; i<=images.length; ++i) {
                count = i
                aspect = findAspectRatio(images, i)
                if (container.clientWidth / aspect < maxHeight)
                    break
                aspect = container.clientWidth / maxHeight
            }
            makeDiv(container, aspect, images, count)
        }
    }
</script>
Logged

Fuzzy fwiend
Linux user
You can also find me on Comfybox.
rolypolyphonic
Jr. Member ⚓︎
**
View Profile WWWArt


The Non-Living World's first and cutest prophet
⛺︎ My Room
StatusCafe: rolypolyphonic
Matrix: Chat!
XMPP: Chat!
Itch.io: My Games
RSS: RSS

Guild Memberships:
Artifacts:
Joined 2025!
« Reply #1 on: March 11, 2026 @620.12 »

Could you explain what the script is intended to do? I'm not sure I understand. It is supposed to be a bunch of pictures arranged in tiles? Right now it looks like all the pictures are stacked vertically inline throughout the entire post, and I don't think I noticed any of them being tiled by the website itself (as opposed to the pictures inside the image being collaged together, I mean).

With that said you can set all images too have a maximum of 100% width in your CSS so that them going past the screen isn't a problem.

Code
img {
  max-width: 100%;
  height: auto;
}

If you need to arrange images in a grid format it might be better to use CSS flex or grid for that instead of JS. Here is how I use flex to have two columns of images side by side on desktop that I use on this page:

Code
.column {
  flex: 50%;
  max-width: 50%;
  padding: 0px 3px;
}
.column img {
  vertical-align: middle;
  width: 100%;
  padding: 3px 0px;
}

Another example I used on this page. This time it's three images in a row, where each .entry-tile is an image inside .container.

Code
.container {
  display: flex;
  flex-wrap: wrap;
  flex-direction: row;
  justify-content: center;
}
.entry-tile {
  width: 27%;
  padding: 10px;
  margin: 10px;
}

(Note: they are only tiled on desktop; I use media queries so that they stack vertically on mobile).

Alternatively if you want to use a different JS solution you can try the Masonry library. Here's an example of how it looks. It is great for when the images are not the same size and you want them to slot cleanly into each other with minimal effort, but it's fiddly to have more than one 'gallery' on a single page using it.

Anyway I'm not sure if getting the images to tile is actually what you need so apologies if I misunderstood. Good luck with it :4u:
Logged


My projects:

Bread, and all variations of the aforementioned - a hypertext multimedia webcomic series about a sentient Doll and the End of the World
Bien, and the Antivirus of the Apocalypse - novella about how an Undead Demon spent their Time [sic] in an underground bunker guided by the Voice of Reality after a metaphysical War
Daydream Attorney - a coagulation of spectres dedicated to turning schizotypy into the world's first viral mind disease
Rubbereon
Jr. Member ⚓︎
**
View Profile WWWArt


⛺︎ My Room
SpaceHey: Friend Me!
Matrix: Chat!
XMPP: Chat!

Guild Memberships:
Artifacts:
Joined 2025!
« Reply #2 on: March 11, 2026 @685.81 »

Could you explain what the script is intended to do? I'm not sure I understand. It is supposed to be a bunch of pictures arranged in tiles? Right now it looks like all the pictures are stacked vertically inline throughout the entire post, and I don't think I noticed any of them being tiled by the website itself (as opposed to the pictures inside the image being collaged together, I mean).
Because cloning the script breaks it, it works just fine otherwise and that's the prioblem here because I want a secondary gallery which I can't do with normally because it relies on the id (ids can only be used once!), so I clone it make a new id and for some reason it breaks the script and I wanna know why.

I posted the script expecting somebody to run it either locally or in a temporary directory of their website, you can't really troubleshoot if you don't try to see what's wrong..

all you gotta do is make a div give it the id "tileMe" and add a bunch of images in the middle, that's how it works.

If you need to arrange images in a grid format it might be better to use CSS flex or grid for that instead of JS. Here is how I use flex to have two columns of images side by side on desktop that I use on this page
I will consider this option, but what I like about this setup is that the images are arranged perfectly into a grid whereas on your website there is 1 column that's longer than the other. It's not nearly as clean.
Alternatively if you want to use a different JS solution you can try the Masonry library. Here's an example of how it looks. It is great for when the images are not the same size and you want them to slot cleanly into each other with minimal effort, but it's fiddly to have more than one 'gallery' on a single page using it.
Problem is they are not the same size nor aspect ratio, they vary heavily from one image from the next because those are random images I downloaded off reddit or google.

This could be helpful in my portfolio page, but otherwise it doesn't help in solving that blog post problem.

I would rather wanna try to fix the issue with the javascript code to allow it to be run more than once or at least in a manner that allows it to accept more ids or replace the id call with a class call instead, so it's reusable, but I have no idea how to do any of that because it's not my code.
Logged

Fuzzy fwiend
Linux user
You can also find me on Comfybox.
rolypolyphonic
Jr. Member ⚓︎
**
View Profile WWWArt


The Non-Living World's first and cutest prophet
⛺︎ My Room
StatusCafe: rolypolyphonic
Matrix: Chat!
XMPP: Chat!
Itch.io: My Games
RSS: RSS

Guild Memberships:
Artifacts:
Joined 2025!
« Reply #3 on: March 11, 2026 @966.16 »

I see, the tiled images on your page are also slightly uneven because they are constrained to have the same height so if the image doesn't fit in a row it gets pushed to the next one, hence I didn't realise it would be bothersome if the grid is uneven if you constrained the images to have the same width instead like I do. For a CSS-only solution you could still use the flex/grid option to have them constrained by height instead of width;, but with that said here is how the original script would be changed to use classes instead of ID's by replacing the function with a for loop that loops all over all .tileMe classes.

Besides ID's the
Code
container.removeChild(container.lastChild)
part of the script was replaced to store the original images and recreate the layout with clones so that the resize can work infinitely.

Code
"use strict";

window.onload = window.onresize = function () {
  resizeAll("tileMe", 14);
};

var pixelsPerEm = function (element) {
  var width;
  var div = document.createElement("div");
  div.style.width = "1000em";
  element.appendChild(div);
  width = div.offsetWidth;
  element.removeChild(div);
  return width / 1000;
};

var findAspectRatio = function (images, count) {
  var i;
  var aspect = 0;
  for (i = 0; i < count; ++i) {
    aspect += images[i].naturalWidth / images[i].naturalHeight;
  }
  return aspect;
};

var makeDiv = function (container, aspect, images, count) {
  var i;
  var div = document.createElement("div");
  div.style.height = (container.clientWidth / aspect) + "px";
  div.style.display = "flex";

  for (i = 0; i < count; ++i) {
    div.appendChild(images.shift());
  }

  container.appendChild(div);
};

var resizeContainer = function (container, maxEms) {
  var aspect, count, i;

  if (!container._originalImages) {
    container._originalImages = Array.from(container.getElementsByTagName("img"));
  }

  var maxHeight = pixelsPerEm(container) * maxEms;

  while (container.lastChild) {
    container.removeChild(container.lastChild);
  }

  var images = container._originalImages.map(function (img) {
    return img.cloneNode(true);
  });

  while (images.length) {
    for (i = 1; i <= images.length; ++i) {
      count = i;
      aspect = findAspectRatio(images, i);

      if (container.clientWidth / aspect < maxHeight) {
        break;
      }

      aspect = container.clientWidth / maxHeight;
    }

    makeDiv(container, aspect, images, count);
  }
};

var resizeAll = function (className, maxEms) {
  var containers = document.getElementsByClassName(className);

  for (var i = 0; i < containers.length; i++) {
    resizeContainer(containers[i], maxEms);
  }
};

You will have to change the two id="tileMe" to class="tileMe" in your page.
Logged


My projects:

Bread, and all variations of the aforementioned - a hypertext multimedia webcomic series about a sentient Doll and the End of the World
Bien, and the Antivirus of the Apocalypse - novella about how an Undead Demon spent their Time [sic] in an underground bunker guided by the Voice of Reality after a metaphysical War
Daydream Attorney - a coagulation of spectres dedicated to turning schizotypy into the world's first viral mind disease
Rubbereon
Jr. Member ⚓︎
**
View Profile WWWArt


⛺︎ My Room
SpaceHey: Friend Me!
Matrix: Chat!
XMPP: Chat!

Guild Memberships:
Artifacts:
Joined 2025!
« Reply #4 on: March 12, 2026 @794.86 »

Thanks a lot for the help!  :cheesy:

The reason they don't show up right is because my website is supposed to be viewed with a 1280x720 viewport. I assume you maximized your browser window into 1920x1080.

This is how it's supposed to look like:


Also the first gallery did have that problem because I was expecting a few more images to include up there, but ran out. It should look good now as long as the window size is 1280x720.
Logged

Fuzzy fwiend
Linux user
You can also find me on Comfybox.
Pages: [1] Print 
« previous next »
 

Melonking.Net © Always and ever was! SMF 2.0.19 | SMF © 2021 | Privacy Notice | ~ Send Feedback ~ Forum Guide | Rules | RSS | WAP | Mobile


MelonLand Badges and Other Melon Sites!

MelonLand Project! Visit the MelonLand Forum! Support the Forum
Visit Melonking.Net! Visit the Gif Gallery! Pixel Sea TamaNOTchi