Move divs vertically within a larger div - html

I am making an animation that involves a set of four divs inside one larger div. The four divs are too large to all fit in the one div at once, so I want to be able to specify the position at which the larger div should start. For example, here I have four boxes inside the div. From top to bottom, the boxes are green, purple, pink, and blue (you can't see the blue in the current jsfiddle because it is cut off). I would like the BOTTOM of the larger fulldisplay div to align with the MIDDLE of the blue box, and everything else to fit above hat until it is cut off at the top of the div. Eventually I am going to be implementing a custom-made scroll button (as I don't want it to look like the overflow:scroll one) but for now I am just trying to get CSS to display the inner divs the way I want.
JS FIDDLE: http://jsfiddle.net/o33gw35w/
CSS:
body {padding: 0; margin: 0; height: 100%; overflow: hidden; font-family: Helvetica;}
.nameblock {
height:10%;
width: 30%;
position: absolute;
background-color: yellow;
}
.fulldisplay {
height:90%;
width: 30%;
position: absolute;
overflow: hidden ;
}
.spacer1 {
height:40%;
position: relative;
background-color: green;
}
.spacer2{
height:40%;
position: relative;
background-color: purple;
}
.spacer3 {
height:40%;
position: relative;
background-color: pink;
}
.spacer4{
height:40%;
position: relative;
background-color: blue;
}
HTML:
<div class="nameblock"></div><br/>
<div class="fulldisplay">
<div class="spacer1">
</div>
<div class="spacer2">
</div>
<div class="spacer3"></div>
<div class="spacer4"></div>
</div>
</body>

Apologize if I got the question wrong as I am not quite sure what you are trying to do, but if you want to have a way of ordering s dynamically, you could use css flexbox to do so. You might need to tweak the classes to have correct width and height (eg. width: 100%; height: 150px;) and define flex container as similar to below snippet.
.fullconversation {
padding: 0;
margin: 0;
list-style: none;
width: 30%;
display: flex;
flex-direction: row;
-webkit-flex-flow: row wrap;
justify-content: space-around;
}
and then
.spacer4{
width: 100%;
height: 150px;
position: relative;
background-color: blue;
order: -1;
}
For more information about flexbox, please refer to the urls below or feel free to ask any questions regarding flexbox or css. Hope this helps.
https://css-tricks.com/almanac/properties/o/order/
https://css-tricks.com/snippets/css/a-guide-to-flexbox/
***********Updated************
If you change the height of spacer1 to be 10%, then you will see the blue box visible at the bottom. Note that the value 10% is just an example, as long as the total size of the heights of inner s dose not take up more than 100%, the blue box will be visible.
.spacer1 {
height:10%;
position: relative;
background-color: green;
}
Also, if you want to see all divs regardless of the size, you could just set overflow to other than hidden.

Related

How to stack divs on top of each other? Position absolute isn't working

So I'm using flexbox to create the grid unfortunately, I'm a little stuck as to how to make the divs stack on top of each other. This is what it looks like when I hide overflow:auto and add position relative to the carddiv. I believe the divs are stacking on top but they don't look the right way.
this is what it looks like:
Image Link
https://imgur.com/a/1KsJDh7
What I want it to look like is this:
Except positon:absolute makes everything disappear.
I'm new to css/html so I'm not exactly sure what I'm doing wrong.
https://imgur.com/a/mrLsTdX
App.css
* {
/*overflow:auto*/
}
.App {
/*display: flex;*/
/*flex-wrap: wrap;*/
}
Card.css
.container{
background-color: yellow;
display: flex;
flex-flow: column;
text-align: center;
position: relative;
margin: 10% 10% 10%;
}
.cardDiv {
height: 100vh;
position: absolute;
}
.cardPicture {
background-color: blue;
height: 50vh;
}
.cardDescription {
background-color: green;
height: 50vh;
}
However, without position:absolute it looks like this which is what I want it to look like except it doesn't stack. I assume the first version is stacked which is why it only shows one div?
The code below is for the second image link:
https://imgur.com/a/mrLsTdX
App.css
* {
overflow:auto
}
.App {
/*display: flex;*/
/*flex-wrap: wrap;*/
}
Card.css
.container{
background-color: yellow;
display: flex;
flex-flow: column;
text-align: center;
position: relative;
margin: 10% 10% 10%;
}
.cardDiv {
height: 100vh;
}
.cardPicture {
background-color: blue;
height: 50vh;
}
.cardDescription {
background-color: green;
height: 50vh;
}
The cardDivs are being generated through a map function that is inserting the divs.
The html looks like this:
<div className='container'>
<div className="cardDiv">
<div className="cardPicture"></div>
<div className="cardDescription"></div>
</div>
</div>
Does anyone have any idea on what I could do make the divs stack up without disappearing?
I think the issue is the combination of a flex container and flex items that have been set to absolute positioning. When you set position: absolute on .cardDiv it takes all the cardDiv elements out of the flex flow, and without any width or content, the cardDiv's disappear. As an experiment, take your first CSS block and add a width (say, 50px) to .cardDiv. You should see the cards reappear, stacked and taking up 50 pixels horizontally.
When you set a element to display: flex or display: inline-flex, all the direct children of that element become flex items. You can see all the things that does to the children by default here, and the purpose of the various flex properties are there to manipulate how the children will be displayed along the axis you specify. If you set one of these flex-items to absolute positioning, however, it takes that element out of that flex configuration.
If I understand what you want correctly, I'm not sure you need the container to be flex at all. Try taking the flex properties out of the container, setting the cardDivs to position:absolute and setting width and height to conform to how much of the screen you want filled.
.container {
position: relative;
margin: 1rem;
}
.cardDiv {
position: absolute;
width: 100%;
height: 100vh;
}
.cardPicture {
background-color: blue;
height: 50%;
}
.cardDescription {
background-color: green;
height: 50%;
}
Let me know if this is not what you were looking for-- I figure you can adjust it to how you want the cards to appear. But that's them stacked and split 50-50 between picture and description.

CSS – Header in display: table element – positioning issue

While creating a HTML layout, I noticed some strange positioning issue I was unable to solve.
Take the following HTML:
<div class="outer-wrap">
<div class="header">
I am a Header
</div>
<div class="element">
Hello world
</div>
And combine with this CSS code:
#import "https://cdnjs.cloudflare.com/ajax/libs/normalize/3.0.2/normalize.css";
html, body { height: 100%; }
.outer-wrap {
width: 100%;
height: 100%;
display: table;
background: grey;
}
.element {
display: table-cell;
vertical-align: middle;
background: blue;
}
.header {
position: absolute;
background: red;
}
Fiddle
As you can see, I've set the wrapper to display: table, which enables me to vertically center any child element with setting display: table-cell and vertical-align: middle.
Now when I try to add a header, strange things start to happen.
First, I have to declare position: absolute on the header, otherwise the header horizontally pushes away .element. I don't know why this happens, but I understand why this fix works: Because position: absolute takes things 'out of the flow'.
But if I take a look at the Fiddle, you'll notice a small gap on the left side which exposes the grey background color defined on .outer-wrap:
What is causing this gap & how to fix this?
Why do I have to use absolute positioning on the header to make it expand to the full container width?
The key reason causing that is you're not defining the table-cell div and would not be 100% wide and you see its shifting towards right seeing the gray border color which is the background of outer-wrap div. So, you need to define the width:100%; when you use display:table-cell; to make it display correctly.
Changed css:
.outer-wrap {
width: 100%;
height: 100%;
display: table;
background: grey;
}
.element {
display: table-cell;
vertical-align: middle;
background: blue;
width: 100%;/*explicitly define width to be 100%*/
}
.header {
position: absolute;
background: red;
z-index: 1;/*to make it display in front*/
}
Fixed fiddle

Floating box to the right

I'm currently creating a website, which has a centered box with text and and such.
Now, i also want a box floating on the right, with a little gap from my main box.
I'll leave a picture here, where the red box i drew is the floating box i want to make.
Btw. the blue box is just a censored box i didn't want on the picture.
So my question for you is, how do i make a floating box like that?
I've tried a couple of times with different methods.
in the CSS, i've made a box and gave it the property float:right;
But when i do that, it just turns out like this
Any help will be greatly appreciated
DEMO
You can keep an element center align by defining its width then using margin: 0 auto; technique. this will make sure your center div is in center then you can use position: absolute to create the other box on offset position.
HTML:
<div class="main-wrapper">
<div class="main">This is in center position.</div>
<div class="side">This is in offset position.</div>
</div>
CSS:
body {
background: #333;
color: #fff;
}
.main-wrapper {
position: relative;
margin: 0 auto;
}
.main, .main-wrapper {
width: 500px;
}
.main {
border: 1px solid #f00;
min-height: 500px;
}
.side {
width: 200px;
border: 1px solid #f00;
min-height: 200px;
position: absolute;
top: 60px;
right: -300px;
}
.main, .side {
text-align: center;
padding: 10px;
}
My best guess is that you have a <div> with a float: right; in the end. Keep it in the first code. So that it gets floated correctly. I would code this way:
<div class="right">Right</div>
<div class="main">
Main Contents
</div>
CSS would be:
.right {float: right; width: 20%;}
.main {margin: auto; width: 60%;}
Preview:
Fiddle: http://jsfiddle.net/praveenscience/8WHyp/
U can have main container display : inline-block
width of each sub container as width : 30%;
and width of the floating box which is inside 3rd sub container as
width : 100%;
In case u dont need first div,
put some margin for the 2nd container
ex .. margin-left : 300px;
and in case u dont want ur floating box width to be 100% of the 3rd container, u can adjust it too

Can't center div in another div

I'm trying to make a menu bar centered horizontally in the header of my page. For some reason, i can't get the centering to work. I made a little test page roughly displaying the problem: JSFiddle. The inner div has to be 5px away from the bottom, that's whatI use the position: absolute for.
I've tried searching on the web alot, but everything I find gives me the same result, or none at all. Most problems I found were when text-align: center wasn't in the container div, but even with it, it still doesn't work.
I removed two css attributes and it work.
position: absolute;
bottom: 5px;
Check this Fiddle
5px from bottom. Fiddle
This is not a perfect way, but it's still kind of useful. I first think of this idea from this Q&A.
You'll have to make some change to your HTML:
<div id="container">
<div id="wrapper-center"> <!-- added a new DIV layer -->
<div id="inner_container">
TEXT ELEMETNES IN THIS THING!!!!
</div>
</div>
</div>
And the CSS will change to:
#container {
background: black;
width: 100%;
height: 160px;
position: relative;
}
#inner_container {
display: inline-block;
width: auto;
color: white;
background-color: #808080;
padding: 5px;
position: relative;
left:-50%;
}
#wrapper-center {
position:absolute;
left:50%;
bottom:5px;
width:auto;
}
Demo fiddle
The trick is to place the wrapper at the given top-bottom position, and 50% from left (related to parent), and then make the true content 50% to left (related to the wrapper), thus making it center.
But the pitfall is, the wrapper will only be half the parent container's width, and thus the content: in case of narrow screen or long content, it will wrap before it "stretch width enough".
If you want to centre something, you typically provide a width and then make the margins either side half of the total space remaining. So if your inner div is 70% of your outer div you set left and right margins to 15% each. Note that margin:auto will do this for you automatically. Your text will still appear to one side though as it is left-aligned. Fix this with text-align: centre.
PS: you really don't need to use position absolute to centre something like this, in fact it just makes things more difficult and less flexible.
* {
margin: 0;
padding: 0;
}
#container {
background: black;
width: 100%;
height: 160px;
}
#inner_container {
color:red;
height:50px;
width: 70%;
margin:auto;
text-align:center;
}
If you don't want a fixed width on the inner div, you could do something like this
#outer {
width: 100%;
text-align: center;
}
#inner {
display: inline-block;
}
That makes the inner div to an inline element, that can be centered with text-align.
working Ex
this CSS changes will work :
#container {
background: black;
width: 100%;
height: 160px;
line-height: 160px;
text-align: center;
}
#inner_container {
display: inline;
margin: 0 auto;
width: auto;
color: white;
background-color: #808080;
padding: 5px;
bottom: 5px;
}
Try this:
html
<div id="outer"><div id="inner">inner</div></div>
css
#outer {
background: black;
width: 100%;
height: 160px;
line-height: 160px;
text-align: center;
}
#inner{
display: inline;
width: auto;
color: white;
background-color: #808080;
padding: 5px;
bottom: 5px;
}
example jsfiddle
You may set the inline style for the inner div.
HTML:
<div id="container">
<div align="center" id="inner_container" style="text-align: center; position:absolute;color: white;width:100%; bottom:5px;">
<div style="display: inline-block;text-align: center;">TEXT ELEMETNES IN THIS THING!!!!</div>
</div>
</div>
Here is working DEMO

Div width 100% minus fixed amount of pixels

How can I achieve the following structure without using tables or JavaScript? The white borders represent edges of divs and aren't relevant to the question.
The size of the area in the middle is going to vary, but it will have exact pixel values and the whole structure should scale according to those values. To simplify it, I'd need a way to set "100% - n px" width to the top-middle and bottom-middle divs.
I'd appreciate a clean cross-browser solution, but in case it's not possible, CSS hacks will do.
Here's a bonus. Another structure I've been struggling with and end up using tables or JavaScript. It's slightly different, but introduces new problems. I've been mainly using it in jQuery-based windowing system, but I'd like to keep the layout out of the script and only control the size of one element (the middle one).
New way I've just stumbled upon: css calc():
.calculated-width {
width: -webkit-calc(100% - 100px);
width: -moz-calc(100% - 100px);
width: calc(100% - 100px);
}​
Source: css width 100% minus 100px
You can use nested elements and padding to get a left and right edge on the toolbar. The default width of a div element is auto, which means that it uses the available width. You can then add padding to the element and it still keeps within the available width.
Here is an example that you can use for putting images as left and right rounded corners, and a center image that repeats between them.
The HTML:
<div class="Header">
<div>
<div>This is the dynamic center area</div>
</div>
</div>
The CSS:
.Header {
background: url(left.gif) no-repeat;
padding-left: 30px;
}
.Header div {
background: url(right.gif) top right no-repeat;
padding-right: 30px;
}
.Header div div {
background: url(center.gif) repeat-x;
padding: 0;
height: 30px;
}
While Guffa's answer works in many situations, in some cases you may not want the left and/or right pieces of padding to be the parent of the center div. In these cases, you can use a block formatting context on the center and float the padding divs left and right. Here's the code
The HTML:
<div class="container">
<div class="left"></div>
<div class="right"></div>
<div class="center"></div>
</div>
The CSS:
.container {
width: 100px;
height: 20px;
}
.left, .right {
width: 20px;
height: 100%;
float: left;
background: black;
}
.right {
float: right;
}
.center {
overflow: auto;
height: 100%;
background: blue;
}
I feel that this element hierarchy is more natural when compared to nested nested divs, and better represents what's on the page. Because of this, borders, padding, and margin can be applied normally to all elements (ie: this 'naturality' goes beyond style and has ramifications).
Note that this only works on divs and other elements that share its 'fill 100% of the width by default' property. Inputs, tables, and possibly others will require you to wrap them in a container div and add a little more css to restore this quality. If you're unlucky enough to be in that situation, contact me and I'll dig up the css.
jsfiddle here: jsfiddle.net/RgdeQ
Enjoy!
You can make use of Flexbox layout. You need to set flex: 1 on the element that needs to have dynamic width or height for flex-direction: row and column respectively.
Dynamic width:
HTML
<div class="container">
<div class="fixed-width">
1
</div>
<div class="flexible-width">
2
</div>
<div class="fixed-width">
3
</div>
</div>
CSS
.container {
display: flex;
}
.fixed-width {
width: 200px; /* Fixed width or flex-basis: 200px */
}
.flexible-width {
flex: 1; /* Stretch to occupy remaining width i.e. flex-grow: 1 and flex-shrink: 1*/
}
Output:
.container {
display: flex;
width: 100%;
color: #fff;
font-family: Roboto;
}
.fixed-width {
background: #9BCB3C;
width: 200px; /* Fixed width */
text-align: center;
}
.flexible-width {
background: #88BEF5;
flex: 1; /* Stretch to occupy remaining width */
text-align: center;
}
<div class="container">
<div class="fixed-width">
1
</div>
<div class="flexible-width">
2
</div>
<div class="fixed-width">
3
</div>
</div>
Dynamic height:
HTML
<div class="container">
<div class="fixed-height">
1
</div>
<div class="flexible-height">
2
</div>
<div class="fixed-height">
3
</div>
</div>
CSS
.container {
display: flex;
}
.fixed-height {
height: 200px; /* Fixed height or flex-basis: 200px */
}
.flexible-height {
flex: 1; /* Stretch to occupy remaining height i.e. flex-grow: 1 and flex-shrink: 1*/
}
Output:
.container {
display: flex;
flex-direction: column;
height: 100vh;
color: #fff;
font-family: Roboto;
}
.fixed-height {
background: #9BCB3C;
height: 50px; /* Fixed height or flex-basis: 100px */
text-align: center;
display: flex;
flex-direction: column;
justify-content: center;
}
.flexible-height {
background: #88BEF5;
flex: 1; /* Stretch to occupy remaining width */
text-align: center;
display: flex;
flex-direction: column;
justify-content: center;
}
<div class="container">
<div class="fixed-height">
1
</div>
<div class="flexible-height">
2
</div>
<div class="fixed-height">
3
</div>
</div>
The usual way to do it is as outlined by Guffa, nested elements. It's a bit sad having to add extra markup to get the hooks you need for this, but in practice a wrapper div here or there isn't going to hurt anyone.
If you must do it without extra elements (eg. when you don't have control of the page markup), you can use box-sizing, which has pretty decent but not complete or simple browser support. Likely more fun than having to rely on scripting though.
Maybe I'm being dumb, but isn't table the obvious solution here?
<div class="parent">
<div class="fixed">
<div class="stretchToFit">
</div>
.parent{ display: table; width 100%; }
.fixed { display: table-cell; width: 150px; }
.stretchToFit{ display: table-cell; vertical-align: top}
Another way that I've figured out in chrome is even simpler, but man is it a hack!
.fixed{
float: left
}
.stretchToFit{
display: table-cell;
width: 1%;
}
This alone should fill the rest of the line horizontally, as table-cells do. However, you get some strange issues with it going over 100% of its parent, setting the width to a percent value fixes it though.
We can achieve this using flex-box very easily.
If we have three elements like Header, MiddleContainer and Footer. And we want to give some fixed height to Header and Footer. then we can write like this:
For React/RN(defaults are 'display' as flex and 'flexDirection' as column), in web css we'll have to specify the body container or container containing these as display: 'flex', flex-direction: 'column' like below:
container-containing-these-elements: {
display: flex,
flex-direction: column
}
header: {
height: 40,
},
middle-container: {
flex: 1, // this will take the rest of the space available.
},
footer: {
height: 100,
}
what if your wrapping div was 100% and you used padding for a pixel amount, then if the padding # needs to be dynamic, you can easily use jQuery to modify your padding amount when your events fire.
I had a similar issue where I wanted a banner across the top of the screen that had one image on the left and a repeating image on the right to the edge of the screen. I ended up resolving it like so:
CSS:
.banner_left {
position: absolute;
top: 0px;
left: 0px;
width: 131px;
height: 150px;
background-image: url("left_image.jpg");
background-repeat: no-repeat;
}
.banner_right {
position: absolute;
top: 0px;
left: 131px;
right: 0px;
height: 150px;
background-image: url("right_repeating_image.jpg");
background-repeat: repeat-x;
background-position: top left;
}
The key was the right tag. I'm basically specifying that I want it to repeat from 131px in from the left to 0px from the right.
In some contexts, you can leverage margin settings to effectively specify "100% width minus N pixels". See the accepted answer to this question.