重新旋转元素中属性背后的计算是什么?

时间:2015-03-02 18:04:57

标签: css3 math rotation

我一直在想着接触卡类型的东西。显然六边形是一个很新的趋势,但我想让它更简单,即:旋转方块。考虑到我对HTML和CSS非常了解,实现这一点并不困难。几分钟后,我想出了this

HTML

<a href="#" title="Profile of Banana">
    <span style="background-image: url(http://s5.favim.com/orig/52/portrait-sigma-50mm-f1.4-hsm-canon-eos-5d-mk2-face-Favim.com-473053.jpg);">
        Queen Elizabeth
    </span>
</a>

CSS

a {
    display: inline-block;
    margin: 50px;
    width: 150px;
    height: 150px;
    transform: rotate(45deg);
    position: relative;
    overflow: hidden;
}

/* Pseudo element for border */
a:after {
    content: "";
    display: block;
    width: 142px;
    width: calc(100% - 8px);
    height: 142px;
    height: calc(100% - 8px);
    border: 2px solid white;
    position: relative;
    z-index: 10;
    top: 4px;
    left: 4px;
}

/* Span for bg-image and text */
a > span {
    display: block;
    height: 213px;
    width: 213px;
    top: -31px;
    left: -31px;
    position: absolute;
    background-size: cover;
    background-position: center;
    transform: rotate(-45deg);
    padding: 76px 24px 0;
}

这个想法非常简单:

  • 使链接本身成为块元素,将其旋转45度。别忘了溢出:隐藏
  • 将其子项向后旋转45度,将背景图像应用于此元素(在我的情况下动态加载,因此内联)

这适用于所有主流浏览器,并在其他浏览器(IE8及以下版本中,优雅地降级为简单方块;但您可能需要background size polyfill)。出于这个原因,我想保留这个HTML结构。

那么,问题是什么?首先,我想让它适用于不同的尺寸,我只需要设置链接本身的宽度和高度(a),之后自动计算其子项的高度和宽度 - 在我的项目我可以使用相对较新的CSS3 calc()函数,如果有任何帮助,还有SASS / SCSS的美感。换句话说,我需要宽度a与其子span之间的比率。据我所知,似乎比率是2的平方根:213 / 150 = 1.42。我的第一个问题是,为什么?这背后的逻辑和/或算法是什么?为什么跨度不能简单地占据其父级的100%宽度?为什么需要它是2倍的正方根?

此外,我还想知道顶部和左侧值的来源。我还没想出哪个算术可能是基础。我知道这可能取决于transform-origin的价值,但我不知道具体如何。换句话说,是否可以使用预定义的transform-origin值使topleft为零,并且这样做可以消除对每个案例计算值的需求?如果没有,那么如何根据其父级的宽度值计算这些属性的值,因为这是唯一应该知道的值?

总结,如果只知道a的宽度和高度,我该怎么做:

  • 计算其子项的宽度,如何解释?
  • 计算/使用top上的偏移量(leftspan),如何解释?

我不想为此使用任何JS解决方案。如果不清楚,请发表评论,以便澄清。

1 个答案:

答案 0 :(得分:1)

<强> UPDATED FIDDLE

首先,由于为span定义的背景图像将与实际的a元素重叠,因此需要更大。当我们谈论45度的角度时,这导致三角形截止形状,其中主要正方形(即图像)的尺寸是长边,而另外两个相同尺寸的线是锚。因此,图片的大小(span)应该等于sqrt(2)*100% ~= 141.42%

然后跨度的定位。首先,我们将图像向后旋转45度。导入此操作的是transform-origin设置为0 0而不是50% 50%。通过这样做,元素围绕菱形的顶部中间的单个点旋转。旋转之后,只需要在X轴上翻译元素,这也可以通过CSS变换完成:translateX(-50%)

无论现在将哪个值传递到a的宽度和高度,图像应始终在其中完美对齐,并且尺寸正确。

(在小提琴中,尝试给a一个400px的值。它看起来不错,不是吗?你也可以给图像nice hover effects。)

a {
    display: inline-block;
    width: 200px;
    height: 200px;
    transform: rotate(45deg)  translate(50%);
    position: relative;
    overflow: hidden;
}
a:after {
    content: "";
    display: block;
    width: calc(100% - 8px);
    height: calc(100% - 8px);
    border: 2px solid white;
    position: relative;
    z-index: 10;
    top: 4px;
    left: 4px;
}
a > span {
    display: block;
    height: 141.42%;
    width: 141.42%;
    top: 0;
    left: 0;
    position: absolute;
    background-size: cover;
    background-position: center;
    transform: rotate(-45deg) translateX(-50%);
    transform-origin: 0 0;
}