创建一个带有前/后面的卡片鳍状肢,无需绝对定位

时间:2016-10-18 22:51:27

标签: html css css3 css-position css-transforms

我想在我的网站上添加一项新功能,该功能使用David Walsh网站的卡片 - 翻转器架构:https://davidwalsh.name/css-flip。问题是,我卡片中的内容是可变的,因此高度未知(并且它也是一个响应式网站)。我的页面底部有一个页脚需要低于此区域,但由于此方法依赖于绝对定位,因此页脚将位于此顶部的顶部:https://codepen.io/anon/pen/ALJmGZ

任何人都可以想到任何css黑客攻击或改变这种方法会使卡片不必绝对定位吗?

HTML:

<div class="flip-container" ontouchstart="this.classList.toggle('hover');">
  <div class="flipper">
    <div class="front">
      <span class="name">David Walsh</span>
    </div>
    <div class="back">
      <div class="back-logo"></div>
      <div class="back-title">@davidwalshblog</div>
      <p>Mozilla Web Developer, MooTools & jQuery Consultant, MooTools Core Developer, Javascript Fanatic, CSS Tinkerer, PHP Hacker, and web lover.</p>
    </div>
  </div>
  <footer>Here is my footer</footer>
</div>

CSS:

.flip-container {
  -webkit-perspective: 1000;
  -moz-perspective: 1000;
  -o-perspective: 1000;
  perspective: 1000;

    border: 1px solid #ccc;
}

    .flip-container:hover .flipper,  
  .flip-container.hover .flipper {
        -webkit-transform: rotateY(180deg);
        -moz-transform: rotateY(180deg);
    -o-transform: rotateY(180deg);
        transform: rotateY(180deg);
    }

.flip-container, .front, .back {
    width: 320px;
    height: 427px;
}

.flipper {
    -webkit-transition: 0.6s;
    -webkit-transform-style: preserve-3d;

    -moz-transition: 0.6s;
    -moz-transform-style: preserve-3d;

  -o-transition: 0.6s;
    -o-transform-style: preserve-3d;

    transition: 0.6s;
    transform-style: preserve-3d;

    position: relative;
}

.front, .back {
    -webkit-backface-visibility: hidden;
    -moz-backface-visibility: hidden;
  -o-backface-visibility: hidden;
    backface-visibility: hidden;

    position: absolute;
    top: 0;
    left: 0;
}

.front {
    background: url(http://davidwalsh.name/demo/dwflip.jpg) 0 0 no-repeat;
    z-index: 2;
}

.back {
    -webkit-transform: rotateY(180deg);
    -moz-transform: rotateY(180deg);
  -o-transform: rotateY(180deg);
    transform: rotateY(180deg);

    background: #f8f8f8;
}

.front .name {
    font-size: 2em;
    display: inline-block;
    background: rgba(33, 33, 33, 0.9);
    color: #f8f8f8;
    font-family: Courier;
    padding: 5px 10px;
    border-radius: 5px;
    bottom: 60px;
    left: 25%;
    position: absolute;
    text-shadow: 0.1em 0.1em 0.05em #333;

    -webkit-transform: rotate(-20deg);
    -moz-transform: rotate(-20deg);
  -o-transform: rotate(-20deg);
    transform: rotate(-20deg);
}

.back-logo {
    position: absolute;
    top: 40px;
    left: 90px;
    width: 160px;
    height: 117px;
    background: url(http://davidwalsh.name/demo/logo.png) 0 0 no-repeat;
}

.back-title {
    font-weight: bold;
    color: #00304a;
    position: absolute;
    top: 180px;
    left: 0;
    right: 0;
    text-align: center;
    text-shadow: 0.1em 0.1em 0.05em #acd7e5;
    font-family: Courier;
    font-size: 2em;
}

.back p {
    position: absolute;
    bottom: 40px;
    left: 0;
    right: 0;
    text-align: center;
    padding: 0 20px;
  font-family: arial;
  line-height: 2em;
}

footer {
  background:red;
}

5 个答案:

答案 0 :(得分:2)

我不认为在不使用绝对定位的情况下可以产生类似的效果。

这样做的最好方法是让JS抓住高峰。

这是一个基础知识的CodePen:https://codepen.io/CourtDemone/pen/vXVbGQ

基本上只需将页脚移出翻盖容器并添加一些这样的JS。

var heightFront, heightBack;

heightFront = $('.front').height();
heightBack = $('.back').height();

if(heightFront > heightBack){
  $('.flip-container').height(heightFront);
}else{
  $('.flip-container').height(heightBack);
}

答案 1 :(得分:2)

我找到了一种方法来使用纯css完成此操作,并且没有绝对位置。我使用css动画而不是过渡,你可以在50%关键帧处将元素的高度/宽度设置为0。看看小提琴:https://codepen.io/anon/pen/bwmkAo

萨斯:

@keyframes no-show {
    0% {
        transform: rotateY(0deg);
    height: auto;
    width: 100%;
    }

    49% {
        height: auto;
        width: 100%;
    }

    50% {
        height: 0;
        width: 0;
    }

    100% {
        transform: rotateY(180deg);
        height: 0;
        width: 0;
    }
}

@keyframes show {
    0% {
        transform: rotateY(-180deg);
        height: 0;
        width: 0;
    }

    49% {
        height: 0;
        width: 0;
    }

    50% {
        height: auto;
        width: 100%;
    }

    100% {
        transform: rotateY(0deg);
        height: auto;
        width: 100%;
    }
}

.flip-container {
    border: 1px solid #ccc;
}

.flip-container, .front, .back {
    width: 320px;
}

.flipper {
    position: relative;
}

.front, .back {
  position: relative;
    perspective: 1000px;

    transform-style: preserve-3d;
    perspective-origin: top center;
    animation-duration: 2s;
    animation-timing-function: linear;
    transition-property: transform;
    animation-fill-mode: forwards;
    -webkit-animation-fill-mode: forwards;
    overflow: hidden;
}

.front {
    z-index: 2;

    transform: rotateY(0deg);
    animation-name: show;
    .flipper.active & {
        animation-name: no-show;
    }

  .inner {
    height: 300px;
    background: green;
  }
}

.back {
    transform: rotateY(-180deg);
    animation-name: no-show;

    .flipper.active & {
        animation-name: show;
    }

  .inner {
    height: 400px;
    background: blue;
  }
}

footer {
    background: red;
}

答案 2 :(得分:0)

您可以强制使用.front.back的容器获取其父级的高度。(height:inherit;
JSfiddle:https://jsfiddle.net/9q7xr4ef/

段:

.flip-container {
  -webkit-perspective: 1000;
  -moz-perspective: 1000;
  -o-perspective: 1000;
  perspective: 1000;
  border: 1px solid #ccc;
}
.flip-container:hover .flipper,
.flip-container.hover .flipper {
  -webkit-transform: rotateY(180deg);
  -moz-transform: rotateY(180deg);
  -o-transform: rotateY(180deg);
  transform: rotateY(180deg);
}
.flip-container,
.front,
.back {
  width: 320px;
  height: 427px;
}
.flipper {
  -webkit-transition: 0.6s;
  -webkit-transform-style: preserve-3d;
  -moz-transition: 0.6s;
  -moz-transform-style: preserve-3d;
  -o-transition: 0.6s;
  -o-transform-style: preserve-3d;
  transition: 0.6s;
  transform-style: preserve-3d;
  position: relative;
  height: inherit;
}
.front,
.back {
  -webkit-backface-visibility: hidden;
  -moz-backface-visibility: hidden;
  -o-backface-visibility: hidden;
  backface-visibility: hidden;
  position: absolute;
  top: 0;
  left: 0;
}
.front {
  background: url(http://davidwalsh.name/demo/dwflip.jpg) 0 0 no-repeat;
  z-index: 2;
}
.back {
  -webkit-transform: rotateY(180deg);
  -moz-transform: rotateY(180deg);
  -o-transform: rotateY(180deg);
  transform: rotateY(180deg);
  background: #f8f8f8;
}
.front .name {
  font-size: 2em;
  display: inline-block;
  background: rgba(33, 33, 33, 0.9);
  color: #f8f8f8;
  font-family: Courier;
  padding: 5px 10px;
  border-radius: 5px;
  bottom: 60px;
  left: 25%;
  position: absolute;
  text-shadow: 0.1em 0.1em 0.05em #333;
  -webkit-transform: rotate(-20deg);
  -moz-transform: rotate(-20deg);
  -o-transform: rotate(-20deg);
  transform: rotate(-20deg);
}
.back-logo {
  position: absolute;
  top: 40px;
  left: 90px;
  width: 160px;
  height: 117px;
  background: url(http://davidwalsh.name/demo/logo.png) 0 0 no-repeat;
}
.back-title {
  font-weight: bold;
  color: #00304a;
  position: absolute;
  top: 180px;
  left: 0;
  right: 0;
  text-align: center;
  text-shadow: 0.1em 0.1em 0.05em #acd7e5;
  font-family: Courier;
  font-size: 2em;
}
.back p {
  position: absolute;
  bottom: 40px;
  left: 0;
  right: 0;
  text-align: center;
  padding: 0 20px;
  font-family: arial;
  line-height: 2em;
}
footer {
  background: red;
}
<div class="flip-container" ontouchstart="this.classList.toggle('hover');">
  <div class="flipper">
    <div class="front">
      <span class="name">David Walsh</span>
    </div>
    <div class="back">
      <div class="back-logo"></div>
      <div class="back-title">@davidwalshblog</div>
      <p>Mozilla Web Developer, MooTools & jQuery Consultant, MooTools Core Developer, Javascript Fanatic, CSS Tinkerer, PHP Hacker, and web lover.</p>
    </div>
  </div>
  <footer>Here is my footer</footer>
</div>

#2,一个孩子是亲戚:
JSfiddle:https://jsfiddle.net/9q7xr4ef/2/

答案 3 :(得分:0)

我今天在玩这个游戏,只是因为我的解决方案带有一点小小的警告而绊脚石。

.flip-container {
  perspective: 1000;
}
.flipper {
  transform-style: preserve-3d;
  display: flex;
  align-items: stretch;
  width: 100%;
  transition: transform 0.6s;
  will-change: transform;
}
.flip-container:hover .flipper {
  transform: rotateY(180deg);
}
.front, .back {
  width: 100%;
  flex: 0 0 auto;
  backface-visibility: hidden;
}
.back {
  transform: rotateY(180deg);
  margin-left: -100%;
}

之所以可行,是因为行中的弹性项目可以占据最高行项目的高度。根据需要设置.front.back的样式,只是不要设置其高度。

需要注意的是,如果在渲染后另一侧变长,则较短的一侧似乎会超出其渲染高度(例如,因为已加载图像)。如果高度是由于调整窗口大小而改变的,那很好,但似乎如果内容突然加载则不会。当然,您可能不会遇到这种情况,但是我不得不为图像提供一个具有一定高度的容器。如果您不需要纯CSS解决方案,也可以在显示整个翻页卡之前等待图像加载,但这有点离题,因为您似乎并没有使用{{1 }}。

答案 4 :(得分:0)

我还遵循了David Walsh的博客示例,并且需要在flex上下文中执行此操作,因此,我发现翻转面板的绝对定位无法正常工作。

我用

解决了这个问题
  • .flipper类中的相对位置
  • 还为.flipper类的块固定了高度,但是为了使用不同的高度模式,我们分别将其设置为高度:15em
  • top:前块为0
  • top:对后挡负片

我必须调整值,以便在元素之间留出一定的空白。 我使用onclick事件而不是将鼠标悬停在UX上。但是两者都可以。

<!-- HTML -->
<p>three boxes on a flex basis with a onclick flipper effect</p>
<div class='flexinl'>
    <div class='flip-container fronted hand' 
      onclick="this.swapClasses('fronted,backed');">
        <div class="flipper fli300">
            <div class='front c1'>
                <h1>This is front 1</h1>
            </div>
            <div class='back c2'>
                <h1>This is back 1</h1>
            </div>
        </div>
    </div>
    <div class='flip-container fronted hand' 
      onclick="this.swapClasses('fronted,backed');">
        <div class="flipper fli300">
            <div class='front c1'>
                <h1>This is front 2</h1>
            </div>
            <div class='back c2'>
                <h1>This is back 2</h1>
            </div>
        </div>
    </div>
    <div class='flip-container fronted hand' 
      onclick="this.swapClasses('fronted,backed');">
        <div class="flipper fli300">
            <div class='front c1'>
                <h1>This is front 3</h1>
            </div>
            <div class='back c2'>
                <h1>This is back 3</h1>
            </div>
        </div>
    </div>
</div>  

/* CSS */
.c1 {color:white; background-color:green}
.c2 {color:white; background-color:orange}
.hand { cursor: pointer; }

/* based on David Walsh Flipper */
.flip-container {
    perspective: 1000px;
    border: 1px dashed #a9a9a9;
    margin-bottom:1.5em;    
}
  /* flip the pane when has the backed */
.flip-container.backed .flipper {
    transform: rotateY(180deg);
}
.fli300 {height: 15em;}
.fli300 .front {
    height: 12em !important;
}
.fli300 .back {
    height: 12em !important;
    top: -15em;
}

/* flip speed goes here */
.flipper {
    transition: .4s;
    transform-style: preserve-3d;
    position: relative;    
}

/* hide back of pane during swap */
.flipper .front, .flipper .back {
    backface-visibility: hidden;
    position: relative;
    left: 0;
    height: 100%;
    padding: 1.5em;    
}

/* front pane, placed above back */
.flipper .front {
    z-index: -1;
    top: 0;
    /* for firefox 31 */
    transform: rotateY(0deg);
}

/* back, initially hidden pane */
.flipper .back {
    transform: rotateY(180deg);
}

/* some flex stuff */
.flexinl {  
    display: inline-flex; 
    flex-wrap: wrap;  
    justify-content: flex-start;
}
.flexinl > div {padding:0.2em}

/* some javascript for swapping two classes */

HTMLElement.prototype.swapClasses = function (dosclasses) {
    var clases = dosclasses.split(/\s*\,\s*/);
    var entra = clases[0];
    var sale = clases[1];
    if (this.classList.contains(sale)) {
        this.classList.remove(sale);
        this.classList.add(entra);
    } else {
        this.classList.remove(entra);
        this.classList.add(sale);
    }
    return this;
};

您可以在此codepen

中找到它