如何使用弹性盒重新排列div? [英] How to reorder divs using flex box?

查看:107
本文介绍了如何使用弹性盒重新排列div?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图为我的DOM保留一个seo友好的和语义的结构,而不用重复整个元素来将它们显示在不同的位置上。

我的布局基于 display:flex 项目。我尝试做到以下几点:



要知道的重要事项:


  • 我不想根据窗口宽度显示/隐藏div(以避免不必要的重复) li>
  • 没有一个div具有已知的或固定的高度

  • 在桌面上,div应该是垂直居中的,而右边的列建立一个标签团队(行为像一个单一的div)
  • 布局需要至少支持IE11 +


    有没有一个CSS的解决方案来实现这一目标?



    如果不是的话,很容易切出绿色的div,并将其内容粘贴到粉红色的使用JavaScript。但是,我对使用这个功能的性能和闪烁感到担忧,尽管调整浏览器的大小使其更加复杂。难道我做这个不必要的复杂吗?



    这里是小提琴工作解决方案,但与JavaScript

    CODEPEN DEMO 一般来说,你不能单独使用Flexbox来做到这一点,虽然可能会根据每种情况做出妥协。



  * {box-sizing:border-box;} body,html {margin:0;}。保证金:5vh汽车;身高:90vh;背景:rgba(0,0,0,0.05);显示:flex; flex-flow:column wrap;}。flex div {flex:1; width:50%;}。flex div:nth-​​child(2){order:-1;}。flex :: before {content:''; height:100%;} @ media(max-width:768px){.flex div {width:auto; } .flex :: before {display:none; } .flex div:nth-​​child(2){order:0; }} / *样式* /。flex-child {color:white; font-size:2em; flex-child:nth-​​child(1){background:#e6007e;}。flex-child:nth-​​child(2){background:#f4997c;}。flex-child: (3){background:#86c06b;}  

< ; div class =flex> < div class =flex-child> < DIV>顶部/右< / DIV> < / DIV> < div class =flex-child> < DIV>中心/左< / DIV> < / DIV> < div class =flex-child> < DIV>底/右和LT; / DIV> < / div>< / div>

,其中没有固定的高度是允许的,你可以结合使用Flexbox和 float



首先在标记中添加中心项目的Flexbox,然后使用顺序将其移动到顶部和使用媒体查询,您只需将 flex容器设置为块元素,然后使用 float 将左边的放在左边,右边的右边
$ b $数据库,数据库,数据库,数据库,数据库,数据库,数据库,数据库,数据库,数据库,数据库,数据库,目前隐藏>

* {box-sizing:border-box;} body,html {margin:0;}。 flex {max-width:1024px;宽度:90%;保证金:5vh汽车;身高:90vh;背景:rgba(0,0,0,0.05);显示:flex; flex-direction:column;}。flex-child {color:white; font-size:2em; font-weight:bold;填充:5%; flex-basis:33.333%;显示:flex; align-items:center;}。flex-child:nth-​​child(1){background:#e6007e; flex-child:nth-​​child(2){background:#f4997c;}。flex-child:nth-​​child(3){background:#86c06b; order:2;} @ media(min-width:768px){.flex {display:block; } .flex-child {width:50%; } .flex-child:nth-​​child(1){float:left;身高:100% } .flex-child:nth-​​child(2).flex-child:nth-​​child(3){float:right;身高:50% }}

< div class =flex> < div class =flex-child> < DIV>中心/左< / DIV> < / DIV> < div class =flex-child> < DIV>顶部/右< / DIV> < / DIV> < div class =flex-child> < DIV>底/右和LT; / DIV> < / div>< / div>


$ b $ hr b

更新

以下是将Flexbox与 position:absolute 结合的另一个版本,在桌面模式中垂直居中



更新后添加了一个脚本来控制绝对位置的元素不会比正确的项目,如果是的话,调整flex容器的高度。



注意,脚本不是优化的,它只是在那里以显示在某些情况下如何修复数据隐藏数据库数据库数据库数据库数据库数据库数据库数据库数据库数据库数据库数据库数据库数据库数据库数据库数据库数据库数据库数据库数据库数据库数据库数据库数据库数据库数据库数据库 console =truedata-babel =false>

(function(){window.addEventListener(resize,resizeThrottler,false); var fp = document.querySelector('。flex'); var fi = fp.querySelector('。flex-child:nth-​​child 1)'); var resizeTimeout;函数resizeThrottler(){//只要actualResizeHandler执行在队列中,忽略resize事件if(!resizeTimeout){resizeTimeout = setTimeout(function(){resizeTimeout = null; actualResizeHandler(); // actualResizeHandler的执行速度是15fps},66); }} function actualResizeHandler(){//处理resize事件if(fp.offsetHeight< = fi.offsetHeight){fp.style.cssText ='height:'+ fi.offsetHeight +'px'; } else {fp.style.cssText ='height:auto'; }} window.addEventListener('load',function(){actualResizeHandler();})}());

  * {box-sizing:border-box;} body,html {margin:0;}。最大宽度:1024px;宽度:90%;保证金:5vh汽车;身高:90vh;背景:rgba(0,0,0,0.05);显示:flex; flex-direction:column;}。flex-child {color:white; font-size:2em; font-weight:bold; flex-child:nth-​​child(1){order:1;}。flex-child:nth-​​child(3){order:2;}。flex-child:nth-​​child(1) )div {background:#e6007e;}。flex-child:nth-​​child(2)div {background:#f4997c;}。flex-child:nth-​​child(3)div {background:#86c06b;} @ media min-width:768px){.flex {justify-content:center; } .flex-child {width:50%; } .flex-child:nth-​​child(1){position:absolute;顶部:50%; transform:translateY(-50%); } .flex-child:nth-​​child(n + 2){margin-left:50%; }}  

< div class =flex> < div class =flex-child>其他项目其他项目其他项目< br>其他项目< br>其他< div>内容>< br>其他< br>其他< br>项目< / DIV> < / DIV> < div class =flex-child> < div>顶部/右侧< br>&更多< br>内容< / div> < / DIV> < div class =flex-child> < div>底部/右侧<>更多< / div> < / div>< / div>


$ b $ hr b

用脚本也可以重新排序/在元素之间移动项目。




更新2(回答在另一个问题,但后来搬到这里)

如果我们谈论较小的项目,如标题或更小的菜单,可以做很多网站平台提供商喜欢广场,weebly,wordpress等。他们的模板拥有不同的标记结构,其中一个项目有时存在两次,一个是桌面可见的,另一个是移动的。另外,如此小,将会减少到没有当涉及到性能(和个人,我不觉得有这个问题比重复CSS规则,每个屏幕大小,并愉快地做到这一点,而不是介绍脚本)。

小提琴演示



stack-in-line-data-data-data-lang =jsdata-hide =truedata-console =truedata-babel = false>

.container {display:flex;} .container> div {width:50%;}。container div:nth-​​child(-n + 2){border:dashed; padding:10px;}。container> div:nth-​​child(1){display:none; / *隐藏外部花* /} @媒体(最大宽度:768px){.container {flex-direction:column; } .container div {width:auto; } .container div:nth-​​child(1){display:block; / * show outerFlower* /} .container div:nth-​​child(3)div:nth-​​child(1){display:none; / *隐藏内部的花* /}}

< ; div class =container> < DIV>花与LT; / DIV> < DIV>树< / DIV> < DIV> < DIV>花与LT; / DIV> < DIV>蜂< / DIV> < / div>< / div>

I am trying to keep a seo friendly and semantic structure for my DOM, without repeating whole elements to display them in various positions.

My layout is based on display: flex items. I try to achieve the following:

Important things to know:

  • I do not want to show/hide divs based on the window width (to avoid unnecessary duplicates)
  • None of the divs has a known or fixed height
  • On desktops the divs should be vertical centered, while the right column builds a tag-team (behaves like one single div)
  • The layout needs to support at least IE11+

Is there a css only solution to achieve this?

If not, it would be easy to cut out the green div and paste its content into the pink one using javascript. But I do have concerns about the performance and "flickering" using this, although resizing the browser makes it more complicated. Do I make this needlessly complicated?

Here is fiddle showing a working solution but with javascript:

CODEPEN DEMO

解决方案

In general, you can't do this with Flexbox alone, though there might be a compromise based on each given case.

With Flexbox alone, using fixed height, you can accomplish this

* {
  box-sizing: border-box;
}

body, html {
  margin: 0;
}

.flex {
  width: 90%;
  margin: 5vh auto;
  height: 90vh;
  background: rgba(0, 0, 0, 0.05);  
  display: flex;
  flex-flow: column wrap;
}
.flex div {
  flex: 1;
  width: 50%;
}
.flex div:nth-child(2) {
  order: -1;
}
.flex::before {
  content: '';
  height: 100%;
}

@media (max-width:768px) {
  .flex div {
    width: auto;
  }
  .flex::before {
    display: none;
  }
 .flex div:nth-child(2) {
    order: 0;
  }
}


/*  styling  */
.flex-child {
  color: white;
  font-size: 2em;
  font-weight: bold;
}
.flex-child:nth-child(1) {
  background: #e6007e;
}
.flex-child:nth-child(2) {
  background: #f4997c;
}
.flex-child:nth-child(3) {
  background: #86c06b;
}

<div class="flex">
  <div class="flex-child">
    <div>Top/Right</div>
  </div>
  <div class="flex-child">
    <div>Center/Left</div>
  </div>
  <div class="flex-child">
    <div>Bottom/Right</div>
  </div>
</div>

In this case, where no fixed height is allowed, you can combine Flexbox and float.

By set up it for mobile using Flexbox where you add the center item first in the markup and then, with order, move it between the top and bottom.

With a media query you then simply make the flex container a block element and use float to position the left to the left and the right to the right.

* {
  box-sizing: border-box;
}

body, html {
  margin: 0;
}

.flex {
  max-width: 1024px;
  width: 90%;
  margin: 5vh auto;
  height: 90vh;
  background: rgba(0, 0, 0, 0.05);
  
  display: flex;
  flex-direction: column;
}

.flex-child {
  color: white;
  font-size: 2em;
  font-weight: bold;
  padding: 5%;
  flex-basis: 33.333%;

  display: flex;
  align-items: center;
}

.flex-child:nth-child(1) {
  background: #e6007e;
  order: 1;
}
.flex-child:nth-child(2) {
  background: #f4997c;
}
.flex-child:nth-child(3) {
  background: #86c06b;
  order: 2;
}

@media (min-width: 768px) {
  .flex {
    display: block;
  }
  .flex-child {
    width: 50%;
  }
  .flex-child:nth-child(1) {
    float: left;
    height: 100%;
  }
  .flex-child:nth-child(2),
  .flex-child:nth-child(3) {
    float: right;
    height: 50%;
  }
}

<div class="flex">
  <div class="flex-child">
    <div>Center/Left</div>
  </div>
  <div class="flex-child">
    <div>Top/Right</div>
  </div>
  <div class="flex-child">
    <div>Bottom/Right</div>
  </div>
</div>


Update

Here is another version combining Flexbox with position: absolute, which also vertically center the items in desktop mode

Updated, added a script to control so the absolute positioned element won't get bigger than the right items, and if so, adjust the flex containers height.

Note, the script is by no means optimized, it is only there to show how a fix in certain situations

(function() {

  window.addEventListener("resize", resizeThrottler, false);

  var fp = document.querySelector('.flex');
  var fi = fp.querySelector('.flex-child:nth-child(1)');
  var resizeTimeout;
  function resizeThrottler() {
    // ignore resize events as long as an actualResizeHandler execution is in the queue
    if ( !resizeTimeout ) {
      resizeTimeout = setTimeout(function() {
        resizeTimeout = null;
        actualResizeHandler();
     
       // The actualResizeHandler will execute at a rate of 15fps
       }, 66);
    }
  }

  function actualResizeHandler() {
    // handle the resize event
    if (fp.offsetHeight <= fi.offsetHeight) {
      fp.style.cssText = 'height: '+fi.offsetHeight+'px';
    } else {
      fp.style.cssText = 'height: auto';
    }
  }

  window.addEventListener('load', function() {
    actualResizeHandler();
  })
  
}());

* {
  box-sizing: border-box;
}

body, html {
  margin: 0;
}

.flex {
  position: relative;
  max-width: 1024px;
  width: 90%;
  margin: 5vh auto;
  height: 90vh;
  background: rgba(0, 0, 0, 0.05);
  
  display: flex;
  flex-direction: column;
}

.flex-child {
  color: white;
  font-size: 2em;
  font-weight: bold;
  padding: 5%;
}

.flex-child:nth-child(1) {
  order: 1;
}
.flex-child:nth-child(3) {
  order: 2;
}

.flex-child:nth-child(1) div {
  background: #e6007e;
}
.flex-child:nth-child(2) div {
  background: #f4997c;
}
.flex-child:nth-child(3) div {
  background: #86c06b;
}

@media (min-width: 768px) {
  .flex {
    justify-content: center;
  }
  .flex-child {
    width: 50%;
  }
  .flex-child:nth-child(1) {
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
  }
  .flex-child:nth-child(n+2) {
    margin-left: 50%;
  }
}

<div class="flex">
  <div class="flex-child">
    <div>Center/Left<br>with more<br>content<br>than any<br>of the<br>other items<br>other items<br>other items<br>other items<br>other items</div>
  </div>
  <div class="flex-child">
    <div>Top/Right<br>with more<br>content</div>
  </div>
  <div class="flex-child">
    <div>Bottom/Right<br>with more</div>
  </div>
</div>


With script one can also reorder/move items between elements.


Update 2 (answered at another question but later moved here)

If we talk about smaller items, like a header or smaller menus, one can do what many website platform providers like "squarespace", "weebly", "wordpress", etc does. Their templates holds different markup structures, where an item sometimes exist twice, one visible for desktop, another for mobile.

Also, being so small, there will be less to nothing when it comes to performance (and personally I don't see anymore issue with this than having duplicate CSS rules, one for each screen size, and happily do this instead of introducing script).

Fiddle demo

Stack snippet

.container {
  display: flex;
}
.container > div {
  width: 50%;
}
.container div:nth-child(-n+2) {
  border: dashed;
  padding: 10px;
}
.container > div:nth-child(1) {
  display: none;                                  /*  hide outer "Flower"  */
}

@media (max-width:768px) {
  .container {
    flex-direction: column;
  }
  .container div {
    width: auto;
  }
 .container div:nth-child(1) {
    display: block;                               /*  show outer "Flower"  */
  }
  .container div:nth-child(3) div:nth-child(1) {
    display: none;                                /*  hide inner "Flower"  */
  }
}

<div class="container">
  <div>Flower</div>
  <div>Tree</div>
  <div>
    <div>Flower</div>
    <div>Bee</div>
  </div>
</div>

这篇关于如何使用弹性盒重新排列div?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆