Take existing value of transform: translateX option - css

Here is <div> with style:
<div style="transform: translateX(1565px) translateY(159px) translateZ(0px)">
</div>
I want to add class that can calculate existing value of translateX and subtract 140(for example) from it. Is it possible to do that?
Regards, Nick

Maybe you would consider using css variables? With them you can define just the offset value in a class, and use that value inside the main class that calculates the actual translation. In the example below you can see that i defined small utility classes just modify the offset value.
/* for visual purposes */
.box {
width: 50px;
height: 50px;
background-color: grey;
margin: 10px;
}
.box{
--offset: 0px;
transform: translateX(calc(15px + var(--offset))) translateY(2px) translateZ(0px);
}
.smallOffset{
--offset: 10px;
}
.bigOffset{
--offset: 40px;
}
.negativeOffset{
--offset: -20px;
}
<div class="box"></div>
<div class="box smallOffset"></div>
<div class="box bigOffset"></div>
<div class="box negativeOffset"></div>
Unfortunately, the support for css variables is not perfect, as IE is not supported at all. For more details about usage of --variable, var(--variable) and related, please refer to the docs.

Use calc()
.decrease{
transform: translateX(calc(1565px - 140px)) translateY(159px) translateZ(0px);
}
<div class="decrease">
div
</div>
With media-query:
.decrease{
transform: translateX(1565px) translateY(159px) translateZ(0px);
}
#media only screen and (max-width: 600px) {
.decrease {
transform: translateX(calc(1565px - 140px)) translateY(159px) translateZ(0px);
}
}
<div class="decrease">
div
</div>
Using Less and parameter:
#translateX : 1565px;
.decrease{
transform: translateX(#translateX) translateY(159px) translateZ(0px);
}
#media only screen and (max-width: 600px) {
.decrease {
transform: translateX(calc(#translateX - 140px)) translateY(159px) translateZ(0px);
}
}

Related

Flexbox Container Overlay Buttons

So I'm not that great at programming sorry, but I use stack overflow and other sources to add site functionality and learn a little more each time. I'm using a Flexible Grid System to display my main content, specifically to re-arrange navigational buttons on the page.
This works great for me, but I've been using an ancient onMouseOver effect to display text when the user moves over an image button link and I'm not happy with the way it looks, and using flex creates issues with text legibility when the sizing gets small.
Ideally, I'd like to use a css overlay on my buttons so I can replace the image with text and format it to my liking. I've tried MANY different overlay solutions, but they all seem to use grid layouts and I can't get them to work with my flex layout for some reason.
Either the images get cropped, or the text can't completely cover the image due to layering issues, or (If I use the grid layout) I lose the flexible resizing capabilities that I really like on the site.
I'm hoping that this is a really simple fix. I'm assuming I need to add a container to my flex layout to place the content over the top of the image, but a hint to where to start would be really appreciated.
Here's a link to the buttons in the flex layout with no overlay:
https://megaauctions.net/megaflextest.htm
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>MEGA Main Flex Buttons</title>
<link rel="stylesheet" href="css/test-code-buttons-no-action-compact.css" type="text/css"/>
</head>
<body>
<div class="buttoncontainer">
<buttonhomea class="buttonhomea column grad-yellow">
<a href=#><img src="http://www.megaauctions.net/images/btn-auctions.gif" /></a>
</buttonhomea>
<buttonhomeb class="buttonhomeb column grad-babyblue">
<img src="http://www.megaauctions.net/images/btn-buying.gif" />
</buttonhomeb>
<buttonhomec class="buttonhomec column grad-salmon">
<img src="http://www.megaauctions.net/images/btn-selling.gif" />
</buttonhomec>
</div>
</body>
</html>
and the CSS...
.buttoncontainer {
margin: 0 auto;
top: 0px;
display: flex;
position: relative;
flex-wrap: wrap;
justify-content: space-evenly;
text-align: center;
background: url('http://www.megaauctions.net/images/bkg-subs-deep.gif');
}
.column {
--columns: 12; /* number of columns in the grid system */
--width: var(--width-mobile, 0); /* width of the element */
padding: 0px;
margin: 9px 1px 2px 1px;
flex-basis: calc(var(--width) / var(--columns) * 94%);
}
/****** VIEWPORTS START ******/
#media (min-width: 350px) {
.column {
--width-mobile: var(--width-mobile);
--width: var(--width-mobile);
}
.buttonhomea img, .buttonhomeb img, .buttonhomec img {
width:100%;
max-width:157px;
}
}
#media (min-width: 512px) {
.column {
--width-tabletp: var(--width-tablet);
--width: var(--width-tabletp);
}
.buttonhomea img, .buttonhomeb img, .buttonhomec img {
width:100%;
max-width:157px;
}
}
#media (min-width: 650px) {
.column {
--width-tablet: var(--width-mobile);
--width: var(--width-tablet);
}
.buttonhomea img, .buttonhomeb img, .buttonhomec img {
width:100%;
max-width:300px;
}
}
#media (min-width: 900px) {
.column {
--width-desktop: var(--width-tablet);
--width: var(--width-desktop);
}
.buttonhomea img, .buttonhomeb img, .buttonhomec img {
width:100%;
max-width:315px;
}
}
/****** VIEWPORTS END ******/
.buttonhomea, .buttonhomeb, .buttonhomec {
--width-mobile: 12;
--width-tabletp: 4;
--width-tablet: 4;
--width-desktop: 4;
height: 100%;
}
.grad-yellow {
background-color:#f3d250;
background-image:linear-gradient(140deg,#f3d250,#EEA315);
}
.grad-babyblue {
background-color:#90CCF4;
background-image:linear-gradient(140deg,#90CCF4,#578FEE);
}
.grad-salmon {
background-color:#F78888;
background-image:linear-gradient(140deg,#F78888,#E7298C);
}
code in fiddle:
https://jsfiddle.net/mattcomps/gfb7k43h/
...and an overlay example of what I'm trying to achieve:
https://megaauctions.net/megaflextestbuttonaction.htm
<html>
<head>
<title>CSS Grid Cards</title>
<link rel="stylesheet" href="css/test-code-buttons-working-grid-compact.css" type="text/css"/>
</head>
<body>
<div class="container">
<section class="cards">
<a href="#" class="card grad-yellow">
<div class="card__overlay grad-yellow">
<div class="card__title">Auctions</div>
<div class="card__description">
Description goes here.
</div>
</div>
<div class="card__image" style="background-image:url('http://www.megaauctions.net/images/btn-auctions.gif')"></div>
<div class="card__content">
</div>
</a>
<a href="#" class="card grad-babyblue">
<div class="card__overlay grad-babyblue">
<div class="card__title">Buying</div>
<div class="card__description">
Description goes here.
</div>
</div>
<div class="card__image" style="background-image:url('http://www.megaauctions.net/images/btn-buying.gif')"></div>
<div class="card__content">
</div>
</a>
<a href="#" class="card grad-salmon">
<div class="card__overlay grad-salmon">
<div class="card__title">Selling</div>
<div class="card__description">
Description goes here.
</div>
</div>
<div class="card__image" style="background-image:url('http://www.megaauctions.net/images/btn-selling.gif')"></div>
<div class="card__content">
</div>
</a>
</section>
</div>
</body>
</html>
and the CSS...
.container{
background-image:url(http://www.megaauctions.net/images/bkg-subs-deep.gif)
}
.cards{
display:grid;
gap:1rem;
margin:0 auto;
padding:1rem;
}
#media (min-width:59em){
.cards{
grid-template-columns:repeat(2,1fr)
}
}
.card{
display:grid;
grid-template-columns:repeat(2,1fr);
grid-template-rows:300px 1fr auto;
color:#fff;
}
#media (min-width:31.25em){
.card{
grid-template-columns:160px (2,1fr);
grid-template-rows:1fr auto
}
}
#media (min-width:50em){
.card{
grid-template-columns:300px (2,1fr)
}
}
#media (min-width:59em){
.card{
grid-template-columns:160px(2,1fr)
}
}
.card__overlay{
min-height:300px;
display:none
}
#media (min-width:59em){
.card__overlay{
position:relative;
opacity:0;
display:grid;
justify-items:center;
align-items:center;
grid-column:1/4;
grid-row:1/3;
transition:opacity .3s ease-in-out}
}
.card:hover .card__overlay{
min-height:300px;
opacity:1
}
.card__content span{
display:inline-block;
border:2px solid #fff;
padding:1rem 3rem;
color:#fff;
}
.card__image{
grid-column:1/3;
grid-row:1/2;
min-height:157px;
background:no-repeat
}
#media (min-width:31.25em){
.card__image{
grid-column:1/4;
grid-row:1/3
}
}
.card__content{
grid-column:1/3;
grid-row:2/3;
padding:1.5rem}
#media (min-width:31.25em){
.card__content{
grid-column:2/4;
grid-row:1/2}
}
.grad-yellow {
background-color:#f3d250;
background-image:linear-gradient(140deg,#f3d250,#EEA315);
}
.grad-babyblue {
background-color:#90CCF4;
background-image:linear-gradient(140deg,#90CCF4,#578FEE);
}
.grad-salmon {
background-color:#F78888;
background-image:linear-gradient(140deg,#F78888,#E7298C);
}
code in fiddle:
https://jsfiddle.net/mattcomps/2eLzkwts/
Thanks!
Hope this answers your query
JSFIDDLE
what i have done is giving relative style to the parent buttonhomea .
then on hover showing the hidden div.
.card__overlay{
position: absolute;
width: 100%;
height: 100%;
top: 0;
opactity:0;
z-index:-1;
}
.buttonhomea{
position:relative;
}
.buttonhomea:hover .card__overlay{
opacity:1;
z-index:1;
}
and added html
<div class="card__overlay grad-yellow">
<div class="card__title">Auctions</div>
<div class="card__description">
Description goes here.
</div>
</div>
under each buttonhomea class

How do I resize css loaders?

I'm wondering how I resize css loaders like resize it for mobile users cause I noticed the loaders don't resize for mobile users they just stay the same size no matter the size of the page, I want it to resize itself like text and stuff does. Here's an example of a css loader if you're confused:
http://jsfiddle.net/hdznz09a
#floatBarsG{
position:relative;
width:234px;
height:28px;
margin:auto;
margin-top: 13%;
}
.floatBarsG{
position:absolute;
top:0;
background-color:rgb(0,0,0);
width:28px;
height:28px;
animation-name:bounce_floatBarsG;
animation-duration:1.5s;
animation-direction:normal;
transform:scale(.3);
}
#floatBarsG_1{
left:0;
animation-delay:0.6s;
}
#floatBarsG_2{
left:29px;
animation-delay:0.75s;
}
#floatBarsG_3{
left:58px;
animation-delay:0.9s;
}
#floatBarsG_4{
left:88px;
animation-delay:1.05s;
}
#floatBarsG_5{
left:117px;
animation-delay:1.2s;
}
#floatBarsG_6{
left:146px;
animation-delay:1.35s;
}
#floatBarsG_7{
left:175px;
animation-delay:1.5s;
}
#floatBarsG_8{
left:205px;
animation-delay:1.64s;
}
#keyframes bounce_floatBarsG{
0%{
transform:scale(1);
background-color:rgb(0,0,0);
}
100%{
transform:scale(.3);
background-color:rgb(255,255,255);
}
}
<div id="floatBarsG">
<div id="floatBarsG_1" class="floatBarsG"></div>
<div id="floatBarsG_2" class="floatBarsG"></div>
<div id="floatBarsG_3" class="floatBarsG"></div>
<div id="floatBarsG_4" class="floatBarsG"></div>
<div id="floatBarsG_5" class="floatBarsG"></div>
<div id="floatBarsG_6" class="floatBarsG"></div>
<div id="floatBarsG_7" class="floatBarsG"></div>
<div id="floatBarsG_8" class="floatBarsG"></div>
</div>
You could use the:
transform: scale(0.5);
on your:
<div id="floatBarsG">
element like shown below
#floatBarsG{
position:absolute;
width: 33%;
height:28px;
margin-left: -117px;
left: 50%;
margin-top: 13%;
transform: scale(0.5);
}
in combination with media querys for your desired width's / devices
Articles about media querys:
https://wiki.selfhtml.org/wiki/CSS/Media_Queries
http://www.w3schools.com/cssref/css3_pr_mediaquery.asp
JSFIDDLE Example: http://jsfiddle.net/hdznz09a/3/ (Try resizing your browser window)
As said in comments:
use dynamic size like vh or vw
float:left; your minitinysquares and
don't to absolute and left values
don't use #ID, use classes instead (code reusability)
#floatBarsG{
position:absolute;
left:50%; top: 50%;
transform: translate(-50%, -50%);
}
.floatBarsG{
float:left;
background-color:rgb(0,0,0);
width:3vh; /* Use responsive units */
height:3vh;
min-width: 20px; /* prevent making them too small */
min-height: 20px;
animation:bounce_floatBarsG 1.5s infinite;
transform:scale(.3);
}
.floatBarsG._1{animation-delay:0.6s;}
.floatBarsG._2{animation-delay:0.75s;}
.floatBarsG._3{animation-delay:0.9s;}
.floatBarsG._4{animation-delay:1.05s;}
.floatBarsG._5{animation-delay:1.2s;}
.floatBarsG._6{animation-delay:1.35s;}
.floatBarsG._7{animation-delay:1.5s;}
.floatBarsG._8{animation-delay:1.64s;}
#keyframes bounce_floatBarsG{
from{
transform:scale(1);
background-color:rgb(0,0,0);
}
to{
transform:scale(.3);
background-color:rgb(255,255,255);
}
}
<div id="floatBarsG">
<div class="floatBarsG _1"></div>
<div class="floatBarsG _2"></div>
<div class="floatBarsG _3"></div>
<div class="floatBarsG _4"></div>
<div class="floatBarsG _5"></div>
<div class="floatBarsG _6"></div>
<div class="floatBarsG _7"></div>
<div class="floatBarsG _8"></div>
</div>

This CSS animation (.less) works in Firefox and Chrome, not in Safari

I have this little CSS3 animation going on in my webapp, its a panel in the bottom left side of the screen. I use Linux so I can't try out the animations in Safari, however my project leader is of course a Mac user and he complained right away it didn't work.
So, here are my two files. I'll paste everything in here that I'm working on, and in the bottom I have a jsfiddle that tried to reproduce it with plain css and fewer HTML tags. :)
Here's the less file.
.panel {
position:absolute;
left:20px;
bottom:20px;
background-image : url("./images/filter_bg.png");
width:476px;
height:126px;
z-index:1;
cursor:pointer;
}
.filter {
position:relative;
float:left;
z-index: 2;
width:119px;
height:119px;
vertical-align:24px;
overflow:hidden;
&.activeLive {
background-image: url("./images/filter_active1.png");
}
&.activeSee {
background-image: url("./images/filter_active2.png");
}
&.activeEat {
background-image: url("./images/filter_active3.png");
}
&.activeDo {
background-image: url("./images/filter_active4.png");
}
}
.filter:hover > .filter-hover {
position:absolute;
height:34px;
width:119px;
-moz-transition:-moz-transform 180ms;
-webkit-transition:-webkit-transform 180ms;
-o-transition:-o-transform 180ms;
transition:transform 180ms;
background-image:url("./images/filter_hoverlabel_bg.png");
}
.filter:hover > .filter-hover {
transform: translate(0,-24px);
}
.filter-hover{
position: relative;
bottom:-26px;
text-align:center;
line-height: 32px;
}
.filter-icon{
width:68px;
height:68px;
margin: 24px auto auto;
&.inactive1{
background-image:url("./images/filter_icon1_inactive.png");
}
&.inactive2{
background-image:url("./images/filter_icon2_inactive.png");
}
&.inactive3{
background-image:url("./images/filter_icon3_inactive.png");
}
&.inactive4{
background-image:url("./images/filter_icon4_inactive.png");
}
&.active1{
background-image:url("./images/filter_icon1_active.png");
}
&.active2{
background-image:url("./images/filter_icon2_active.png");
}
&.active3{
background-image:url("./images/filter_icon3_active.png");
}
&.active4{
background-image:url("./images/filter_icon4_active.png");
}
}
.filter-text{
text-align:center;
}
It adds a class to the divs when clicked upon, I use angular for this. So don't care to much about that.
<div class="panel" ng-controller="PanelCtrl">
<div class="{{liveEnabled ? 'filter activeLive' : 'filter'}}" ng-click="liveButton()">
<div class="{{liveEnabled ? 'filter-icon active1' : 'filter-icon inactive1'}}"></div>
<div class="filter-hover">
Bo
</div>
</div>
<div class="{{seeEnabled ? 'filter activeSee' : 'filter'}}" ng-click="seeButton()">
<div class="{{seeEnabled ? 'filter-icon active2' : 'filter-icon inactive2'}}"></div>
<div class="filter-hover">
<span class="filter-text">Se</span>
</div>
</div>
<div class="{{eatEnabled ? 'filter activeEat' : 'filter'}}" ng-click="eatButton()">
<div class="{{eatEnabled ? 'filter-icon active3' : 'filter-icon inactive3'}}"></div>
<div class="filter-hover">
<span class="filter-text">Äta</span>
</div>
</div>
<div class="{{doEnabled ? 'filter activeDo' : 'filter'}}" ng-click="doButton()">
<div class="{{doEnabled ? 'filter-icon active4' : 'filter-icon inactive4'}}"></div>
<div class="filter-hover">
<span class="filter-text">Göra</span>
</div>
</div>
</div>
I made this fiddle: http://jsfiddle.net/j97ahnkv/ wich tries to show out what I'm trying to do.
It's not working in Safari because it still requires the -webkit prefix on transform.
You have to add it to this rule:
.filter:hover > .filter-hover {
-webkit-transform: translate(0, -24px);
transform: translate(0,-24px);
}

How to transition 2 divs at the same time?

I'm trying to make an animated menu that when I hover over it , the background (or image) reduces and at the same time the text expands.
Thats my style sheet :
.menus {
float: left;
background-image: url(images/menus_bg.png);
width: 208px;
height: 283px;
}
.menusimg {
width: 208px;
height: 283px;
position: absolute;
background-size: 100% 100%;
background-repeat: no-repeat;
background-position: center center;
background-image: url(images/menu1.png);
}
.menusimg:hover {
background-size: 80% 80%;
}
.menusimg, .menusimg:hover {
-webkit-transition: background-size 0.2s ease-in ;
}
.menustxtbox {
font-family: MP;
padding-top: 240px;
width: 208px;
height: 283px;
color: #4c4c4c;
font-size: large;
text-shadow: gray 0.1em 0.1em 0.2em;
}
.menustxtbox:hover {
padding-top: 235px;
font-size: x-large;
color: #4fa3f9;
}
.menustxtbox, .menutxtbox:hover {
-webkit-transition:font-size 0.1s linear;
-moz-transition:font-size 0.1s linear;
}
and the html :
<div class="menus">
<div class="menusimg">
</div>
<div class="menustxtbox">
Text
</div>
</div>
Any ideas? A simple Java script or anything that will solve this problem? :)
Thank you in advance ^^
I second what ntgCleaner said.
In addition you can use:
$('.menus').hover(function(){
$('.menusimg').addClass('active');
$('.menustxtbox').addClass('active');
}, function(){
$('.menusimg').removeClass('active');
$('.menustxtbox').removeClass('active');
});
And your css would have:
.menusimg.active, .menusimg.active{
-webkit-transition: background-size 0.2s ease-in ;
}
etc.
Well, without any code to see that you've done anything or tried anything with javascript, I would suggest this:
Change your CSS to make real sizes of font size first:
.menustxtbox {
font-size:40px;
}
then make some jquery
$('.menus').hover(function(){
$('.menusimg').animate({width: "100px"});
$('.menustxtbox').animate({fontSize: "90px"});
}, function(){
$('.menusimg').animate({width: "208px"});
$('.menustxtbox').animate({fontSize: "40px"});
});
Then delete your :hover css styles
And if you want to use hover, I would suggest looking into hoverintent
UPDATE for a comment below
To do this for each separate menu item, you will have to name things a certain way. Here's an example.
HTML
<div class="menu">
<div class="menuItem" id="menu1">
<div class="menusimg"></div>
<div class="menustxtbox"></div>
</div>
<div class="menuItem" id="menu2">
<div class="menusimg"></div>
<div class="menustxtbox"></div>
</div>
<div class="menuItem" id="menu3">
<div class="menusimg"></div>
<div class="menustxtbox"></div>
</div>
</div>
Then with jQuery, you will have to use $(this) and .children()
$('.menuItem').hover(function(){
$(this).children('.menusimg').animate({width: "100px"});
$(this).children('.menustxtbox').animate({fontSize: "90px"});
}, function(){
$(this).children('.menusimg').animate({width: "208px"});
$(this).children('.menustxtbox').animate({fontSize: "40px"});
});
When you use $(this), you will do whatever you want to the specific thing you are trying to use. Then you just go up or down from there using parent or children to do something to either of those.

Any reliable, cross-browser way to distribute the remaining space in parent element between several DIVs?

Background
I am working on a browser-based UI that needs to fill the entire screen without any scrolling. The basic layout is like this:
What I want to achieve
The title div should has a fixed height (2em) and the rest 4 divs/panels should devide the remaining space of the screen according to percentages I set.
What I've tried
The best solution I've found is " CSS - How to force elements to 100% of remaining/available space of parent element without extending beyond it? ", which involves using a container div with position:absolute. This works across all browsers, but requires some additional DIVs to be created. Also, panel 2 can sometimes be forced to start on the next line due to inaccuracies in percentage widths.
My previous solution was based on CSS3 Flexbox, but the model is flawed as it does not resize child elements that have a percentage height after stretching the container boxes (at least Chrome doesn't). (The newer flex-* attributes are only implemented in Chrome and the standard is still changing.)
I have also tried the calc() function; however, it's not yet implemented in Chrome. Also, it requires hard-coding the height of the title element in two places, which I've been trying to avoid.
Edit:
What am I looking for
Just to be clear, I am not asking for a perfect/pure-CSS solution (as none seems to exist). If anyone can suggest any jQuery plug-in or open-source framework that can do this, it would be good enough for me.
In addition, I don't require any backwards compatibility with browser releases before 2012. (As long as the solution uses technology that is implemented in some browser and is going to be implemented by Firefox and Chrome in the near future, it's good enough for me.)
A little something thrown together:
http://jsfiddle.net/gDTGn/2/
Here is a pure CSS version:
http://jsfiddle.net/t0nyh0/KHzsg/63/
The trick to this technique is using position:absolute and using top, bottom, and height to create a fixed header with expanding panels. It is also really important to use:
box-sizing: border-box;
-moz-box-sizing: border-box;
to make the height and width calculations consistent across browsers. Tested and works in IE9, Firefox, and Chrome.
Pure CSS solution: http://jsfiddle.net/ehqcx/7/embedded/result/
This assumes you set width that don't sum up than more than 100%, the small gap at the right side can usually be fixed by using the same background or the background of the page. An alternative is to introduce some Javascript that sets the width of the last panel correctly, but that should be some trivial jQuery code... $("#panels .small:last").width(browser width - other small panels);
Should work correctly for the height, think away the jsFiddle header which takes away some height...
Edit:
Meh, seems the #title is bugging me... http://fiddle.jshell.net/ehqcx/7/show/light/
ECMAScript is the way to go, leaving my answer in place because of the other simplicity... :(
HTML:
<div id="content">
<div id="title">Title!</div>
<div id="panels">
<div id="panel0" class="small">0</div>
<div id="panel1" class="small">1</div>
<div id="panel2" class="small">2</div>
<div id="panel3" class="wide">3</div>
</div>
</div>​
CSS:
* { margin, padding: 0px; }
#content { background-color: black; }
#title { background-color: red; }
#panels { background-color: orange; }
#panel0 { background-color: purple; }
#panel1 { background-color: brown; }
#panel2 { background-color: orange; }
#panel3 { background-color: green; }
html, body, #content, #panels { max-height: 100%; height: 100%; max-width: 100%; width: 100%; }
#panels .small { float: left; }
#panels .wide { clear: both; }
#title { height : 2em; }
#panels .small { height: 75%; }
#panels .wide { height: 25%; }
#panel0, #panel1, #panel2 { width: 33.33%; }
It's possible using the new CSS3 flexbox model. It was basically designed to solve the problem you are facing.
Here is a simple example:
CSS:
*{margin:0 padding:0;}
html{height:100%;}
body{height:100%; display:box; box-orient:vertical;}
body > div {box-flex:1; border:1px solid black;}
.header {box-flex:0; height:4em;}
.content {
display: box;
box-orient: horizontal;
}
.content div {
box-flex: 1;
border:1px solid black;
}
HTML:
<html>
<body>
<div class="header">Title</div>
<div class="content">
<div>Panel 0</div>
<div>Panel 1</div>
<div>Panel 2</div>
</div>
<div>Panel 3</div>
</body>
</html>
It has good support in Chrome, Safari, and Firefox, with planned support in IE.
edit 2:
Tested it in
Chrome/Safari: some 1 or two pixel failure, because of percent calculations
FireFox: Perfect
IE9: Perfect
Opera: Can't have decimal places in percentage width values. This is bad
lte IE8: Does not support Array reduce function. One has to make one up (like from here: Array.reduce), Then it works at least in IE8
edit 1:
I added horizontal layout and window resize function
I've fiddled around a bit:
This is just a demonstration: To have a full fledged application you have to add the programming for the horizontal layout. But it's start
http://jsfiddle.net/HerrSerker/PmHtf/
Here is the code
HTML
<div class="full-stretch">
<div class="flex-layout flex-layout-vertical">
<div class="flex-layout-fixed" style="height:50px; text-align: center">
<div class="padding">Title</div>
</div>
<div class="flex-layout-consume flex-layout-consume-3" style="text-align: center">
<div class="flex-layout flex-layout-horizontal">
<div class="flex-layout-consume flex-layout-consume-1" style="text-align: center">
<div class="padding">Panel 0</div>
</div>
<div class="flex-layout-consume flex-layout-consume-1" style="text-align: center">
<div class="padding">Panel 1</div>
</div>
<div class="flex-layout-consume flex-layout-consume-1" style="text-align: center">
<div class="padding">Panel 2</div>
</div>
</div>
</div>
<div class="flex-layout-consume flex-layout-consume-1" style="text-align: center">
<div class="padding">Panel 3</div>
</div>
</div>
</div>​
CSS
.full-stretch {
position: absolute;
top: 2px;
right:2px;
bottom:2px;
left: 2px;
}
.padding {
position: absolute;
top: 2px;
right:2px;
bottom:2px;
left: 2px;
border: 1px solid darkGray;
background: lightBlue;
border-radius: 10px;
}
.flex-layout {
position: absolute;
top: 0;
right:0;
bottom:0;
left: 0;
overflow: hidden;
}
.flex-layout-consume {
height: 100%;
float:left;
overflow: hidden;
position: relative;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
.flex-layout-vertical > .flex-layout-consume {
width: 100%;
}
.flex-layout-fixed {
height: 100%;
float:left;
overflow: hidden;
position: relative;
}
.flex-layout-vertical > .flex-layout-fixed {
width: 100%;
}
jQuery
(function($) {
var flex = function() {
$('.flex-layout').each(function() {
var fixed = $(this).children('.flex-layout-fixed');
if ($(this).hasClass('flex-layout-horizontal')) { // horizontal
var fixed_widths = $(this)
.children('.flex-layout-fixed')
.get()
.reduce(function(total, elem) {
return (total + $(elem).outerWidth())
},0)
;
var remain_width = ($(this).outerWidth() - fixed_widths)/$(this).outerWidth() * 100; // percent
var consumers = $(this)
.children('.flex-layout-consume')
.get()
;
var count_consumers = consumers
.reduce(function(total, elem) {
var cm = parseInt($(elem).attr('class').match(/flex-layout-consume-(\d+)/)[1]);
$(elem).data('consume_multiplicator', cm);
return total + cm;
},0)
;
var consumers_tic = (remain_width/count_consumers)
$(consumers).each(function() {
$(this).width(Math.round((consumers_tic * $(this).data('consume_multiplicator'))*1000)/1000+'%')
})
} else if ($(this).hasClass('flex-layout-vertical')) { // vertical
var fixed_heights = $(this)
.children('.flex-layout-fixed')
.get()
.reduce(function(total, elem) {
return (total + $(elem).outerHeight())
},0)
;
var remain_height = ($(this).outerHeight() - fixed_heights)/$(this).outerHeight() * 100; // percent
var consumers = $(this)
.children('.flex-layout-consume')
.get()
;
var count_consumers = consumers
.reduce(function(total, elem) {
var cm = parseInt($(elem).attr('class').match(/flex-layout-consume-(\d+)/)[1]);
$(elem).data('consume_multiplicator', cm);
return total + cm;
},0)
;
var consumers_tic = (remain_height/count_consumers)
$(consumers).each(function() {
$(this).height(Math.round((consumers_tic * $(this).data('consume_multiplicator'))*1000)/1000+'%')
})
}
})
};
$(function() {
flex()
$(self).resize(flex)
})
}(jQuery))
​
I might be missing something in your question, but see if this is what you are looking for. Pure CSS solution that works in all browsers down to IE7.
http://jsfiddle.net/nyHgM/1/
This is my suggestion (pure css)... Tested on IE7+, Chrome & FF http://jsfiddle.net/victmo/hKGUe/
HTML
<div id='header'></div>
<div id='col0'></div>
<div id='col1'></div>
<div id='col2'></div>
<div id='footer'></div>
CSS
div{
position:absolute;
}
#header{
top:0px;
left:0px;
right:0px;
height:3em;
}
#footer{
bottom:0px;
left:0px;
right:0px;
height:2em;
}
#col0,
#col1,
#col2{
top:3em; /* header height */
bottom:2em; /* footer height */
width:33.33%;
}
#col0{ left:0%; width:30%; } /* left = 0 */
#col1{ left:30%; width:40%; } /* left = 0 + 30 */
#col2{ left:70%; width:30%; } /* left = 30 + 40 */
/* Colors */
#header{ background:#bbb; }
#col0{ background:#ccc; }
#col1{ background:#ddd; }
#col2{ background:#eee; }
#footer{ background:#aaa; }
​

Resources