Flexbox: Centering element in the middle of the screen - html

If I'm going to center an element in the middle of the screen with flexbox, is the following approach the most elegant?
HTML
<div class='btn'></div>
CSS
body{
overflow: hidden;
position: absolute;
width: 100%;
height: 100%;
display: flex;
}
.btn{
width: 10rem;
height: 10rem;
background-color: #033649;
margin: auto;
}
It seems that I have to use position: absolute and height+weight 100% to achieve this.

You have to use position: absolute because the default for an element is position: relative, and in this case, there is nothing to be relative to because you have made the flex container the body.
Your code will work fine, but there is a command to center objects in the actual flex model itself like so:
body{
overflow: hidden;
position: absolute;
width: 100%;
height: 100%;
display: flex;
justify-content: center; /*centers items on the line (the x-axis by default)*/
align-items: center; /*centers items on the cross-axis (y by default)*/
}
If you do this you can remove the margin: auto from your .btn class to perhaps give some more wiggle room in your code.
Here is a good resource for all things flexbox.

You can position an element inside a container by using place-items without the need to add any CSS property to that element. In this case I'm using the body of document as the container.
Snippet
body{
margin:0;
height:100vh; /* use 100% of the height of the viewport */
display:grid;
place-items: center;
}
<body>
<button>I'm a lonely button :B</button>
</body>
About place-items
The CSS place-items shorthand property allows you to align items along
both the block and inline directions at once (i.e. the align-items and
justify-items properties) in a relevant layout system such as Grid or
Flexbox. If the second value is not set, the first value is also used
for it.
Find more info here

Related

How can you easily center a div when it comes to shapes?

newbie here starting with the basics of HTML and CSS. I really have a hard time centering a simple div (a square in my example). I've watched many tutorials as well as read many articles but still cannot really figure out the "best" way to do it. With so many different ways like align-items, align-content, justify-items, justify-content, I get overwhelmed at some point especially with how these behave with different displays (flex, grid, inline-block etc), not to mention the positions of parents and childs. Below is an example that I still can't quite easily manipulate/center. The HTML is only the boilerplate and a blank div with class square inside the body. Thank you all in advance for your tips!
html {
height: 100%;
}
body {
min-height: 100%;
background-color: #162944;
}
.square {
height: 10rem;
width: 10rem;
background-color: salmon;
display: flex;
align-items:center;
justify-items: center;
align-content: center;
justify-content:center;
place-content: center;
place-items: center;
}
The above example has been tried with all possible combinations and NOT only as you see it. Also with display:grid; and others. Is there really not a simple way to center an object on your page?
One way to center a div is to set the width of the element and then use the margin property to set the left and right margins to auto. This will horizontally center the element within its container.
For example:
.element {
width: 400px;
margin-left: auto;
margin-right: auto;
}
You can also by using the text-align property.
.shape {
text-align: center;
}
Also by using the margin property.
For example:
.shape {
margin: 0 auto;
}
Finally, you can center a div when it comes to shapes by using the transform property.
For example:
.shape {
transform: translate(50%, 50%);
}
Centering a div can be easy or hard based on your layout options and what you want to achieve.
The simplest way to horizontally center a div, add a width and margin: 0 auto.
Simplest way to horizontally and vertically center a div is using a flexbox, display: flex; justify-content:center; align-items:center. Also you can go with display:table and display:table-cell.
Last option is to use Positioning. You can take a div, style it with position:relative and add a height:300px,width:300px. Then inside the parent div, add a child div and style it with position:absolute; top:50%; left:50%; transform:translate(-50%,-50%); height:50px; width:50px

Stacking Imgs/Video vertically

I have code to center my images (and eventually videos) like I want inside a div, but I am trying to get the images to stack vertically in a column.
It works if the space is confined enough, but I want it to work all the time. What can I do? Here is my codepen:
div{
margin: 0 auto;
height: 100vh;
text-align: center;
overflow: hidden;
max-width: 172vh;
}
img{
height: 50%;
}
https://codepen.io/thejaredmosley/pen/OJPVqBa
try below:
div {
....
display: flex;
flex-direction: column;
}
You can simply do it with the display:block CSS property.
https://www.w3schools.com/cssref/pr_class_display.asp
Give this CSS to your image and your image will get full-width space and will come in a stack.
So for Image, add this property:
img{
display:block;
}

Flexbox align-items overflow text get cuts off at top [duplicate]

This question already has answers here:
Can't scroll to top of flex item that is overflowing container
(12 answers)
How to use safe center with flexbox?
(3 answers)
Closed 5 years ago.
I have the following situation, the text get cuts off at the top when it not longer fits inside the container. What can I do to fix that? I'd still like the text to be centered if it's smaller than the container, and I can't change the container size.
div {
display: flex;
align-items: center;
width: 100px;
height: 50px;
overflow: auto;
word-break: break-word;
}
<div>
sdjhfkahsdkjfadsfhk jaskjfsj fsldflkasjklsjflakj flksjfakljflksjflkasfjklasjflfd
</div>
The problem here is caused by the fact that when using align-items (or justify-content) to center a flex row item, it will, by design, overflow at its top/bottom (or left/right).
To solve that a new keyword, safe, is introduced, though not many browsers support it yet.
How to use safe center with flexbox?
The other option is to use auto margin's, though with the given markup you can't, as the text doesn't have an inner wrapper (well, it has an anonymous one, though those we can't target with a CSS selector).
So by adding an inner wrapper (fiddle with wrapper) you can use auto margin's, and is well explained here:
Can't scroll to top of flex item that is overflowing container
But sometimes we just can't change the markup, and when, here is a little trick, using the pseudo elements, and use auto margin's on them.
To vertical center the text we also need the flex direction to be column so the pseudo is rendered above/below.
Stack snippet
div {
display: flex;
flex-direction: column; /* added */
width: 100px;
height: 50px;
overflow: auto;
word-break: break-word;
border: 1px solid gray;
}
div::before, div::after {
content: '';
}
div::before {
margin-top: auto; /* added */
}
div::after {
margin-bottom: auto; /* added */
}
<div>
sdjhfkahsdkjfadsfhk jaskjfsj fsldflkasjklsjflakj flksjfakljflksjflkasfjklasjflfd
</div>
<div>
sdjhf
</div>
If you wrap the text into another tag, and set margin: auto 0; it seems to be working well.
div {
display: flex;
width: 100px;
height: 50px;
overflow: auto;
word-break: break-word;
background: pink;
margin-bottom: 20px;
}
span {
margin: auto 0;
}
<div>
<span>sdjhfkahsdkjfadsfhk jaskjfsj fsldflkasjklsjflakj flksjfakljflksjflkasfjklasjflfd</span>
</div>
<div>
<span>sdjhfkah</span>
</div>

How to force a div to scroll after a certain size?

The Fiddle
This fiddle explains the problem clearly: fiddle (Edit: fixed broken fiddle.)
The Problem
I have a container div that has 3 divs inside of it.
The top div and middle div are dynamic in height. The bottom div is fixed.
Once the middle div expands enough, I want it to be scrollable.
Code Snippet
The basic structure:
<div id='container'>
<div id='top'>Top (dynamic) content</div>
<div id='middle'>Middle (dynamic) content</div>
<div id='bottom'>Bottom (fixed) content</div>
</div>
The basic CSS:
#container {
position: absolute;
top: 0;
left: 0;
bottom: 0;
width: 250px;
padding-bottom: 100px; /* bottom div height */
}
#top {
???
}
#middle {
???
}
#bottom {
position: absolute;
bottom: 0;
left: 0;
height: 100px;
}
The Question
Is there a way to accomplish this using just CSS? (By just CSS, I mean no JavaScript.)
Here is an approach using flexboxes for the layout:
Example Here
Set the display of the parent #container element to flex. Since you want the element to stack vertically, set the flex-direction property's value to column. And justify-content: space-between is used to position the last element at the bottom when the height of the middle element decreases.
It's worth pointing out that vh units are used to set the height of the parent element to the height of the viewport.
#container {
height: 100vh;
display: flex;
flex-direction: column;
justify-content: space-between;
}
I also set the middles element's flex-shrink property to a relatively arbitrary number in order for it to shrink. Then flex-basis: 100% is used to force the element to fill the remaining space.
#middle {
overflow-y: auto;
flex-shrink: 50;
flex-basis: 100%;
}
Yes, set a max-height on the #container. You may also need to fiddle with the overflow property. Start by setting it to scroll.
You could do
#middle {
overflow-y: auto; /* does nothing */
height: calc(100% - 100px);
}

Centering in the unknown

I would like to center and clamp the dimensions of a child div inside its parent.
<style type='text/css'>
.parent {
width: 100%;
height: 100%;
}
.child {
max-width: 100%;
max-height: 100%;
}
</style>
<div class="parent">
<div class="child">
<img src='dog.jpg' />
</div>
</div>
Here are the constraints:
The parent div is set to occupy the entire screen (of unknown size), so width:100% and height:100%.
The width and height of the child div are unknown. In one use case, the child div contains an image. In another, it contains a video.
The width and height of the child div must be constrained to the size of the parent, so max-width: 100% and max-height: 100%.
The child div must be vertically and horizontally centered inside the parent.
Ideally, this should work without javascript.
IE can be left unsupported :)
I've tried all the techniques listed in this excellent article, 'Absolute Centering in CSS' , and none of them pan out. Here's why:
Absolute centering: In order for this technique to work with a child of unknown size, you must set display:table on the child. You can then constrain the max-width of the child's contents, but not the max-height, because by CSS 2.1 rules, tables render to fit their contents.
Negative margins: Doesn't allow for variable height.
Transforms: Undesirable because it can result in blurry rendering.
Table-cell: Fails for the same reason that absolute centering fails, i.e. table rendering.
Inline-block: Doesn't work in the important case where the child is 100% width.
Flexbox: Works well until a window resize occurs, at which point you have to force a Webkit redraw to propagate the centering changes. This hack does the job, but it's still a hack. I want to believe there's a more elegant solution to this.
Best solution here is to use :before pseudo element. Check out this article on centering the unknown, http://css-tricks.com/centering-in-the-unknown/
SEE THE DEMO HERE
body,html {
width: 100%;
height: 100%;
margin: 0;
}
.container {
text-align: center;
background: #ccc;
width: 100%;
height: 100%;
}
.container:before {
content: '';
display: inline-block;
height: 100%;
vertical-align: middle;
margin-right: -0.25em; /* Adjusts for spacing */
}
.image {
display: inline-block;
max-width: 100%;
max-height: 100%;
vertical-align: middle;
padding: 10px 15px;
border: #a0a0a0 solid 1px;
background: #f5f5f5;
}
You could use display:table and display:table-cell like so Jsfiddle. Though this will just center the image of the child div.
If you need to have a centered div around the image you could always add another div inside of the child div with the style display: inline-block example