I need two columns, basically blocks side-by-side, that wrap when necessary for a responsive design.
The issue that I'm running into is that the first column/block is statically sized, but the second column/block needs to fill the remaining width. However, they should still wrap when necessary.
Say the left-most block has a static width of 200px, while the right-most fills the remaining width, BUT with a min-width of 300px. That way it should wrap (the second block placed below the first block instead of on the right side) when necessary.
I've tried a variety of methods to no avail--floating the left block, using absolute position, etc., but I can't get the results I'm looking for.
Hopefully it's possibly using CSS alone, and not using a CSS3 media query to show/hide two different versions. Or resorting to JS... :P
Did you want something like this
HTML
<div class="outer">
<div class="leftBar">Test</div>
<div class="rightCnt"></div>
</div>
CSS
* {margin: 0}
.leftBar {
width: 200px;
min-height: 600px;
float: left;
background: red;
}
.rightCnt {
margin-left: 200px;
min-height: 600px;
background: yellow;
}
#media (max-width : 500px) {
.leftBar {
float: none;
width: auto;
min-height: 200px;
}
.rightCnt {
margin-left: 0;
}
}
Related
I have following HTML:
<div>
<div class="elemA"></div>
<div class="elemB"></div>
<div class="elemC"></div>
</div>
I would like to achieve following result on medium breakpoint:
Is there any way to position elements like that, without wrapping B and C into additional parent-container?
Such solution is not an option as element A should be positioned in between B and C on small breakpoint:
It can be easily achieved with regular foundation grid by adding float left and float right styles, however it stops working with flex-grid...
Foundation Float grid is not able to do that (and probably no other flex grids do either). They are simply not designed for such usage. Most FE frameworks provide other grids based on Flex and other techniques, which may or may not give a way to do it.
However once your project uses the Flex grid there's little help in that.
A possible solution is to use custom CSS with floats and source ordering. The only issue is for this, if the height of "B" + "C" is less then the height of "A", you have to know/set the height of your "A" div, because the outer one would only grow to fit "B" and "C" and can cause "A" to overflow other elements coming after the outer div.
/* Core of layout */
.wrapper {
position: relative;
}
#media screen and (min-width: 40em) {
.elemB {
width: 50%;
float: right;
}
.elemA {
top: 0;
position: absolute;
width: 50%;
clear: both;
}
.elemC {
width: 50%;
float: right;
clear: both;
}
}
/* If the height of B + C is less than height of A, unfortunatelly we need to know the height of A */
.elemA {
height: 120px; /* must be known */
}
.wrapper {
min-height: 120px; /* this must be set to the same as the height of A :( */
}
/* Nothing important below this line, only appearance for the example */
.wrapper {
background-color: #bbb;
}
.wrapper div {
color: white;
text-align: center;
}
.elemB {
background-color: #3a598e;
height: 20px; /* simulate some content */
}
.elemA {
background-color: #618745;
}
.elemC {
background-color: #515658;
height: 80px; /* simulate some content */
}
<div class="wrapper">
<div class="elemB">B</div>
<div class="elemA">A</div>
<div class="elemC">C</div>
</div>
This will work regardless of your grid.
Indeed it is not ideal if you'd like to use the breakpoints exactly as defined by your grid, but in fact if you compile your CSS files from the Foundation sources, you can use the media query mixins in your Sass.
If you on the other hand use pre-compiled Foundation CSS, than the breakpoints are fixed and you can simply use the same on your custom CSS. For example to use 1 col layout only on small and two columns above, use #media screen and (min-width: 40em) as in my example above. You can find the media queries of the default breakpoints in the last part of this chapter.
Here is my template:
<div id="block1">text</div>
<div id="block2">
<span>content of variable size</span>
</div>
and some basic CSS
#block1 {
float:left;
}
#block2 {
float:right;
}
#block2 span {
}
When reducing the width, how could I make it behave so that, once the two divs cannot fit the page inline, the second div will go below the first (rather than be right floated anymore)?
NOTE: I would like to avoid using media queries.
This responsive theme CSS would be used for multiple sites with content of different sizes.
JSFiddle
In this current JSFiddle, The second div is on the right hand-side. It is fine to me.
If possible without media queries, i would like to design css so that once the second div goes below , the span content is not at the right-hand side
If you mean "I want div2 to go below, but aligned left this time", it's not possible as this behaviour is not predictable using CSS only.
There's no CSS-way to know when it goes below, so impossible to change the floating attribute at this moment.
You could achieve this using Javascript or jQuery. Logic would be:
on ( window resize ) {
if ( div1_width + div2_width > container_width ) {
Change div2 CSS.
}
}
Of course I would suggest to use media queries too.
You can set min-width on the divs. Then, when the line is too small, the one on the right will drop down. However, it will still be floated which may cause issues. That's where media queries come into play to fix such things.
Too many media queries would not make for a pretty responsive design, not to mention they would be a headache.
Anyway, you would have to use at least one media query to achieve a truly responsive design, the simplest example is below:
<div id="block1">text</div>
<div id="block2"> <span>content of variable size</span>
</div>
* {
padding: 0;
margin: 0;
}
#block1 {
float:left;
height: 200px;
background: yellow;
width: 49.5%;
margin-right: .5%;
}
#block2 {
float:right;
height: 200px;
background: tomato;
width: 49.5%;
margin-left: .5%;
}
#block2 span {
}
#media only screen and (max-width : 768px) {
#block1 {
float:none;
width: 100%;
}
#block2 {
float:none;
width: 100%;
}
}
Fiddle here.
If you want to have a look at something more practical, a good starting point is here(its an example of an accordion changing layouts depending on screen size, using media queries).
Lets say I have a website where, on every page, there is a large picture of a kitten. This picture is exactly the same on every page. Below it are smaller divs, containing pictures of related kittens, which are dynamically generated... the number also varies, on some pages there may be five, on others there could be 30. I've drawn a crude picture of the layout here:
Here's what I'm looking to do... I need to:
Make sure the smaller pictures both align left and align right with the larger picture above it.
Give the divs a small percentage of space between each other.
Allow the divs to stack when the screen gets smaller.
When aligning smaller divs in a row with a larger one above it, my usual approach is to do something like this:
.little_divs {
margin-left:2%;
}
.little_divs:first-child {
margin-left: 0px;
}
That would easily allow me to have both the left and right sides match up with the div above it. My problem is that this technique will not work for the next rows, if there are more than three.
My next idea was to contain each group of three in their own div, and apply the first child rule there... however, that brings up a problem of when it collapses down to the smaller screen sizes. If I group them in three and apply the rule, once they are two across, it will no longer work.
I could make a complicated solution involving JavaScript, but I was hoping for a pure CSS/HTML solution.
Let me know if you have any questions on this.
You can change .little_divs:first-child to ...
.little_divs:nth-child(3n+1) {
margin-left: 0px;
}
... or ...
.little_divs:nth-of-type(3n+1) {
margin-left: 0px;
}
... to select the first item on each row where there are 3 items on each row. Adjust the count for the amount of columns e.g. 4n+1 for 4 columns, etc.
This takes every 3rd natural number and offsets it by 1 (next item) which matches 1, 4, 7, etc.
Edit:
If you want this to work with a different amount of columns, you'll need to add the selectors inside mediaqueries as follows:
#media only screen and (min-width:1025px){
.little_divs:nth-child(3n+1) {
margin-left: 0px;
}
}
#media only screen and (max-width:1024px){
.little_divs:nth-child(2n+1) {
margin-left: 0px;
}
}
... or similar for each break point.
My preferred method is to add a container to the small ones, and make the width of that the width of the container plus the width of one of your margins, and give it a negative margin.
.container {
margin: 0 auto;
width: 300px;
}
.main {
background: #0f0;
height: 100px;
width: 300px;
}
.small-container {
margin-left: -15px;
width: 315px;
}
.small {
background: #f0f;
float: left;
height: 100px;
margin-left: 15px;
margin-top: 15px;
width: 90px;
}
<div class="container">
<div class="main"></div>
<div class="small-container">
<div class="small"></div>
<div class="small"></div>
<div class="small"></div>
<div class="small"></div>
<div class="small"></div>
</div>
</div>
With this, it lines up and you don't have to mess with first-child at all or anything.
How to horizontally center a floating element of a variable width?
Edit: I already have this working using a containing div for the floating element and specifying a width for the container (then use margin: 0 auto; for the container). I just wanted to know whether it can be done without using a containing element or at least without having to specify a width for the containing element.
Assuming the element which is floated and will be centered is a div with an id="content"
...
<body>
<div id="wrap">
<div id="content">
This will be centered
</div>
</div>
</body>
And apply the following CSS:
#wrap {
float: left;
position: relative;
left: 50%;
}
#content {
float: left;
position: relative;
left: -50%;
}
Here is a good reference regarding that.
.center {
display: table;
margin: auto;
}
You can use fit-content value for width.
#wrap {
width: -moz-fit-content;
width: -webkit-fit-content;
width: fit-content;
margin: auto;
}
Note: It works only in latest browsers.
This works better when the id = container (which is the outer div) and id = contained (which is the inner div). The problem with the highly recommended solution is that it results in some cases into an horizontal scrolling bar when the browser is trying to cater for the left: -50% attribute. There is a good reference for this solution
#container {
text-align: center;
}
#contained {
text-align: left;
display: inline-block;
}
Say you have a DIV you want centred horizontally:
<div id="foo">Lorem ipsum</div>
In the CSS you'd style it with this:
#foo
{
margin:0 auto;
width:30%;
}
Which states that you have a top and bottom margin of zero pixels, and on either left or right, automatically work out how much is needed to be even.
Doesn't really matter what you put in for the width, as long as it's there and isn't 100%. Otherwise you wouldn't be setting the centre on anything.
But if you float it, left or right, then the bets are off since that pulls it out of the normal flow of elements on the page and the auto margin setting won't work.
The popular answer here does work sometimes, but other times it creates horizontal scroll bars that are tough to deal with - especially when dealing with wide horizontal navigations and large pull down menus. Here is an even lighter-weight version that helps avoid those edge cases:
#wrap {
float: right;
position: relative;
left: -50%;
}
#content {
left: 50%;
position: relative;
}
Proof that it is working!
To more specifically answer your question, it is probably not possible to do without setting up some containing element, however it is very possible to do without specifying a width value. Hope that saves someone out there some headaches!
Can't you just use display: inline block and align to center?
Example.
for 50% element
width: 50%;
display: block;
float: right;
margin-right: 25%;
I've found a lot of similar questions, and tried out several solutions (including some of the so-called "holy grail" CSS layouts), but they don't quite do what I need.
I have a containing div (a CSS containing block) with id right. Inside it on the left side, I want a fixed-width div (a splitter bar, but it doesn't matter what it's being used for; id splitpane); on the right, filling the rest of the space, another div (id right-box below).
I've tried making the two inner divs display: inline-block (with vertical-align: top), setting the left one to width: 3px, but then there's no way to set the right to have width 100% - 3px. I've also tried using the float: left/margin-left: -100%/margin-left: 3px trick, but it has the same problem: the 100% plus the 3px overflows the parent containing block and causes a scroll bar to pop up. (Of course, it's not the scroll bar per se that's the problem; I could use overflow: hidden to remove it, but then content on the right would be truncated.)
Currently I'm using width: 99.5% for the right div, but that's a terrible hack (and is subject to overflow depending on screen width). It looks a bit like this:
<div id="right"><div id="splitpane"></div><div id="right-box">
...
</div></div>
With CSS as follows (float version, but the inline-block version is similar):
#right {
display: inline-block;
vertical-align: top;
height: 100%;
width: 85%; /* this is part of a larger div */
}
#right-box {
width: 99.5%; /* stupid hack; actually want 100% - 3px for splitter */
height: 100%;
}
#splitpane {
float: left;
width: 3px;
height: 100%;
background: white;
border-left: solid gray 1px;
border-right: solid gray 1px;
cursor: e-resize;
}
Is it even possible to do this? This is for an internal app., so solutions only need to work in Firefox 3 (if they are specific to FF3, though, preferably it's because the solution is standards-compliant but other browsers aren't, not because it's using Firefox-only code).
DIVs are the wrong element type for this since they don't "talk" to each other. You can achieve this easily with a table:
<table style="width:200px">
<tr>
<td id="splitpane" style="width: 3px">...</td>
<td id="rightBox" style="width: 100%">...</td>
<tr>
</table>
The 100% will make the rightBox as wide as possible but within the limits of the table.
This is possible. Because block level elements automatically expand to take up any remaining horizontal space, you can utilise a block level element next to an uncleared floated element with your desired width.
<style type="text/css">
div {
height: 100px;
}
#container {
width: 100%;
}
#left {
background: #FF0;
}
#splitpane {
position: relative;
float: right;
background: #000;
width: 3px;
}
</style>
<div id="container">
<div id="splitpane"></div>
<div id="left"></div>
</div>
See http://jsfiddle.net/georeith/W4YMD/1/
why you didn't use margin-left (since it was float layout) on right box?
so no need to create a splitter div...
#right{
width:200px; /*specify some width*/
}
#rightbox{
float:left;
margin-left: 3px; /*replace the splitter*/
/*margin: 0 3px; /*use this to give left & right splitter*/ */
}
yeah something like that, i hate empty div, it's not semantic and it's like putting a splitter on the "old" table way
If the div #right-box is only going to contain non-floated content it might be an idea to just put the content inside #right instead and let it wrap around the floated #splitpane.