.c-container {
background-color: coral;
display: flex;
margin: 0 auto;
width: 90%;
}
.c-column {
position: relative;
}
.c-column--left, .c-column--right {
flex: 0 0 auto;
width: 344px;
max-width: 344px;
min-width: 344px;
}
.c-column--left {
order: -1;
}
.c-column--center {
flex: 1 1 auto;
display: flex;
flex-direction: column;
background-color: #ff5213;
}
.c-topic__header, .c-topic__footer {
padding: 24px;
background-color: #e93f00;
}
.c-topic__body {
position: relative;
}
.c-message {
padding: 24px;
position: relative;
}
.c-message__list {
padding: 0;
position: relative;
display: flex;
flex-direction: column;
list-style: none;
}
.c-message__item {
background-color: skyblue;
border-radius: 3px;
border-bottom: 2px solid rgba(0, 0, 0, 0.2);
padding: 24px;
min-width: 0%;
margin-bottom: 5px;
flex: 1 1 auto;
}
.c-message__item--right {
align-self: flex-end;
margin-left: 10%;
}
.c-message__item--left {
align-self: flex-start;
margin-right: 10%;
}
.o-box {
padding: 24px;
}
.u-relative {
position: relative;
}
<div class='c-container'>
<div class='c-column c-column--center'>
<div class='c-topic__header'>
Header: flex-child
</div>
<div class='c-topic__body'>
<div class='c-message'>
<ul class='c-message__list'>
<li class='c-message__item c-message__item--right'>
Hi, I'm a message placed on the right side and I'm quite wide
</li>
<li class='c-message__item c-message__item--left'>
How swell. I'm on the left and a bit shorter.
</li>
</ul>
</div>
</div>
<div class='c-topic__footer'>
Footer: flex-child
</div>
</div>
<div class='c-column c-column--left'>
<div class='o-box u-relative'>
<span>Left column: 344px</span>
</div>
</div>
<div class='c-column c-column--right'>
<div class='o-box u-relative'>
<span>Right Column: 344px</span>
</div>
</div>
</div>
Recently I've been working on implementing flexbox into a webapp interface. One page consists of three columns, with the left and right column having a fixed width, and the center being flexible.
The center column in turn consists of 3 flexed children. A fixed height header and footer, with a flexible center. This column-center (hence CC) gets a vertical scrollbar if the content it holds overflows.
Inside the CC, there is a wrapper with a padding. This is there because javascript doesn't handle the scrolling well with the padding being on the CC item itself.
The problem is that in IE10 the text inside the blue blocks doesn't wrap when the viewport gets smaller. Safari, Chrome and Firefox all don't have this issue. Does anyone know how to get IE10 to behave like the rest?
An example of the problem can be found here:
http://codepen.io/csssavvy/pen/qOgjmN
Tl;dr. IE10 flexbox text overflow not working. Need help. Code example: http://codepen.io/csssavvy/pen/qOgjmN
Thanks for the answers. Fixed this issue this afternoon:
Changes on .c-message__item:
Add max-width: 90%; Remove min-width: 0%;.
Changes on .c-column--center:
Add min-width: 0%;
See the codepen for the updated version: codepen.io/csssavvy/pen/qOgjmN
Related
The code that appears below creates the following layout:
The important part is that the content, although centered on the screen when not overflowing, never overlaps the navbar and has its own scrollbar:
The problem is that this layout is achieved with the help of padding (marked by a comment in the code below), which results in the additional scrollbar on the right of the screen.
How can I design the same layout that would have only one scrollbar - the one in the content?
Please note that the solution should not break the following details:
The rounded corners and the shadow.
The title in the content block not participating in scrolling.
The image covering the whole scrollable content, so it scrolls together with the content.
In addition, it would be great if this can be achieved without as many nested div's as I have right now.
Edit: I am ready to go with the suggestion of #JHeth in the comments section. However, I would still be interested if someone can come up with an alternative design that does not rely on padding for centering.
Here is the code (CodePen):
* {
padding: 0;
margin: 0;
}
html {
font-size: 62.5%;
}
:root {
--navbar-height: 3rem;
}
.navbar {
width: 100%;
text-align: center;
font-size: 2rem;
line-height: var(--navbar-height);
background-color: lightgreen;
}
.centering {
position: absolute;
inset: var(--navbar-height) 0 0 0;
display: flex;
flex-direction: column;
align-items: center;
& .auto-margin {
margin: auto;
// For scrollable content
display: flex;
max-height: 100%;
padding-bottom: calc(var(--navbar-height)); // Causes scrolling
}
}
.content-block {
display: flex;
flex-direction: column;
.title {
font-size: 2rem;
position: sticky;
}
.content-outer-container {
display: flex;
flex-direction: column;
overflow-y: auto;
border-radius: 1em;
box-shadow: 0 1em 2em rgba(black, 0.4);
.content-container {
width: 300px;
overflow-y: auto;
.content {
position: relative;
padding: 1em;
&:before {
content: "";
z-index: -1;
position: absolute;
top: 0;
left: 0;
right: 0;
height: 100%;
background-position: center;
background-image:
url(http://www.freegreatpicture.com/files/147/18380-hd-color-background-wallpaper.jpg);
}
}
}
}
}
<div class="navbar">An Amazing Navbar</div>
<div class="centering">
<div class="auto-margin">
<div class="content-block">
<div class="title">My Title</div>
<div class="content-outer-container">
<div class="content-container">
<div class="content">
<h1>Line1</h1>
<h1>Line2</h1>
<h1>Line3</h1>
<h1>Line4</h1>
<h1>Line5</h1>
</div>
</div>
</div>
</div>
</div>
</div>
simply remove max-height:100%; to .centering .auto-margin and it'll works!
.centering .auto-margin {
margin: auto;
display: flex;
/* max-height: 100%; */
padding-bottom: calc(var(--navbar-height));
}
This question already has an answer here:
Why is 'position: sticky' not working with Core UI's Bootstrap CSS
(1 answer)
Closed 1 year ago.
I'm having trouble getting my flexbox two-column setup to work.
Basically I just want the left column to be sticky while scrolling down the right one and then end scrolling at the exact same point.
It should also be collapsible as in the example below.
It's supposed to substitute this solutions i made using a regular grid which I'm unfortunately not able use anymore.
You can see my current progress below - I'm not really able to figure out what to do from here - as I'm a rookie I hoped you guys would know.
.wrapper {
display: flex;
flex-flow: row wrap;
overflow: auto;
gap: 2em;
justify-content: flex-start;
height: auto;
font-weight: bold;
text-align: center;
}
.wrapper > * {
padding: 10px;
flex: 1 100%;
}
.aside-1 {
position: -webkit-sticky;
position: sticky;
background: gold;
height: auto;
top: 0;
align-self: flex-start;
}
.aside-2 {
background: hotpink;
height: 900px;
top: 0;
}
#media all and (min-width: 300px) {
.aside { flex: 1 0 0; }
}
<section class="page-width">
<div class="wrapper">
<aside class="aside aside-1"><img width="100%" src="https://cdn.shopify.com/s/files/1/0044/2852/9698/files/242370040_4238706352865614_2798039132201744827_n.jpg"> Aside 1
</aside>
<aside class="aside aside-2">
Aside 2
</aside>
</div>
</section>
I've checked the forum without really finding what I need and hope that somebody would be able to help me :o) Thanks a million!
Remove overflow:auto on parent container of sticky element to make stickiness work
.wrapper {
display: flex;
flex-flow: row wrap;
gap: 2em;
justify-content: flex-start;
height: auto;
font-weight: bold;
text-align: center;
}
.wrapper > * {
padding: 10px;
flex: 1 100%;
}
.aside-1 {
position: -webkit-sticky;
position: sticky !important;
background: gold;
top: 0 !important;
align-self: flex-start;
}
.aside-2 {
background: hotpink;
height: 900px;
top: 0;
}
#media all and (min-width: 300px) {
.aside { flex: 1 0 0; }
}
.other-content{
margin-top: 2rem;
height: 20rem;
width: 100%;
background: red;
position:sticky;
top:0;
}
<section class="page-width">
<div class="wrapper">
<aside class="aside aside-1"><img width="100%" src="https://cdn.shopify.com/s/files/1/0044/2852/9698/files/242370040_4238706352865614_2798039132201744827_n.jpg"> Aside 1
</aside>
<aside class="aside aside-2">
Aside 2
</aside>
</div>
<div class="divider"></div>
<div class="other-content"></div>
</section>
How can I properly center the #content without overflowing the #container? margin: auto kinda works, but looks like a hack to me, I would like not to use any margins with CSS Flexbox.
Keep in mind that the #container has position: fixed.
Here's the code demonstrates the issue: [View in JSFiddle ↗]
document.getElementById('content').innerHTML = [...Array(100).keys()].join('<br>')
#container {
position: fixed;
background: lightblue;
top: 0; bottom: 0;
left: 0; right: 0;
display: flex;
align-items: center;
justify-content: center;
overflow: auto;
}
#content {
border: 1px solid green;
/* uncomment the hack below to get desired behavior */
/* margin: auto */
}
<div id="container">
<div id="content">
</div>
</div>
Desired behavior you can check with uncommenting margin: auto, question is how to achieve the same result with only flex- properties and without margin: auto.
Without a markup change you can't, as when using align-items: center, it by design overflow in both directions if the content exceed the flex container.
‘center’
The flex item’s margin box is centered in the cross axis within
the line. (If the cross size of the flex line is less than that of the
flex item, it will overflow equally in both directions.)
Also note that auto margins has a special meaning in Flexbox, and it is not a hack, quite the opposite, so in this case, they are the flex based solution to accomplish exactly that.
Update: Here's a later answer of mine, showing a few more solutions, inlcuding the new safe keyword: Flexbox align-items overflow text get cuts off at top
document.getElementById('content').innerHTML = [...Array(100).keys()].join('<br>')
#container {
position: fixed;
background: lightblue;
top: 0; bottom: 0;
left: 0; right: 0;
display: flex;
overflow: auto;
}
#content {
border: 1px solid green;
margin: auto;
}
<div id="container">
<div id="content">
</div>
</div>
Try this. I have taken one parent div of content id and give height:100vh to content_wrap class.
document.getElementById('content').innerHTML = [...Array(100).keys()].join('<br>')
#container {
position: fixed;
background: lightblue;
top: 0; bottom: 0;
left: 0; right: 0;
display: flex;
align-items: center;
justify-content: center;
overflow: auto;
}
#content {
border: 1px solid green;
/* uncomment the hack below to get desired behavior */
/*margin: auto ;*/
}
.content_wrap {
height: 100vh;
}
<div id="container">
<div class="content_wrap">
<div id="content">
</div>
</div>
</div>
Just replace align-items: center; to align-items: left; in your css
because you are using flex and align-items: center; div is showing from center part so just replace it with left.
document.getElementById('content').innerHTML = [...Array(100).keys()].join('<br>')
#container {
position: fixed;
background: lightblue;
top: 0; bottom: 0;
left: 0; right: 0;
display: flex;
/*align-items: center;*/
align-items: left;
justify-content: center;
overflow: auto;
}
#content {
border: 1px solid green;
/* uncomment the hack below to get desired behavior */
/* margin: auto */
}
<div id="container">
<div id="content" class="mx-auto">
</div>
</div>
you can set the position of the #content as absolute and set top: 0; in the style, here0s a working plunkr
Seems like it should be possible with flexbox, but I can't figure it out.
http://codepen.io/MichaelJCole/pen/NGBVGe
Goals:
textarea (for typeing in messages) stays at the bottom the whole time.
chats start at the bottom, then scroll up as needed.
If you use the "Google Hangouts", like the message app in that.
Here's the markup:
<div id="chatBar">
<div id="chatList">
<div class="chat mine">hello world</div>
<div class="chat theirs">hello moon</div>
</div>
<input id="chatBarInput" class="form-control" type="textarea">
</div>
And here's the CSS:
html, body { height: 100%; }
#chatBar {
height: 100%;
display: flex;
flex-flow: column nowrap;
justify-content: flex-end;
overflow: none;
}
#chatList {
flex: 0 1 auto;
display: flex;
flex-flow: column nowrap;
justify-content: flex-end;
overflow-y: scroll;
}
#chatBarInput {
flex: 1 0 auto;
}
.chat {
flex: none;
align-self: flex-start;
background-color: lightgreen;
}
.chat.mine {
align-self: flex-end;
background-color: pink;
}
I can't get #chatBar to "squeeze" #chatList without setting a height. Which is what I was trying to avoid by using flexbox :-/
Sorry, I'm a backend coder. Tried a bunch of stuff, then pared it down for the CodePen.
Seems like I should be able to tell the inner flexbox to scroll, while leaving the outer alone. Do I have to use position:absolute?
I can't get #chatBar to "squeeze" #chatList without setting a height.
Which is what I was trying to avoid by using flexbox
You had the flex-basis set to auto for all elements. Without explicit height, the flex model will automatically try to accommodate everything inside the available space by shrinking or expanding the elements. This is why you are unable to get the #chatList to work as intended. The div itself as well as the individual chats all expand or shrink within the available space.
What you should do is to start simple:
#chatBar {
height: 100%; overflow: hidden;
display: flex; flex-flow: column;
}
#chatList {
/* grow or shrink as required from flex-basis height of 20% */
flex: 1 1 20%;
display: flex; flex-direction: column;
overflow: auto;
}
/* do not grow or shrink with a flex-basis height of 80% */
#chatBarInput { flex: 0 0 80%; }
And you will be able to see it working. You could then take it further from here.
Your modified codepen: http://codepen.io/Abhitalks/pen/ZbjNvQ/
Goals:
textarea (for typeing in messages) stays at the bottom the whole time.
chats start at the bottom, then scroll up as needed.
If you use the "Google Hangouts", like the message app in that.
The trick would be to use flex-direction: column-reverse and prepend the new messages to the container instead of appending those.
I took an old answer of mine and changed the layout to flex-model for a demo of this purpose. You can peruse the code to see how it's done.
Demo Fiddle: http://jsfiddle.net/abhitalks/khj4903t/
Demo Snippet:
var btn = document.getElementById('btn'),
inp = document.getElementById('inp'),
chats = document.getElementById('chatWindow')
;
btn.addEventListener('click', postMsg);
inp.addEventListener('keyup', function(e) {
if (e.keyCode == 13) { postMsg(); }
});
function postMsg() {
var msg = inp.value,
bubble = document.createElement('div'),
p = document.createElement('p');
if (msg.trim().length <= 0) { return; }
bubble.classList.add('bubble');
bubble.classList.add('right');
p.textContent = msg;
bubble.appendChild(p);
inp.value = '';
chats.insertBefore(bubble, chats.firstChild);
}
* { box-sizing: border-box; margin: 0; padding: 0; }
html, body { height: 100%; overflow: hidden; }
.wrap {
margin: 8px; height: 90%; width: 50%;
display: flex; flex-direction: column;
}
.container {
flex: 1 1 90%; display: flex; flex-direction: column;
background-color: #eee; border: 1px solid #ccc; overflow: auto;
}
.form { flex: 0 0 32px; display: flex; border: 1px solid #ddd; }
.form > input[type=text] { flex: 1 1 auto; border: 1px solid #eee; }
.form > input[type=button] { flex: 0 0 20%; border: 1px solid #eee; }
.bubble { flex: 1 1 auto; clear: both; } /* clear the floats here on parent */
.bubble p {
border-radius: 5px;
padding: 8px; margin: 8px 12px;
max-width: 80%; /* this will make it not exceed 80% and then wrap */
position: relative; transition: background-color 0.5s;
}
.left p { background-color: #ccc; float: left; } /* floated left */
.right p { background-color: #33c; color: #fff; float: right; } /* floated right */
/* classes below are only for arrows, not relevant */
.left p::before {
content: ''; position: absolute;
width: 0; height: 0; left: -8px; top: 8px;
border-top: 4px solid transparent;
border-right: 8px solid #ccc;
border-bottom: 4px solid transparent;
}
.right p::after {
content: ''; position: absolute;
width: 0; height: 0; right: -8px; bottom: 8px;
border-top: 4px solid transparent;
border-left: 8px solid #33c;
border-bottom: 4px solid transparent;
}
<div class="wrap">
<div id="chatWindow" class="container">
<div class="bubble left"><p>msg</p></div>
<div class="bubble left"><p>long message</p></div>
<div class="bubble right"><p>ultra long message which can wrap at eighty percent </p></div>
<div class="bubble left"><p>lorem ipsum</p></div>
<div class="bubble right"><p>very long message</p></div>
<div class="bubble right"><p>one more message</p></div>
<div class="bubble left"><p>lorem ipsum</p></div>
<div class="bubble right"><p>another message</p></div>
<div class="bubble left"><p>lorem ipsum</p></div>
<div class="bubble right"><p>yet another message</p></div>
<div class="bubble left"><p>lorem ipsum</p></div>
</div>
<div id="inputWindow" class="form">
<input id="inp" type="text" />
<input id="btn" type="button" value="Send" />
</div>
</div>
The vertical scrollbar on the browser exists because you've set a height: 100% to the body, and the user agent stylesheet applies a default margin to the body, typically 8px all around. So, 100% + 16px launches the vertical scroll.
Add this to your CSS: body { margin: 0; }
To apply the scrollbar to the inner flexbox (.chatlist), here are two adjustments:
#chatList {
flex: 0 1 75px; /* specify a height */
display: flex;
flex-flow: column nowrap;
/* justify-content: flex-end; REMOVE */
overflow-y: scroll;
}
DEMO: http://jsfiddle.net/5p2vy31p/1/
I have a web page using a column flexbox, with fixed size header and footer, and a content area which takes up the remaining space. This works fine.
The content area is a row flexbox, and I have 2 square divs side by side. I am making them square by using padding-bottom. This works fine, unless the window is >2x the content area height. Then my squares start bleeding into the footer, because padding is based on element width.
I would like the squares to never overlap the footer. I'm ok with there just being dead space to the right of the squares. I would like to stick with flexbox and avoid floats if possible. Only modern browsers need be supported.
Is this possible with only CSS? Or is this a job for JS.
Fiddle
html, body {
height: 100%;
margin: 0;
padding: 0;
}
#box {
display: flex;
flex-flow: column;
height: 100%;
}
div {
border: 1px solid tomato;
box-sizing: border-box;
margin: 0;
padding: 2px;
}
#header {
flex: 0 0 5em;
}
#footer {
flex: 0 0 5em;
}
#content {
background: blue;
display: flex;
flex: 1 1 auto;
flex-flow: row wrap;
min-height: 30%;
}
#content > div {
background: tomato;
border-color: black;
flex: 1 0 auto;
max-height: 50%;
padding-bottom: 50%;
}
<div id="box">
<div id="header">
<p><b>header</b>
</p>
</div>
<div id="content">
<div id='am'></div>
<div id='pm'></div>
</div>
<div id="footer">
<p><b>footer</b>
</p>
</div>
</div>
TIA!
Simple soluton:
#box
{
display: flex;
flex-flow: column;
min-height: 100%; /* this*/
}
JSfiddle Demo
Note: This assumes you want the page to overflow...but I didn't see any reference to containing the page height to the viewport.