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

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

问题描述

我试图为我的 DOM 保持 seo 友好和语义结构,而不是重复整个元素以在不同位置显示它们.

我的布局基于 display: flex 项目.我尝试实现以下目标:

重要事项:

  • 我不想根据窗口宽度显示/隐藏 div(以避免不必要的重复)
  • 没有一个 div 具有已知或固定的高度
  • 在台式机上 div 应该垂直居中,而右列构建一个标记团队(表现得像一个 div)
  • 布局至少需要支持IE11+

是否有唯一的 css 解决方案来实现这一目标?

如果没有,可以很容易地使用 javascript 剪下绿色 div 并将其内容粘贴到粉红色的 div 中.但是我确实担心使用它的性能和闪烁",尽管调整浏览器的大小会使它变得更加复杂.我是否让这不必要地复杂化了?

这是显示工作解决方案但使用 javascript 的小提琴:

CODEPEN 演示

解决方案

一般来说,您不能单独使用 Flexbox 做到这一点,尽管可能会根据每个给定的情况做出妥协.

单独使用 Flexbox,使用固定高度,你可以做到这一点

* {box-sizing: 边框框;}正文,HTML {边距:0;}.柔性 {宽度:90%;边距:5vh 自动;高度:90vh;背景:rgba(0, 0, 0, 0.05);显示:弹性;flex-flow:列包装;}.flex div {弹性:1;宽度:50%;}.flex div:nth-child(2) {顺序:-1;}.flex::before {内容: '';高度:100%;}@media(最大宽度:768px){.flex div {宽度:自动;}.flex::before {显示:无;}.flex div:nth-child(2) {订单:0;}}/* 样式 */.flex-子{白颜色;字体大小:2em;字体粗细:粗体;}.flex-child:nth-child(1) {背景:#e6007e;}.flex-child:nth-child(2) {背景:#f4997c;}.flex-child:nth-child(3) {背景:#86c06b;}

<div class="flex-child"><div>上/右</div>

<div class="flex-child"><div>中心/左</div>

<div class="flex-child"><div>底部/右侧</div>

在这种情况下,不允许固定高度,可以结合使用 Flexbox 和 float.

通过使用 Flexbox 为移动设备设置它,您首先在标记中添加 center 项目,然后使用 order,将其移动到 topbottom.

通过媒体查询,您只需将 flex 容器 设为块元素并使用 floatleft 定位到左侧,然后将向右向右.

* {box-sizing: 边框框;}正文,HTML {边距:0;}.柔性 {最大宽度:1024px;宽度:90%;边距:5vh 自动;高度:90vh;背景:rgba(0, 0, 0, 0.05);显示:弹性;弹性方向:列;}.flex-子{白颜色;字体大小:2em;字体粗细:粗体;填充:5%;弹性基础:33.333%;显示:弹性;对齐项目:居中;}.flex-child:nth-child(1) {背景:#e6007e;订单:1;}.flex-child:nth-child(2) {背景:#f4997c;}.flex-child:nth-child(3) {背景:#86c06b;订单:2;}@media(最小宽度:768px){.柔性 {显示:块;}.flex-子{宽度:50%;}.flex-child:nth-child(1) {向左飘浮;高度:100%;}.flex-child:nth-child(2),.flex-child:nth-child(3) {浮动:对;高度:50%;}}

<div class="flex-child"><div>中心/左</div>

<div class="flex-child"><div>上/右</div>

<div class="flex-child"><div>底部/右侧</div>

<小时>

更新

这是另一个结合 Flexbox 和 position: absolute 的版本,它也在 桌面模式

更新,添加了一个脚本来控制绝对定位的元素不会比正确的项目大,如果是这样,调整弹性容器的高度.

请注意,脚本绝不是优化的,它只是为了显示在某些情况下如何修复

(function() {window.addEventListener("resize", resizeThrottler, false);var fp = document.querySelector('.flex');var fi = fp.querySelector('.flex-child:nth-child(1)');变量调整大小超时;函数调整大小节流器(){//只要实际的ResizeHandler 执行在队列中,就忽略调整大小事件如果(!调整大小超时){resizeTimeout = setTimeout(function() {resizeTimeout = null;实际ResizeHandler();//actualResizeHandler 将以 15fps 的速率执行}, 66);}}函数 actualResizeHandler() {//处理调整大小事件如果(fp.offsetHeight <= fi.offsetHeight){fp.style.cssText = '高度:'+fi.offsetHeight+'px';} 别的 {fp.style.cssText = '高度:自动';}}window.addEventListener('load', function() {实际ResizeHandler();})}());

* {box-sizing: 边框框;}正文,HTML {边距:0;}.柔性 {位置:相对;最大宽度:1024px;宽度:90%;边距:5vh 自动;高度:90vh;背景:rgba(0, 0, 0, 0.05);显示:弹性;弹性方向:列;}.flex-子{白颜色;字体大小:2em;字体粗细:粗体;填充:5%;}.flex-child:nth-child(1) {订单:1;}.flex-child:nth-child(3) {订单:2;}.flex-child:nth-child(1) div {背景:#e6007e;}.flex-child:nth-child(2) div {背景:#f4997c;}.flex-child:nth-child(3) div {背景:#86c06b;}@media(最小宽度:768px){.柔性 {对齐内容:居中;}.flex-子{宽度:50%;}.flex-child:nth-child(1) {位置:绝对;顶部:50%;变换:translateY(-50%);}.flex-child:nth-child(n+2) {左边距:50%;}}

<div class="flex-child"><div>中心/左<br>比任何<br>内容<br>比任何<br>其他项目<br>其他项目<br>其他项目<br>其他项目<br>其他项目项目

<div class="flex-child"><div>顶部/右侧<br>更多<br>内容</div>

<div class="flex-child"><div>底部/右侧<br>更多</div>

<小时>

使用脚本还可以在元素之间重新排序/移动项目.

堆栈片段

您也可以将其与媒体查询结合起来,并使用它来对元素进行实际重新排序

$( document ).ready(function() {$(window).resize(function() {如果 ($( window ).width() <600 ) {$(".one").insertBefore("#b");} 别的 {$(".one").insertBefore(".two");}});});

.outer, #flex, #flex2 {显示:弹性;弹性方向:列;}#一个 {订单:4;背景:#ccc;}#b {订单:1;背景:#aaa;}#C {订单:3;背景:#d33;}.一 {订单:2;背景:#aaa;}.二 {订单:5;背景:#aaa;}

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script><div class="外层"><div id="flex"><div id="a">A</div><div id="b">B</div><div id="c">C</div>

<div id="flex2"><div class="one">显示第二个</div><div class="two">给我看第 5 个</div>

<小时>

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

如果我们谈论较小的项目,例如标题或较小的菜单,您可以执行许多网站平台提供商(如squarespace"、weebly"、wordpress"等)所做的事情.他们的模板包含不同的标记结构,其中一个项目有时存在两次,一个在桌面上可见,另一个在移动端可见.

此外,体积如此之小,在性能方面几乎没有任何问题(我个人认为这比重复 CSS 规则没有任何问题,每个屏幕尺寸一个,并且很高兴地这样做而不是介绍脚本).

小提琴演示

堆栈片段

.container {显示:弹性;}.container >div {宽度:50%;}.container div:nth-child(-n+2) {边框:虚线;填充:10px;}.container >div:第n个孩子(1){显示:无;/* 隐藏外部花" */}@media(最大宽度:768px){.容器 {弹性方向:列;}.container div {宽度:自动;}.container div:nth-child(1) {显示:块;/* 显示外部花" */}.container div:nth-child(3) div:nth-child(1) {显示:无;/* 隐藏内部花" */}}

<div>花</div><div>树</div><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:

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.

Stack snippet

You can also combine this with a media query, and use it to do the actual re-order of the elements

$( document ).ready(function() {
  $(window).resize(function() {
    if ($( window ).width() < 600 ) {
      $(".one").insertBefore("#b");
    } else {
      $(".one").insertBefore(".two");
    }
  });
});

.outer, #flex, #flex2 {
  display: flex;
  flex-direction: column;
}
#a {
  order: 4;
  background: #ccc;
}
#b {
  order: 1;
  background: #aaa;
}
#c {
  order: 3;
  background: #d33;
}
.one {
  order: 2;
  background: #aaa;
}
.two {
  order: 5;
  background: #aaa;
}

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<div class="outer">
  <div id="flex">
    <div id="a">A</div>
    <div id="b">B</div>
    <div id="c">C</div>
  </div>

  <div id="flex2">
    <div class="one">Show me 2nd</div>
    <div class="two">Show me 5th</div>
  </div>

</div>


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天全站免登陆