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?
Related
I'm looking to learn how I can position images in CSS, multiple ones, without affecting my footers position, size, etc.
I coded some CSS I thought would work, but it messed up my footers position. (It wouldn't stay at the bottom.)
So, I fixed that issue but found the code I wrote for the image position messed with the footers position.
I don't really know how, but I would like to have my images positioned, perhaps by px/space.. they just need to look good in a row spaced.
The example is in red, is how I want it to look.
look here for an example of how I want it to look.
HTML
<div class="batesimg">
<p><strong>Bates</p></strong>
<div class="shadow"> <!-- makes a shadow, surrounding the characters picture. -->
<img src="images/bates.png" alt="Bates" width="150" height="150"> <!-- defines the img -->
CSS
/* Bates profile picture. */
.batesimg { /* or whatever class name works for you */
position: auto;
left:250px;
top:250px;
margin-right: 500px;
}
NOTE, the css above isn't positioning the image how i want it, showed in the image example, can someone help me positiong the image like i have it in my example image?
Thanks!
You want to repeat same type of pattern of name,img and descriptions. We will call this 'card'. Now you have two problems in hand.
1) Placing multiple cards in page. For this use some layout like flexbox.
2) Setting inside of card properly..
/*1st Problem*/
#flex-container{
display: flex;
flex-wrap:wrap;
width: 600px;
justify-content: space-around;
}
#flex-container>div.card{
flex-grow:0;
flex-shrink:0;
}
/*1st Problem ends*/
/*2nd Problem*/
.card{
width: 200px;
height:calc(200px + 2em);
}
.card>.name ,.card>.desc{
width: 100%;
text-align: center;
}
.card>div.img{
position: relative;
margin-left: 25px;
width: 150px;
height: 150px;
border-radius: 100%;
}
/*2nd Problem ends*/
.card:nth-child(1) div.img{background-color: red;}
.card:nth-child(2) div.img{background-color: green;}
.card:nth-child(3) div.img{background-color: blue;}
.card:nth-child(4) div.img{background-color: yellow;}
/*Centering Content*/
#flex-container{
margin: 0 auto;
/*top,bottom both zero.. and left,right both auto..
handling margin is complicated..read about them
*/
}
<div id="flex-container">
<div class="card">
<div class="name">Name1</div>
<div class="img"></div>
<div class="desc">Desc1</div>
</div>
<div class="card">
<div class="name">Name2</div>
<div class="img"></div>
<div class="desc">Desc2</div>
</div>
<div class="card">
<div class="name">Name3</div>
<div class="img"></div>
<div class="desc">Desc3</div>
</div>
<div class="card">
<div class="name">Name4</div>
<div class="img"></div>
<div class="desc">Desc4</div>
</div>
</div>
For any other problem visit Flexbox
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.
I have code that embedded video within text. However the space between the title and the video
is too high.
<section id="Number">
<article class="container">
<div class="row">
<div class="span12">
<div class="sub_header">
<h2>ABC Number</h2>
The following video will be saparated too high from ABC Number with only one line (but the line seems too high)
<div class="video">
<div class="vdwrapper">
<div class="fluidvids" style="width:100%;position:relative;padding-top:56.2%">
<iframe src="https://player.vimeo.com/video/87745355?
title=0&byline=0&portrait=0" width="100%" height="100%"
frameborder="0" style="position:absolute;top:-0.85px;left:0"></iframe>
</div>
</div>
</div>
<div class="featurecont"> <p> Number is a proxy phone number assigned to you when
you sign up on with your regular mobile number.</p>
<p>Number can be used in many ways, you can register your Number as a separate
profile on can keep your real phone number entirely anonymous. You can share your
Number with lesser known people or acquaintances that you meet at various places, or
while posting Ads. This way, people can only reach you on and cannot call you on your
personal mobile number.
</p>
<p>Another cool advantage of Number is that your Number can also be transferred to
non-SIM devices like , etc. This would allow your kids and family members to stay
connected with you and have safe and secure communications.</p></div>
</div>
</div>
</div>
The css is as follows:
.chaatzvideo {
position: relative;
padding-top: 50px;
padding-bottom: 50px;
background: url('../images/tv.png') center center no-repeat;
background-size: 78%;
}
.row {
margin-left: -20px;
*zoom: 1;
}
.span12 {
width: 980px;
}
.vdwrapper {
margin: 0 auto;
text-align: center;
width: 75%;
}
.container,
.navbar-static-top .container,
.navbar-fixed-top .container,
.navbar-fixed-bottom .container {
width: 980px;
}
#Number .sub_header h2{background: url('../images/features/Chaatz-Notop.png') no-repeat
center top; padding-bottom: 50px; padding-top:110px}
You are having padding top and bottom for "#Number .sub_header h2"... try to use something like this
#Number .sub_header h2 {
background: url('../images/features/Chaatz-Notop.png') no-repeat center top;
padding-bottom: 20px;
padding-top:20px
}
DEMO
I warned you, I can be a little vague
Anyway, what I am after are those pages that fill the whole screen, but if you scroll down and you come to a different section ( some specific content or just a footer), it breaks away from the previous content by having a different background.
Sorry, if I sleep on it, I can maybe come up whith a better explanation and/or an example page.
Does that style have a name and how is it done? If it needs to be responsive?
thanks
Yes. It's simple to do. Setup like so, and customize to your heart's content.
<div id="header" class="container">
<div class="wrapper">
[...]
</div>
</div>
<div id="feature_area" class="container">
<div class="wrapper">
[...]
</div>
</div>
<div id="content" class="container">
<div class="wrapper">
[...]
</div>
</div>
<div id="footer" class="container">
<div class="wrapper">
[...]
</div>
</div>
CSS:
.container {
width: 100%;
text-align: center;
}
.wrapper {
margin: 0px auto;
width: 70%;
text-align: left;
}
The parent (container) <div>s will stretch to 100% page width. The child (wrapper) <div>s will stretch to 70% of their parents (or, you can set this to fixed pixel dimensions and change based upon screen dimensions) and will be centered. You apply decorative backgrounds to the parent .container like:
#header {
background: #ff0000;
}
#footer {
background: #000;
}
#content {
background: url(img/bg_pattern.gif);
}
#feature_area {
background: url(img/hero_feature_img.jpg) top center no-repeat;
}
I need the center div div#b to fill out the gab between div#a and div#c.
<div id="a">
<span>Div1</span>
</div>
<div id="b">
<span>Div2</span>
</div>
<div id="c">
<span>Div3</span>
</div>
I tried to do this by placing width: 100% on div#b but without luck.
div
{
border:1px solid red;
}
div#a
{
float:left;
width:50px;
}
div#b
{
float:left;
width:100%; ?? <!-- Doesn't work!!! -->
}
div#c
{
float:right;
width:50px;
}
How can I get div#b to expand from div#a to div#c?
There can be no line breaks.
CSS3
You can implement this dynamic behavior using the CSS3 Flexible Box Layout Module:
<style type="text/css">
div.Container
{
width: 100%;
display: box;
display: -moz-box;
display: -ms-box;
display: -webkit-box;
}
div.B
{
background: magenta;
box-flex: 1;
-moz-box-flex: 1;
-ms-box-flex: 1;
-webkit-box-flex: 1;
}
</style>
<div class="Container">
<div style="width: 50px; background: cyan;">
A
</div>
<div class="B">
B
</div>
<div style="width: 50px; background: yellow;">
C
</div>
</div>
A new version of FireFox, a new version of Google Chrome, Internet Explorer 10 and a new version of Safari supports CSS3 flexible box layout. Internet Explorer 9 and Opera is lacking support at the moment.
I also want to mention this new way to do it in FireFox:
<div style="float: left; width: 50px; background: cyan;">
A
</div>
<div style="float: left; width: -moz-calc(100% - 100px); background: magenta;">
B
</div>
<div style="float: left; width: 50px; background: yellow;">
C
</div>
FireFox is the only browser that support the calc function at the moment.
CSS2
Here is the old way to do it:
<div style="padding-left: 100px;">
<div style="float: left; width: 50px; margin-left: -100px; background: cyan;">
A
</div>
<div style="float: left; width: 100%; margin-left: -50px; background: magenta;">
B
</div>
<div style="float: left; width: 50px; background: yellow;">
C
</div>
</div>
A width of 100% inside the container div is the width of the container minus the 100px left padding. Then there is room for the left and right 50px div elements. Then you have to position them using some negative margin and floating.
Feature detection
Use feature detection with Modernizr. Then you can use CSS2 for browsers that lack support for CSS3 flexbox.
If you do .NET development you can download Modernizr with NuGet.
I've hit similar problems myself. The problem here is "width: 100%" will basically inherit the width of the parent container.
The other problem is the float. When you ask div#b to float to the left alongside div#a, you can't use the fancy margin trick to force div#b to stay out of the way of div#a. (In other words, margin can be used to keep div#b from entering and interfering with a certain amount of space on any of its sides.) However, with float, the margin is now not pushing div#b away from the edge of the page, but away from the edge of div#a.
OK, so the solution looks like this. Remove the float on div#b, and then apply left and right margins so div#b doesn't interfere with either side columns. Let div#b determine its own size (i.e. don't give it a "width"), so it will fit between the two floats. Lastly, shift div#b so that the floats occur before div#b is put in place, so that div#b is put between the floats.
Here's the new code:
<style type="text/css">
div
{
border:1px solid red;
}
div#a
{
float:left;
width:50px;
}
div#b
{
margin-left: 55px;
margin-right: 55px;
}
div#c
{
float:right;
width:50px;
}
</style>
<div id="a">
<span>Div1</span>
</div>
<div id="c">
<span>Div3</span>
</div>
<div id="b">
<span>Div2</span>
</div>
Determining margins is tricky. Borders aren't counted in the width calculation of an element, so a 50px-wide div with a 1px border is actually 52px-wide.
I have a feeling you won't like this answer, but the easiest way to do it is to remove float: left and any width from div#b, and then switch up the order of your divs, so both the sidebars are before your main content area. Here's the code:
HTML:
<div id="a">
<span>Div1</span>
</div>
<div id="c">
<span>Div3</span>
</div>
<div id="b">
<span>Div2</span>
</div>
CSS:
div
{
border:1px solid red;
}
div#a
{
float:left;
width:50px;
}
div#b
{
overflow: hidden;
/*margin: 0 60px;*/
}
div#c
{
float:right;
width:50px;
}
Note that I've applied overflow: hidden to the middle div - this will force it into columns (in most browsers). You could use the given margins instead, if you're not comfortable with a "magic" solution (there is a reasonable explanation for it, but I can never remember it off the top of my head).