Centering a div inside a flex item - css

I've checked similar posts and they are not helping.
I want my innermost div to appear in the center of the parent div.
For example:
<container>
<div class="parent">
<div class="child">
</div>
</div>
</container>
The parent div is a flex item inside an inline-flex container. margin: 0 auto is only allowing it to horizontally align, but I need it vertically aligned as well. Height and width are 80% of parent div.
How do I go about this?
Also, I will need to add a display: none at times. When I don't want display: none active, what can I leave display as?
Edit:
.Card {
width: 150px;
height: 220px;
border: 2px solid rgb(218, 186, 186);
margin: 10px;
display: inline-flex;
}
.FaceUp {
display: none;
}
.FaceDown {
height: 80%;
width: 80%;
margin: 0 auto;
}
I've tried margin, justify-content, justify-items, align-content, align-items, vertical-align. None seem to be working.
FaceDown and FaceUp will never display at the same time. They are the child/sibling divs inside the parent div.

Did u try writing:
parentDiv {
display: flex;
justify-content: center;
align-content: center;
}
childDiv {
align-self: center;
}
Because every parent should have display: flex; in order to affect a child

try this
position: absolute;
top: 50%;
transform: translateY(-50%)

Related

Flex child to determind parent's width

I have a parent with a flex child :
.card {
background-color: white;
max-width: 80vw;
height: auto;
left: 0;
right: 0;
margin-left: auto;
margin-right: auto;
position: fixed;
bottom: 10;
overflow: hidden;
border-radius: 32.5vw;
z-index: 100001;
}
.menusC {
width: auto;
height: auto;
margin: auto;
display: inline-flex;
flex-wrap: nowrap;
flex-direction: row;
align-content: flex-start;
justify-content: center;
background-color: red;
}
<div class="card">
<div class="menusC">
<div class="menuBC">
......
</div>
</div>
</div>
As you can see my flex is inline-flex which means the flex get the size of its items.
But the parent card insist to have it's own width (takes the max otherwise 100%).
How would i make the card - be exactly at the width of the flex - menusC ?
I have not seen what it looks like when the code is executed, but why has the parent got a fixed position with left and right set to 0?
This is telling it to go all the way from left to right.
Maybe change position: fixed to something else, or remove the left or right properties if fixed position is needed.

Does 'position: absolute' conflict with Flexbox?

I want to make a div stick on the top of the screen without any influence to other elements, and its child element in the center.
.parent {
display: flex;
justify-content: center;
position: absolute;
}
<div class="parent">
<div class="child">text</div>
</div>
When I add the position: absolute line, justify-content: center becomes invalid. Do they conflict with each other and, what's the solution?
EDIT
Thanks guys it's the problem of parent width. But I'm in React Native, so I can't set width: 100%. Tried flex: 1 and align-self: stretch, both not working. I ended up using Dimensions to get the full width of the window and it worked.
EDIT
As of newer version of React Native (I'm with 0.49), it accepts width: 100%.
No, absolutely positioning does not conflict with flex containers. Making an element be a flex container only affects its inner layout model, that is, the way in which its contents are laid out. Positioning affects the element itself, and can alter its outer role for flow layout.
That means that
If you add absolute positioning to an element with display: inline-flex, it will become block-level (like display: flex), but will still generate a flex formatting context.
If you add absolute positioning to an element with display: flex, it will be sized using the shrink-to-fit algorithm (typical of inline-level containers) instead of the fill-available one.
That said, absolutely positioning conflicts with flex children.
As it is out-of-flow, an absolutely-positioned child of a flex
container does not participate in flex layout.
you have forgotten width of parent
.parent {
display: flex;
justify-content: center;
position: absolute;
width:100%
}
<div class="parent">
<div class="child">text</div>
</div>
You have to give width:100% to parent to center the text.
.parent {
display: flex;
justify-content: center;
position: absolute;
width:100%
}
<div class="parent">
<div class="child">text</div>
</div>
If you also need to centre align vertically, give height:100% and align-itens: center
.parent {
display: flex;
justify-content: center;
align-items: center;
position: absolute;
width:100%;
height: 100%;
}
In my case, the issue was that I had another element in the center of the div with a conflicting z-index.
.wrapper {
color: white;
width: 320px;
position: relative;
border: 1px dashed gray;
height: 40px
}
.parent {
position: absolute;
display: flex;
justify-content: center;
top: 20px;
left: 0;
right: 0;
/* This z-index override is needed to display on top of the other
div. Or, just swap the order of the HTML tags. */
z-index: 1;
}
.child {
background: green;
}
.conflicting {
position: absolute;
left: 120px;
height: 40px;
background: red;
margin: 0 auto;
}
<div class="wrapper">
<div class="parent">
<div class="child">
Centered
</div>
</div>
<div class="conflicting">
Conflicting
</div>
</div>

how could I realize css vertical and horizontal centering?

How could I vertically center a child within a parent ?
And, the width and height of child and parent is fixed, but unknown.
How could I realize it?
<div class="parent">
<div class="child"></div>
</div>
My prefered technique for centering a box both vertically and horizontally requires two containers.
The outher container
should have display: table;
The inner container
should have display: table-cell;
should have vertical-align: middle;
should have text-align: center;
The content box
should have display: inline-block;
should re-adjust the horizontal text-alignment to eg. text-align: left; or text-align: right;, unless you want text to be centered
The elegance of this technique, is that you can add your content to the content box without worrying about its height or width!
Just add your content to the content box.
Demo
body {
margin : 0;
}
.outer-container {
position : absolute;
display: table;
width: 100%; /* This could be ANY width */
height: 100%; /* This could be ANY height */
background: #ccc;
}
.inner-container {
display: table-cell;
vertical-align: middle;
text-align: center;
}
.centered-content {
display: inline-block;
text-align: left;
background: #fff;
padding : 20px;
border : 1px solid #000;
}
<div class="outer-container">
<div class="inner-container">
<div class="centered-content">
<p>You can put anything here</p>
<p>Yes, really anything!</p>
</div>
</div>
</div>
See also this Fiddle!
in css vertical-align:middle is used to align a child vertically centre. But this property is applied to only those elements which havedisplay:inline-block or display:table-cell. So accordingly try to apply display property and you will get vertically centre position of your elements.
You can center things through:
margin: 0 auto;
Try this code
body {
margin: 0;
padding:0;
}
.div1 {
display: flex;
align-items: center;
justify-content: center;
height: 100vh;
}
.div2 {
width: 50vw;
height: 50vh;
background: #999;
}

How can I have a position: fixed; behaviour for a flexbox sized element?

I have a div called .side-el which I would like to have in a position: fixed; behavior, but as soon as I apply position fixed the width alternates from the right one. The right width would be the one set by flexbox. How can I achieve this goal?
.container {
-webkit-align-content: flex-start;
align-content: flex-start;
-webkit-align-items: flex-start;
align-items: flex-start;
display: -webkit-flex;
display: flex;
-webkit-flex-direction: row;
flex-direction: row;
-webkit-flex-wrap: wrap;
flex-wrap: wrap;
-webkit-justify-content: flex-start;
justify-content: flex-start;
* {
box-sizing: border-box;
-webkit-flex-grow: 1;
flex-grow: 1;
-webkit-flex-shrink: 0;
flex-shrink: 0;
}
}
.main-el {
box-sizing: border-box;
padding:0 2em;
width: 70%;
}
.side-el {
box-sizing: border-box;
width: 30%;
}
<div class="container" style="background-color: blue; height: 100px;">
<div class="main-el">
<div style="background-color: red; height: 1000px;">content</div>
</div>
<div class="side-el" >
<div style="background-color: red; height: 100px;">content</div>
</div>
</div>
Here's a way to do this inspired by bootstrap:
.fixed-top {
display: flex;
position: fixed;
top: 0;
left: 0;
right: 0;
}
This gives your flex-box room to breathe and do it's flex-box thing. If your flex-direction is column, you could use top, left, bottom instead.
This works because when you give an element a fixed position and a left and right of 0 or a top and bottom of 0, the element is stretched to fill the space from left to right, or top to bottom. That in turn allows a flex-box to use the amount of space you would expect without position fixed.
You can't.
As explained by the CSS2.1 spec:
Absolutely positioned boxes are taken out of the normal flow.
And the Flexible Box Layout spec confirms that:
An absolutely-positioned child of a flex container does not
participate in flex layout. However, it does participate in the
reordering step (see order), which has an effect in their
painting order.
(Emphasis mine)
#Daniel , I know this is very late but ... while the accepted answer is correct, I don't feel it's very helpful.
I had the same question (which is how I came across this post), and the solution I think I'll go with is to wrap the position fixed element within the flex element.
Here's a (very ugly) example
Relevant Markup
<aside class="Layout-aside" ng-class="{'isCollapsed': collapsed}" ng-controller="AsideCtrl">
<div class="Layout-aside-inner">
<button ng-click="collapsed = !collapsed">
<span ng-show="collapsed">></span>
<span ng-hide="collapsed"><</span>
</button>
<ul class="Layout-aside-content">
<li ng-repeat="i in items">{{i}}</li>
</ul>
</div>
</aside>
Relevant CSS
.Layout-aside {
order: 0;
min-width: 140px;
width: 140px;
background-color: rgba(0, 255, 0, .4);
transition: width .4s, min-width .4s;
}
.Layout-aside.isCollapsed {
min-width: 25px;
width: 25px;
}
.Layout-aside-inner {
position: fixed;
}
.Layout-aside.isCollapsed .Layout-aside-inner {
width: 25px;
}
.Layout-aside.isCollapsed .Layout-aside-content {
opacity: 0;
}
position:sticky was mentioned by Juozas Rastenis above but without code example.
Here's a minimalist example:
* {
box-sizing: border-box;
}
body {
display: flex;
margin: 0;
}
nav {
width: 20%;
height: 100vh;
top: 0; /* this is required for "sticky" to work */
position: sticky;
background: lightblue;
padding: 1rem;
}
main {
height: 3000px; /* cause scroll */
background: lightpink;
flex-grow: 1;
padding: 1rem;
}
<body>
<nav>
sidebar here
</nav>
<main>
content here
</main>
</body>
You can achieve it with a css alternative position: sticky
It acts great but the only problem is browser support (June 2018):
https://caniuse.com/#feat=css-sticky
Hope it gets better soon.
A far simpler solution would be to use overflow-y:scroll and height: 100vh on the main-el container. This will give the appearance of fixed position to the side-el container without resorting to position: fixed.
You are saying you want position:fixed;-like behavior that plays together with flexbox. As mentioned in the accepted answer, applying this property to an element drops it out of the normal flow, so this isn't really possible.
If what you want is to have a fixed sidebar .side-el and a scrollable content box .main-el as the items of a flex container, here's how you might do this:
Disable scrolling in the flex container's parent; let's assume it's
<body>, as you don't provide div.container's parent. Also, hard-set
it's height to viewport-height (100vh) so that no part of the body's
box remains outside view (imagine the body's box normally extending
beyond your screen to contain the entire document; you don't want
that, if you are to disable the ability to move the viewport via
scrolling).
Set the flex container's (.container) height to that of it's parent.
Selectively re-enable scrolling for the content box (.main-el).
In CSS:
body{
overflow: hidden;
height: 100vh;
}
.container {
display: flex;
height: 100%;
}
.main-el {
overflow-y: auto;
}
You can achieve this without position: fixed; by just adding overflow: auto; and height: 100%; to the flex-item that contains the long content:
.container {
display: flex;
}
.main-el {
padding:0 2em;
width: 70%;
overflow: auto;
height: 100%;
}
.side-el {
width: 30%;
}
<div class="container" style="background-color: blue; height: 300px;">
<div class="main-el">
<div style="background-color: red; height: 1000px;">content</div>
</div>
<div class="side-el" >
<div style="background-color: red; height: 100px;">content</div>
</div>
</div>
I had the same issue, I actually just found a way to have flex-box, a width for the nav bar, and center it while in a fixed position.
nav {
display: flex;
height: 50px;
width: 90%;
left: 5%;
position: fixed;
}
I wanted to be able to have a flex-box nav bar in a fixed position but centered. So what I did was do the left 5% since that's equal to half of the 10% width left over. Try it out, it might help you! :)

Scrollable paragraph having limited height to its parent

I want to make P to be able to take more text than the height can contain, just so the text can be scrolled down to be read. DIV CLASS="others" has the right height I want. (500px)
The problem is, when I use the overflow: scroll function it goes all the way to the bottom of the page.
EDIT: Forgot to mention I want the titles "News" and "Products" to be without the scroll bar.
Thanks.
.others {
position: relative;
vertical-align: middle;
width: 70%;
background-color: #d0d0d0;
height: 500px;
margin: 0px;
padding: 40px 15% 20px 15%;
display: flex;
justify-content: center;
}
.others div {
width: 400px;
display: inline-block;
float: left;
margin: 0px 15px;
}
.others #news {
background-color: black;
color: white;
text-align: center;
}
.others #products {
background-color: black;
color: white;
text-align: center;
}
.others a {
color: white;
text-decoration: none !important;
}
.others #newsfeed, #productsfeed {
margin: 0px;
padding: 10px 0px;
background-color: lightgreen;
}
.others p {
margin: 0px;
padding: 10px 10px;
vertical-align: middle;
height: 800px;
overflow: scroll;
}
<DIV CLASS="others">
<DIV ID="news">
<H3 ID="newsfeed">News</H3>
<P>News will come here.</P>
</DIV>
<DIV ID="products">
<H3 ID="productsfeed">Products</H3>
<P>Cool photos here.</P>
</DIV>
</DIV>
As I mentioned in my comment, the issue is caused by specifying an explicit height to the inner paragraphs.
Besides, in order to make the inner paragraphs respect the height of their parents (#news and #products flex items which have the same height of their flex container, the .other) you could change the display type of the parents to flex as well and set their flex-direction to column.
And then give flex: 1; to the paragraphs as follows:
Example Here
#news, #products {
display: flex;
flex-direction: column;
}
#news p, #products p {
flex: 1;
overflow: auto; /* up to you */
}
As a side-note: make sure you have included the old (prefixed) syntax of flexbox as well for the sake of browser support. You could use tools like Auto Prefixer to achieve that.
You need a containing div on the paragraphs, then set overflow: scroll; and height: 460px; on that container (or whatever height you need to have it contained within the 500px tall .others block).
You'd also need to make sure your .others div styling doesn't apply to that container - in my example below, I changed that selector to .others > div to only select immediate children of .others. And you should remove the height: 800px; from the inner paragraphs, as mentioned by Hashem Qolami.
jsfiddle example

Resources