Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How control vertical spacing of div children?

Task:

Keep a vertical list of thumb nails. Thumb nails must scale with window dimensions. Thumb nails are contained in a div the dimensions of which are given using vw, vh. On every resize, a Javascript function recomputes width and height of all thumb nails so that a fixed number of them appears in the visible area of the div and is as big as possible. To keep the thumb nails' vertical spacing constant, the height of the visible thumb nails is added up, increased by a factor and assigned to the div's height.

Problem:

When making the window very narrow, vertical space between the thumb nails is getting bigger and bigger. The values calculated for hFit and hTotal (see Javascript code below) seem to be incorrect and lead to unwanted overlay or too big vertical spacing of the thumb nails.

Details:

The entire layout is as follows:

An outmost div (.content-area) controls vertical alignment of the entire control (centered). A child of .content-area (.content-control) controls the layout of the actual list (.content-data) plus a close button (.close-btn-area) that will appear left of that list.

Code:

CSS:

.content-area
{
    position: absolute;
    left: 2vw;
    top: 5vh;
    width: 30vw;
    height: 90vh;
    display: flex;
    flex-direction: column;
    align-items: start;
    justify-content: center;
    list-style: none;
    opacity: 0.0;
}

.content-control
{
    position: relative;
    margin: 0 0 0 0;
    display: flex;
    flex-direction: row;
    align-items: start;
    justify-content: flex-start;
    overflow: hidden;
}

.content-data
{
    position: relative;
    margin: 0 0 0 0;
    padding: 0 0 0 0;
    width: auto;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    overflow: hidden;
}

#thumbs-content
{
    margin: 1vmin 1vmin 1vmin 1vmin;
    height: 78vh;
    font-family: 'Alegreya Sans SC', Verdana, sans-serif;
    font-variant: small-caps;
    overflow: hidden;
    color:#404040;
}

.thumb-size
{
    margin: 1vmin 0;
    width: 16vw;
    height: 12vh;
    display: flex;
    justify-content: center;
    align-items: center;        
}

.close-btn-area
{
    margin: 1vmin 1vmin 1vmin 1vmin;
    width: 4vh;
    height: 4vh;
    display: flex;
    align-items: start;
    justify-content: flex-start;
    cursor: pointer;
    -webkit-user-select: none;
    -khtml-user-select: none;
    -moz-user-select: none;
    -o-user-select: none;
    -ms-user-select: none;
    user-select: none;
}

.close-btn
{
    width:    4vh;
    height: 4vh;
    border: 0;
}

HTML:

<div class="content-area" id="thumbs-area">
    <div class="content-control" id="thumbs-control">
         <div class="close-btn-area" id="close-thumbs">
             <a><img class="close-btn" id="close-btn-thumbs" src="close-btn-inverted-128x128.png">
         </div>
         <div class="content-data" id="thumbs-data">
            <article id="thumbs-content">
                <div class="thumb-size"><img class="thumb" id="thumb1" src="img1.jpg"></div>
                <div class="thumb-size"><img class="thumb" id="thumb2" src="img2.jpg"></div>
                <div class="thumb-size"><img class="thumb" id="thumb3" src="img3.jpg"></div>
                <div class="thumb-size"><img class="thumb" id="thumb4" src="img4.jpg"></div>
                <div class="thumb-size"><img class="thumb" id="thumb5" src="img5.jpg"></div>
                <div class="thumb-size"><img class="thumb" id="thumb6" src="img6.jpg"></div>
                <div class="thumb-size"><img class="thumb" id="thumb7" src="img7.jpg"></div>
                <div class="thumb-size"><img class="thumb" id="thumb8" src="im8.jpg"></div>
                <div class="thumb-size"><img class="thumb" id="thumb9" src="im9.jpg"></div>
                <div class="thumb-size"><img class="thumb" id="thumb10" src="img10jpg"></div>
                <div class="thumb-size"><img class="thumb" id="thumb11" src="img11.jpg"></div>
            </article>
        </div>
    </div>
</div>

JavaScript:

const nVisibleThumbs = 6;
var nTopThumb = 0;
var nThumbCount = 11; // simplified; will be computed in the actual code
var nThumbScale = 0.9;

function RecalcThumbsLayout () 
{
    var elem = $('#thumbs-content');
    var w = elem.width ();
    var h = Math.round (elem.height () * nThumbScale);
    var hFit = 0;
    var wFit = 0;
    var hTotal = 0;

    for (i = 1; i <= nThumbCount; i = i + 1) 
    {
        var idStr = "#thumb" + i;
        var ar = Math.min (1.5, $(idStr).prop ('naturalWidth') / $(idStr).prop ('naturalHeight'));
        var ph = Math.round (h / nVisibleThumbs * 0.9);
        var pw = Math.round (Math.min (ph * ar, w * 0.9));
        ph = Math.floor (pw / ar); // considers portrait format images
        $(idStr).css ("width", pw);
        $(idStr).css ("height", ph);
        hTotal += ph;
        if ((i > nTopThumb) && (i <= nTopThumb + nVisibleThumbs))
            hFit += ph;
        if (wFit < pw)
            wFit = pw;
    }
    wFit *= 1.25; // compensate for scaling above
    hFit *= 1.25; // compensate for scaling above
    $('#thumbs-data').css ('width', wFit + 'px'); 
    $('#thumbs-data').css ('height', hFit + 'px'); 
    elem.css ('height', hTotal + 'px');
}

Demonstration:

To see the unwanted effect, you can go here: http://www.brockart.de/S, click on "Schmuck" and then horizontally resize the browser window.

Questions:

  1. What do I need to change in the Javascript to make this work?
  2. Is there a more elegant way to do this with css / html only?
like image 655
Razzupaltuff Avatar asked Feb 17 '18 11:02

Razzupaltuff


People also ask

How do I reduce vertical space in HTML?

HTML allows one to reduce vertical space, using something like p { margin-top: -20px; } or such as shown in number of places on the net. For example how-to-reduce-the-space-between-p-tags.

How do I make vertical spacing in CSS?

Use the line-height property in CSS to do so. Browsers by default will create a certain amount of space between lines to ensure that the text is easily readable. For example, for 12-point type, a browser will place about 1 point of vertical space between lines.

How do I put vertical space between two divs?

To give to space between two divs, just add display: flex in the parent element. Then add an justify-content: space-between after adding this you will see a space between two divs.

How do I put vertical space between elements in HTML?

So <spacer size="32"></spacer> will create 32px of vertical space. You can use the spacer inside of your element to provide more space or between elements.


2 Answers

You might get it without JS and with a simpler HTML and CSS (flexboxes and excessive containers look unnecessary).

Since

Keep a vertical list of thumb nails. ... a fixed number of them appears in the visible area of the div

Horizontal resize should not affect the thumbnails size to maintain the images aspect ratio.

So all we need is to calculate and set image height depending on the desired number of visible thumbnails.

Run the snippet below in fullscreen and resize the window:

.content {
  position: absolute;
  left: 2vw;
  top: 5vh;
  height: 90vh;
}

.thumbs {
  height: 100%;
  padding: 0 1rem;
  overflow-y: auto;
}

.thumbs img {
  display: block;
  box-sizing: border-box;
  /*
  since we need to fit 6 images,
  set img height = 1/6 of the container height
  */
  height: 16.667%;
  width: auto;
  border: solid 1vh transparent;
}

.close-btn {
  float: left;
  width: .9em;
  height: .9em;
  border: solid .15em;
  border-radius: 55%;
  color: #fff;
  background: #000;
  box-shadow: 0 0 2px #000;
  text-align: center;
  font: 400 2rem/.9 sans-serif;
}
<div class="content">
  <a class="close-btn">&times;</a>
  <div class="thumbs">
    <img src="https://picsum.photos/400/200/?1">
    <img src="https://picsum.photos/400/200/?2">
    <img src="https://picsum.photos/400/200/?3">
    <img src="https://picsum.photos/400/200/?4">
    <img src="https://picsum.photos/400/200/?5">
    <img src="https://picsum.photos/400/200/?6">
    <img src="https://picsum.photos/400/200/?7">
    <img src="https://picsum.photos/400/200/?8">
    <img src="https://picsum.photos/400/200/?9">
    <img src="https://picsum.photos/400/200/?0">
    <img src="https://picsum.photos/400/200/?a">
    <img src="https://picsum.photos/400/200/?b">
  </div>
</div>
like image 166
Kosh Avatar answered Oct 31 '22 16:10

Kosh


Replace your .thumb-size

  .thumb-size
   {
      margin: 1vmin 0;
     width: 16vw;
    height: 12vh;
    display: flex;
     justify-content: center;
     align-items: center;        
    }

To

   .thumb-size
   {
      margin: 1vmin 0;
     width: 16vw;
    height: auto;
    display: flex;
     justify-content: center;
     align-items: center;
    }

it will be worked as expected

like image 35
Nikhil Ghuse Avatar answered Oct 31 '22 18:10

Nikhil Ghuse