Image overflows fixed-height flex container - html

I'm using a fixed-height flex container to do the layout. In the container, there are three components: header, content, footer. I want to force the content to use the rest of the height (i.e. content height = fixed-height minus header and footer). In my content, it will include an image and some texts.
However, the image always overflows a fixed-height flex container even providing max-height: 100% to constrain the height, but I want to put header, content, and footer into a fixed flex container.
Does anyone know how to fix it?
code: https://codepen.io/mrchung402/pen/wvGPJxz
<div class="container">
<div class="header">
header
</div>
<div class="content">
<div class="my-img">
<img src="http://via.placeholder.com/274x295">
</div>
<div class="my-text">
my-text
</div>
</div>
<div class="footer">
footer
</div>
</div>
.container {
border: solid 1px red;
display: flex;
max-width: 500px;
height: 200px;
flex-direction: column;
}
.header {
flex: 0 0 auto;
background: #A7E8D3;
}
.content {
display: flex;
flex-direction: column;
}
.footer {
flex: 0 0 auto;
background: #D7E8D4;
}
.my-img {
max-height: 100%;
height: auto;
max-width: 100%;
}
img {
max-height: inherit;
height: inherit;
}
.my-text {
background: #C7A8D4;
}

Instead of styling .my-img you should style .my-img img
.my-img img{
height: 100%;
width: 100%;
}

Related

Contenteditable div resizing instead adding scrollbar

I'm having problem with my div with contenteditable=true which break my whole page.
When you type a lot of text, instead adding scrollbar it make div bigger so it move others parts of the page...
So what I would like my editable div fill remaining width and height of the page but add scrollbar when text being too big whitout moving others elments of the page. Thanks
JsFiddle
HTML
<body>
<h1>TEXT</h1>
<div class="all">
<div class="container">
<div class="lines"></div>
<div class="editor" contenteditable="true" spellcheck="false"></div>
</div>
<div class="manage">
<h1>TEXT</h1>
</div>
</div>
</body>
CSS
html, body {
margin: 0;
padding: 0;
display: flex;
height: 100%;
width: 100%
}
h1 {
margin: 20px;
}
.all {
display:flex;
flex-direction: column;
width: 100%;
height: 100%;
}
.container {
display: flex;
width: 100%;
height: 400px;
overflow: auto;
}
.lines {
background-color: red;
border-radius: 20px 0 0 20px;
height: 100%;
width:40px;
}
.editor {
border-radius: 0 20px 20px 0;
background-color: orange;
width: 100%;
height: 100%;
}
All you need to do is to add a max-width property to your .editor class.
Here is a working code: https://codesandbox.io/s/html-code-editor-forked-g27d9o?file=/index.html

positioning sticky sidebar right beside a centered div

I'm trying to customize my blog layout by adding a sticky sidebar. I managed to get position:sticky to work as excepted, but I can't figure out how to position the blocks where I want.
I want the main block to be centered, and the sidebar right beside the main block. here's an example of what I'm aiming for: https://theme-next.js.org/ except I want the main block to be centered.
this is the layout I want
I've tried using margin-left with the sidebar, but it doesn't work well in smaller windows, as the left margin is constant and pushes the real content away in smaller windows.
this is what happens by using margin-left
(I'm not sure why the sticky dosen't work here, but it works fine on my website. All I'm trying to figure out is how to position them where I want.
.wrapper {
display: flex;
justify-content: space-between;
}
.sidebar {
width: 80px;
background-color: #FF0000;
position: webkit-stiky;
position: sticky;
align-self: flex-start;
height: 1000px;
}
.main {
width: 100px;
background-color: #CFCFCF;
margin: auto;
height: 1600px;
}
.header {
background-color: #F3FF00;
width: 150px;
margin: auto;
}
<div class="header">
<p>
this is centered header
</p>
</div>
<div class="wrapper">
<div class="sidebar">
<p> sidebar here</p>
</div>
<div class="main">
<p>
I want this block to be centered;
</p>
</div>
</div>
There's a few things you need to do here:
Set a top property for your sticky sidebar, or it won't stick
Make your main element a flex parent since we'll need to offset its child element to make it centered with your header.
Create an inner element for your main element so you can move it to the left 80px to accommodate for the sidebar width.
.wrapper {
display: flex;
position: relative;
}
.sidebar {
width: 80px;
height: 1000px;
background-color: #FF0000;
position: sticky;
/* you need a top position set for sticky */
top: 0;
}
.main {
height: 1600px;
background-color: #eeeeee;
/* This needs to be a flex parent */
display: flex;
justify-content: center;
/* This element needs to be 100% MINUS the sidebar width of 80px */
flex: 1 0 calc(100% - 80px);
}
.main-inner {
width: 100px;
position: relative;
background-color: #CFCFCF;
/* Move the inner element 80px to the left */
margin-left: -80px;
text-align: center;
}
.header {
background-color: #F3FF00;
width: 150px;
margin: 0 auto;
}
<div class="header">
<p>this is centered header</p>
</div>
<div class="wrapper">
<div class="sidebar">
<p>sidebar here</p>
</div>
<div class="main">
<div class="main-inner">
<p>I want this block to be centered;</p>
</div>
</div>
</div>
However, I believe this is what you really want:
Make the header a flex parent as well.
.wrapper {
display: flex;
position: relative;
}
.sidebar {
width: 80px;
height: 1000px;
background-color: #FF0000;
position: sticky;
/* you need a top position set for sticky */
top: 0;
}
.main {
height: 1600px;
background-color: #eeeeee;
/* This needs to be a flex parent */
display: flex;
justify-content: center;
/* This element needs to be 100% MINUS the sidebar width of 80px */
flex: 1 0 calc(100% - 80px);
}
.main-inner {
width: 100px;
position: relative;
background-color: #CFCFCF;
/* Move the inner element 80px to the left */
text-align: center;
}
.header {
display: flex;
justify-content: flex-end;
}
.header-inner {
background-color: #F3FF00;
text-align: center;
width: calc(100% - 80px);
background-color: #F3FF00;
}
<div class="header">
<div class="header-inner">
<p>this is centered header</p>
</div>
</div>
<div class="wrapper">
<div class="sidebar">
<p>sidebar here</p>
</div>
<div class="main">
<div class="main-inner">
<p>I want this block to be centered;</p>
</div>
</div>
</div>

Problem with flexbox layout and nested scrollbar

Embedded scroll bars do not work within a simple flexbox container. The browser automatically displays the horizontal scroll bar.
What am I doing wrong on this simple example?
When I remove "display: flex;" on the flexContainer, the embedded scrollbar works. Of course, my entire layout is then destroyed.
I only found the following, but the solution relates to a vertical scrollbar and does not work here:
Stackoverflow nesting-flexbox-inside-flexbox-overflow-how-to-fix-this
.flexContainer {
display: flex;
}
.sidebar {
flex: 1 0 auto;
min-width: 150px;
max-width: 190px;
color: white;
background: blue;
}
.content {
flex: 1 0 auto;
background: green;
}
.scrollableElement {
display: flex;
overflow-x: scroll;
}
.textElement {
color: white;
background: grey;
}
<html>
<body>
<div class="flexContainer">
<div class="sidebar">
<div>Sidebar</div>
</div>
<div class="content">
<div class="scrollableElement">
<div class="textElement">
<div>Content11111111111111111111111111111111111111111111111111111111111111111111111</div>
<div>Content22222222222222222222222222222222222222222222222222222222222222222222222</div>
<div>Content33333333333333333333333333333333333333333333333333333333333333333333333</div>
<div>Content44444444444444444444444444444444444444444444444444444444444444444444444</div>
<div>Content55555555555555555555555555555555555555555555555555555555555555555555555</div>
<div>Content66666666666666666666666666666666666666666666666666666666666666666666666</div>
<div>Content77777777777777777777777777777777777777777777777777777777777777777777777</div>
<div>Content88888888888888888888888888888888888888888888888888888888888888888888888</div>
</div>
</div>
</div>
</div>
</body>
</html>
You need to allow .content to shrink then add min-width:0 or overflow:hidden so its size is calculated at screen inside its parent so overflow works on the children:
.content {
flex: 1 1 auto;/* updated*/
background: green;
min-width:0;/* added */
}
.flexContainer {
display: flex;
}
.sidebar {
flex: 1 0 auto;
min-width: 150px;
max-width: 190px;
color: white;
background: blue;
}
.content {
flex: 1 1 auto;
background: green;
min-width:0;
}
.scrollableElement {
display: flex;
overflow-x: scroll;
}
.textElement {
color: white;
background: grey;
}
<html>
<body>
<div class="flexContainer">
<div class="sidebar">
<div>Sidebar</div>
</div>
<div class="content">
<div class="scrollableElement">
<div class="textElement">
<div>Content11111111111111111111111111111111111111111111111111111111111111111111111</div>
<div>Content22222222222222222222222222222222222222222222222222222222222222222222222</div>
<div>Content33333333333333333333333333333333333333333333333333333333333333333333333</div>
<div>Content44444444444444444444444444444444444444444444444444444444444444444444444</div>
<div>Content55555555555555555555555555555555555555555555555555555555555555555555555</div>
<div>Content66666666666666666666666666666666666666666666666666666666666666666666666</div>
<div>Content77777777777777777777777777777777777777777777777777777777777777777777777</div>
<div>Content88888888888888888888888888888888888888888888888888888888888888888888888</div>
</div>
</div>
</div>
</div>
</body>
</html>
Your flex container has no set width, so it is taking up the entire width of the screen.
You could try setting the width to achieve the behavior you are looking for, for example:
.flexContainer {
display: flex;
width: 500px;
}
OR you could set the width of the .scrollableElement to resize based on the screen:
.scrollableElement {
overflow-x: scroll;
width: 65%;
}

Make html page take at least 100% of view port if content is too small

Not-so-experienced developer here
I am currently working on a web page with a "Header - Content - Footer" design.
<html>
<body>
<div id="root">
<div class="header">
HEADER
</div>
<div class="content">
CONTENT
</div>
<div class="footer">
FOOTER
</div>
</div>
</body>
</html>
Header is a sticky div. Something like a navbar.
Content can be of ANY size.
Header and footer have fixed height.
I want the content div to take the remaining page space even when the content inside is not big enough to fill the div.
Here is the css that I came up with:
html, body, #root {
min-height: 100vh;
}
body {
margin: 0
}
.content {
background-color: red;
height: 100%;
}
.header {
position: sticky;
top: 0;
}
.header, .footer {
height: 56px;
width: 100%;
line-height: 56px;
background-color: green;
}
Although this works as intended when the content is larger than the viewport, it doesn't on the opposite case.
When looking through a developer console, the height values of the html, body, #root tags rightfully equals 100% of the viewport, but the content div does not take the remaining space (even when specifying height: 100%).
Why is that so?
Here is a jsfiddle: https://jsfiddle.net/c91p0yot/
Use the flexbox layout mode and make your <body> display: flex;
Then, give the .content a flex value of 1 which will force the .content to take up all remaining space.
Also get rid of the #root div
html
height: 100%;
}
body {
margin: 0;
min-height: 100%;
display: flex;
flex-flow: column nowrap;
}
.content {
background-color: red;
flex: 1;
}
.header {
position: sticky;
top: 0;
}
.header, .footer {
height: 56px;
width: 100%;
line-height: 56px;
background-color: #f8f9fa;
}
Set the content to be at least the height of the viewport minus the header and footer height.
html, body, #root {
min-height: 100vh;
}
body {
margin: 0
}
.content {
background-color: red;
min-height: calc(100vh - 112px);
}
.header {
position: sticky;
top: 0;
}
.header, .footer {
height: 56px;
width: 100%;
line-height: 56px;
background-color: #f8f9fa;
}
<body>
<div id="root">
<div class="header">
HEADER
</div>
<div class="content">
CONTENT
</div>
<div class="footer">
FOOTER
</div>
</div>
</body>

Creating a cross-browser fixed height scrollable display: table-row

I am trying to create a container, of height 80% of the page height, which has a fixed height header and footer with a content pane that stretches to fit the rest of the available space.
I've tried to use display: table with the following layout:
<body>
<div class="ticket">
<div class="header">header</div>
<div class="body">
<div class="wrapper">
<div class="content">content</div>
</div>
</div>
<div class="footer">footer</div>
</div>
</body>
With these styles
body {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
}
.ticket {
background: #ccc;
width: 600px;
margin: 0 auto;
height: 80%;
display: table;
}
.header {
background: blue;
height: 36px;
display: table-row;
}
.body {
background: orange;
display: table-row;
}
.wrapper {
height: 100%;
overflow-y: auto;
overflow-x: hidden;
}
.content {
height: 600px;
}
.footer {
background: green;
height: 72px;
display: table-row;
}
In Chrome this gives me a scrollable middle panel that grows with the height of the container:
Unfortunately this doesn't work in IE8 or Firefox, the '.body' div stretches to fit the '.content'.
Is there a way to do this that will work cross browser, and IE8+?
Check out http://caniuse.com/#search=flexbox and/or http://caniuse.com/#search=vh
Those are the ways to get it, but none of them works on IE 8.
You must use JS