skip to Main Content

I am creating a simple little "Hall of Flags" HTML page that should have a narrow column of flags shown as png images, each inside a CSS picture frame. The CSS frames example here was my starting point. My outermost DIV, i.e. my hall-of-flags, has a flex display. Inside I am putting divs with figures that I stack vertically. Below is how I wish for this stack of image picture frames to look:

enter image description here

But here is how it currently looks, note I have a couple of drawn notes on it pointing out the problems:

enter image description here

I am happy with the way the flags look inside the frames, but I have 3 problems:

  1. Positioning the placard. A figurecaption won’t work, but neither will a div. When I try to use absolute positioning it does so relative to the document, not the box that contains it.
  2. Vertically centering the picture frame. Right now it is at the top of its container, which has a pink background. I would like it centered horizontally (which it is) and also vertically inside that container.
  3. My stack is a narrow column and the size of the picture frame is supposed to be the same percentage of its container but if I change the size of the window, it becomes longer than the container and spills out of the container below it. I would like it so that even if I change the width of the hall-of-flags div, the picture frame will remain wholly inside and centered, both vertically and horizontally.

Here is my complete code, any help figuring out the best way to do this would be appreciated:

let countries = ["Albania", "Austria", "Belarus", "Croatia"];
let flagURLs = [
  "https://upload.wikimedia.org/wikipedia/commons/d/d0/Flag_of_Albania.png",
  "https://upload.wikimedia.org/wikipedia/commons/7/76/Flag_of_Austria.png",
  "https://upload.wikimedia.org/wikipedia/commons/7/78/Flag_of_Belarus.png",
  "https://upload.wikimedia.org/wikipedia/commons/1/18/Flag_of_Croatia.png",
];

let html = "";
for (let i = 0; i < countries.length; i++) {
  let country = countries[i];
  let flagImgURL = flagURLs[i];
  html +=
    '<div class="flag-frame-container" id="flag-frame-container-' +
    country +
    '"">' +
    ' <figure class="flag-frame-figure">' +
    '  <div class="flag-frame-outerBevel">' +
    '   <div class="flag-frame-flatSurface">' +
    '    <div class="flag-frame-innerBevel">' +
    '     <img src="' +
    flagImgURL +
    '" class="flag-frame-img">' +
    "    </div>" +
    "   </div>" +
    "  </div>" +
    '  <figurecaption class="flag-frame-caption">' +
    country +
    "  </figurecaption>" +
    " </figure>" +
    "</div>";
}
let div = document.getElementById("hall-of-flags");
div.innerHTML += html;

for (let i = 0; i < countries.length; i++) {
  let country = countries[i];
  let el = document.getElementById("flag-frame-container-" + country);
  el.addEventListener("click", function () {
    alert("I am an alert box!");
  });
}
#hall-of-flags {
  background-color: lightblue;
}

.flag-frame-container {
  background-color: pink;
  padding: 0;
  margin: 0;
  box-sizing: border-box;
  height: 40%;
}

.flag-frame-figure {
  align-self: center;
  width: 90%;
  height: 50%;
  margin: 1em auto;
}

.flag-frame-outerBevel {
  box-shadow: 4px 6px 12px 0 black;
  border-width: 5px;
  border-style: solid;
  border-color: rgb(109, 84, 58) rgb(24, 19, 13) rgb(24, 19, 13)
    rgb(109, 84, 58);
}

.flag-frame-flatSurface {
  border: 12px solid rgb(65, 40, 16);
}

.flag-frame-innerBevel {
  border-width: 5px;
  border-style: solid;
  border-color: rgb(24, 19, 13) rgb(109, 84, 58) rgb(109, 84, 58)
    rgb(24, 19, 13);
}

.flag-frame-img {
  display: block;
  clear: both;
  height: 100%;
  width: 85%;
  padding: 7.5% 7.5% 10% 7.5%;
  background-color: rgb(255, 249, 224);
  border-width: 3px;
  border-style: solid;
  border-color: rgb(207, 166, 0) rgb(207, 166, 0) rgb(145, 110, 0)
    rgb(145, 110, 0);
}

.flag-frame-caption {
  background: #d19e1d;
  background: -webkit-linear-gradient(to right, #d19e1d, #ffd86e, #e3a812);
  background: linear-gradient(to right, #d19e1d, #ffd86e, #e3a812);
  font-family: cursive;
  text-align: center;
  border-radius: 10%;
}
<div id="hall-of-flags"></div>

Tried mixing flex and absolute positioning and was expecting to be able to center the placard at the bottom of the picture frame and vertically center the frame itself within its container.

2

Answers


  1. Problem 1:
    set position to relative for both .flag-frame-container and .flag-frame-caption. Then you can set the bottom of .flag-frame-caption to move up into the frame.

    Problem 2:
    Give .flag-frame-outerBevel some margin-top so it has a similar vertical space as left at the bottom from moving the caption up.

    Problem 3:
    I could not reproduce the problem as you described.

    .flag-frame-container {
      /* EDIT Need this so that flag-frame-caption is positioned relative to this and not the body */
      position: relative;
      text-align: center;
    }
    
    .flag-frame-caption {
      /* EDIT */
      position: relative;
      bottom: 70px;
    }
    
    .flag-frame-outerBevel {
      /* EDIT Make it so the cyan gap between frames is centered vertically */
      margin-top: 1rem;
    }
    
    Login or Signup to reply.
  2. Basically, you need to have a parent which is position: relative so you can position yourself relative to it.

    let countries = ["Alabama"];
    let flagURLs = [
      "https://upload.wikimedia.org/wikipedia/commons/d/d0/Flag_of_Albania.png",
    ];
    
    let html = "";
    for (let i = 0; i < countries.length; i++) {
      let country = countries[i];
      let flagImgURL = flagURLs[i];
      html +=
        '<div class="flag-frame-container" id="flag-frame-container-' +
        country +
        '"">' +
        ' <figure class="flag-frame-figure">' +
        '  <div class="flag-frame-outerBevel">' +
        '   <div class="flag-frame-flatSurface">' +
        '    <div class="flag-frame-innerBevel">' +
        '     <img src="' +
        flagImgURL +
        '" class="flag-frame-img">' +
        "    </div>" +
        "   </div>" +
        "  </div>" +
        '  <figurecaption class="flag-frame-caption">' +
        `<span>${country}</span>` +
        "  </figurecaption>" +
        " </figure>" +
        "</div>";
    }
    let div = document.getElementById("hall-of-flags");
    div.innerHTML += html;
    
    for (let i = 0; i < countries.length; i++) {
      let country = countries[i];
      let el = document.getElementById("flag-frame-container-" + country);
      el.addEventListener("click", function() {
        alert("I am an alert box!");
      });
    }
    #hall-of-flags {
      background-color: lightblue;
    }
    
    .flag-frame-container {
      background-color: pink;
      padding: 0;
      margin: 0;
      box-sizing: border-box;
      height: 40%;
    }
    
    .flag-frame-figure {
      align-self: center;
      width: 90%;
      height: 50%;
      margin: 1em auto;
    }
    
    .flag-frame-outerBevel {
      box-shadow: 4px 6px 12px 0 black;
      border-width: 5px;
      border-style: solid;
      border-color: rgb(109, 84, 58) rgb(24, 19, 13) rgb(24, 19, 13) rgb(109, 84, 58);
    }
    
    .flag-frame-flatSurface {
      border: 12px solid rgb(65, 40, 16);
    }
    
    .flag-frame-innerBevel {
      border-width: 5px;
      border-style: solid;
      border-color: rgb(24, 19, 13) rgb(109, 84, 58) rgb(109, 84, 58) rgb(24, 19, 13);
    }
    
    .flag-frame-img {
      display: block;
      clear: both;
      height: 100%;
      width: 85%;
      padding: 7.5% 7.5% 10% 7.5%;
      background-color: rgb(255, 249, 224);
      border-width: 3px;
      border-style: solid;
      border-color: rgb(207, 166, 0) rgb(207, 166, 0) rgb(145, 110, 0) rgb(145, 110, 0);
    }
    
    .flag-frame-caption span {
      background: #d19e1d;
      background: -webkit-linear-gradient(to right, #d19e1d, #ffd86e, #e3a812);
      background: linear-gradient(to right, #d19e1d, #ffd86e, #e3a812);
      font-family: cursive;
      text-align: center;
      border-radius: 10%;
    }
    
    .flag-frame-figure {
      position: relative;
    }
    
    .flag-frame-figure figurecaption {
      position: absolute;
      width: 100%;
      text-align: center;
      left: 0;
      right: 0;
      bottom: 9.5%;
    }
    <div id="hall-of-flags"></div>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search