How do you make a floated element fill the remaining horizontal space when it is between its fixed width siblings? - css

I am trying to create an accordion menu with multiple floated elements. I want all of the inactive menu items to collapse to a small fixed width (40px or so) and the active item to expand to the remaining width. I want the menu to be responsive/elastic, so only the inactive menu items will have fixed widths.
Below is an example of what I want my menu to look/function like (without using jQuery to set the widths)...
Accordionza - CodeCanyon.com
I was able to accomplish the desired effect when only two menu items are displayed by floating one of the elements and giving it a fixed width, while NOT floating the elastic item and giving it a width of 100%.
Two Columns (Works)
<style type="text/css">
#one {
float:left;
width:40px;
}
#two {
width:100%;
}
</style>
<div class="row">
<div class="col" id="one">One</div>
<div class="col elastic" id="two">Two</div>
</div>
Four Columns - Elastic In Between (Does Not Work)
<style type="text/css">
#one, #three, #four {
float:left;
width:40px;
}
#two {
width:100%;
}
</style>
<div class="row">
<div class="col" id="one">One</div>
<div class="col elastic" id="two">Two</div>
<div class="col" id="three">Three</div>
<div class="col" id="four">Four</div>
</div>
Please note: applying float:right; to the elements to the right of the elastic item did not work either...
The problem is that if the elastic element is NOT on the end of the row, then the menu items do not remain on a single row. Please examine the fiddle below to see what I mean...
jsfiddle
So how do I apply this desired elasticity to the elements that reside in between their siblings? I really really want to keep the markup as simple as possible. Thanks in advance!
Update: I am getting close to a solution, however there is a slight problem with every method I've attempted. I will break them down, along with the issues I'm running into with each one.
METHOD 1: display: table-cell; (Suggested by onetrickpony)
Seemed like the answer, however there will not always be contents (text or html) inside the slide elements, and elements formatted with the display: table-cell; property do not recognize applied widths unless there is content inside of them. So this only works if I have content inside the slide... (I could modify the markup of my slider, but I would like to keep it the way I have it).
METHOD 2: CSS calc() (Also suggested by onetrickpony)
Not supported by some of the browsers I would like it to be... CaniIUse.com Browser Support Chart for calc(). Another excellent possibilty! One I did not know existed, and could be utilized if I made a fallback JS script for older browsers (want to avoid).
METHOD 3: Flexbox (Also suggested by onetrickpony)
Probably my favorite solution, but limited support is making me timid. Also could be used along with a fallback script. I learned about this a while back, and this is the future of CSS and layouts. Our salvation! Can't wait for full support...
METHOD 4: jQuery (Suggested by Tomasz Golinski)
What I was originally going to use, but decided I wanted to see if there was a CSS method that could be used instead. I have had some issues when using jQuery to set the width of elements. Mainly when the container is resized, and the script calculates the appropriate width while the container is resized.
So, the kind people who responded to my question have provided me with viable solutions to this issue. Any of the below is certainly an acceptable method to do what I am asking. I am simply seeking an answer that is more of a common CSS method. I am hoping that it is possible to accomplish this with some combination of styles I have not tried. I will admit I think Tomasz is correct- it cannot be done. I am leaving this question open just in case someone has a solution for me. Both Tomasz and onetrickpony have given me great answers. But I am still seeking a CSS-only solution that is widely supported by older browsers- and new, that I do not need to include a secondary script for, and that works without the need for characters inside the elements. Just want to see someone prove us wrong (that it is possible with good old fashioned CSS). If this magic answer does not come, I will be marking onetrickpony's answer as the best solution due to the fact it is CSS based, and he provided multiple solutions that are clean and simple. A combination of his flexbox CSS and Tomasz jQuery (as the secondary script) will most likely be what I use. Thanks!

If you're set to use floats, calculate the width of your "elastic" column by subtracting the widths of other columns from 100%. Example:
<div class="row cols-4">
<div class="col" id="one">One</div>
<div class="col" id="two">Two</div>
<div class="col elastic" id="three">Three</div>
<div class="col" id="four">Four</div>
</div>
CSS:
.cols-4 .elastic{
width: calc(100% - 45px * 3);
}
/* add more rules for other possible variations here */
http://jsfiddle.net/QM4LZ/
But a cleaner and easier approach is to use flexible boxes. This is exactly what they were designed for.
.row{
display: flex;
}
.col{
flex: none; /* <- don't flex */
width: 45px;
}
.elastic{
flex: auto; /* <- flex */
width: 100%;
}
http://jsfiddle.net/F7sxU/
It's also possible to achieve this with tables (fiddle), but you'll most likely run into some limitations when adding the real content and you need more wrapper elements.

the previous answer does resolve the issue however there are some problems with #onetrickpony's solution
example #1 will not work properly with dynamic number of items.
example #2 in most browsers it will work but not all browsers do support flexible boxes.
here is simple javascript code
jsFiddle: http://jsfiddle.net/aQEt3/5/
var count = $('.row').children().length; // counts how many items are in the entire row
var totWidth = $('.row').width(); // checks total width of the row
var elWidth = totWidth - ((count - 1) * 45); // counts how wide should be the elastic it
$(document).ready(function () {
$('.elastic').css('width', elWidth); // when document is ready, apply the new width to the elastic
});
beware, this is very simple code and there will be some issues if:
*there are 2 or more .row items
*you have more than one elastic class

Related

Bootstrap: Class reference

This may seem like a dumb question, but is there an official bootstrap class reference? I looked on the website and was unable to find one.
I'm looking though some of the examples and I'll see stuff like:
<div class="container-fluid">
How am I supposed to figure out what all the contain-fluid tag does? Am I expected to dig through the css for every class to look at the rules and then divine how it will affect my page? That seems like a quick way to make assumptions and run into problems later.
Is there an official reference somewhere that I'm missing? I've seen some class lists compiled by third parties, but it seems like those are always going to lag behind new changes and may contain assumptions of intensions.
Not official but current as of 2/2016 https://bootstrapcreative.com/resources/bootstrap-3-css-classes-index/
Printable pdf and a sortable table with descriptions to help sort through the list of classes.
http://www.tutorialspoint.com/bootstrap/bootstrap_quick_guide.htm contains a very good reference for many of the bootstrap layout and css components.
Bootstrap 3 moved to a "mobile first" approach. .container is really only there in instances where you need/want a boxy layout. but, if you exempt the div.container-fluid entirely, you're left with a fluid layout by default.
for example, to have a two-column fluid layout, simply use:
<body>
<header>...</header>
<div style="padding:0 15px;"><!-- offset row negative padding -->
<div class="row">
<div class="col-md-6">50%</div>
<div class="col-md-6">50%</div>
</div>
</div>
<footer>...</footer>
</body>
The 2.x .container-fluid was replaced by .container in Bootstrap 3.x (http://getbootstrap.com/getting-started/#migration), so the .container is fluid, but it's not full width.
You can use the row as a fluid container, but you must tweak it a little to avoid a horizontal scroll bar. Excerpt from the docs (http://getbootstrap.com/css/#grid)..
"Folks looking to create fully fluid layouts (meaning your site stretches the entire width of the viewport) must wrap their grid content in a containing element with padding: 0 15px; to offset the margin: 0 -15px; used on .rows."
More on changes in 3.x: http://bootply.com/bootstrap-3-migration-guide
Demo: http://bootply.com/91948
UPDATE for Bootstrap 3.1
container-fluid has returned again in Bootstrap 3.1. Now container-fluid can be used to create a full width layout: http://www.bootply.com/116382

css only - Table overflow with fixed header

I am trying to build a table which is scrollable in the x and y directions if the content is bigger than the container. I also want the header to always be visible at the top. I've got the first part working, and the header is always visible at the top, however the header column sizes do not match up with the table table sizes.
I've created this fiddle:
http://jsfiddle.net/xxQQS/1/
I am after a CSS only solution.
EDIT: There seem to be a quite a few people who seem to think that this cannot only be done with CSS. This may be true, however please don't just post to say 'no this can't be done'. If you can explain why this can't be done without CSS I'll accept your answer.
Create a clone of your table. For the first table, hide all rows except the headers using visibility: hidden. Hide the header of the other table using visibility: hidden. Place your tables inside divs with overflow properties set as follows:
<div style="overflow-x: hidden; width: 400px;">
<div style="overflow-y: hidden; height: 20px;">
<table id="head-only">
</table>
</div>
<div style="overflow-y: scroll; height: 100px;">
<table id="body-only">
</table>
</div>
</div>
May be for this you have to use JS. Check this http://www.tablefixedheader.com/
I too was searching for a solution for sticky headers to use it in my site. Finally found a Jquery plugin that seamlessly does this sticky header part.
https://github.com/jmosbech/StickyTableHeaders
You need not add any CSS, the plugin takes care of it. It clones the table header during scroll. Initialization is pretty simple
$('table').stickyTableHeaders();
Hope this helps :) As told in other answers, this cannot be achieved purely through CSS I guess.

Construction of layout in CSS

How do i go about piecing each and every div together?
I'm learning how to code in CSS and i'm fairly new, and i want to piece 3 - 8 pieces of the divs in each row. Once i've pieced some together, they appear uneven inside the dreamweaver IDE (and also inside the browser display).
Also, how do i get to resize them automatically? I've been trying width:100%; but all i'm getting is weird resized shapes and sizes.
If you don't get what i mean, my webpage technically looks like this
----------------------------------------------------------------------------------
| |
| background image 1 |
|--------------------------------------------------------------------------------|
| | | | |
| bg img 2 | bg img 3 | bg img 4 | bg img 5 |
| | | | |
|--------------------------------------------------------------------------------|
| |
| background image 5 |
| |
|--------------------------------------------------------------------------------|
but everytime i put my divs in the same row with a containing div for each row, i.e
<div class="container">
<div id="bg1" width:100; height:20;>
<div id="bg2" width:150; height:20;>
<div id="bg3" width: 250; height:20; >
<div id="bg4" width:130; height:20;>
</div>
</div>
</div>
</div>
</div>
it gets all jumbled up at the same location. Am i doing something wrong?
Would appreciate if someone could tell me a step by step solution...
Once again, i want to go about doing:
Construction of website with CSS for the layout.
Auto resizing of entire page according to web browser size.
Thanks.
First, don't use inline styles for prototyping something when you're a beginner. They're too hard to edit live. It will slow the process way way down.
You sound new to this, but that's cool! We all started somewhere.
Create your 5 divs first, and give them each a unique ID. IDs are for things that only appear on the page once. Classes are for things that appear more than once, or might at some future point appear more than once.
Then link a css file that your a separate declaration for each div. You're on the right track with width=100% for responsive design, although in practice it's often something like 92% even for a "full-width" div, because a little spacing is nice, and borders and padding add to the overall width. A 90% width div with 6% padding is always wider than the window itself (greater than 100%) which makes for strange behavior, so keep the box model in mind from the start.
Here are some tips I wish somebody had broken down to me early on:
Nowadays things are a LOT easier than they used to be for rapid prototyping CSS. The best way to figure this stuff out is to edit the stylesheet live in Chrome Developer Tools. Download and install Chrome if you're not using it already. Control click on your div and choose "Inspect Element." Play around in the inspector, and see how all the CSS styles can be edited live by doubleclicking on them and entering new values. If you click the "resources" tab you can see your whole stylesheet at once, and similarly edit the properties, and even add new ones. The best way to see what's happening with sizing is to temporarily declare an outline like:
#mydiv1 {outline: 2px dashed red;}
because outlines don't add to the width of the element, unlike borders. Then when you're done you can remove the outline declarations. Also keep in mind that any changes to a document's CSS in Chrome Dev Tools will be lost when you navigate away. So copy and paste your work into a text editor as you go.
If you're interested in responsive design, which is great, once you're getting good at all of the above, buckle in and read Ethan Marcotte's book:
http://www.abookapart.com/products/responsive-web-design
Marcotte's instructional approach is to start with pixels and then translate into percentages and ems in the stylesheet, but it doesn't need to be that way. You can design "live" with those variables in the browser.
hope this helps!
First of all, get rid of Dreamweaver. It's a hindrance. And has always been buggy. The sooner you get rid of that crutch, the better off you will be.
Secondly, looking at your example, I see a template for the old slice-n-dice photoshop into a table methodology. Replicating that with DIVs in CSS is rather pointless.
Third. If you truly need a table (data) keep it a table. Nothing wrong with that.
Fourth. The key to all of this is understanding floats and what contains floats. Most of the CSS grid systems base everything off of that. I'd take a look at 960.css and start playing with that a bit. It should help point you in the right direction of understanding what is going on.
You could use a <header> tag for the topmost part, and a <footer> tag for the bottom part. Clearly it works also with divs, but in my opinion it's cleaner that way.
That means that you'll have the following code:
HTML:
<header id="img1">
</header>
<div id="img2">
</div>
<div id="img3">
</div>
<div id="img4">
</div>
<div id="img5" class="newrow">
</div>
<footer id="img6">
</footer>
that could represent your desired structure pretty well. To style this, you can use CSS, and there are many possible solutions to the problem. One simple solution would be to set <header> and <footer> to 100% width, and to float all <div>s but the last one to the left, so that the remaining content (the other <div>s, in this case) will be on its right. Then you just have to set the width on all the <div>s, if you want you can even set it in percent, just make sure that it adds up to 100 or else you'll have a gap on the right. Also, you should put a margin-left on the last div to ensure that the content is placed properly.
This could be coded like this
CSS
body > header,
body > footer {
width: 100%;
clear: both;
}
body > div {
float: left;
}
#img2 {
width: 30%;
}
#img3 {
width: 10%;
}
#img4 {
width: 30%;
}
#img5 {
width: 30%;
}
body > div.newrow {
float: none;
margin-left: 70%;
}
You can see a little example of this code here, and you can grab it's code and play around with it here.
but like I said, there are many ways to achieve the layout you want, this is just one example.
As per your layout, what you want, Its better to have semantic HTML markup.
Example
<div class="containerWrap">
<div class="fullWidth"><img src="/imagePath"/></div>
<ul class="container">
<li id="bg1"><img src="/imagePath"/></li>
<li id="bg2"><img src="/imagePath"/></li>
<li id="bg3"><img src="/imagePath"/></li>
<li id="bg4"><img src="/imagePath"/></li>
</ul>
<div><img src="/imagePath"/></div>
<div>
CSS Would be
.fullWidth{
width:100%;
}
.containerWrap ul li{
list-style-type: none;
height:20px;
float:left;
}
#bg1{
width:100px;
}
#bg2{
width:150px;
}
#bg3{
width:250px;
}
#bg4{
width:130px;
}

Vertically center elements in CSS

I have two elements side-by-side. Element 2 is smaller than Element 1. Both elements do not have a fixed height. I need to vertically center Element 2. How do I achieve this using CSS?
Edited:
This is what I have so far:
<div id="container" style="width: 100%;">
<div id="img1" style="float: left;">
<img src="image1.jpg".../>
</div>
<div id="img2" style="float: right;">
<img src="image2.jpg".../>
</div>
</div>
img1's height will always be greater than img2's height. I want img2 to be aligned vertically-center. Hopefully this clarifies what I am trying to accomplish.
The most straightforward and clean way to do it is to use display: table and vertical-align. However, IIRC (it's been a while since I was up on browser compatibility issues) support for display: table and friends is absent from ... some common-then version of IE, perhaps? Anyway, adding other rules to make an adequate fallback if the display: table is ignored might be good.
<div id="container" style="display: table;">
<div id="div1" style="display: table-cell; vertical-align: middle;">
<img id="img1" src="image1.jpg" />
</div>
<div id="div2" style="display: table-cell; vertical-align: middle;">
<img id="img2" src="image2.jpg" />
</div>
</div>
(Of course the styles ought to be in a stylesheet; this is just matching your original example and not knowing the use case.)
The display values table, table-row, and table-cell basically perform exactly like HTML table, tr, and td, but you are permitted to omit any of them (as I do here, using table-cells directly within tables) and the layout engine will do the sensible thing.
Not easily. Some popular hacks include using display: table-cell and a parent using display: table (I don't remember if the valign="center" attribute is needed), or using absolute positioning with top: 45% or so (not precise, but OK for small elements).
To determine the best method, we need to know more about your layout. What are they centered within? Will/can there be a large Y-distance between elements 1 and 2? Does their parent have a fixed height? Do they both have the same parents, or is one a sibling of the other? What method are you using to place them side by side?
Keep in mind that many tricks require additional hacking to work in IE, and that using Javascript is just cheating and will make your site inaccessible/annoying to people with low vision (who may be using script-unaware screen readers), people with scripts disabled (esp. on mobile or command-line browsers that may not support them well if at all), search engines, etc. It's possible using only CSS (though you may have to add some container elements), but the exact method depends what exactly you're doing.
If you only need to support new browsers like Safari (e.g., building webapp for the iPhone), CSS3 offers an elegant approach with no floats or negative margins. All details here: http://www.html5rocks.com/en/tutorials/flexbox/quick/#toc-center
I don't think you can do this reliably without a table. Kevin's solution would probably work, unless you need to support IE (which most of us do). And, in this case, the table markup might actually be smaller than the div-based markup.
Put them both inside another element, give it a min-width and set the left and right margins to auto.

how to make three inside divs the same height?

I have a container div#content, which contains three divs inside. Now, how could I make sure that three divs inside have the same height? Of course, I hope each div's height could be expanded according to its content. For example:
here is what I tried
<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
<html>
<head>
<title></title>
<style type="text/css">
#content{background-color:#DDDDD;width:100%;overflow:auto;clear:both;height:100%;}
#col1{background-color:yellow;width:10%;float:left;height:100%;}
#col2{background-color:red;width:30%;float:left;height:100%;}
#col3{background-color:#AAAAAA;width:10%;float:left;;height:100%;}
</style>
</head>
<body>
<div id="content">
<div id="col1">
<script language="javascript">
for(i=0;i<1000;i++){
document.write(i+"<br />");
}
</script>
</div>
<div id="col2">
<script language="javascript">
for(i=0;i<100;i++){
document.write(i+"<br />");
}
</script>
</div>
<div id="col3">
<script language="javascript">
for(i=0;i<10;i++){
document.write(i+"<br />");
}
</script>
</div>
I regularly get bashed by the CSS purists for this suggestion, but whenever I run into a problem like this for which – to the best of my knowledge – CSS simply doesn't offer a solution (no, "change your design" doesn't count!)...
I recommend using a table for that part of your layout.
Tables do equal vertical sizing easily and correctly across all major browsers. I'll continue to recommend them until CSS offers workable solutions for those problems.
A very useful technique for creating divs of equal height is to emulate it with a technique called "Faux Columns". This was an idea first suggested by Dan Cederholm (You can read his original article here), and has since evolved. You can see a good tutorial here. If you need it in a liquid layout environment, you might want to read this article.
Basically, the idea builds on NOT trying to force the divs to be of equal height, but have a wrapper of the three divs with a background-image that simulates the background of the columns. This approach works consistently among all modern browsers (ie6 even counts as modern in this context). The negative part is that you'll need a background image that is at least as wide as the page is allowed to expand. i.e. X pixels wide and 1px high.
First of all: if you have an equal attribute on different elements, please adhere to the DRY principle (Don't Repeat Yourself) and write it like so:
.content div{
border:1px solid #404040
}
That way you'll only have to change it in one place.
Now about your question. For a dynamic height, I'd specify that the div's should have a height of 100%, so they fill all the vertical space. This doesn't work nicely cross-browser so look for a hack that does this. If you don't want the div's to fill up the content div, put another div inside the content div and put that around the 3 divs.
So:
<div id="content">
<div class="innerContent">
<div class="1">Lorem Ipsum</div>
<div class="2">Lorem Ipsum</div>
<div class="3">Lorem Ipsum</div>
</div>
</div>
I may be wrong, but I think you either put the same values for the heights in the divs (either in percent or px) or you'll have to do some script (for example in JavaScript) that will check on the content height and set the other heights. I don't think it's doable with CSS. If I'm wrong I'd like to know the answer though:P
You could try it using css for modern browsers (display:table-cell, etc.), however, that will not work in IE6 and IE7.
If IE6 and IE7 are a requirement (I suppose it is...), you can include some javascript just for them using conditional statements and have that javascript set the height of all columns to the tallest. Not really pretty, but the percentages of IE6 and 7 should be going down fast anyway.
By the way, Machine's solution (faux columns) is another solution that works for a lot of designs.

Resources