Place (fixed) dropdown menus with javascript to avoid z-index inheritance issues - javascript

I am working on a project that includes pages to view and select actions on multiple different entities of the same category set. Those entities are presented in the form of cards (e.g. employees, projects etc). On each card there is a classic gear button that expands a hidden drop menu so that the user can select actions (which might be the same or different for each entity/card). In order to avoid z-index inheritance issues (e.g. drop menu appearing on top of the parent but behind the sibling card) I implemented the solution presented in the link below (minimal representation).
The solution seems to be working fine, but i am wondering if it is elegant / acceptable in the context of implementing it on a production environment. If someone could comment on it or propose other solutions if this is not "acceptable" that would be great.
function getFixedElementPosition(el, menuid) {
var dropmenu = document.getElementById(`dropmenu${menuid}`);
if (dropmenu.style.display === "" || dropmenu.style.display === "none") {
var pos = el.getBoundingClientRect();
dropmenu.style.top = `${pos.bottom}px`;
dropmenu.style.left = `${pos.right}px`;
dropmenu.style.display = "block";
} else {
dropmenu.style.display = "none";
}
};
.card {
width: 225px;
height: 295px;
background: #fff;
float: left;
padding: 20px;
margin: 15px;
box-shadow: rgba(100, 100, 111, 0.2) 0px 0px 20px 0px;
transition: all 0.25s linear 0s;
position: relative;
border: 2px solid transparent;
backface-visibility: hidden;
-webkit-font-smoothing: subpixel-antialiased;
}
.card:hover {
box-shadow: rgb(38, 57, 77) 0px 2px 30px -10px;
}
.gear {
cursor: pointer;
float: right;
}
.dropmenu {
display: none;
position: absolute;
background: #fff;
box-shadow: rgba(100, 100, 111, 0.2) 0px 0px 20px 0px;
width: 80px;
padding: 10px;
z-index: 10;
}
a {
text-decoration: none;
display: block;
transition: all 0.2s linear;
}
a:hover {
color: #003a95;
}
p {
margin: 35px 10px;
}
<div class="wrapper">
<div class="card">
<img class="gear" onclick="getFixedElementPosition(this, 1)" src="https://www.indivstock.com/static35/preview2/stock-vector-gear-icon-illustrated-in-vector-on-white-background-520258.jpg" width="34">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt</p>
</div>
<!-- /Card #1 -->
<div id="dropmenu1" class="dropmenu" onmouseleave="this.style.display='none';">
View
Edit
Delete
</div>
<div class="card">
<img class="gear" onclick="getFixedElementPosition(this, 2)" src="https://www.indivstock.com/static35/preview2/stock-vector-gear-icon-illustrated-in-vector-on-white-background-520258.jpg" width="34">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt</p>
</div>
<!-- /Card #2 -->
<div id="dropmenu2" class="dropmenu" onmouseleave="this.style.display='none';">
View
Edit
Delete
</div>
<div class="card">
<img class="gear" onclick="getFixedElementPosition(this, 3)" src="https://www.indivstock.com/static35/preview2/stock-vector-gear-icon-illustrated-in-vector-on-white-background-520258.jpg" width="34">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt</p>
</div>
<!-- /Card #3 -->
<div id="dropmenu3" class="dropmenu" onmouseleave="this.style.display='none';">
View
Edit
Delete
</div>
</div>
https://codepen.io/t3l3machus/pen/GRvbjzM
P.S. The numbered ids (dropmenu1, dropmenu2..) are created by a template engine on document load.

There are a couple of things you could change and also some bugs.
The dropdown only works once because you're setting display = "none" but comparing it with empty string.
You can wrap this on a <div> that has position:absolute and then use position:relative to position the dropdown relative to the wrapper. This way you only have to set the display value.
Check out my updated version:
https://codepen.io/samura_lesi/pen/MWvMpKX

Related

How to make ellipses vertically aligned?

I have several lines of text, each of them is truncated with ellipses.
.container {
display: block;
border: 1px solid;
width: 200px;
}
.text {
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
font-size: 20px;
text-align: justify;
}
<div class="container">
<p class="text">
This is text1 that has very very very long string.
</p>
<p class="text">
The ellipses of the line is not vertically aligened with the above one.
</p>
<p class="text">
This is text3 that has very very very long string.
</p>
<p class="text">
Lorem ipsum dolor sit amet consectetur adipisicing elit.
</p>
</div>
As you can see from the demo, all the ellipses are not aligned vertically even though the element width is all the same.
How can I make all of them to be aligned vertically?
P.S. Screenshot attached
The text-align property is only used in cases where the length of the child element is less than the width of the parent (or containing element). If the length of the child element is wider than its parent / containing element then the text-align property isn't used. I get what you are trying to do with text-align: justify, but it doesn't work in this case as the paragraph elements lengths are actually extending past the 200px that you set for the container element.
So, in order to vertically align them, you just need to set a width and add it to the .text class.
Adding
width: 180px to your .text class should do the trick to set a width for the paragraph elements which will get it much closer.
However you'll still have the odd instance where they cut off at different characters and they won't align exactly as you expect, so you can do the below, which is a bit more tricky as you'll have to add a wrapper to each of the paragraph elements. It can potentially look a bit naff, but this would be how you do it:
.container {
display: block;
border: 1px solid;
width: 200px;
}
.text{
text-overflow: clip;
font-size: 20px;
height: 20px;
width: 170px;
overflow: hidden;
word-break: break-all;
}
.ellipsis{
position: relative;
}
.ellipsis::after {
content: "...";
position: absolute;
left: 170px;
top:0;
font-size: 20px;
}
.ellipsis:first-of-type::after {
top: 20px;
}
<div class="container">
<span class="ellipsis"><p class="text">
This is text1 that has very very very long string.
</p></span>
<span class="ellipsis"><p class="text">
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
</p></span>
<span class="ellipsis"><p class="text">
Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
</p></span>
<span class="ellipsis"><p class="text">
This is text1 that has very very very long string.
</p></span>
</div>
Up to you which of those you use though :)
I think it's possible with css tricks.
.container {
border: 1px solid;
width: 200px;
}
.text {
position: relative;
overflow: hidden;
font-size: 20px;
height: 1.5em;
padding-right: 1em;
text-align: justify;
word-break: break-all;
}
.text::after {
content: '...';
position: absolute;
right: 0;
top: 0;
z-index: 1;
width: 1em;
text-align: center;
background: white;
}
<div class="container">
<p class="text">
<span>This is text1 that has very very very long string.</span>
</p>
<p class="text">
<span>The ellipses of the line is not vertically aligened with the above one.</span>
</p>
<p class="text">
<span>This is text3 that has very very very long string.</span>
</p>
<p class="text">
<span>Lorem ipsum dolor sit amet consectetur adipisicing elit.</span>
</p>
</div>
But with this method, if 'text' is smaller than 'container' it looks weird, so apply'::after' to a specific class.
For example,'.overflow::after' and apply the 'overflow' class when 'text' is larger than 'container' via JavaScript.
window.onload = function() {
var tmpContainer = document.getElementsByClassName('container');
var tmpContainerWidth = tmpContainer[0].clientWidth;
var tmpText = document.getElementsByClassName('text');
var tmpTextLen = tmpText.length;
for (var i = 0; i < tmpTextLen; i++) {
var tmpTextWidth = tmpText[i].children[0].offsetWidth;
var tmpTextFontSize = parseFloat(getComputedStyle(tmpText[i]).fontSize);
if (tmpTextWidth + tmpTextFontSize >= tmpContainerWidth) tmpText[i].classList.add('overflow');
}
}
.container {
border: 1px solid;
width: 500px;
}
.text {
position: relative;
overflow: hidden;
font-size: 20px;
height: 1.5em;
padding-right: 1em;
text-align: justify;
word-break: break-all;
}
.overflow::after {
content: '...';
position: absolute;
right: 0;
top: 0;
z-index: 1;
width: 1em;
text-align: center;
background: white;
}
<div class="container">
<p class="text">
<span>This is text1 that has very very very long string.</span>
</p>
<p class="text">
<span>The ellipses of the line is not vertically aligened with the above one.</span>
</p>
<p class="text">
<span>This is text3 that has very very very long string.</span>
</p>
<p class="text">
<span>Lorem ipsum dolor sit amet consectetur adipisicing elit.</span>
</p>
</div>

How to count pageX, pageY for divs with same classes separately from each other

I'm trying to make hover effect like here: https://andstudio.lt/work/
So when user hover on title of project there is image appear which pinned to cursor.
I found some code in internet and created in codepen, here https://codepen.io/ChicagoJostik/pen/abzqXOv
It's actually working, but not properly.
First of all, I got problem here:
function moveCircle(e) {
TweenMax.to(".cursor", 0.5, {
css: {
left: e.pageX,
top: e.pageY
},
});
}
So when I hover on any project all "cursor's" pageX and pageY will be count.
How can I make count only for that "cursor" in which project I hovered?
I don't know maybe it's the problem that makes code working not properly,
but if you have any advice, you can write courageously.
Thanks in advance and sorry for my English.
Here is a working example to play around with.
Snippet:
$(".hoverme a").mouseenter(function() {
img = $(this).attr("data-image");
$(".image-placeholder").attr("style","background:url(" + img + ") no-repeat center center");
$(".image-placeholder").addClass("close");
$(document).on("mousemove", function(e) {
$(".image-placeholder").css({
left: e.pageX,
top: e.pageY
});
});
});
$(".hoverme").mouseleave(function() {
$(".image-placeholder").removeClass("close");
});
body {
background-color: #8f8d8d;
}
.container {
padding: 75px;
position: relative;
z-index: 10;
}
.hoverme {
padding-bottom: 20px;
}
.hoverme a {
opacity: 0.5;
display: inline-block;
font-size: 20px;
color: #fff;
transition: 0.2s;
}
.hoverme a:hover {
opacity: 1;
}
.image-placeholder {
visibility: hidden;
opacity: 0;
width: 30%;
padding-bottom: 21%;
position: absolute;
transform: translate(-50%, -50%) scale(0.7);
z-index: 9;
background-size: cover !important;
transition: opacity 0.1s, visibility 0.1s, transform 0.2s;
left: -100%;
top: -100%;
}
.image-placeholder.close {
display: block;
visibility: visible;
opacity: 1;
transform: translate(-50%, -50%) scale(1.1);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="image-placeholder"></div>
<div class="container">
<div class="hoverme">
<a data-image="https://i.imgur.com/kuqQfXB.jpg">
1. Lorem ipsum dolor sit amet, consectetur adipiscing elit</a>
</div>
<div class="hoverme">
<a data-image="https://i.imgur.com/UVP46pV.jpg">
2. Lorem ipsum dolor sit amet, consectetur adipiscing elit</a>
</div>
<div class="hoverme">
<a data-image="https://i.imgur.com/8YLDZ4B.jpg">
3. Lorem ipsum dolor sit amet, consectetur adipiscing eli</a>
</div>
<div class="hoverme">
<a data-image="https://i.imgur.com/9uAL5Oh.jpg">
4. Donec et velit volutpat, posuere orci pulvinar lobortis</a>
</div>
</div>

Nested accordion not expanding properly javascript

I have created a nested accordion using HTML/CSS and javascript. I have multiple main accordions with 2 sub-accordions in each. My intended result is to expand the sub-accordions and have the next main accordion shift down, however the actual result is that the main accordion does not move down and the sub-accordions aren't expanding properly.
If you run my fiddle example, clicking the first sub-accordion pushes down the second sub-accordion but doesn't push Main#2, and the second sub-accordion doesn't expand on either Main#1 or Main#2.
If someone could help point me in the right direction here I'd really appreciate it! Thanks!
Link to fiddle
HTML:
<div class="collapsible">
<h3><strong>Main#1</strong></h3>
</div>
<div class="content">
<div class="collapsible">
<h4>Sub#1</h4>
</div>
<div class="content">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit</p>
</div>
<div class="collapsible">
<h4>Sub#2</h4>
</div>
<div class="content">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit</p>
</div>
</div>
<div class="collapsible">
<h3><strong>Main#2</strong></h3>
</div>
<div class="content">
<div class="collapsible">
<h4>Sub#1</h4>
</div>
<div class="content">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit</p>
</div>
<div class="collapsible">
<h4>Sub#2</h4>
</div>
<div class="content">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit</p>
</div>
</div>
CSS:
.collapsible {
background-color: white;
color: black;
cursor: pointer;
padding: 1vw;
width:97%;
height: 60px;
max-height: 100%;
margin: 5px 10px 5px 10px;
border: 2px solid black;
text-align: left;
outline: none;
font-size: 25px;
}
.content {
padding: 0 18px;
max-height: 0;
overflow: hidden;
background-color: white;
transition: max-height 0.2s ease-out;
}
h3{
display:inline-block;
vertical-align: middle;
}
h4{
display:inline-block;
vertical-align: middle;
font-size: 22px;
}
Javascript:
$(function() {
var coll = document.getElementsByClassName("collapsible");
//setting buttons of class 'collapsible' to extend on click
for (i = 0; i < coll.length; i++) {
coll[i].addEventListener("click", function () {
this.classList.toggle("active");
var content = this.nextElementSibling;
if (content.style.maxHeight) {
content.style.maxHeight = null;
} else {
content.style.maxHeight = content.scrollHeight + "px";
}
});
}
});
I made some changes in your code.
I add this part to your CSS:
.collapsible ~ .content{
height: 0px;
}
.collapsible.active + .content{
height: 100%;
}
Commented the 'max-height' line:
.content {
padding: 0 18px;
overflow: hidden;
/*max-height: 0;*/
background-color: white;
transition: max-height 0.2s ease-out;
}
And simplify the JS:
$(function() {
var coll = document.getElementsByClassName("collapsible");
//setting buttons of class 'collapsible' to extend on click
for (i = 0; i < coll.length; i++) {
coll[i].addEventListener("click", function () {
this.classList.toggle("active");
});
}
});
Here you can check the changes:
https://jsfiddle.net/xpvt214o/501924/
With this, the hide and show is controlled by CSS.
Hope this help you.

(Circular) (PowerPoint like) transitions between two div's

I have been searching for hours now. Animate.css seems to be pretty good but it only contains some basic animations like moves and scales. But i need something more difficult.
I would like to create a transition between two div elements. The first div is in the foreground and the second behind it. I would like to achieve some PowerPoint-Like transitions between them. I've posted an example Transition I would like to achieve.
I don't see a way to split or transform a div with text inside in the way shown. But I come up with a similar transition that could give some hints or might be even satisfactory.
How it works
I use an overlay composed of eight triangles. These triangles can be designed in CSS like this:
.triangle-down-left {
width: 0;
height: 0;
border-bottom: 150px solid darkgreen;
border-right: 150px solid transparent;
}
And then arranged like this:
The triangles will appear one after the other to hide the first slide. Then they will disappear in a second turn one after the other to reveal the second slide (two turns is what's different from the OP's transition!). You can use this overlay then again when changing to the third slide or use another one, maybe with other colors for the triangles.
Result
You can check it out and play around in the JSFiddle.
$('#next-slide').click(function() {
var triangles = $('#overlay1 div');
showTriangles(triangles).done(function() {
setTimeout(function() {
$('#slide1').hide();
hideTriangles(triangles);
}, 200);
});
});
function showTriangles(triangles) {
var promises = [];
$(triangles).each(function(i) {
var def = new $.Deferred();
setTimeout(function() {
$(triangles[i]).css('opacity', '1');
def.resolve();
}, 200 * i);
promises.push(def);
})
return $.when.apply(undefined, promises).promise();
}
function hideTriangles(triangles) {
$(triangles).each(function(i) {
setTimeout(function() {
$(triangles[i]).css('opacity', '0');
}, 200 * i);
});
}
#next-slide {
margin-left: 350px;
}
.slide {
position: relative;
background: white;
padding: 20px;
box-sizing: border-box;
overflow: hidden;
}
.slide,
.overlay {
position: absolute;
width: 300px;
height: 300px;
}
#slide1 {
z-index: 2;
}
#slide2 {
z-index: 1;
}
#overlay1 {
z-index: 100;
}
.triangle {
position: absolute;
opacity: 0;
}
.triangle1 {
left: 150px;
}
.triangle2 {
left: 150px;
}
.triangle3 {
left: 150px;
top: 150px;
}
.triangle4 {
top: 150px;
left: 150px;
}
.triangle5 {
top: 150px;
}
.triangle6 {
top: 150px;
}
.triangle-up-right {
width: 0;
height: 0;
border-top: 150px solid white;
border-left: 150px solid transparent;
}
.triangle-up-left {
width: 0;
height: 0;
border-top: 150px solid white;
border-right: 150px solid transparent;
}
.triangle-down-right {
width: 0;
height: 0;
border-bottom: 150px solid white;
border-left: 150px solid transparent;
}
.triangle-down-left {
width: 0;
height: 0;
border-bottom: 150px solid white;
border-right: 150px solid transparent;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="slide1" class="slide">
Slide 1.
<br>Now that we know who you are, I know who I am. I'm not a mistake! It all makes sense! I wanna help you. But I can't give you this case, it don't belong to me. Besides, I've already been through too much shit this morning over this case to hand it over
to your dumb ass.
</div>
<div id="overlay1" class="overlay">
<div class="triangle triangle1 triangle-up-left"></div>
<div class="triangle triangle2 triangle-down-right"></div>
<div class="triangle triangle3 triangle-up-right"></div>
<div class="triangle triangle4 triangle-down-left"></div>
<div class="triangle triangle5 triangle-down-right"></div>
<div class="triangle triangle6 triangle-up-left"></div>
<div class="triangle triangle7 triangle-down-left"></div>
<div class="triangle triangle8 triangle-up-right"></div>
</div>
<div id="slide2" class="slide">
Slide 2.
<br>Some wonderful lorem ipsum text. Did you know dolor sit amet? At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing
elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.
</div>
<button id="next-slide">Next slide</button>
Try Magic Animations, https://www.minimamente.com/example/magic_animations/. They offer quite a few different animations and transitions.

On a two-column page, how can I grow the left div to the same height of the right div using CSS or Javascript?

I'm trying to make a two-column page using a div-based layout (no tables please!). Problem is, I can't grow the left div to match the height of the right one. My right div typically has a lot of content.
Here's a paired down example of my template to illustrate the problem.
<div style="float:left; width: 150px; border: 1px solid;">
<ul>
<li>nav1</li>
<li>nav2</li>
<li>nav3</li>
<li>nav4</li>
</ul>
</div>
<div style="float:left; width: 250px">
Lorem ipsum dolor sit amet, consectetur adipisicing elit,
sed do eiusmod tempor incididunt ut labore et dolore magna
....
</div>
Your simplest answer lies in the next version of css (3), which currently no browser supports.
For now you are relegated to calculating heights in javascript and setting them on the left side.
If the navigation is so important to be positioned in such a way, run it along the top.
you could also do a visual trick by moving the borders to the container and the bigger inner, and make it appear to be the same size.
this makes it look the same, but it isn't.
<div style="border-left:solid 1px black;border-bottom:solid 1px black;">
<div style="float:left; width: 150px; border-top: 1px solid;">
<ul>
<li>nav1</li>
<li>nav2</li>
<li>nav3</li>
<li>nav4</li>
</ul>
</div>
<div style="float:left; width: 250px; border:solid 1px black;border-bottom:0;">
Lorem ipsum dolor sit amet, consectetur adipisicing elit,
sed do eiusmod tempor incididunt ut labore et dolore magna
Lorem ipsum dolor sit amet, consectetur adipisicing elit,
...
</div>
<div style="clear:both;" ></div>
</div>
It can be done in CSS! Don't let people tell you otherwise.
The easiest, most pain-free way to do it is to use the Faux Columns method.
However, if that solution doesn't work for you, you'll want to read up on this technique. But be warned, this is the kind of CSS hackery that will make you wake up in a cold sweat in the middle of the night.
The gist of it is that you assign a large amount of padding to the bottom of the column, and a negative margin of the same size. Then you place your columns in a container that has overflow: hidden set. More or less the padding/margin values allow the box to keep expanding until it reaches the end of the wrapper (which is determined by the column with the most content), and any extra space generated by the padding is cut off as overflow. It doesn't make much sense, I know...
<div id="wrapper">
<div id="col1">Content</div>
<div id="col2">Longer Content</div>
</div>
#wrapper {
overflow: hidden;
}
#col1, #col2 {
padding-bottom: 9999px;
margin-bottom: -9999px;
}
Be sure to read the entire article I linked to, there are a number of caveats and other implementation issues. It's not a pretty technique, but it works fairly well.
You can do it in jQuery really simple, but I am not sure JS should be used for such things. The best way is to do it with pure css.
Take a look at faux columns or even Fluid Faux Columns
Also another technique(doesn't work on the beautiful IE6) is to position:relative the parent container. The child container(the nav list in your case) should be positioned absolute and forced to occupy the whole space with 'top:0; bottom:0;'
Use jQuery for this problem; just call this function in your ready function:
function setHeight(){
var height = $(document).height(); //optionally, subtract some from the height
$("#leftDiv").css("height", height + "px");
}
This is one of those perfectly reasonable, simple things that CSS can't do. Faux Columns, as suggested by Silviu, is a hacky but functional workaround.
It would be lovely if someday there was a way to say
div.foo {
height: $(div.blah.height);
}
This can be done with css using background colors
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Untitled Document</title>
<style type="text/css">
* {
margin: 0;
padding: 0;
}
body {
font-family: Arial, Helvetica, sans-serif;
background: #87ceeb;
font-size: 1.2em;
}
#container {
width:100%; /* any width including 100% will work */
color: inherit;
margin:0 auto; /* remove if 100% width */
background:#FFF;
}
#header {
width: 100%;
height: 160px;
background: #1e90ff;
}
#content {/* use for left sidebar, menu etc. */
background: #99C;
color: #000;
float: right;/* float left for right sidebar */
margin: 0 0 0 -200px; /* adjust margin if borders added */
width: 100%;
}
#content .wrapper {
background: #FFF;
margin: 0 0 0 200px;
overflow: hidden;
padding: 10px; /* optional, feel free to remove */
}
#sidebar {
background: #99C;
color: inherit;
float: left;
width: 180px;
padding: 10px;
}
.clearer {
height: 1px;
font-size: -1px;
clear: both;
}
/* content styles */
#header h1 {
padding: 0 0 0 5px;
}
#menu p {
font-size: 1em;
font-weight: bold;
padding: 5px 0 5px 5px;
}
#footer {
clear: both;
border-top: 1px solid #1e90ff;
border-bottom: 10px solid #1e90ff;
text-align: center;
font-size: 50%;
font-weight: bold;
}
#footer p {
padding: 10px 0;
}
</style>
</head>
<body>
<div id="container">
<!--header and menu content goes here -->
<div id="header">
<h1>Header Goes Here</h1>
</div>
<div id="content">
<div class="wrapper">
<!--main page content goes here -->
<p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Duis ligula lorem, consequat eget, tristique nec, auctor quis, purus. Vivamus ut sem. Fusce aliquam nunc
vitae purus. Aenean viverra malesuada libero. </p>
</div>
</div>
<div id="sidebar">
<!--sidebar content, menu goes here -->
<p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Duis ligula lorem, consequat eget, tristique nec, auctor quis, purus.</p>
</div>
<div class="clearer"></div><!--clears footer from content-->
<!--footer content goes here -->
<div id="footer">
<p>Footer Info Here</p>
</div>
</div>
</body>
</html>
#hoyhoy
If a designer can make this work in html, then he can have this design. If he is a true master of web design, he will realize that this is a limitation of the media, as video is not possible in magazine ads.
If he would like to simulate weight by giving the 2 columns equal importance, than change the borders, so that they appear to be of the same weight, and make the colors of the borders contrast to the font color of the columns.
But as for making the physical elements the same height, you can only do that with a table construct, or setting the heights, at this point in time. To simulate them appearing the same size, they don't have to be the same size.
Come to think of it, I've never done it with a bottom border on the column. It's probably just overflowing, and getting cut off. You might want to have the bottom border come from a separate element that's part of the column content.
Anyway, I know it's not a perfect magic bullet solution. You might just have to play with it, or hack around its shortcomings.
There is also a Javascript based solution. If you have jQuery, you can use the below plugin.
<script type="text/javascript">
// plugin
jQuery.fn.equalHeights=function() {
var maxHeight=0;
this.each(function(){
if (this.offsetHeight>maxHeight) {maxHeight=this.offsetHeight;}
});
this.each(function(){
$(this).height(maxHeight + "px");
if (this.offsetHeight>maxHeight) {
$(this).height((maxHeight-(this.offsetHeight-maxHeight))+"px");
}
});
};
// usage
$(function() {
$('.column1, .column2, .column3').equalHeights();
});
</script>
I use this to align 2 columns with ID "center" and "right":
var c = $("#center");
var cp = parseInt(c.css("padding-top"), 10) + parseInt(c.css("padding-bottom"), 10) + parseInt(c.css("borderTopWidth"), 10) + parseInt(c.css("borderBottomWidth"), 10);
var r = $("#right");
var rp = parseInt(r.css("padding-top"), 10) + parseInt(r.css("padding-bottom"), 10) + parseInt(r.css("borderTopWidth"), 10) + parseInt(r.css("borderBottomWidth"), 10);
if (c.outerHeight() < r.outerHeight()) {
c.height(r.height () + rp - cp);
} else {
r.height(c.height () + cp - rp);
}
Hope it helps.
To grow the left menu div with same height as the right content div.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Untitled Document</title>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js">
</script>
<script>
$(document).ready(function () {
var height = $(document).height(); //optionally, subtract some from the height
$("#menu").css("height", (height) + "px");
$("#content").css("height", (height) + "px");
});
</script>
<style type="text/css">
<!--
html, body {
font-family: Arial;
font-size: 12px;
}
#header {
background-color: #F9C;
height: 200px;
width: 100%;
float: left;
position: relative;
}
#menu {
background-color: #6CF;
float: left;
min-height: 100%;
height: auto;
width: 10%;
position: relative;
}
#content {
background-color: #6f6;
float: right;
height: auto;
width: 90%;
position: relative;
}
#footer {
background-color: #996;
float: left;
height: 100px;
width: 100%;
position: relative;
}
-->
</style>
</head>
<body>
<div id="header">
i am a header
</div>
<div id="menu">
i am a menu
</div>
<div id="content">
I am an example of how to do layout with css rules and divs.
<p> I am an example of how to do layout with css rules and divs. </p>
<p> I am an example of how to do layout with css rules and divs. </p>
<p> I am an example of how to do layout with css rules and divs. </p>
<p> I am an example of how to do layout with css rules and divs. </p>
<p> I am an example of how to do layout with css rules and divs. </p>
<p> I am an example of how to do layout with css rules and divs. </p>
<p> I am an example of how to do layout with css rules and divs. </p>
</div>
<div id="footer">
footer
</div>
</body>
</html>

Categories

Resources