将 div 置于黄金比例:替代绝对位置?

Place div in golden ratio: Alternative to absolute position?

我已经构建了一个页面,如下面的示例所示。您也可以在 codepen.

上试用它

我们的想法是,将深灰色的英雄框放在视口的底部。到目前为止很容易。 但是如果屏幕高度太小(例如对于小型笔记本电脑),那么文本将填满视口的大部分(甚至全部),背景图像就很难实现。在这种情况下,hero box 应该放置在黄金比例而不是视口底部。

我也已经在示例中构建了该解决方案。只需降低浏览器的高度 window.

我总觉得自己做错了什么。目前我将英雄、内容和页脚放在绝对定位的 div 中。只要#content div 中只有静态内容,它就可以正常工作。但是,如果有手风琴或其他 collapsing/dynamic 东西,则必须重新计算页脚的位置。

我可以在重新调用比率函数时轻松做到这一点。但与此同时,整个解决方案对我来说确实看起来不对或者太复杂了。

难道没有另一种更简单的解决方案可以将内容 div 放置在 hero 容器之后的 RELATIVE 位置吗?

// call function after everything has been loaded
$(window).load(function() { 
    checkRatio();
});

window.dispatchEvent(new Event('resize'));

$(window).resize(function() {
    checkRatio();
});


function checkRatio() {   

    var ratio = 0;
    var contentTopPos = 0;
    var footerTopPos = 0;

    var windowHeight = $(window).height();
    var headerHeight = $("#hero").height();
    var contentHeight = $("#content").height();

    ratio = (windowHeight / headerHeight);
    contentTopPos = (windowHeight / 1.618);


    if(ratio < 1.618) {
        // Window too small or Content too long
        $("#hero").css('bottom', 'initial');            
        $("#hero").css('top', contentTopPos);            
    } else {
        // Default Position: bottom 0
        $("#hero").css('top', 'initial');
        $("#hero").css('bottom', 0);        
    }


    var sumHeight  = $("#hero").offset().top + $("#hero").height();
    $("#content").css('top', sumHeight + "px");   

    footerTopPos = (sumHeight + contentHeight);
    $("#footer").css('top', footerTopPos + "px");
}
body {
     padding: 0;
     margin: 0;
     font-family:Verdana, Geneva, Tahoma, sans-serif;
}
#header_img { 
     position: fixed;
     top: 0;
     height: 100vh;
     width: 100%;
     background-size: cover;
     z-index: 1;
 }

 #hero_container {
     position: relative;
     height: 100vh;
     width: 100%;
 }
 #hero {
     position: absolute;
     margin: 0 5%;
     bottom: 0;
     width: 90%;
     height: auto;
     background-color: #333;
     box-shadow: 0 -2px 6px rgba(0, 0, 0, 0.46);
     z-index: 2;
 }

 #hero_text {
     padding: 20px;
     color: #fff;
 }

 #content {
     position: absolute;
     width: 100%;
     background-color: transparent;
     z-index: 3;
 }

 section {
     background-color: #dedede;
     padding: 20px;
     border-bottom: solid 1px #333;
 }

 #footer {
     position: absolute;      
     width: 100%;      
     z-index: 3;
     background-color: #999;
     color: #555;
 }
 #footer_text {
     padding: 10px 20px;
 }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
<div id="header_img" style="background: #ffffff url('https://cdn4.vectorstock.com/i/1000x1000/80/28/free-sample-rubber-stamp-vector-13448028.jpg') no-repeat center top; background-size: cover;"></div>


<div id="hero_container">
    <div id="hero">
        <div id="hero_text">
            <h1>Lorem ipsum dolor sit</h1>
            <h4>Cras felis leo, pellentesque non dui ut, molestie mollis lorem.</h4>
            <p>Fusce venenatis metus id est venenatis ornare. Aliquam id ante et nulla rutrum malesuada vel sit amet felis. Maecenas maximus, quam vitae cursus ultrices, est augue consequat magna, vitae bibendum ex urna eget lacus. Donec quis sagittis diam.</p>
        </div>
    </div>
</div>


<div id="content">
    <section>
        <h2>Vivamus molestie</h2>
        <p>Sem sit amet posuere elementum, ligula dolor laoreet eros, sed ultrices mi lacus quis est. Sed ut venenatis metus, id consectetur mauris.</p>
    </section>

    <section>
        <h2>Mauris sollicitudin ante est</h2>
        <p>Ut ultrices neque volutpat quis. Aenean bibendum dui sed pulvinar vestibulum. Vestibulum finibus ornare dui at lobortis.</p>
    </section>

    <section>
        <h2>Sed consequat euismod sem</h2>
        <p>In venenatis lacus luctus in. Nam elementum dolor a magna eleifend consectetur. Curabitur efficitur magna erat, et eleifend enim placerat sit amet. Fusce cursus, sem vel porta tempor, diam dolor auctor lorem, eu venenatis velit lorem ac lectus.</p>
    </section>
</div>


<div id="footer">
    <div id="footer_text">&copy; 2020 SchweizerSchoggi</div>        
</div>

.hero-container {
    height: 100vh;
    display: flex;
    
}
.hero-content {
    width: 100%;
    background: grey;
    align-self: flex-end;
}

@media only screen and (max-height: 300px) {
  .hero-container{
    padding-top: 25vh;
  }
  .hero-content{
    align-self: flex-start;
  }
}
<div class="hero-container">
    <div class="hero-content">
         <h1>Lorem ipsum dolor sit</h1>
            <h4>Cras felis leo, pellentesque non dui ut, molestie mollis lorem.</h4>
            <p>Fusce venenatis metus id est venenatis ornare. Aliquam id ante et nulla rutrum malesuada vel sit amet felis. Maecenas maximus, quam vitae cursus ultrices, est augue consequat magna, vitae bibendum ex urna eget lacus. Donec quis sagittis diam.</p>
        
    </div>
</div>

<div id="content">
    <section>
        <h2>Vivamus molestie</h2>
        <p>Sem sit amet posuere elementum, ligula dolor laoreet eros, sed ultrices mi lacus quis est. Sed ut venenatis metus, id consectetur mauris.</p>
    </section>

    <section>
        <h2>Mauris sollicitudin ante est</h2>
        <p>Ut ultrices neque volutpat quis. Aenean bibendum dui sed pulvinar vestibulum. Vestibulum finibus ornare dui at lobortis.</p>
    </section>

    <section>
        <h2>Sed consequat euismod sem</h2>
        <p>In venenatis lacus luctus in. Nam elementum dolor a magna eleifend consectetur. Curabitur efficitur magna erat, et eleifend enim placerat sit amet. Fusce cursus, sem vel porta tempor, diam dolor auctor lorem, eu venenatis velit lorem ac lectus.</p>
    </section>
    
</div>

<div id="footer">
    <div id="footer_text">&copy; 2020 SchweizerSchoggi</div>        
</div>