Stack some floated elements on top of each other without wrapper - html

I have a responsive site that contains some elements that have the float: left css. For smaller screens, I want to move the second element beneath the first one.
HTML:
<div>A</div>
<div>B</div>
<div>C</div>
CSS:
div {
float: left;
}
Picture: Above the red line is the current layout, below it the desired layout for smaller screens. The size or alignment of the divs does not need to change.
Can I achieve this effect without wrapping divs A and B in a new div?

UPDATED: You can use clear:left on the div B then use translate-Y to let the C div on top;
body {
width: 100%;
height: 100%;
background-color: honeydew;
}
div {
display: inline-block;
padding: 36px;
}
#a {
float: left;
background-color: tomato;
}
#b {
float: left;
clear:left;
background-color: gold;
}
#c {
float: left;
background-color: skyblue;
-webkit-transform: translateY(-100%);
-ms-transform: translateY(-100%);
transform: translateY(-100%);
}
<div id=a>1.</div>
<div id=b>2.</div>
<div id=c>3.</div>

I'm not sure if you'd be interested in some jQuery, but let me provide a bit rough example, something like structural programming and could be surely cleaned up, but this allows you to add some classes and rearrange elements dynamically, without touching the HTML code at all.
<div class="first">A</div>
<div class="second">B</div>
<div class="third">C</div>
CSS:
.first {
float: left;
width: 100%;
}
.second {
float: left;
width: 100%;
}
.third {
float: left;
width: 100%;
}
#left-row {
width: 50%;
float: left;
}
.need-wrapper-right {
width: 50%;
float: right;
}
jQuery
jQuery(document).ready(function($) {
if ($(window).width() < 800) {
$(".second").detach().insertAfter(".first");
$(".first").addClass("need-wrapper-left");
$(".second").addClass("need-wrapper-left");
$(".third").addClass("need-wrapper-right");
$(".need-wrapper-left").wrapAll("<div id='left-row'>");
$(".second").detach().insertAfter(".first");
$(".third").insertAfter($("#left-row"));
}
});
Check the demo on Codepen (the code is set to rearrange elements below 800px). You can check the jQuery documentation about .detach(), addClass() and other functions.
EDIT: Also, you should use media queries so these CSS classes would apply only on lower resolutions.

Related

Reposition div left of another div rather than below

I am attempting to tile a webpage with div elements of various sizes. However, I am running into an issue with once x number of div elements have filled the width of the screen the following div is placed below the previous 'row', rather than being floated to fit into space between elements in the previous 'row'. The code below better demonstrates what I mean; I'd like the 'game' div to be floated to fit into the space above where it is currently positioned.
h1 {
color: white;
}
.center {
display: flex;
justify-content: center;
align-items: center;
text-align: center;
}
.container {
display: inline-block;
}
.default {
margin: 1em;
float: left;
}
/* For hover text */
.hover_img {
width: 100%;
height: 100%;
position: relative;
float: left;
}
.hover_img h4 {
color: white;
}
.hover_img:hover img {
opacity: .2;
}
.hover_img:hover .center_text {
display: block;
}
.center_text {
position: absolute;
top: 50%;
left: 0;
display: none;
font-weight: bold;
text-align: center;
}
img {
margin: 0;
}
.rectangle-tile-horizontal {
height: 15em;
width: 35em;
}
.red {
background-color: rgba(255, 63, 63, 0.8);
}
#game, #game img {
width: 30em;
height: 30em;
}
#app, #app img {
width: 40em;
height: 35em;
}
<div class="container">
<div class="rectangle-tile-horizontal red center default">
<h1><b>Projects</b></h1>
</div>
<div class="rectangle-tile-horizontal hover_img default" id="app">
<img src="http://cohenwoodworking.com/wp-content/uploads/2016/09/image-placeholder-500x500.jpg">
<div class="center_text"><h4>Web App</h4></div>
</div>
<div class="hover_img default" id="game">
<img src="http://cohenwoodworking.com/wp-content/uploads/2016/09/image-placeholder-500x500.jpg">
<div class="center_text"><h4>Breakout</h4> </div>
</div>
I'm afraid what you want to do is actually re-order your divs to create a space-filling layout. To the best of my knowledge, using only CSS for this is difficult, if not outright impossible.
I suggest you take a look at this SO post, or perhaps even the Bulma framework is what you want.
If, however, you move away from re-ordering the containers automagically and instead look towards a solution that elastically adapts the width of each container to fill the available space while maintaining its "order" (first, second, third), I am sure CSS will be a viable solution. If you require assistance, please use the search or ask anew.
Create a style for your div class or id like
.className
{display:inline;}
and use it in your each div
Hope this will help you
An example of this
http://jsfiddle.net/JDERf/

Fluid layout with optional sideboxes

I want a layout with three boxes (two optional) like this:
[side box 1] [ main content
[side box 2] . main content ]
or
[ main content spans 100% if side boxes aren't provided ]
I want the main content box to span the entire height and width available in #load (minus margins) except if the side boxes are there, then I want it to only span up until those boxes (and their right margin).
My CSS:
#load {
margin: 10px;
height: 100%;
min-width: 1080px;
}
#primary,#secondaryOne,#secondaryTwo {
border-radius: 8px;
background: #f5f5f5;
border: 1px solid #ccc;
}
#primary {
float: right;
height: inherit;
width: 75%;
height:500px;
background:red;
}
#secondaryOne,#secondaryTwo {
min-width: 250px;
max-width: 300px;
height: 220px;
margin-right: 10px;
width: 20%;
clear:left;
float:left;
}
#secondaryTwo {
margin-top: 10px;
}
Simple HTML
<div id='load'>
<div id='primary'></div>
<div id='secondaryOne'></div>
<div id='secondaryTwo'></div>
</div>
JSFiddle
Problems
*SOLVED*Making #primary span the entire width if the sideboxes are missing.
*SOLVED*Is there a way to line the two sideboxes (#secondaryOne,#secondaryTwo) on the left side of #primary without nesting them in a separate div? If I use float: left on them, they line side by side, if I don't float them, the #primary generates below them, not beside them.
Solutions
Problem #1 was solved by joeytje50 using the secondary + primary tags and placing the secondary side boxes before the primary in HTML.
Problem #2 was solved in more than one way. The way I chose so that the secondary tags were placed together and before the primary was by NoobEditor using clear: left and a negative margin-top.
The solution can be found at: http://jsfiddle.net/v4cvv/67/
The main part of the solution is:
#primary {
width: 100%;
}
#secondaryOne + #primary, #secondaryTwo + #primary {
margin-top: -221px;
width: 75%;
}
Alternate Solution
One problem I found with the above solution, is it requires the two boxes and them to be the same height. A solution around this is by grouping the boxes in their own div. This solution is:
HTML
<div id='load'>
<div id="sideboxes">
<div id="boxOne" class="box"></div>
<div id="boxTwo" class="box"></div>
<div id="boxThree" class="box"></div>
</div>
<div id="primary" class="box"></div>
</div>
CSS
.box {
border-radius: 8px;
background: #f5f5f5;
border: 1px solid #fff;
}
#primary {
float: right;
display:block;
height: 97%;
width: 100%;
}
#sideboxes + #primary {
width: 75%;
}
#sideboxes {
float: left;
height: 97%;
width: 23%;
margin-right: 10px;
}
#sideboxes .box {
float: left;
height: 220px;
margin-bottom: 10px;
width: 100%;
}
The alternate solution no longer requires clear and can be extended for other uses. You may now also have 1, 2, 3, or however many boxes you want in the sideboxes div.
Thanks all for their help.
To answer your question about the primary box being 100% width when the secondary boxes are not there, you could do the following:
#primary {width:100%;}
.secondary + #primary {width:75%;}
If you put that CSS code at the bottom of your stylesheet, and then put the primary div tag after your first secondary div tag, then it'll by default be 100% wide, unless there's an element that has class="secondary". This won't change anything about the position the div is rendered, but it will fix your problem.
Alternatively, if your secondary divs are possibly hidden instead of not being there, you could do this:
#primary, .secondary.hidden + #primary {width:100%;}
.secondary + #primary {width:75%;}
That is, assuming you hide the secondary tabs via a class such as .hidden.
Here is a working version that becomes 100% width when the secondaries are removed, but still is 75% width when there is a .secondary element before it.
Keeping your HTML markup smae, here is the solution for your problem : demo
CSS
html.body {
height:100%;
}
#load {
margin: 10px;
height: 100%;
width:100%;
}
#primary, #secondaryOne, #secondaryTwo {
border-radius: 8px;
background: #f5f5f5;
border: 1px solid #ccc;
}
#primary {
float: right;
display:block;
height: 100%;
max-width:100%;;
width: 68%;
margin-top:-70%; /* this is the key */
}
#secondaryOne, #secondaryTwo {
width:30%;
height: 220px;
margin-right: 10px;
}
#secondaryTwo {
margin-top: 10px;
}
Problem #1
To get your #primary div to adapt it's width, you can use jquery to verify the presence of the .secondary divs and to set the an other width to the #primary div.
With .secondary demo
without .secondary demo
JQUERY:
if ($('.secondary').length){
$('#primary').css('width', '75%');
}
Problem #2
You can use clear:left; and by changing the order of the divs in your html markup you will have your 2 divs stacked on the left and your content div on the right.
FIDDLE
HTML:
<div id='load'>
<div id='primary'></div>
<div id='secondaryOne' class="secondary"></div>
<div id='secondaryTwo' class="secondary"></div>
</div>
CSS :
.secondary{
clear:left;
float:left;
}
Try
#primary {
min-width:75%;
max-width:100%;
}
http://jsfiddle.net/Paramasivan/v4cvv/65/

Sum of percent widths not rounded to 100%

I want to make a multi-segment progress bar.
It has to be horizontally centered, with a maximum width, but not a static one, so it can shrink if there is not enough space.
The problem is that sometimes the total progress is at 100%, but the segments could be at 33.33% and 66.66%.
The percentages are being calculated based on the width of the document, which may be an odd number, so the bar segments' widths are rounded in a way that leaves one pixel empty on the bar.
HTML
<div class="CENTER">
<div class="BAR">
<div class="SEGMENT ONE" style="width: 33.33%;"></div>
<div class="SEGMENT TWO" style="width: 66.66%;"></div>
</div>
</div>
CSS
.CENTER {
max-width: 400px;
margin-left: auto;
margin-right: auto;
}
.BAR {
height: 10px;
}
.SEGMENT {
float: left;
height: 100%;
}
.BAR { background-color: #F00; border: 1px solid #000; }
.SEGMENT.ONE { background-color: #FDA; }
.SEGMENT.TWO { background-color: #ADF; }
Play around with the width of the window after it's big enough for the bar to reach its maximum width.
There will be a red one pixel wide section on the right side of the bar.
How can I avoid it?
Example: http://jsfiddle.net/CV6fp
Can you do it using that same HTML and without JavaScript, CSS?
Maybe with table display?
http://jsfiddle.net/CV6fp/6/
.CENTER {
max-width: 400px;
margin-left: auto;
margin-right: auto;
}
.BAR {
height: 10px;
display: table;
width: 100%;
}
.SEGMENT {
display: table-cell;
height: 100%;
}
.BAR { background-color: #F00; border: 1px solid #000; }
.SEGMENT.ONE { background-color: #FDA; }
.SEGMENT.TWO { background-color: #ADF; }
Here is how I would do it:
http://jsfiddle.net/CV6fp/3/
Basically, drop the width property off the div with class TWO. Then make the same div NOT float left:
<div class="CENTER">
<div class="BAR">
<div class="SEGMENT ONE" style="width: 33.33%;"></div>
<div class="SEGMENT TWO"> </div>
</div>
</div>
And the style change:
.SEGMENT.TWO { background-color: #ADF; float:none; }
This means that second segment no longer floats:left, but I do think this may be what you are looking for.
Update: And finally after much soul searching, a CSS only solution to solve all the issues mentioned on this page:
http://jsfiddle.net/CV6fp/7/
Two changes to CSS: (1) segments set to float:right, and (2) .SEGEMENT.ONE to override that and always float:left
.SEGMENT {
float: right;
height: 100%;
}
.SEGMENT.ONE { background-color: #FDA; float:left; }
In this case you may need to reduce accuracy to the tenth's place and use a ceiling rounding function on the final segment. This way you would get 33.3% and 66.7%.
Try: .SEGMENT:last-child { float: none; width: auto !important; }. This should make the last segment to fill the remaining space.

Make floating divs the same height

I have 2 divs side by side. I don't know the height of them upfront, it changed according to the content. Is there a way to make sure they will always be the same height, even when one of them stretches, only with CSS?
I made a fiddle to show. I want the red and blue divs to be the same height...
http://jsfiddle.net/7RVh4/
this is the css:
#wrapper {
width: 300px;
}
#left {
width:50px;
background: blue;
float:left;
height: 100%; /* sadly, this doesn't work... */
}
#right {
width:250px;
background: red;
float:left;
}
You could try instead of using float, use display: table-cell. You might find some older browsers don't understand this rule however. See below:
#wrapper {
display: table; // See FelipeAls comment below
width: 300px;
}
#left {
display: table-cell;
width: 50px;
background: blue;
}
#right {
display: table-cell;
width: 250px;
background: red;
}
Antony answer works ok, but you need all the divs to have the same parent and to have a wrapper, I have a solution that use javascript but works with any kind of element, they just need to have the same selector.
function setEqualHeight(selector, triggerContinusly) {
var elements = $(selector)
elements.css("height", "auto")
var max = Number.NEGATIVE_INFINITY;
$.each(elements, function(index, item) {
if ($(item).height() > max) {
max = $(item).height()
}
})
$(selector).css("height", max + "px")
if (!!triggerContinusly) {
$(document).on("input", selector, function() {
setEqualHeight(selector, false)
})
$(window).resize(function() {
setEqualHeight(selector, false)
})
}
}
setEqualHeight(".sameh", true)
http://jsfiddle.net/83WbS/2/
I would recommend reading this article that explains how to do what you are trying to do. I would put a fiddle up that shows, but its pretty extensive and pure css. http://matthewjamestaylor.com/blog/equal-height-columns-cross-browser-css-no-hacks
There is a much simpler solution I want to point to. Using large padding-bottom: 500em and negative margin-bottom:-500em of the same amount on columns while the wrapper has simply overflow:hidden to cut the columns to the right size.
Found here:
HTML/CSS: Making two floating divs the same height
As indicated by Hexodus you can padding-bottom and margin-bottom, but a better solution would be to use flexbox or grid.
You can check this codepen if you want. I included a footer area because that is something I needed and it required a little bit more of hack.
.section {
width: 500px;
margin: auto;
overflow: hidden;
padding: 0;
}
div {
padding: 1rem;
}
.header {
background: lightblue;
}
.sidebar {
background: lightgreen;
width: calc(25% - 1rem);
}
.sidebar-left {
float: left;
padding-bottom: 500rem;
margin-bottom: -500rem;
}
.main {
background: pink;
width: calc(50% - 4rem);
float: left;
padding-bottom: 500rem;
margin-bottom: -500rem;
}
.sidebar-right {
float: right;
padding-bottom: 500rem;
margin-bottom: -500rem;
}
.footer {
background: black;
color: white;
float: left;
clear: both;
margin-top: 1rem;
width: calc(100% - 2rem);
}
<div class="section">
<div class="header">
This is the header
</div>
<div class="sidebar sidebar-left">
This sidebar could have a menu or something like that. It may not have the same length as the other
</div>
<div class="main">
This is the main area. It should have the same length as the sidebars
</div>
<div class="sidebar sidebar-right">
This is the other sidebar, it could have some ads
</div>
<div class="footer">
Footer area
</div>
</div>
You can do this without using tables, by using this CSS trick.
Example - http://jsfiddle.net/LMGsv/
HTML
<div id="wrapper">
<div id="columns">
<div id="left">text</div>
<div id="right">text<br/>another line<br /></div>
</div>
</div>
CSS
#wrapper {
float:left;
width: 300px;
}
#columns {
float:left;
width:300px;
background:blue;
}
#left {
float:left;
width:50px;
background: blue;
}
#right {
width:250px;
background: red;
float:left
}

Div positioning on same line

I have a problem with some divs. In short here is what I need: 2 divs with a certain width (same width) - one with float left and one with right, and a third div that takes all the remaining space. The divs are using display : inline-block to have them on same line.
I have tried this :
<div class="wrapper">
<div class="control leftControl"></div>
<div class="display"></div>
<div class="control rightControl"></div>
</div>
And here is my css:
.wrapper {
width: 100%;
height: 100%;
min-width: 960px;
background-color: #E8E8E8;
}
.control {
width: 10%;
height: 100%;
display: inline-block;
background-color: #ADADAD;
}
.leftControl {
float: left;
}
.rightControl {
float: right;
}
.display {
width: 80%;
height: 100%;
display: inline-block;
}
The problem is that using % on some resolution causes the last div (controlRight) to be moved on a new line.I can understand why and found that if i use 79% on display the divs display almost correctly (1% left unsued.)
It is clear to me that this is not a correct solution.
Any help is appreciated.
You can put all your elements float:left and your 100% will always fit: fiddle
HTML
<div class="control"></div>
<div class="display"></div>
<div class="control"></div>
CSS
.control {
width: 10%;
height: 200px;
background-color: green;
float:left;
}
.display {
width: 80%;
height: 200px;
background-color:blue;
float:left;
}​
Putting everything on float left will simply push divs one by one on the right.