Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a CSS way to position an HTML element vertically following the golden ratio?

Tags:

html

css

web

I want to position an HTML element in the horizontal middle and vertical golden ratio with CSS only. The height of the element must be absolutly flexible, so I can not just set the top-attribute and the element-height to a percentage value. Is there any way to do that?

Schematic representation:

diagram

In the image, arrows of the same color are in golden ratio to each other (38.2% : 61.8%). The dotted line is only imaginary.

like image 898
user1030151 Avatar asked Nov 04 '11 19:11

user1030151


People also ask

How do I make a div float above everything?

Look for the highest and then give a higher z-index to your popup element. This way it will flow even over the other elements with z-index. If you don't have a z-index in any element on your page, you should give like z-index:2; or something higher. Save this answer.

How do I make an element on top in CSS?

Using CSS position property: The position: absolute; property is used to position any element at the absolute position and this property can be used to stack elements on top of each other. Using this, any element can be positioned anywhere regardless of the position of other elements.

Which display mode allows elements to be stacked in the same horizontal line in CSS?

Inline elements display in a line.

How do you position an element on top of another?

You can use the CSS position property in combination with the z-index property to overlay an individual div over another div element. The z-index property determines the stacking order for positioned elements (i.e. elements whose position value is one of absolute , fixed , or relative ).


1 Answers

I believe the math works out to be this (vertical centering only discussed here):

See Fiddle (thanks to Daniel for making that)

CSS

div {
    position: absolute; /* or fixed */
    top: 23.6%; /* height is 100% of viewport * 38.2% (blue)  * 61.8% (red) */
    bottom: 38.2%; /* height is 100% of viewport * 61.8% (blue) * 61.8% (red) */
}

That should get your ratio correct for green. Height is flexible to viewport size.

EDIT: More explanation. Note that the blue arrows start out dividing 100% of the height into 38.2 and 61.8. The red top arrow is going to be 61.8 of the top blue section (38.2), hence 23.6. The red bottom arrow is going to be 61.8 of the bottom blue section (61.8), hence 38.2. Now the double check: 23.6 + 38.2 = 61.8 (that is the TOTAL distance of the two red arrows added together). So their ratio is 23.6/61.8 = 38.2% and 38.2/61.8 = 61.8% (red arrows meet your golden ratio). The green is 100 - 61.8 (the red arrow totals) = 38.2 (the total green area). The top green arrow is 38.2 (top blue) - 23.6 (top red) = 14.6. The bottom green area is 61.8 (bottom blue) - 38.2 (bottom red) = 23.6 (bottom green). Let's check the green ration: 14.6/38.2 = 38.2% and 23.6/38.2 = 61.8% (green arrows meet your golden ratio). Here's a golden ratio addict html/css version of your picture (I know your picture was for illustration purposes, but this was fun):

HTML

<div class="golden"></div>
<div class="dotted"></div>
<div class="blue top arrow"></div>
<div class="blue bottom arrow"></div>
<div class="red top arrow"></div>
<div class="red bottom arrow"></div>
<div class="green top arrow"></div>
<div class="green bottom arrow"></div>

CSS

html {
    background-color: #000;
    width: 100%;
    height: 100%;
}   

body {
    background-color: #fff;
    width: 38.2%;
    height: 100%;
    margin: 0 30.9%;
    position: relative;
}

.golden {
    position: absolute;
    top: 23.6%;
    bottom: 38.2%;
    width: 38.2%;
    background-color: #ddd;
    left: 50%;
    margin-left: -19.1%;
}

.dotted {
    position: absolute;
    top: 38.2%;
    height: 0;
    width: 100%;
    border-top: 1px dotted #444;
}

.blue {
    position: absolute;
    right: 14.6%;
    width: 2px;
    background-color: #00f;
}

.blue.top {
    height: 38.2%;
    top: 0;
}

.blue.bottom {
    height: 61.8%;
    bottom: 0;
}

.red {
    position: absolute;
    right: 38.2%;
    width: 2px;
    background-color: #f00;
}

.red.top {
    height: 23.6%;
    top: 0;
}

.red.bottom {
    height: 38.2%;
    bottom: 0;
}

.green {
    position: absolute;
    right: 50%;
    width: 2px;
    background-color: #83f92c;
    border-color: #83f92c;
}

.green.top {
    height: 14.6%;
    top: 23.6%;
}

.green.bottom {
    height: 23.6%;
    bottom: 38.2%;
}

.arrow:before,
.arrow:after {
    content: '';
    position: absolute;
    display: block;
    left: 0;
    width: 0;
    height: 0;
    margin-left: -6px;
    border-right:  7px solid transparent;
    border-left:   7px solid transparent;
}

.arrow:before {top: 0;}
.arrow:after {bottom: 0;}

.blue:before {border-bottom: 10px solid #00f;}
.red:before  {border-bottom: 10px solid #f00;}
.green:before {border-bottom: 10px solid #83f92c;}

.blue:after {border-top: 10px solid #00f;}
.red:after  {border-top: 10px solid #f00;}
.green:after {border-top: 10px solid #83f92c;}

EDIT 11-10-11: Based on the questioner's comment that my first interpretation above was not correct. I offer the fact that my solution will still work assuming the white area is the content container controlling the height (in case this is useful for anyone). In such a case, do this:

HTML

<div class="content">
    ...place some arbitrary length content here...
    [copy above HTML here]
</div>

CSS--first, remove html and body CSS from above. Then add:

.content {
    position: relative; 
   /* this is the only vital point, you can also style it 
      similar to the body css in the first version above, minus the height */
}
like image 164
ScottS Avatar answered Oct 12 '22 20:10

ScottS