A method to distribute elements evenly in a container using CSS appeared on Smashing Magazine today.
I recently had to use Javascript to achieve the same effect for elements of variable width, but the method presented on SM made me wonder if it was possible to do this without Javascript.
There's this question, where gargantaun says:
IMHO, and you probably don't want to hear this, but the design is probably flawed. It's common knowledge that distributing items evenly across a layout with CSS is a pain, so designers should avoid it.
But I can't tell the designer to change his design, and I don't agree that the shortcomings of CSS should limit designers.
Anyway, here's what I have in HTML (translated and simplified):
<div id="menu">
<ul>
<li>Home</li>
<li>News</li>
<li>Theme</li>
<li>Activities</li>
<li>Contact</li>
</ul>
</div>
in CSS (irrelevant properties removed and simplified):
#menu li { float: left; margin-right: 20px; }
#menu a { display: block; padding: 0 1em; }
and in Javascript:
function justifyMenu() {
var menuItems = $$("#menu li");
var menuWidth = $("menu").getWidth();
var totalWidth = 0;
menuItems.each(function(e) {
totalWidth += e.getWidth();
});
var margin = (menuWidth - 4 - totalWidth) / (menuItems.length - 1);
margin = parseInt(margin);
menuItems.each(function(e) {
e.setStyle({ marginRight: margin + 'px' });
});
menuItems[menuItems.length - 1].setStyle({ marginRight: '0' });
}
And here's a scaled-down screenshot (see how the menu aligns with the header image):
Any idea how I can achieve this without Javascript?
Of course this is exactly what the table element is for. It's sad and hilarious at the same time to see people twist themselves into a gordian knot with CSS, most of them not even knowing why they're avoiding tables.
Whatever reason you might have dreamed up to reject tables, it can't possibly be worse than depending on Javascript to layout your page.
Yes, I know this is not the answer you were looking for, but golly, it's so obvious.
There have been casual claims that tables are the obvious solution, however, there hasn't been any real discussion of how to implement it. I'll show you that displaying divs as a table is the right way to do this, but it is not as easy as centering all of the cells and setting an automatic width. The problem with this is that you have no control of the outer margins of the further-most left and right cell-contents. They both are inset from its containing box an arbitrary amount you cannot control. Here's a work around:
First, a slight modification of Guder's html:
<div id="menu">
<ul>
<li class="left">Home</li>
<li>News</li>
<li>Theme</li>
<li>Activities</li>
<li>Contact</li>
</ul>
</div>
Now the css:
#menu {display:table; width:// some width in px //}
#menu ul {display:table-row; width: 100%}
#menu li.left {display: table-cell; text-align: left; width: 20px; white-space:nowrap;}
#menu li {display: table-cell; text-align: right; width: auto;}
Now, we have full control of the outer-most sides of the menu, which align with the far-left and far-right sides of the containing box, and the distance between each element is consistent. You'll notice that I used a trick to get the furthest left cell to be the exact-width of it's content. I set the width property to a small size obviously below what its contents would normally be. I then set the white-space to no-wrap, which stretches the cell the least amount to fit the text of the cell. You can see here an image which shows the effect of this (using different html elements):
The beauty of this code is that it can accept however many cells and text-widths, without any knowledge of their actual widths, and distribute them evenly across the page. All the while, left and right elements reaching their perimeters, and ofcourse we have all our html in divs, no browser or internet geek is mislead to believe we're presenting tabular data. No known compromises here!
This is what display:table-cell is supposed to achieve - however, the IE's just don't do it, and FF<3 has problems with it too, I believe.
These styles work in FF3, Chrome, Safari, and (I think) Opera 9:
#menu ul {display:table;padding:0;}
#menu li {display:table-cell;text-align:center;}
But you'll need a fair few hacks to get them working in the usual, commercial set of browsers.
Even though Colin Brogan's answer provides solid foundation to approach a "almost there" resolution to the problem, it still depends on text length. If text is too long, the "cell" will be wider and thus have more space on the left. I tried to address the problem based on the code presented in his answer, but I concluded that the problem has not a real possible solution with tables or fake-tables (display:table-cell).
So we'll have to wait for CSS3 flexible box model to be more widely supported (you can check updated support here). In the meantime, you can use the Flexie polyfill to patch browsers that don't support it.
If you want to check how it'll look like on WebKit now (without needing polyfill), you can try the following CSS:
#menu ul {
display: -webkit-box;
-webkit-box-orient: horizontal;
-webkit-box-pack: justify;
width: 940px;
list-style: none;
padding: 0;
border: 1px solid gray;
}
#menu li {
border: 1px solid silver;
}
Notice it only uses WebKit prefixes. You should add prefixes for the other browsers aswell if you decide to take it to production website.
This approach does accept an unknown amount of items and text-widths, without any knowledge of their actual widths, and distribute them evenly across their container (in this case, #menu ul).
If you decide to be conservative, the approach suggested by Colin Brogan is the most acceptable given that you keep your texts on the same approximately length. If not, wider spaces will start to show.
Yes, you can do it, as long as the widths of the elements to be distributed are known in advance. But it's a bit messy.
The trick is, you want a spacing between each element of ‘(Wp-sum(Wc))/(Nc-1)’, that is width of the parent element minus the total width of all the child elements, divided equally between the number of gaps between the elements.
Because CSS doesn't have the ability to do expressions, we have to hack it a bit. First we add a margin to the parent element of the size ‘sum(Wc)’, the total width of all child elements. So now the parent has width ‘(Wp-sum(Wc))’, and we can use a padding value in % relative to that width.
So for example, for four images of sizes 10px, 20px, 40px and 80px respectively, our ‘sum(Wc)’ is 150px. Set that as the parent margin, then the children can have one-third of that width as padding between them.
<style type="text/css">
#nava { width: 10px; height: 20px;}
#navb { width: 20px; height: 20px;}
#navc { width: 40px; height: 20px;}
#navd { width: 80px; height: 20px;}
#nav { margin-right: 150px; white-space: nowrap; }
#nava, #navb, #navc { padding-right: 33.3%; }
</style>
<div id="nav"
><img id="nava" src="nava.png" alt="a"
><img id="navb" src="navb.png" alt="b"
><img id="navc" src="navc.png" alt="c"
><img id="navd" src="navd.png" alt="d"
></div>
The funny tag indentation is to avoid there being any whitespace between images. ‘nowrap’ is necessary because with the parent width set narrower than the page width, it wouldn't otherwise be possible to fit all the elements on the row. Finally, in IE you may need to add a wrapper div around the lot with ‘width: 100%; overflow: hidden’ to prevent unwanted scrollbars if you're spanning the whole page. And certainly you'll want to be in Standards Mode.
This can work with textual elements too, if you make them inline blocks so you can add padding, and you size them explicitly in ems. It won't work if the sizes of the child elements are not known in advance (eg. they contain dynamic content), as you won't know the ‘sum(Wc)’ value to use.
To be honest I would probably just use a table. The table layout algorithm copes very smoothly with calculating how to distribute spare table width. (Use ‘table-layout: fixed’ for best results with known-width cells, or ‘auto’ to respond to dynamic contents.) This way you also don't have to worry about pixel rounding errors.
If you were using text-based sizes (em, ex) it'd be a lot easier. You can then deal in letters rather than pixels.
Example: The whole thing is 30 capital letter Ms wide. You can then use the width of each nav element (based on its textual content) and do your math statically from there.
Here is the code in jQuery format for anyone who finds it useful
function justifyClients() {
var menuItems = $("#clients-wrapper ul li").get();
var menuWidth = $("#clients-wrapper ul").width();
var totalWidth = 0;
$("#clients-wrapper ul li").each(function(i,e)
{
totalWidth += $(e).width();
});
var margin = (menuWidth - 4 - totalWidth) / ($("#clients-wrapper ul li").length - 1);
margin = parseInt(margin);
$("#clients-wrapper ul li").each(function(i,e) {
if(i < $("#clients-wrapper ul li").length - 1)
{
alert(i + " " + $("#clients-wrapper ul li").length);
$(e).css('margin-right', margin);
}
});
}
$(document).ready(function() {
justifyClients();
});
The top answer didn't work for me, and GarciaWebDev's answer won't do it for me yet because I need to support a few other browsers, including IE8.
This method worked for me. The idea is to make a containing element text-align: justify and to make the elements to distribute display: inline-block.
HTML:
<div id="menu">
<ul>
<li>Home</li>
<li>News</li>
<li>Theme</li>
<li>Activities</li>
<li>Contact</li>
<li class="filler"></li>
</ul>
</div>
CSS:
#menu {
text-align: justify;
}
ul {
margin: 0;
padding: 0;
}
#menu li {
display: inline-block;
}
.filler {
width: 100%;
height: 0;
}
AFAIK there is no way to achieve this just with CSS.
Anybody correct me if this is wrong, pls.
If you use the Yahoo! User Interface Library (YUI) grids.css, it might work.
Demo - http://codepen.io/vsync/pen/tFwxu
all you need if to make the list itself text-align:justify and then add some pseudo item top the end of it and make it fill all the width, to trick the list into justifying all it's items across it's total width.
Trevor Dixon's improved variant (without extra <li>)
HTML
<ul>
<li>Home</li>
<li>News</li>
<li>Theme</li>
<li>Activities</li>
<li>Contact</li>
</ul>
CSS
ul {
margin: 0;
padding: 0;
}
ul li {
display: inline-block;
text-align: justify;
}
ul:after{
display: inline-block;
content: '';
width: 100%;
height: 0;
}
Thanks to the CSS3 Flexbox module, this is possible with two lines of CSS.
Check the Browser compatibility table for Flexbox
HTML
<div id="menu">
<ul>
<li>Home
</li>
<li>News
</li>
<li>Theme
</li>
<li>Activities
</li>
<li>Contact
</li>
</ul>
</div>
CSS
ul {
display: flex;
}
li {
flex: 1; /* Short hand for flex-grow: 1 and flex-shrink: 1 */
}
Output:
ul, li {
margin: 0;
padding: 0;
}
ul {
display: flex;
list-style: none;
}
li {
flex: 1;
text-align: center;
}
<div id="menu">
<ul>
<li>Home
</li>
<li>News
</li>
<li>Theme
</li>
<li>Activities
</li>
<li>Contact
</li>
</ul>
</div>
Related
I have a 100vh flex container, direction column.
Below it I have a dynamic number of flex items with the same height.
This flex items altogether take all vertical space:
<div>
<ul class="container">
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
</ul>
</div>
and css:
ul {
display: flex;
flex-direction: column;
height: 100vh;
}
li {
flex: 1 1 auto;
}
The items contain text. And I want to fit the text to the height of the item. So I use js, with viewport units to calculate the right font size:
var lis = document.querySelectorAll('li');
var fontsize = (100 / lis.length) * 0.8;
document.querySelector('.container').style.fontSize = fontsize + "vh";
Here is the full working fiddle I just described.
My problem is that if a flex item contains text enough that it wraps onto one or more new lines, the approach does not work anymore.
<div>
<ul class="container">
<li>1</li>
<li>2</li>
<li>multiline becomes a problem with this approach</li>
</ul>
</div>
Here is the demonstration of the problem.
To calculate font-size for a multi line item, I need to know how many lines it occupies, but that in itself depends on font-size. So it is a problem that eats its own tail.
My approach
A possible approach I can think of would be the following:
1 Detect number of li's
2 Trigger font-size calculation as seen above and apply
3 Calculate if any lis text will wrap onto new lines and how many (how?)
3.a. If no texts wrap into new lines stop here.
3.b. If there is text that wraps into new lines
3.b.1. Sum number of li's + all new lines on all multiline li's
3.b.2. Re-trigger font-size calculation with this number and apply
3.b.3. Calculate again if any li's text will wrap onto how many new lines, and compare with before font-size change.
3.b.4.a. If there are the same number of new lines, stop here.
3.b.4.b. If there are more new lines, repeat from step 3.b.1
But this approach seems dirty, and can lead to many steps of font size calculation and adjustment. Plus I am not sure how could I perform step 3.
So, how to approach this problem?
This question has been flagged as possible duplicate of this other question. But that question specifically asks for fitting the text into one line, which is a very different matter.
That said I could be taking some hints out of some of the answers, as they attempt to guess if a text overflows a div. In particular I am curious about this answer as #Hoffmann specifically says to attempt to avoid the loop problem I mention in my approach. I'll attempt to understand the code of his plugin, now maintained by someone else here: https://github.com/BrOrlandi/big-text.js/blob/master/big-text.js
Thank you
Using a monospaced font, intrinsic units (vh only not vw), justify-content: spaced evenly, line-height are major factors used in demo.
/* Reset */
* {
margin: 0;
padding: 0;
}
/*
- Serif and Sans Serif fonts vary greatly, monospaced
fonts are a lot easier to use.
- Assign the primary font on :root so if an explicit font-
size is set elsewhere rem units reference font-size on
:root directly.
- The font shorthand is as follows:
font: font-weight, font-size/line-height, font-family
line-height set at 10vh fits 100vh high <ul> well.
*/
:root {
font: 400 6vh/10vh Consolas;
}
html, body {
width: 100%;
height: 100%;
}
body {
overflow-x: hidden;
overflow-y: scroll;
margin: 5vh 15vh 0 10vh;
}
/*
Assign max-height: 100vh to the element containing the <ul>
*/
main {
width: 96%;
max-height: 100vh;
}
/*
justify-content: space-evenly is exactly what it says
*/
ul {
display: flex;
flex-direction: column;
justify-content: space-evenly;
height: 100vh;
}
li {
flex: 1 1 auto;
}
<main>
<ul>
<li>One morning, when Gregor Samsa woke from troubled dreams, he found himself transformed in his bed into a horrible vermin.</li>
<li>He lay on his armour-like back, and if he lifted his head a little he could see his brown belly, slightly domed and divided by arches into stiff sections.</li>
<li>The bedding was hardly able to cover it and seemed ready to slide off any moment.</li>
<li>His many legs, pitifully thin compared with the size of the rest of him, waved about helplessly as he looked.</li>
<li>"What's happened to me?" he thought. It wasn't a dream.</li>
</ul>
</main>
I am creating a mega menu trying to keep to current standards; CSS, jquery, bootstrap.
Google Images - Mega Menu
My menu is for product categories, which I want dynamically created in columns newspaper style. Easy enough, I have that working nicely. It requires a fixed height, which makes it overflow horizontally.
My current thinking is to, onload, increase the heights of each sub menu until there is no horizontal overflow. I can get it working with some manual intervention, which defeats to purpose of a dynamic layout.
.container {
width: 800px;
height: 100px;
display: flex;
flex: 1 1 auto;
}
.container .wrap {
display: flex;
flex: 1 1 auto;
flex-flow: column wrap;
align-content: flex-start;
}
.container .wrap .item {
width: 150px;
}
<div class="container">
<div class="wrap">
<div class="item">Item 1<br>a<br>b</div>
<div class="item">Item 2<br>a</div>
<div class="item">Item 3<br>a<br>b<br>c<br>d</div>
<div class="item">Item 4<br>a</div>
<div class="item">Item 5<br>a</div>
</div>
</div>
This style works perfectly aligning items top to bottom, left to right, as required.
Now I am trying to increase the height of each sub menu as required. Best solution is to detect width overflow and increase height to compensate.
I've tried native JS and jQuery, I seem to be getting stuck running it in a function. I can detect overflow and increase height, as my code below. What I want is to have the if statements in a loop and exit when no more overflow, and end up with a perfect fit.
EDIT
Current working solution
$(function () {
$(".container").each( function( index, element ){
var my_height = $(element).outerHeight();
if( $(element).prop('scrollWidth') > $(element).outerWidth() ) {
while( $(element).prop('scrollWidth') > $(element).outerWidth() )
{
my_height += 100;
$(element).css('height', my_height + "px");
}
}
});
});
Works exactly as intended.
EDIT
Updated question. Is there a better solution? Something that doesn't involve looping over every item every page. Pure CSS would be nice, but don't think it's possible just yet.
Solved my transition issue. When trying to update the height in a loop as above, transition CSS interferes and creates an infinite loop. Was an easy fix, I added a new class to .container .transition and added $(element).removeClass("transition"); to the start or the loop and $(element).addClass("transition"); to the end. This removes the transition CSS from the inner loop and adds it back at the end.
FINAL EDIT
My first attempt was using css columns, but I couldn't get it working to my spec. It wasn't until reading the accepted answer below I revisited columns and after some testing got it working.
Ref https://developer.mozilla.org/en-US/docs/Web/CSS/columns
There is a way of doing this using pure CSS using the column CSS properties:
Base CSS:
.container {
width: 800px;
}
.container .wrap {}
.container .wrap .item {
width: 150px;
}
To have columns of a fixed width:
.container .wrap {
column-width: 125px;
}
To have a set number of columns:
.container .wrap {
column-count: 5;
}
JSFiddle
Another answer giving details about browser support
So I'm trying to get two individual divs which are close in proximity to share one background image but I'm not sure if this is possible. I've uploaded two pictures, the second being designed for a smaller screen (just to further explain what I mean) http://imgur.com/a/2dypd . I can't imagine two separate background images would work as they wouldn't line up when resizing the window.
The only solution I can think of is creating two plain white divs to overlay on one single div but that seems like a dodgy way to go about it. I'm not expecting a hunk of code to be written for me, maybe just explain if it's possible and a reference so I can learn. Cheers.
Based on #cale_b's comment, you can set the same background to both div's and then use the background-position property to do the delusion of background sharing.
Then you can use media queries to make it look good in mobile too.
Here you've got a simple example that looks like the one you posted:
#wrapper {
width: 800px;
font-family: sans-serif;
}
#top {
height: 200px;
margin-bottom: 20px;
background-image: url("https://placekitten.com/800/400");
background-position: 0 0;
line-height: 150px;
color: #FFF;
font-size: 32px;
text-indent: 50px;
}
#bottom {
width: 500px;
height: 100px;
background-image: url("https://placekitten.com/800/400");
background-position: 0 -220px;
}
#bottom ul {
list-style: none;
}
#bottom ul li {
display: inline-block;
list-style: none;
padding: 0 10px;
line-height: 50px;
color: #000;
font-size: 24px;
}
<div id="wrapper">
<div id="top">
I'm a banner
</div>
<div id="bottom">
<ul>
<li>I'm</li>
<li>a</li>
<li>menu</li>
</ul>
</div>
</div>
As I understand, you want to use only one image copy of one image over two div and you dont want to use any overlay.
So you can do the following:
On the bottom div, use background-position-y:-100px or any other desired value. This way you push the image upwards.
This looks promising so far, but you will face an issue with the size of the background size specially if you are making a responsive web page.
I would say that background-size:100% 100%for both div would do the job yet it will make the image stretching (unless you go really responsive).
I still recommend using an overlay or even a ready made image. But if you insist on using two div then the above steps should be enough while you have to make your design suitable for this image.
N.B. keep in mind that you might need to use background-repeat:no-repeat
I know a lot of responsive design uses percentage width and absolute positioning to adapt to screen widths of different media types. But what if we can take advantage of the float right css style that is not commonly used but highly cross browser compatible?
Demo: http://jsfiddle.net/3A89Q/48/
.wrapper { width: 70%; margin: 0 auto; }
div, span { display: block; float: left; position: relative; }
.wrapper > div { width: 60px; }
.b1 { background-color: blue; height: 132px; }
.b2 { background-color: red; height: 88px; }
.b3 { background-color: green; height: 44px; }
.test { background-color: black; max-width: 160px; min-width: 100px; float: right; border: 2px solid black; }
.test div { width: 16px; height: 16px; background-color: yellow; margin: 2px; }
<section class="wrapper">
<div class="b1"></div>
<div class="b2"></div>
<div class="b3"></div>
<span class="test">
<div></div>
<div></div>
<div></div>
</span>
</section>
My idea is to shrink a right floating element to a minimum width without using percentages. This shrinking process should only occur on the condition of neighboring elements restricting the available space of the element when the window width is reduced in size. If the available space available to said element is not restricted, the element will increase its width to a max length. So virtually the element has a max and a min width governing a given range of flexibility in size. (Note: This range of width can be easily demonstrated by shrinking the results window to a small size in the jsfiddle demo I have linked above.)
At this time if the right floating element merges into a left floating element, it will float down underneath the left floating element maintaining its max width.
My desired result is to have this right floating element shrink to its minimum size before floating down under its neighbor. Once the element reaches its min-size it will drop down under its neighbor and in turn increase its width to fill in the remaining space up to its max width, and begin to repeat the process of adapting to its available space while floating right.
My question is, can my desired results be accomplished by just using css / css3? If not, is there a JavaScript / jQuery plugin that performs this functionality?
I have linked a jsfiddle demo above to help you understand and utilize a solution to this idea.
Thank you for your help.
Have you though about using CSS media tags to target different screen sizes?
here is a reference link.
http://webdesignerwall.com/tutorials/css3-media-queries
A jQuery approach would be using a resize event handler, and adjusting the CSS accordingly with jQuery. This will be for only when the browser window has been resized. Alternative during document when ready, you can calculate widths and heights dynamically.
see this stack solution Using jQuery To Get Size of Viewport
here is another reference link
http://api.jquery.com/resize/
I am currently developing a web application using jQuery.
The layout for the same goes as shown in the figure given below:
The orange color box at the very back should be 100% in height and width with some margin like 5px or so.
The logo and the tab-bar are placed as shown and are about 50px in height. But tab-bar should take size as shown with some margin.
The tab content should occupy the remaining height and should scroll for the contents it occupies.
Similar structure is required for the internal menubar and tab content.
Can anyone please suggest the layout method to employ?
Or how can I manipulate different heights/widths?
The requirement also suggests a responsive window i.e. the width/height to manipulate on resize.
The jsFiddle I said I'd make.
As you'll see, I make use of jQueryUI for the "tabs" layout and simply "add" a few things. The few things I "Add" are simple and the jQueryUI alreqady provides a strong CSS with which to manipulate to get desired result. Also attached to that page is a theme-switcher, so you could see what it would look like using different jQueryUI Default Themes.
I'll try to explain the process as shortly as possible without being to vague.
HTML
I first start with a basic page wrapper. Not too necessary, but it provides a nice "element" with which to work inside of and possibly make manipulations for page layout change in otherways in the future. For now it simply holds our page "padding" of 5px. The HTML and BODY tags will be set to a default and should not be manipulated beyond that as height and other properties begin to take different meanings for these tags in different browsers.
I then place 2 divs inside this wrapper, again, these could be done without depending on your needs. I like these 2 divs and use this alot because it provides "vertical align -> middle" as one might expect. The first, parent, is a div with class table. This will have its display set to table to provide a "table-like" layout but still have the ability to do things like "round the corners" or, as in my case, set height! The second, child, is the same except it will have a class and style as table-cell, respectively. This allows us to set something like vertical-align: middle; and ensure that this element is in the vertical middle of the page/table element. Again, with your layout, this may seem unneccessary, but I don't know your full expected end result and I'm trying to give as much "fluid dynamics" to the page as possible.
Finally, I first insert the jQueryUI tabs HTML in their expected layout, with 2 small differences. I place our "logo" in a custom span tag just before the ul. I also take the ui-tab-panel(s) and place them in their own container. This helps us adjust the height of our tabs area as needed. I also gave this container overflow, so even tho overflow maybe hidden on the body, it's still available for the tabs. (see also: small blog i wrote on jQueryUI Tabs)
<div class="page-wrapper">
<div class="table">
<div class="table-cell">
<div id="tabs">
<span class="my-logo">
<img src="http://www.w3.org/html/logo/downloads/HTML5_Logo_512.png" alt="logo here" />
</span>
<ul>
<li>Nunc tincidunt</li>
<li>Proin dolor</li>
<li>Aenean lacinia</li>
</ul>
<div class="ui-tabs-panel-container">
<div id="tabs-1">
<<p> ... </p>
</div>
<div id="tabs-2">
<p> ... </p>
</div>
<div id="tabs-3">
<p> ... </p>
</div>
</div>
</div>
</div>
</div>
</div>
CSS
As I mentioned before, jQueryUI provides us with a strong CSS to work with already. As you might have noticed, I made use of some of this by using their predefined class names throughout the HTML. This established things like background, color, and even font-family and more! Now that that is over with, let's layout our page mechanics first. As I mentioned, I give a very "direct" set of properties to HTML and BODY. This will help eliminate "Cross-browser-issues". I also provided a background color, tho you could set that at one of the children levels. This was done just to show you where HTML, BODY exist.
I then set our "frame" elements. .page-wrapper will provide our page wrapping, sizing will come from within, so there is no need to deal with it here. The .table and .table-cell provide display exactly as their name suggest. As previously mentioned, this provides a nice ability to maintain an element in the exact "center" of something, even vertically!
Now we manipulate our tabs and content. I use #tabs throughout to maintain "name-spacing". This will not only help with any "css overrides" on jQueryUI presets, but also helps keep page layout confusions to a minimum. This is always a good thing.
The first thing I manipulate is the placement and setting of our custom span for the logo. Then, of course, I have to change the ul to next to it. Thus I look at the CSS for the uls class. If I open edit tools in a browser, I can see the ul is given the classname ui-tabs-nav and I can see it has a margin setting. If I play with the margin-left of this ul I can see that nothing is affected but the left side of the ul. PERFECT! Here is what I must manipulate to set our log in its "own space".
Finally, I simply set our tabs container (given custom class name, ui-tabs-panel-container, made to match jQueryUI) to have overflow, so that if any content exceeds our page height, it can still be scrolled within this element.
html, body {
background-color: #ADDFFF;
height: 100%;
padding: 0;
margin: 0;
overflow: hidden;
width: 100%;
}
.page-wrapper {
padding: 5px;
}
.table { display: table; }
.table-cell { display: table-cell; vertical-align: middle; }
#tabs .my-logo {
display: inline-block;
float: left;
height: 2em;
margin: .5em 0 0;
padding: 0;
width: 2em;
}
#tabs .my-logo img {
max-height: 100%;
max-width: 100%;
float: left;
}
#tabs .ui-tabs-nav {
margin-left: 2em;
}
#tabs .ui-tabs-panel-container {
overflow: auto;
}
JS
Finally, the easy work. I write a function to set the height of our tabs content area, since it will be "filling" the rest of the page. This take a little thought, but not hard to figure out. With the function written, I simply add it to the window resize event and call that event right after. This way it's resized on load, thus giving us our "end height" for first view. I also establish the tabs, although not much work there since I'm just making "default tabs". Feel free to experiment, go wild!
// the following will resize our tabs content area and account for all the spacing neccessary
function setContentHeight(e) { return $(window).innerHeight() - $(this).offset().top - 10; } // -10 to account for padding
$(function() { // our on page load call
$("#tabs").tabs(); // establish tabs
// add ability to resize tabs content area on window resize, then call resize event
$(window).resize(function(e) { $("#tabs .ui-tabs-panel-container").height(setContentHeight) }).resize();
})
As for the layout of tab content, it's all up to you and your imagination. Hopefully this will give you a good idea of where to get started though! Good luck!
You could use something like Blueprint CSS:
http://www.blueprintcss.org/
Here's a very quick and dirty layout (not using blueprint CSS, just plain CSS), as a general guideline. It still needs work, but it could be used as a starting point:
<html>
<head>
<style>
html, body {
margin: 0;
padding: 0;
width: 100%;
height: 100%;
overflow: hidden; /* hide page scrollbars */
}
div {
margin: 0 auto;
padding: 0;
border: 1px solid black; /* for debugging */
text-align: center;
}
#header {
width: 100%;
position: relative;
overflow: auto;
}
#header > div {
height: 5%;
float: left;
}
#logo {
width: 23%;
}
#spacer {
width: 1%; /* -1% for borders */
}
#tabbar {
width: 75%;
}
#tabContent {
}
#tabContent > div {
width: 100%;
}
#tabContentMenuBar {
height: 5%;
}
#tabContentMain {
min-height: 80%;
}
</style>
</head>
<body>
<div id="header">
<div id="logo">Logo</div>
<div id="spacer"></div>
<div id="tabbar" class="fullWidth">Tab bar</div>
</div>
<div id="tabContent">
Tab content
<div id="tabContentMenuBar">Tab content - menu bar</div>
<div id="tabContentMain">Tab content - main content</div>
</div>
</body>
</html>