为什么使用高度的保证金最高百分比,我该如何解决它?

时间:2016-10-21 10:53:44

标签: html css css3 margin reflow

我有一个CSS下拉菜单,可以显示的元素数量不同。

我使用overflow: hidden包装和margin-top: -100%来隐藏菜单,并使用margin-top: 0进行CSS转换,以便向下滑动动画。

问题似乎是margin-top: -100%似乎正在拾取任何父元素的显式width并忽略内容高度。



.outer {
  overflow: hidden;
  border: 10px solid red;
  cursor: pointer;
}
.outer > .slide {
  margin-top: -100%;
  transition-property: margin-top;
  transition-duration: 1s;
}
.outer:hover > .slide {
  margin-top: 0;
}
.outer.bug {
  width: 100px;
}

<div class="outer">
  <div class="slide">
    <ul>
      <li>
        Ayy
      </li>
      <li>
        Bee
      </li>
      <li>
        See
      </li>
      <li>
        Dee
      </li>
      <li>
        Eee
      </li>
      <li>
        Eff
      </li>
      <li>
        Gee
      </li>
    </ul>
  </div>
</div>

<div class="outer bug">
  <div class="slide">
    <ul>
      <li>
        Ayy
      </li>
      <li>
        Bee
      </li>
      <li>
        See
      </li>
      <li>
        Dee
      </li>
      <li>
        Eee
      </li>
      <li>
        Eff
      </li>
      <li>
        Gee
      </li>
    </ul>
  </div>
</div>
&#13;
&#13;
&#13;

运行该代码段,您应该会看到两个红色框,鼠标悬停在任一个上方以获得下拉菜单。

问题是第二个框 - 唯一的区别是父设置了width: 100px;

如果您检查第二个框,您应该看到margin-top: -100%;已计算为-100px。

事实上,任何针对父div的显式或继承宽度都将成为负边距。

我发现它的唯一方法是明确地将margin-top设置为与滑动菜单的高度相同,但这涉及DOM布局和JS,我不会这样做真的想为每个菜单做。

这是浏览器如何处理margin-top负百分比的错误吗? IE11,Chrome和FX似乎都以同样的方式对待它。

有没有更好的解决方法,不需要明确的高度计算和额外的Javascript?

2 个答案:

答案 0 :(得分:1)

要移动与其自身尺寸相关的元素(无论其高度如何),您可以使用transform:translate()代替边距。

因此,要求将元素向上移动其高度需要在Y轴上进行-100%的平移。像这样:

* {
  margin: 0;
  padding: 0;
}
.outer {
  /* overflow: hidden; */
  padding: 10px;
  background: red;
  cursor: pointer;
  position: relative;
}
.outer > .slide {
  position: absolute;
  top: 0;
  left: 0;
  transform: translateY(-100%);
  transition-property: transform;
  transition-duration: 1s;
}
.outer:hover > .slide {
  transform: translateY(0%);
}
<div class="outer">
  <div class="slide">
    <ul>
      <li>Ayy</li>
      <li>Bee</li>
      <li>See</li>
      <li>Dee</li>
      <li>Eee</li>
    </ul>
  </div>
</div>

然后我们可以使用绝对定位从文档流中删除子项。

答案 1 :(得分:1)

margin-top:-100%仅在删除20px已分配.outer的边界时才有效,10px + 10px使用两次ul。所以我们可以在这里使用CSS calc()函数来获取输出。

padding-top:40px有一个默认40px + 40px,所以这也是0px两次使用,我们必须将其设置为margin-top:-100%;

因此,ul和border是ul{ display: block; list-style-type: disc; margin-before: 1em; margin-after: 1em; margin-start: 0; margin-end: 0; padding-start: 40px; }

不工作的原因

默认ul属性:

.outer {
  overflow: hidden;
  border: 10px solid red;
  cursor: pointer;
  width:auto;
  height:auto;
}
.outer > .slide {
  margin-top: calc(-26px + (-100%));
  transition-property: margin-top;
  transition-duration: 1s;
  background:#ccc;
}
.outer > .slide > ul{
  padding:0;
  margin:0;
}
.outer:hover > .slide {
  margin-top: 0;
}
.outer.bug {
  width: 100px;
}

&#13;
&#13;
<div class="outer">
  <div class="slide">
    <ul>
      <li>Ayy</li>
      <li>Bee</li>
      <li>See</li>
      <li>Dee</li>
      <li>Eee</li>
      <li>Eff</li>
      <li>Gee</li>
    </ul>
  </div>
</div>

<div class="outer bug">
  <div class="slide">
    <ul>
      <li>Ayy</li>
      <li>Bee</li>
      <li>See</li>
      <li>Dee</li>
      <li>Eee</li>
      <li>Eff</li>
      <li>Gee</li>
    </ul>
  </div>
</div>
&#13;
<?php
$date = '38-10-2016';
$date = explode('-',$date);

echo date("Y-m-d", strtotime( "$date[2]W$date[0]".'monday this week' ) ), "\n";   

echo date("Y-m-d", strtotime( "$date[2]W$date[0]".'sunday this week' ) ), "\n";
&#13;
&#13;
&#13;