CSS- Getting 100% width div to wrap under another [jsfiddle] - css

In a responsive layout, I have two columns. The left column is the sidebar and the right column is the content.
Using a media query, when the screen width is tiny, the columns turn to 100% width and stack on top of each other.
In this case, I want the sidebar (the first div) to appear beneath the content (the second div).
I tried using float: right on a small screen once it's at 100%, but at 100% width, the float apparently doesn't matter.
.left, .right {
width: 100%;
float: left;
background: green;
}
.left {
float: right;
background: red;
}
.half {
width: 50%;
}
.space {
width: 100%;
display: block;
height: 40px;
}
And on the page:
<div class="left half"> <!-- To mimic full screen size -->
Left
</div>
<div class="right half">
Right
</div>
<div class="space"></div>
<div class="left"> <!-- To mimic small screen size -->
Left
</div>
<div class="right"><!-- This should appear first -->
Right
</div>
Here is the fiddle: https://jsfiddle.net/ph09frvw/
I'm sure this is not the first time someone wanted to wrap the sidebar under the content, I just haven't been able to find a solution.

You can use display: flex and use the order property to change the order of the <div> elements. While floating can be helpful for horizontal alignment, it will be of little help for vertical alignment, Here is an example:
.flex {
display: flex;
flex-flow: row wrap;
}
.left {
order: 2;
flex: 1 0 50%;
background: red;
}
.right {
order: 1;
flex: 1 0 50%;
background: green;
}
.full {
margin-top: 20px;
}
.full > .left,
.full > .right {
flex: 1 0 100%;
}
<div class="flex">
<div class="left">
Left
</div>
<div class="right">
Right
</div>
</div>
<div class="flex full">
<div class="left">
Left
</div>
<div class="right">
Right
</div>
</div>

You could use the display:flex; property combined with flex-direction to reorder your divs. Ref: https://css-tricks.com/almanac/properties/f/flex-direction/

Remember to reference your related class-names in your HTML elements' class attribute.
Your CSS display:block should do the trick, else try something like:
float: left
When you use: display:block on a div element, you do not need to specify width:100% as it should automatically span across the width if it is not hindered by anything else.
Make sure the position of these elements are "relative", else it may not work as expected; it may be stated globally that some specific tags should be displayed "absolute" and that may break what you're trying to achieve.

Related

Align scroll down arrow to the bottom center of a full-screen div in WPBakery Visual Composer

I have a series of full-screen divs in Visual Composer and I want an arrow at the bottom of each one indicating to users they should scroll for more content. I tried absolute positioning on the divs containing the icon with no luck. All I've done is move the icon a few pixels to th
<section class="l-section wpb_row height_full valign_center width_full with_img" id="home">
<div class="l-section-img loaded" data-img-width="1920" data-img-height="809">
</div>
<div class="l-section-h i-cf">
<div class="g-cols vc_row type_default valign_top">
<div class="vc_col-sm-12 wpb_column vc_column_container">
<div class="vc_column-inner">
<div class="wpb_wrapper">
<div class="w-image align_center" id="mainlogo">
<div class="w-image-h"><img src="logo.png" class="attachment-full size-full">
</div>
</div>
<div class="ult-just-icon-wrapper">
<div class="align-icon" style="text-align:center;">
<a class="aio-tooltip" href="#whatis">
<div class="aio-icon none " style="display:inline-block;">
<i class="Defaults-chevron-down"></i>
</div>
</a>
</div></div></div></div></div></div></div>
</section>
Existing CSS:
.aio-icon.none {
display: inline-block;
}
.aio-tooltip {
display: inline-block;
width: auto;
max-width: 100%;
}
.vc_column-inner {
display: flex;
flex-direction: column;
flex-grow: 1;
flex-shrink: 0;
}
.wpb_column {
position: relative;
}
.vc_column_container {
display: flex;
flex-direction: column;
}
.vc_row {
position: relative;
}
.l-section-h {
position: relative;
margin: 0 auto;
width: 100%;
}
The icon itself is the Defaults-chevron-down.
Do you have an idea how to position that icon properly?
I also struggled a little with this. But there is a rather quick and dirty fix for this:
Just put another row below the full height row. Place your icon there and give this element a top margin of i.e. -200px.
For some strange reason the rather logical approach to put the icon in the full height row itself and to position it absolute to the bottom is not properly supported by the source generated from WPB.
I had this issue this week. The way I resolved it was added the icon in that row/section (in my case a single image element with a custom link to a .svg) and added a class to it.
The CSS for the class was then:
position:absolute;
margin-left: auto;
margin-right: auto;
left: 0;
right: 0;
text-align: center;
margin-top:-30px;
(I added a negative margin top as I noticed the icon was cutting of a little on my Google Pixel phone with the fixed bottom bar so that pulled it up a little.)

Using calc() with a dynamic value?

I am wondering if this is possible: I have a header that can contain a variable amount of text. Below that I have another element which I want to take up the remaining height of the page.
<div class="header row">
<div class="title column large-5">Potentially very long text</div>
<div class="menu column large-7">Menu items</div>
</div>
<div class="content">
</div>
<div class="footer">
</div>
Normally I would do this using calc, eg:
.content {
height: calc(100vh - 75px);
}
Where 75px is the set height of .header.
But in this example, the .header element is dynamic and does not have a set height. Only a padding and font-size are set.
To complicate things, this also uses the Foundation Grid layout, which makes me nervous about using display: table (.title and .menu sit side by side on desktop, but stacked on mobile) .
Is there anyway to get the height of the dynamic header element (without resorting to JQuery)?
You can use flexbox and set .content to flex-grow: 1 so that it will fill to grow the available space.
body {
display: flex;
flex-direction: column;
min-height: 100vh;
margin: 0;
}
.content {
flex-grow: 1;
background: #eee;
}
<div class="header row">
<div class="title column large-5">Potentially very long text</div>
<div class="menu column large-7">Menu items</div>
</div>
<div class="content">
</div>
<div class="footer">
</div>
I made a small pen to show the way to do this using flex box, it involved changing your markup a bit:
css:
.container {
display: flex;
flex-direction: column;
height: 250px; // whatever you want here
}
.header {
width: 100%;
background: red;
padding: 10px;
}
.content {
background: yellow;
width: 100%;
flex-grow: 1;
}
So the content will always take the available space inside the content div.
check the whole pen: http://codepen.io/anshul119/pen/yMYeLa
hope this helps.

responsive 2 column 2 row layout

I have been trying to figure out how to create this layout, I have a 2 column layout with the left column having 1 row and the right side having 2. Im trying to get it to adjust fluidly. What im having trouble with is I would like the top of the top image on the right to align with the top of the left image while the bottom of the bottom image stays aligned with the bottom of the left image. Should I use a table?
here is what I have so far.. not very close I really appreciate the help.
http://jsfiddle.net/#&togetherjs=TpsEptHKit
here is an image of what I would like to acomplish
The closest I could come up with was a table with a single row and two cells (so both sides would be equal in height).
Then on the right we have two divs with heights adding up to 100% (say, 60% for the top and 40% for the bottom).
We'll specify vertical-align: top for the upper block, and vertical-align: bottom for the lower one. On top this will produce the desired effect, but on the bottom the vertical align doesn't kick in properly because we only have one element to align. To fix this, we need a spanner element with 100% height and place this adjacent to the "real" block.
Here, .block would represent the content inside the cell, e.g. image and caption.
JSFiddle
HTML
<table class="container">
<tr>
<td class="left">
</td>
<td class="right">
<div class="top">
<div class="block"></div>
</div>
<div class="bottom">
<div class="filler"></div><div class="block"></div>
</div>
</td>
</tr>
</table>
CSS
.container {
width: 100%;
height: 100%;
}
.left {
width: 60%;
height: 200px;
}
.right {
height: 100%;
}
.right .top {
height: 60%;
width: 100%;
vertical-align: top;
}
.right .bottom {
height: 40%;
width: 100%;
vertical-align: bottom;
}
.block {
display: inline-block;
}
.filler {
height: 100%;
display: inline-block;
}
What you can do is first wrap the whole thing in a container, than give your .right:{float:right} and remove the float:left in other classes. See the code
.container{
width: 620px;
height: 400px;
}
.right {
float: right;
}
.blackBox {
background-color: black;
width: 200px;
height: 175px;
}
.redBox {
background-color: red;
width: 400px;
height: 400px;
}
This looks the same as your pic: http://jsfiddle.net/aC7j6/1/
Here's the fiddle: http://jsfiddle.net/RGaw5/
<div id="left-container">
<div id="left" class="black"></div>
<p class="description-text-left">Printed Lexington</p>
</div>
<div id="right">
<div id="right-top" class="black"></div>
<p class="description-text">Printed Lexington</p>
<div id="right-bottom" class="black"></div>
<p class="description-text">Printed Lexington</p>
</div>
You can make it responsive by giving the width in vw or %.
EDIT: Here's a responsive, updated fiddle: http://jsfiddle.net/RGaw5/1/
EDIT 2: Note that the first column's height can vary - no matter what's the height, the rest of the divs will scale accordingly. Here's one more fiddle with a different left column's height: http://jsfiddle.net/RGaw5/2/

Make element width stretch to fit its children when element's parent has overflow: auto;

In this simplified example, I have a bookcase with books sitting on bookshelves. The bookcase is the outermost element with a defined width. The books on a bookshelf are supposed to appear left to right without wrapping. The bookshelf is supposed to stretch its width to show all the books on its shelf. All bookshelves need to be the same width, the width of the widest bookshelf.
My HTML:
<div class="bookcase">
<div class="bookshelf">
<div class="book">
<div class="book">
<div class="book">
</div>
<div class="bookshelf">
<div class="book">
<div class="book">
<div class="book">
<div class="book">
</div>
<div class="bookshelf">
<div class="book">
</div>
</div>
My CSS:
.bookcase {
width: 40%;
height: 300px;
margin: 0 auto;
background: lightgrey;
overflow-x: auto;
}
.bookshelf {
background: lightgreen;
white-space: nowrap;
}
.book {
display: inline-block;
height: 60px;
width: 60px;
background: pink;
}
jsFiddle demo
The problem with the current code is that when the bookcase width is smaller than the longest bookshelf and the bookcase makes the overflow scrollable, the bookshelf elements don’t stretch to fit all the books. Currently the shelves appear to be defining their width equal to the parent, the bookcase.
These pictures illustrate the problem. This is how the bookcase looks normally, which is fine:
or
But when you scroll right when the bookcase is narrow, the bookshelves’ green background is cut off, instead of reaching to the right side of the last red book:
How can I make the bookshelves take the full width of the overflowed element, rather than the width of the bookcase parent container?
Thanks to Javalsu, Hashem Qolami, and Danield for helping me find a suitable solution. Indeed, the trick is to utilize inherent display properties of tables. The solution I found was to wrap the .bookcase in another element (I'm calling this wrapper element the .wall). Move the overflow: auto; with the static height: and width: properties from the .bookcase to the .wall, and add display: table; and width: 100%; to the .bookcase.
The display: table; property is needed for when overflow is scrolling, and the width: 100%; is needed for when the overflow is not scrolling.
My New HTML:
<div class="wall">
<div class="bookcase">
<div class="bookshelf">
<div class="book"></div>
<div class="book"></div>
<div class="book"></div>
</div>
<div class="bookshelf">
<div class="book"></div>
<div class="book"></div>
<div class="book"></div>
<div class="book"></div>
</div>
<div class="bookshelf">
<div class="book"></div>
</div>
</div>
</div>
My New CSS:
.wall {
width: 60%;
height: 300px;
margin: 0 auto;
background: lightgrey;
overflow: auto;
}
.bookcase {
display: table;
width: 100%;
}
.bookshelf {
background: lightgreen;
white-space: nowrap;
}
.book {
display: inline-block;
height: 60px;
width: 60px;
background: pink;
}
jsFiddle demo
Result:
or
Adding display:table on the .bookcase element does almost what you need.
FIDDLE
The only difference is that instead of the scrollbars appearing when the longest bookshelf > 60% of the viewport width, they appear when the longest bookshelf > 100% of the viewport width.
But the problem with the disappearing background is gone.
your problem is that you've declared a width on .bookcase, and each bookshelf will inherit that width. If you want the bookcase and each bookshelf to always be the width of the widest row of books, set display: inline-block on .bookcase, and remove its width rule. If you need it centered, you'll need to find a way other than margin: 0 auto.

Responsive-friendly fluid CSS grid with no JS

Five of us have spent a day and a half working on this - got some very close solutions, but seems like it might be impossible to do without pulling in Javascript.
Scenario
We're using a responsive (media-query based), 960 grid layout. There are four divs with content. These four divs need to semantically be in the order shown in the image below. Since it is the 960 grid, we also have wrapper divs per "row" - like this:
<div id="topzone">
<div id="one">1</div>
<div id="two">2</div>
</div>
<div id="bottomzone">
<div id="three">3</div>
<div id="four">4</div>
</div>
Div one has the intro to an article, div two has an advertisement, div three has the actual article and div four has random stuff (facebook feeds, whatever).
On mobile, the divs need to display in order from one to four. On desktop they need to display the same, but in two columns, horizontally ordered first.
So far so good. Here is the kicker:
We don't know what height the divs will be - they will vary with each page (even the advertisement one).
There can't be any vertical gaps between divs.
We can't use Javascript (or really, really, really don't want to - we know we can do this easily with JS)
If you just do floats left and right you get gaps:
<div id="topzone">
<div id="one" style="float: left; height: 300px">1</div>
<div id="two" style="float: right; height: 200px">2</div>
</div>
<div id="bottomzone">
<div id="three" style="float: left; height: 100px">3</div>
<div id="four" style="float: right; height: 300px">4</div>
</div>
Attempted Solutions
CSS tables don't allow for rowspans. Workarounds either have the empty div get overlayed or leave gaps.
Masonry CSS orders the divs vertically so mobile would incorrectly drop divs two and four below one and three.
The closest we came was hijacking the overflow property to display the third div below the first one. This worked brilliantly - until we tried to add a footer to the page. Because overflow has no height according to the browser, the footer overlayed the third div.
<style type="text/css">
#one {
height: 300px;
background-color: yellow;
}
#two {
height: 200px;
background-color: brown;
}
#three {
background-color: blue; /* only shows in mobile, otherwise hidden behind #one */
}
#three-inner {
height: 100px;
border: 2px solid black;
}
#four {
height: 300px;
background-color: burlywood;
}
/* Non-mobile */
#media all and (min-width: 740px) and (min-device-width: 740px),
(max-device-width: 800px) and (min-width: 740px) {
#one {
float: left;
width: 50%;
}
#two {
float: right;
width: 50%;
}
#three {
height: 0px; /* turns into overflow */
width: 50%;
}
#three-inner {
clear: left;
}
#four {
float: right;
width: 50%;
clear: right;
}
}
</style>
<div id="topzone">
<div id="one">
<p><strong>First block.</strong></p>
</div>
<div id="two">
<strong>Second block</strong>
</div>
<div id="bottomzone">
<div id="three">
<div id="three-inner">
<p><strong>Third block.</strong></p>
</div>
</div>
<div id="four">
<p><strong>Fourth block.</strong></p>
</div>
</div>
</div>
There must be a way to do this in all CSS - tell me there is?

Resources