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>
Related
This question already has an answer here:
Why is a flex item limited to parent size?
(1 answer)
Closed 10 months ago.
I like to have a div that keeps all it's children in the center (vertical and horizontal). I can easily achieve this by using flexbox. But when my children width get bigger than the parent, overflow: scroll does not work
Codepen
Anybody know why and how can be fixed?
Update
My issue has been fixed. BUT, when I add a content to children, the content not showing correctly.
.container {
height: 500px;
width: 500px;
background: red;
display: flex;
justify-content: center;
align-items: center;
overflow: scroll;
}
.children {
min-width: 1200px;
height: 50px;
background: blue;
}
<div class='container'>
<div class="children"><h1>Welcome to my city, California</h1></div>
</div>
It looks like the child object is not actually 1200px - it's getting squished down to 500px. However, if you set min-width: 1200px; in the child component, it seems to override this and produces the behavior you expect.
This question already has answers here:
How can I center text (horizontally and vertically) inside a div block?
(27 answers)
Closed 2 years ago.
I am trying to horizontally center one div inside parent div (Which is display flex in column mode) using margin 0 auto. When I do this the inner div is getting shrinked to the size of its content. Can someone explain why this is happening and how to fix this?
HTML
<div class="container">
<div class="mydiv">
CENTER THIS DIV
</div>
</div>
CSS
.container{
background-color: brown;
height: 100px;
display: flex;
flex-direction: column;
}
.mydiv{
background-color: chartreuse;
max-width: 500px;
margin: 0 auto;
}
If I remove flex from parent, then I am getting the correct output :
However, with the flex properties as in above code, this is what I get :
When you use display: flex; in a parent, the children automatically get the default flex values:
The item is sized according to its width and height properties. It shrinks to its minimum size to fit the container, but does not grow to absorb any extra free space in the flex container. This is equivalent to setting "flex: 0 1 auto".
That's why your .mydiv adjusts to fit the text.
(more info: https://developer.mozilla.org/en-US/docs/Web/CSS/flex)
If you don't want that to happen you could do something like this:
.container{
background-color: brown;
height: 100px;
display: flex;
flex-direction: column;
align-items: center; /* add this */
}
.mydiv{
background-color: chartreuse;
width: 100%; /* add this */
max-width: 500px; /* add this */
}
Working example:
https://codepen.io/sergiofruto/pen/dyMqbrm
This question already has answers here:
Why don't flex items shrink past content size?
(5 answers)
Closed 3 years ago.
EDIT: added flex-direction: column, missed it in the initial code.
When the child has overflow:auto and the parent has overflow:auto, the scrollbars appear on the child.
But when overflow:auto is removed from the parent, the scrollbars appear on the grand-parent .
html,
body {
height: 100%;
width: 100%;
overflow: hidden;
font-family: "Roboto", sans-serif;
}
body {
margin: 0;
padding: 0;
}
.App {
display: flex;
height: 100%;
}
.grand-parent {
display: flex;
flex-direction: column;
background: red;
overflow: auto;
padding: 20px;
}
.parent {
display: flex;
overflow: auto;
padding: 20px;
background: green;
}
.child {
overflow: auto;
font-size: 156px;
}
<div class="App">
<div class="grand-parent">
<div class="parent">
<div class="child">
Some content which grows bigger
</div>
</div>
</div>
</div>
Why is that? I would still expect the scrollbars to appear on the child.
How is the browser layout algorithm working here?
EDIT:
weirdly enough, the behavior seems to depend on the grand-parent having flex-direction: column. It works as I expect when flex-direction: row
tested on Chrome 75, firefox 67
This seems to have something to do with flex-direction on the grand-parent, if flex-direction is row, the horizontal scroll shows this behavior, if flex-direction is column, the vertical scroll shows this behavior
EDIT:
On further experiment, If we set min-height: 0 on parent, it behaves as expected, so this issue might be similar to
https://moduscreate.com/blog/how-to-fix-overflow-issues-in-css-flex-layouts/
https://css-tricks.com/flexbox-truncated-text/
For overflow-y, the CSS property which controls how content overflows parent vertical edges, the default value is visible. Here is how it works:
Content is not clipped and may be rendered outside the padding box's top and bottom edges.
This means that if the content doesn't fit in the box, some content will be rendered outside the box.
This property is not inherited, however. The CSS below will not set the overflow property to auto on children of div with ID parent:
var parentElem = document.getElementById('parent');
var childElem = document.getElementById('child');
console.log('overflow-y property of parent element: ' + window.getComputedStyle(parentElem).overflowY)
console.log('overflow-y property of child element: ' + window.getComputedStyle(childElem).overflowY)
#parent {
overflow: auto;
}
<div id="parent">
<div id="child">
Some content
</div>
</div>
This means that when content overflows in children boxes, scrollbars are automatically displayed by browsers on parent boxes; you will have to specify explicitly the property on children nodes as needed.
This question already has answers here:
Word-wrap in flexbox is not respecting 100% width limit [duplicate]
(2 answers)
Why don't flex items shrink past content size?
(5 answers)
Closed 4 years ago.
I have two flex children. I don't know the size of those children, but I want the .right (which contains unknown, but finite number of e.g. status icons) to not break, and fit on line, while .left child (which contains label of potentially too-long text) to break so that the .right child fits.
In the snippet, the .left should break the text so that the .right fits. Neither of the two children should overflow the .container.
I'm able to accomplish this by using word-break: break-word on .left, but that's non-standard. I can also use word-break: break-all, but that doesn't try to wrap the word on next line (as word-wrap does), first, which is undesirable. word-wrap: break-word doesn't do anything.
As stated, I cannot use width: calc( 100% - <right-width> ) on .left, because I don't know width of .right child.
note: the children's height: 20px is just to see the parent container. It's not part of the requirement.
Bonus: in the example the width of .container is known, but it may potentially not be known, either (i.e. it may inherit it in some way).
.container {
display: flex;
width: 200px;
height: 40px;
background: pink;
}
.left {
background: rgba(0,255,0,.1);
height: 20px;
// word-break: break-word; // works in WebKit, but non-standard
word-wrap: break-word;
}
.right {
background: rgba(0,0,255,.1);
height: 20px;
}
<div class="container">
<div class="left">xoxoxoxoxoxoxoxoxoxoxoxoxoxoxox</div>
<div class="right">rarararara</div>
</div>
the min-width: 0 on left ensures the element doesn't auto-resize to the parent flex container, and wraps as needed. It can be substituted with overflow: hidden, which has same effect.
If left to auto (default min-width flex value), it would overflow the container if it got too big. (thanks #Michael_B)
flex: 1 (shorthand for flex: 1 0 0, or flex-grow: 1; flex-shrink: 0; flex-basis: 0) ensures the left grows and pushes the right element to the right (thanks #LGSon)
right has initial flex values (flex: 0 1 auto) which ensures it doesn't word-break and doesn't grow above its content size, either.
WTBS, if it gets too big, it will also need word-wrap: break-word; min-width: 0 same as left.
Note: removed the 20px height which was not part of the OP requirement.
.container {
display: flex;
width: 200px;
background: pink;
}
.left {
background: rgba(0,255,0,.1);
word-wrap: break-word;
min-width: 0;
flex: 1;
}
.right {
background: rgba(0,0,255,.1);
}
<div class="container">
<div class="left">aaaaaaaa bbbbbbbbbbbbbbbbbbbb</div>
<div class="right">cccccc ccccc</div>
</div>
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