两个旋转div的父级,用于获取生成的转换div

时间:2017-10-12 17:30:45

标签: html css css3 flexbox css-transitions

似乎有很多关于同一问题的问题,但似乎找不到满意的答案......我有:

1 container (flex) (green)
   2 columns (block) -> left: red, right: orange
      in the left column, I have two divs (green) who follow each other 'menu1''menu2'

这两个菜单本身都包含在div(黑色)中,因此当我旋转它时,两个菜单是垂直的而不是水平的(旋转90度)

目标是让顶部包装器/容器(绿色)占据垂直黑色包装的高度,并使左列包装器不大于旋转的黑色包装器的“宽度”。

以下示例说明了我得到的内容:

https://jsfiddle.net/pg373473/

<div id='container' style='display: flex; border: 3px solid green; flex-direction=row'>
  <div id='leftbox' style='position: relative; display: block; border: 3px solid red'>
    <div id='textwrapper' style='transform-origin: bottom left; transform: translateY(-100%) rotate(90deg); border: 2px solid black;'>
      <div style='border: 3px solid green; display: inline-block'>menu 1</div>
      <div style='border: 3px solid green; display: inline-block'>menu 2</div>
    </div>
  </div>
  <div id='rightbox' style='position: relative; display: flex; flex: 1 1 auto; border: 3px solid orange';>
    xx
  </div>
</div>

enter image description here

这有可能吗?

默认情况下,旋转似乎应用 后计算所有div的所有宽度/高度。我个人认为这种行为与任何人的期望相反,但也许有人非常了解这些规格可以解释为什么会如此?但最后,我更感兴趣的是知道我试图实现的目标是否存在解决方案(thx)。

修改

Rotate elements in CSS that affect their parents...正在询问有关旋转的问题,但解释并不令人满意,问题略有不同,因为它只是确保旋转的孩子的div考虑到旋转的孩子的高度。本文中提出的问题有3个限制因素:

  • 你有2个div,它们被旋转了90度(或者超过2个)
  • 包装容器需要承担:
    • 宽度
    • 和儿童旋转元素的高度

上述问题只是询问高度,并没有解决宽度问题。另外,jsfiddle也不起作用。

关于这个问题的唯一好处是writing-mode的评论中提到的但是我还没有成功地使用它。我尝试了这个选项,虽然我可以解决高度问题,但我无法解决宽度问题......

<div id='container' style='display: flex; border: 3px solid green; flex-direction: row'>
  <div style='display: flex; flex-direction: column; border: 3px solid red; flex: 1 1 auto;'>
    <div style='flex: 0 0 auto; display: inline-block; flex-direction: row; writing-mode: vertical-rl; border: 3px solid black;'>
      <div style='flex: 0 0 auto; border: 1px solid green; display: inline-block'>menu 1</div>
      <div style='flex: 0 0 auto; border: 1px solid green; display: inline-block'>menu 2</div>
    </div>
  </div>
  <div id='rightbox' style='display: flex; flex: 1 1 auto; border: 3px solid orange';>
    Right Box
  </div>
</div>

enter image description here

https://jsfiddle.net/dyae4xru/

为了清楚起见,这就是我想要的:

enter image description here

ANSWER / EDIT 2

此时此问题无法解决。 CSS / HTML /浏览器不支持开箱即用。我通过编写一个小的JS函数来解决问题,该函数在水平时给出了div的确切宽度和高度,并使用这些值设置旋转90度后div的宽度(使用writing-mode: vertical-rl)。

5 个答案:

答案 0 :(得分:4)

可能有 hacky 解决方案,但我认为CSS转换不是为此类内容构建的。

  

如果属性的值不是none,则为堆叠上下文   将被创建。在这种情况下,对象将充当包含   block for position:它包含的固定元素。

     

来源:MDN

(有关缩放转换问题,请参阅this post。)

CSS写作模式

我建议您使用较新的CSS writing mode - 请参阅here获取浏览器支持:

  

写入模式CSS属性定义是否放置文本行   水平或垂直方向以及方块的方向   进展。

在div上使用writing-mode: vertical-lr - 请参阅下面适用于Chrome的演示:

#container {
  display: flex;
  border: 1px solid green;
  flex-direction: row;
}

#container>div:first-child {
  position: relative;
  display: block;
  border: 1px solid red;
  writing-mode: vertical-lr; /* ADDED */
  -webkit-writing-mode: vertical-lr;
}

#container>div>div {
  /*transform-origin: bottom left;
  transform: translateY(-100%) rotate(90deg);*/
  border: 2px solid black;
}

#container>div>div>div {
  border: 1px solid green;
  display: inline-block;
}

#rightbox {
  position: relative;
  display: flex;
  flex: 1 1 auto;
  border: 1px solid orange;
}
<div id='container'>
  <div>
    <div>
      <div>menu 1</div>
      <div>menu 2</div>
    </div>
  </div>
  <div id='rightbox'>
    xx
  </div>
</div>

Firefox中的问题

请注意,这在Firefox中不起作用,因为 flex items 在垂直书写模式下表现不佳 - 存在未解决的问题:

上面关于flexboxes中垂直模式的问题在Firefox 60中得到了修复,现在你可以看到上面的演示在Chrome和& Firefox浏览器。

答案 1 :(得分:3)

我怀疑没有JavaScript可以解决这个任务,因为转换的元素是在不同的“层”上绘制的,它们的视觉外观不会影响DOM属性。但是,由于您的转换已修复 - 您可以计算元素的结果可视大小并相应地更新父元素的大小。此外,如果容器的内容将在运行时更改,则可以使用mutation observers更新容器的大小。此示例显示正确的容器大小,并对菜单项的运行时突变做出反应。测试到Firefox和Chrome

    document.addEventListener('DOMContentLoaded', function () {
        const container = document.querySelector('#container .menu-container');
        const menu = document.querySelector('#container .menu-items');
        let items = [];

        const updateItems = () => {
            const nodes = document.querySelectorAll('#container .menu-item');
            for (let node of nodes) {
                if (items.indexOf(node) === -1) {
                    items.push(node);
                    new MutationObserver(updateSize).observe(node, {attributes: true, characterData: true, subtree: true});
                }
            }
            updateSize();
        }

        const updateSize = () => {
            container.style.width = menu.offsetHeight + 'px';
            container.style.height = menu.offsetWidth + 'px';
        }

        new MutationObserver(updateSize).observe(menu, {attributes: true, characterData: true});
        new MutationObserver(updateItems).observe(menu, {childList: true});
        updateItems();
        updateSize();
    });
#container {
    display: flex;
    border: 1px solid green;
    flex-direction: row;
}

.menu-container {
    position: relative;
    display: block;
    border: 1px solid red;
}

.menu-items {
    transform-origin: bottom left;
    transform: translateY(-100%) rotate(90deg);
    border: 2px solid black;
    display: flex;
    position: absolute;
}

.menu-item {
    border: 1px solid green;
    display: inline-block;
    white-space: nowrap;
}

#rightbox {
    position: relative;
    display: flex;
    flex: 1 1 auto;
    border: 1px solid orange;
}
<div id="container">
    <div class="menu-container">
        <div class="menu-items">
            <div class="menu-item">menu 1</div>
            <div class="menu-item">menu 2</div>
        </div>
    </div>
    <div id="rightbox">
        xx
    </div>
</div>

答案 2 :(得分:1)

以下是解决方案的方法:

我在容器和LEFT BOX上使用flex,然后用户书写模式从左到右垂直,最后是flex方向列,以便它们堆叠。

&#13;
&#13;
*,
*:before,
*:after {
  /* So 100% means 100% */
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

.container {
  display: flex;
  border: 2px solid tomato;
}

.box-left {
  flex: 0 2.5%; // change % value for the size you want it!
}

.box-right {
  flex: 1 auto;
  border: 2px solid green;
}

.box-left ul {
  display: flex;
  flex-direction: column;
  border: 2px solid blue;
}

.box-left ul li {
  list-style: none;
  writing-mode: vertical-lr;
  margin-bottom: 0.5em;
}
&#13;
<div class="container">
  <div class="box-left">
    <ul>
      <li>menu01</li>
      <li>menu02</li>
    </ul>
  </div>
  <div class="box-right">
    box right
  </div>
</div>
&#13;
&#13;
&#13;

答案 3 :(得分:1)

我修改了您的代码,下面是CSS和HTML代码段enter image description here

*,
*:before,
*:after {box-sizing: border-box;margin: 0;padding: 0;}

.container {display: flex;border: 2px solid green;}

.left-box {flex: 0 2.5%;}

.right-box {flex: 1 auto;border: 2px solid orange;}

.left-box {flex: 0 5.5%;border: 2px solid red;}

.menu {border: 1.5px solid green;}

.inner-left-box ul {display: flex;flex-direction: column;border: 2px solid black;}

.inner-left-box ul li {list-style: none;writing-mode: vertical-lr;}
<div class="container">
  <div class="left-box">
   <div class="inner-left-box">
    <ul>
      <li class="menu">menu 1</li>
      <li class="menu">menu 2</li>
    </ul>
    </div> 
  </div>
  <div class="right-box">Right Box</div>
</div>

答案 4 :(得分:1)

答案在问题的writing-mode解决方案的实际编辑答案中。唯一的问题是红色边框div上的flex: 1 1 auto样式,删除它解决了宽度问题。

HTML w / Style Tag Variant

&#13;
&#13;
<div id='container' style='display: flex; border: 3px solid green; flex-direction: row'>
    <div style='display: flex; flex-direction: column; border: 3px solid red;'>
        <div style='flex: 0 0 auto; display: inline-block; flex-direction: row; writing-mode: vertical-rl; border: 3px solid black;'>
            <div style='flex: 0 0 auto; border: 1px solid green; display: inline-block'>
                menu 1
            </div>
            <div style='flex: 0 0 auto; border: 1px solid green; display: inline-block'>
                menu 2
            </div>
        </div>
    </div>
    <div id='rightbox' style='display: flex; flex: 1 1 auto; border: 3px solid orange';>
        Right Box
    </div>
</div>
&#13;
&#13;
&#13;

CSS Classes Variant

&#13;
&#13;
#container
{
  display: flex;
  flex-direction: row;
  border: 3px solid green;
}

#leftbox
{
  display: flex;
  flex-direction: column;
  border: 3px solid red;
}

#inner-leftbox
{
  display: inline-block;
  flex-direction: row;
  flex: 0 0 auto;
  writing-mode: vertical-rl;
  border: 3px solid black;
}

#rightbox
{
  display: flex;
  flex: 1 1 auto;
  border: 3px solid orange;
}

.menu
{
  display: inline-block;
  flex: 0 0 auto;
  border: 1px solid green;
}
&#13;
<div id="container">
    <div id="leftbox">
        <div id="inner-leftbox">
            <div class="menu">menu 1</div>
            <div class="menu">menu 2</div>
        </div>
    </div>
    <div id="rightbox">
        Right Box
    </div>
</div>
&#13;
&#13;
&#13;