Vertically center child element, but allow parent to expand when child overflows - css

I'm looking for a css-only solution to this problem. I have a parent and a child div. The parent has a minimum height. When the child div has a smaller height, I want it to be vertically centered in the parent. But when the child div expands past the parent's min-height, I want the parent to expand.
Illustrated in this image:
I can come close; position: relative on the child allows me to affect the parent height while still positioning the child, but I can't figure out how to determine the correct position (top: 50% plus transform: translateY won't work for me since the parent's height is not fixed).
This one has me stumped! Thanks in advance for any suggestions.

You can easily do this with flex:
.container {
min-height: 300px;
display: flex;
background: red;
justify-content: center; /* Center horizontally */
}
.container>div {
height: 200px;
width: 200px;
background: blue;
margin: auto; /* Center vertically */
}
<div class="container">
<div>some content</div>
</div>
With bigger content height:
.container {
min-height: 300px;
display: flex;
background: red;
justify-content: center;
}
.container>div {
height: 800px;
width: 200px;
background: blue;
margin: auto;
}
<div class="container">
<div>some content</div>
</div>

Related

Container wrapping around tallest child in CSS Grid

I think I might be having the wrong approach with this design problem. Here is a codepen with a reproduction of the issue and a Stack Snippet :
Codepen
body {
display: flex;
justify-content: center;
}
.main-container {
background-color: grey;
width: 1000px;
display: grid;
grid-template-areas: "img description" "share share";
grid-template-columns: 271px 1fr;
}
.img-meta {
grid-area: img;
width: 272px;
align-self: center;
position: relative;
}
.red {
width: 272px;
height: 380px;
background-color: red;
}
.green {
background-color: green;
height: 150px;
align-self: center;
}
.blue {
background-color: blue;
position: absolute;
padding-top: 10px;
height: 100px;
width: 272px;
}
<div class="main-container">
<div class="img-meta">
<div class="red"></div>
<div class="blue"></div>
</div>
<div class="green"></div>
</div>
Problem is immediately apparent: the blue container is out of the parent grid container. The green container contains text and expands depending on the quantity of said text, which is what is wanted. The red container has fixed dimensions and contains an image which needs to position itself at the center of the green container at all times. Blue container needs to be just under the red container regardless of position of red container.
When the text is longer than the img-meta container, design is as expected.
But when the text is shorter than img-meta, the design appears as shown in the snippet: because the blue container is relatively positioned, it escapes the flow of the document and the grey grid container doesn't wrap around it.
I understand this is normal behaviour for a relatively positioned container, but I am out of ideas to get the expected design.
I have tried to design this with flexboxes initially, before picking a grid.
I tried to use min-height on the text container to force it to always have the height of the of the img-meta container but no luck because it will create a lot of empty space at the top.
I have also tried to have the blue container out of its parent and remove its positioning in order to get the grid to wrap around it, but this will leave a space between the red and the blue container!
Maybe the grid direction is wrong for that type of design, and I'm looking forward to see your ideas!
I'd go with
.blue { 
position: absolute;
width: 100%;
height: 100%;
}
.grey {
position: relative;
display: flex;
align-items: center;
}

Why can't I adjust the height of flex items using "align-items: stretch" when the flex container is a scroll box?

I have two elements inside a scroll box like this. However, here the left element does not match the right element. The element on the left ignores align-items and matches the height of the scroll box.
Why is this, can I match the height of the left element with the right element?
I guess there is a duplicate question on this issue, but for now I haven't found it.
.box {
position: fixed;
top: 0;
right: 0;
bottom: 0;
left: 0;
width: 100vw;
height: 100vh;
display: flex;
align-items: stretch; /* not worked. why? */
overflow: hidden scroll;
background: green;
}
.item1 {
background: red; /* doesnt stretch */
}
.item2 {
width: 200px;
height: 500px;
background: red;
margin: auto;
}
<div class="box">
<div class="item1">
<span>sample text</span>
</div>
<div class="item2"></div>
</div>
align-item:center; in box class
and give height as needed in item1 and item2
item2 is not taking full height as item1 because of margin:auto in item1

Centering a div inside a flex item

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%)

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>

CSS html 100 % width height layout

I am trying to build a layout that consumes all the space that is visible in browser. I set html, body height 100% as was suggested in different SO posts. Following is the markup that I am trying
<div>
<div class="header">
</div>
<div class="main">
<div class="container">
<div class="content"></div>
</div>
</div>
</div>
CSS:
html, body {
height: 100%;
max-height: 100%;
}
.header {
height: 30px;
background-color: #000;
}
.main {
height: auto;
padding-right: 0px;
max-height: 100%;
width: 100%;
display: block;
clear: both;
background-color: #eee;
}
.container {
width: 90%;
overflow-y: scroll;
background-color: #ccc;
}
.content {
height: 2000px;
width: 80%;
background-color: #fff;
}
the content div height cause the whole body to grow and hence the browser's default scroll bars are shown. Though I have set the container div to scroll in order to display the content of content div, still the scroll bars for container div don't show. How can I fix this.
here is the jsfiddle
Edited:
By default the height of the div element depends on its content (unlike width which takes 100% width of the parent). That's why when you specify the height of inner element as a percentage it won't be accurate if your parent tag has no explicitly defined height (that means height has to be defined up to the very top of the DOM since height is not inheritable).
In your case you need to add height: 100%; or any other height to your .container , .main and the wrapper div
modified fiddle

Resources