admin管理员组

文章数量:1024603

I tried using flexbox, as sweet as flexbox is for keeping it responsive, I quickly found out that it wasn't possible to selectively place a div in between rows when wrapping.

Tried doing it via inline-block rather than using flexbox, and it works fine if I ignore keeping the page responsive. But that's the crux of the matter; I need for it to stay responsive.

Regardless of how many items are in the row, it should display the bio row below the row of where the row of the selected (clicked) picture is. If a picture is selected in a different row, the original bio row is closed, and reopened in the row below the row of the newly selected picture.

This is the closest I've managed for flexbox:

    .container {
        max-width: 1220px;
        border: 5px solid black;
        display: flex;
        margin: 0 auto;
        flex-direction: row;
        flex-wrap: wrap;
        align-items: center;
        justify-content: center;
    }
    
    .item {
        border-width: 1px;
        border-style: solid;
        border-color: black;
        width: 200px;
        height: 300px;
    }
    
    .one {
        background: #B5AC01;
    }
    .two {
        background: #ECBA09;
    }
    .three {
        background: #E86E1C;
    }
    .four {
        background: #D41E45;
    }
    .five {
        background: #D41EFF;
    }
    .six {
        background: #D4FF45;
    }

    body {
        margin: 0px;
        padding: 0px;
    }
<div class="container">
  <div class="item one"></div>
  <div class="item two"></div>
  <div class="item three"></div>
  <div class="item four"></div>
  <div class="item five"></div>
  <div class="item six"></div>
  <div class="item four"></div>
  <div class="item five"></div>
  <div class="item six"></div>
  <div class="item one"></div>
  <div class="item two"></div>
  <div class="item three"></div>
</div>

I tried using flexbox, as sweet as flexbox is for keeping it responsive, I quickly found out that it wasn't possible to selectively place a div in between rows when wrapping.

Tried doing it via inline-block rather than using flexbox, and it works fine if I ignore keeping the page responsive. But that's the crux of the matter; I need for it to stay responsive.

Regardless of how many items are in the row, it should display the bio row below the row of where the row of the selected (clicked) picture is. If a picture is selected in a different row, the original bio row is closed, and reopened in the row below the row of the newly selected picture.

This is the closest I've managed for flexbox:

    .container {
        max-width: 1220px;
        border: 5px solid black;
        display: flex;
        margin: 0 auto;
        flex-direction: row;
        flex-wrap: wrap;
        align-items: center;
        justify-content: center;
    }
    
    .item {
        border-width: 1px;
        border-style: solid;
        border-color: black;
        width: 200px;
        height: 300px;
    }
    
    .one {
        background: #B5AC01;
    }
    .two {
        background: #ECBA09;
    }
    .three {
        background: #E86E1C;
    }
    .four {
        background: #D41E45;
    }
    .five {
        background: #D41EFF;
    }
    .six {
        background: #D4FF45;
    }

    body {
        margin: 0px;
        padding: 0px;
    }
<div class="container">
  <div class="item one"></div>
  <div class="item two"></div>
  <div class="item three"></div>
  <div class="item four"></div>
  <div class="item five"></div>
  <div class="item six"></div>
  <div class="item four"></div>
  <div class="item five"></div>
  <div class="item six"></div>
  <div class="item one"></div>
  <div class="item two"></div>
  <div class="item three"></div>
</div>

That didn't work out, as it's apparently a toughie to be able to find a row and insert a div in between those rows. So I switched tacks and tried inline-block, only to find that while it's less plicated, it's still plicated.

.container {
  max-width: 1220px;
  border: 5px solid black;
  margin: 0 auto;
  font-size: 0; 
}
    
.item {
  display: inline-block;
  width: 200px;
  height: 300px;
  margin: 0px;
  padding: 0px;
  border: 1px solid black;
  font-size: 14pt;
  color: white;
  text-align: center;
  line-height: 300px;
}

.bio {
  height: 500px;
  width: 100%;
  background: #333;
  color: white;
  font-size: 24pt;
  text-align: center;
  line-height: 500px;
}

.selected {
  box-shadow: inset 0 0 10px #000000;
  font-weight: 800;
}

.row {
  display: inline-block;
  font-size: 0; 
}

.subrow {
  display: inline-block;
  font-size: 0; 
}
    
.one {
  background: #B5AC01;
}

.two {
  background: #ECBA09;
}

.three {
  background: #E86E1C;
}

.four {
  background: #D41E45;
}

.five {
  background: #D41EFF;
}

.six {
  background: #D4FF45;
}

body {
  margin: 0px;
  padding: 0px;
}
<div class="container">
    <div class="row">
        <div class="subrow">
            <div class="item one">Pic</div>
            <div class="item two">Pic</div>
            <div class="item three selected">Clicked Pic</div>
        </div>
        <div class="subrow">
            <div class="item four">Pic</div>
            <div class="item five">Pic</div>
            <div class="item six">Pic</div>
        </div>
    </div>
    <div class="bio">
        Bio goes here with pic
    </div>
    <div class="row">
        <div class="subrow">
            <div class="item four">Pic</div>
            <div class="item five">Pic</div>
            <div class="item six">Pic</div>
        </div>
        <div class="subrow">
            <div class="item one">Pic</div>
            <div class="item two">Pic</div>
            <div class="item three">Pic</div>
        </div>
    </div>
</div>

Haven't had much luck. Would love a CSS/HTML only solution, but I'm open to Javascript/jQuery if that's necessary to pull it off. Ideas? Thanks in advance for your time.

Edit: someone posted a solution below suggesting using offsetTop to track wrappage to determine where to insert the bio row. While it's not a CSS/HTML only solution, it's not a bad solution. I'll experiment with the JS code some more tomorrow morning when I've had more sleep in me.

Share Improve this question edited Nov 30, 2016 at 4:46 Ayla Cullen asked Nov 30, 2016 at 2:44 Ayla CullenAyla Cullen 4531 gold badge6 silver badges22 bronze badges 4
  • So what you are trying to achieve is display the bio row on every even position? or do you want it along the with the column elements in the same row? – user4447799 Commented Nov 30, 2016 at 3:28
  • If you look at the second code snippet (better yet, run it), you'll see one "pic" is selected, and immediately below that row in where that selected "pic" is, the bio row displays. Ideally (but not yet implemented), if another picture is selected in the same row of the original selected pic, the bio row remains in same place. If a picture is selected in a different row, then the bio closes and opens in a row below that selected picture. – Ayla Cullen Commented Nov 30, 2016 at 4:27
  • So there is just one bio row which will be reused by all the pics? How about giving a bio row to each pic? – user4447799 Commented Nov 30, 2016 at 4:45
  • Correct, only one bio row is displayed at a time. If a picture is selected in a different row, bio row closes in previous location and opens in a row below the newly selected picture. – Ayla Cullen Commented Nov 30, 2016 at 4:48
Add a ment  | 

2 Answers 2

Reset to default 5

$(function(){

  $('.item').click(function() {
    var $this = $(this);
    
    $('.selected').removeClass('selected');
    $this.addClass('selected');

    moveBio();
  });
  
  function moveBio() {

    var $bio = $(".bio");    
    var itemsPerRow = 0;

    $bio.hide(); // hide so doesn't affect calculations

    var firstItem = $('.item').eq(0);
    var itemTop = firstItem.position().top;
       
    $('.item').each(function(i) { // loop till we hit next row
      if($(this).position().top != itemTop) {
            itemsPerRow = i;
            return false;
        }   
    });
    
    selectedIndex = $(".item").index($('.selected')[0]);
    selectedRowNum = Math.floor(selectedIndex / itemsPerRow) + 1;
    
    $(".bio").insertAfter($(".item").eq((selectedRowNum * itemsPerRow) - 1)).show();    
  }
  
  $(window).resize(function() {
    $(".bio").hide(); // hide Bio so it doesn't interfere with the flex layout during resize
    clearTimeout(window.resizedFinished);
  
    window.resizedFinished = setTimeout(function(){
        moveBio(); // show Bio again now that resize has stabilised
    }, 250);
  });
  
});
.container {
        max-width: 1220px;
        border: 5px solid black;
        display: flex;
        margin: 0 auto;
        flex-direction: row;
        flex-wrap: wrap;
        align-items: center;
        justify-content: center;
        position: relative;
    }
    
    .item {
        border-width: 1px;
        border-style: solid;
        border-color: black;
        width: 200px;
        height: 300px;
    }
    
.bio {
  height: 500px;
  width: 100%;
  background: #333;
  color: white;
  font-size: 24pt;
  text-align: center;
  line-height: 500px;
}
    .one {
        background: #B5AC01;
    }
    .two {
        background: #ECBA09;
    }
    .three {
        background: #E86E1C;
    }
    .four {
        background: #D41E45;
    }
    .five {
        background: #D41EFF;
    }
    .six {
        background: #D4FF45;
    }
    .selected {
        box-shadow: inset 0 0 10px #000000;
        font-weight: 800;
    }
    body {
        margin: 0px;
        padding: 0px;
    }
<script src="https://ajax.googleapis./ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<div class="container">
  <div class="item one"></div>
  <div class="item two"></div>
  <div class="item three"></div>
  <div class="item four"></div>
  <div class="item five"></div>
  <div class="item six selected"></div>
    <div class="bio">
        Bio goes here with pic
    </div>  
  <div class="item one"></div>
  <div class="item two"></div>
  <div class="item three"></div>
  <div class="item four"></div>
  <div class="item five"></div>
  <div class="item six"></div>
</div>

Added dynamic browser resizing

Here's an easier to resize example: http://jsbin./wamisiliza/edit?output

It's an interesting question. I have no idea with CSS. But I came up with a quite plicated javascript method.

First get the array of all the items, just like your first example. And for each item, pare the offsetTop with the former item, if the values are not equal, insert a new Bio row between the two rows.

Sorry about the poor English, looking forword to a better answer.

I tried using flexbox, as sweet as flexbox is for keeping it responsive, I quickly found out that it wasn't possible to selectively place a div in between rows when wrapping.

Tried doing it via inline-block rather than using flexbox, and it works fine if I ignore keeping the page responsive. But that's the crux of the matter; I need for it to stay responsive.

Regardless of how many items are in the row, it should display the bio row below the row of where the row of the selected (clicked) picture is. If a picture is selected in a different row, the original bio row is closed, and reopened in the row below the row of the newly selected picture.

This is the closest I've managed for flexbox:

    .container {
        max-width: 1220px;
        border: 5px solid black;
        display: flex;
        margin: 0 auto;
        flex-direction: row;
        flex-wrap: wrap;
        align-items: center;
        justify-content: center;
    }
    
    .item {
        border-width: 1px;
        border-style: solid;
        border-color: black;
        width: 200px;
        height: 300px;
    }
    
    .one {
        background: #B5AC01;
    }
    .two {
        background: #ECBA09;
    }
    .three {
        background: #E86E1C;
    }
    .four {
        background: #D41E45;
    }
    .five {
        background: #D41EFF;
    }
    .six {
        background: #D4FF45;
    }

    body {
        margin: 0px;
        padding: 0px;
    }
<div class="container">
  <div class="item one"></div>
  <div class="item two"></div>
  <div class="item three"></div>
  <div class="item four"></div>
  <div class="item five"></div>
  <div class="item six"></div>
  <div class="item four"></div>
  <div class="item five"></div>
  <div class="item six"></div>
  <div class="item one"></div>
  <div class="item two"></div>
  <div class="item three"></div>
</div>

I tried using flexbox, as sweet as flexbox is for keeping it responsive, I quickly found out that it wasn't possible to selectively place a div in between rows when wrapping.

Tried doing it via inline-block rather than using flexbox, and it works fine if I ignore keeping the page responsive. But that's the crux of the matter; I need for it to stay responsive.

Regardless of how many items are in the row, it should display the bio row below the row of where the row of the selected (clicked) picture is. If a picture is selected in a different row, the original bio row is closed, and reopened in the row below the row of the newly selected picture.

This is the closest I've managed for flexbox:

    .container {
        max-width: 1220px;
        border: 5px solid black;
        display: flex;
        margin: 0 auto;
        flex-direction: row;
        flex-wrap: wrap;
        align-items: center;
        justify-content: center;
    }
    
    .item {
        border-width: 1px;
        border-style: solid;
        border-color: black;
        width: 200px;
        height: 300px;
    }
    
    .one {
        background: #B5AC01;
    }
    .two {
        background: #ECBA09;
    }
    .three {
        background: #E86E1C;
    }
    .four {
        background: #D41E45;
    }
    .five {
        background: #D41EFF;
    }
    .six {
        background: #D4FF45;
    }

    body {
        margin: 0px;
        padding: 0px;
    }
<div class="container">
  <div class="item one"></div>
  <div class="item two"></div>
  <div class="item three"></div>
  <div class="item four"></div>
  <div class="item five"></div>
  <div class="item six"></div>
  <div class="item four"></div>
  <div class="item five"></div>
  <div class="item six"></div>
  <div class="item one"></div>
  <div class="item two"></div>
  <div class="item three"></div>
</div>

That didn't work out, as it's apparently a toughie to be able to find a row and insert a div in between those rows. So I switched tacks and tried inline-block, only to find that while it's less plicated, it's still plicated.

.container {
  max-width: 1220px;
  border: 5px solid black;
  margin: 0 auto;
  font-size: 0; 
}
    
.item {
  display: inline-block;
  width: 200px;
  height: 300px;
  margin: 0px;
  padding: 0px;
  border: 1px solid black;
  font-size: 14pt;
  color: white;
  text-align: center;
  line-height: 300px;
}

.bio {
  height: 500px;
  width: 100%;
  background: #333;
  color: white;
  font-size: 24pt;
  text-align: center;
  line-height: 500px;
}

.selected {
  box-shadow: inset 0 0 10px #000000;
  font-weight: 800;
}

.row {
  display: inline-block;
  font-size: 0; 
}

.subrow {
  display: inline-block;
  font-size: 0; 
}
    
.one {
  background: #B5AC01;
}

.two {
  background: #ECBA09;
}

.three {
  background: #E86E1C;
}

.four {
  background: #D41E45;
}

.five {
  background: #D41EFF;
}

.six {
  background: #D4FF45;
}

body {
  margin: 0px;
  padding: 0px;
}
<div class="container">
    <div class="row">
        <div class="subrow">
            <div class="item one">Pic</div>
            <div class="item two">Pic</div>
            <div class="item three selected">Clicked Pic</div>
        </div>
        <div class="subrow">
            <div class="item four">Pic</div>
            <div class="item five">Pic</div>
            <div class="item six">Pic</div>
        </div>
    </div>
    <div class="bio">
        Bio goes here with pic
    </div>
    <div class="row">
        <div class="subrow">
            <div class="item four">Pic</div>
            <div class="item five">Pic</div>
            <div class="item six">Pic</div>
        </div>
        <div class="subrow">
            <div class="item one">Pic</div>
            <div class="item two">Pic</div>
            <div class="item three">Pic</div>
        </div>
    </div>
</div>

Haven't had much luck. Would love a CSS/HTML only solution, but I'm open to Javascript/jQuery if that's necessary to pull it off. Ideas? Thanks in advance for your time.

Edit: someone posted a solution below suggesting using offsetTop to track wrappage to determine where to insert the bio row. While it's not a CSS/HTML only solution, it's not a bad solution. I'll experiment with the JS code some more tomorrow morning when I've had more sleep in me.

Share Improve this question edited Nov 30, 2016 at 4:46 Ayla Cullen asked Nov 30, 2016 at 2:44 Ayla CullenAyla Cullen 4531 gold badge6 silver badges22 bronze badges 4
  • So what you are trying to achieve is display the bio row on every even position? or do you want it along the with the column elements in the same row? – user4447799 Commented Nov 30, 2016 at 3:28
  • If you look at the second code snippet (better yet, run it), you'll see one "pic" is selected, and immediately below that row in where that selected "pic" is, the bio row displays. Ideally (but not yet implemented), if another picture is selected in the same row of the original selected pic, the bio row remains in same place. If a picture is selected in a different row, then the bio closes and opens in a row below that selected picture. – Ayla Cullen Commented Nov 30, 2016 at 4:27
  • So there is just one bio row which will be reused by all the pics? How about giving a bio row to each pic? – user4447799 Commented Nov 30, 2016 at 4:45
  • Correct, only one bio row is displayed at a time. If a picture is selected in a different row, bio row closes in previous location and opens in a row below the newly selected picture. – Ayla Cullen Commented Nov 30, 2016 at 4:48
Add a ment  | 

2 Answers 2

Reset to default 5

$(function(){

  $('.item').click(function() {
    var $this = $(this);
    
    $('.selected').removeClass('selected');
    $this.addClass('selected');

    moveBio();
  });
  
  function moveBio() {

    var $bio = $(".bio");    
    var itemsPerRow = 0;

    $bio.hide(); // hide so doesn't affect calculations

    var firstItem = $('.item').eq(0);
    var itemTop = firstItem.position().top;
       
    $('.item').each(function(i) { // loop till we hit next row
      if($(this).position().top != itemTop) {
            itemsPerRow = i;
            return false;
        }   
    });
    
    selectedIndex = $(".item").index($('.selected')[0]);
    selectedRowNum = Math.floor(selectedIndex / itemsPerRow) + 1;
    
    $(".bio").insertAfter($(".item").eq((selectedRowNum * itemsPerRow) - 1)).show();    
  }
  
  $(window).resize(function() {
    $(".bio").hide(); // hide Bio so it doesn't interfere with the flex layout during resize
    clearTimeout(window.resizedFinished);
  
    window.resizedFinished = setTimeout(function(){
        moveBio(); // show Bio again now that resize has stabilised
    }, 250);
  });
  
});
.container {
        max-width: 1220px;
        border: 5px solid black;
        display: flex;
        margin: 0 auto;
        flex-direction: row;
        flex-wrap: wrap;
        align-items: center;
        justify-content: center;
        position: relative;
    }
    
    .item {
        border-width: 1px;
        border-style: solid;
        border-color: black;
        width: 200px;
        height: 300px;
    }
    
.bio {
  height: 500px;
  width: 100%;
  background: #333;
  color: white;
  font-size: 24pt;
  text-align: center;
  line-height: 500px;
}
    .one {
        background: #B5AC01;
    }
    .two {
        background: #ECBA09;
    }
    .three {
        background: #E86E1C;
    }
    .four {
        background: #D41E45;
    }
    .five {
        background: #D41EFF;
    }
    .six {
        background: #D4FF45;
    }
    .selected {
        box-shadow: inset 0 0 10px #000000;
        font-weight: 800;
    }
    body {
        margin: 0px;
        padding: 0px;
    }
<script src="https://ajax.googleapis./ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<div class="container">
  <div class="item one"></div>
  <div class="item two"></div>
  <div class="item three"></div>
  <div class="item four"></div>
  <div class="item five"></div>
  <div class="item six selected"></div>
    <div class="bio">
        Bio goes here with pic
    </div>  
  <div class="item one"></div>
  <div class="item two"></div>
  <div class="item three"></div>
  <div class="item four"></div>
  <div class="item five"></div>
  <div class="item six"></div>
</div>

Added dynamic browser resizing

Here's an easier to resize example: http://jsbin./wamisiliza/edit?output

It's an interesting question. I have no idea with CSS. But I came up with a quite plicated javascript method.

First get the array of all the items, just like your first example. And for each item, pare the offsetTop with the former item, if the values are not equal, insert a new Bio row between the two rows.

Sorry about the poor English, looking forword to a better answer.

本文标签: javascriptHow to insert a div in between flexbox rows and keep everything responsiveStack Overflow