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
Related
This question already has answers here:
Why don't flex items shrink past content size?
(5 answers)
Fill remaining vertical space with CSS using display:flex
(6 answers)
Closed 3 years ago.
I have a <div> that takes up 60% of the window space, and it contains two things:
a narrow header line
an image that I want to take up the remainder of the div.
How can I do this with pure CSS (no Javascript)? I've been trying a bunch of things, no luck.
This is the closest I can get; the image sneaks outside of the green border of the div.container
html, body {
height: 100%;
overflow: hidden;
margin: 0px;
}
div.container {
height: 60%;
border: 2px solid green;
box-sizing: border-box;
}
div.rest {
height: 40%;
border: 2px solid red;
box-sizing: border-box;
}
div.img-container {
height: 100%; /* this is wrong, but what do I do? */
}
div.img-container img {
max-height: 100%;
max-width: 100%;
height: auto;
width: auto;
opacity: 0.5;
}
<html>
<body>
<div class="container">
<div class="header">hieronymus bosch last judgement</div>
<div class="img-container"><img src="https://i.imgur.com/TT6drhn.jpg"></div>
</div>
<div class="rest">
<h1>blah blah blah</h1>
</div>
</body>
</html>
Here's my attempt at using flex but that fails.
html, body {
height: 100%;
overflow: hidden;
margin: 0px;
}
div.container {
height: 60%;
border: 2px solid green;
box-sizing: border-box;
display: flex;
flex-direction: column
}
div.rest {
height: 40%;
border: 2px solid red;
box-sizing: border-box;
}
div.img-container {
flex: 1;
}
div.header {
flex: 0;
}
div.img-container img {
max-height: 100%;
max-width: 100%;
height: auto;
width: auto;
opacity: 0.5;
}
<html>
<body>
<div class="container">
<div class="header">hieronymus bosch last judgement</div>
<div class="img-container"><img src="https://i.imgur.com/TT6drhn.jpg"></div>
</div>
<div class="rest">
<h1>blah blah blah</h1>
</div>
</body>
</html>
#Christian's approach works if you know the height of the header element, however alternatively you could use flex.
This allows the element to grow to fill the remaining space dynamically, so your header can be any height.
html,
body {
height: 100%;
overflow: hidden;
margin: 0px;
}
div.container {
height: 60%;
border: 2px solid green;
box-sizing: border-box;
display: flex;
flex-direction: column;
}
div.rest {
height: 40%;
border: 2px solid red;
box-sizing: border-box;
}
div.img-container {
flex: 1;
position: relative;
}
div.img-container img {
opacity: 0.5;
height: 100%;
position: absolute;
}
<html>
<body>
<div class="container">
<div class="header">hieronymus bosch last judgement</div>
<div class="img-container"><img src="https://i.imgur.com/TT6drhn.jpg"></div>
</div>
<div class="rest">
<h1>blah blah blah</h1>
</div>
</body>
</html>
If you look at div.img-container in Chrome Inspector, you can see what the issue is - the img element is doing its job and filling its container, but the container itself is overflowing.
This is happening because it is set to height: 100% - what this says is "make my height 100% of my parent's height", but this does not mean "fill the remaining space." The browser just reads the computed height of the element's parent, and then multiplies it by your % value - basically, it's all in absolute terms. You can see that the blue box is 100% as tall as the box outlined in green, but because it sits below a line of text, it overflows by the height of that text.
flex could be used to solve this problem, but you can patch this pretty quickly by using calc to subtract out the height of that text. In your example, it's 19px, and I would recommend manually setting the height of that text element container just to be sure nothing will break in edge cases. Then, the .img-container gets height: calc(100% - 19px) and it works as expected.
html, body {
height: 100%;
overflow: hidden;
margin: 0px;
}
div.container {
height: 60%;
border: 2px solid green;
box-sizing: border-box;
}
div.rest {
height: 40%;
border: 2px solid red;
box-sizing: border-box;
}
div.img-container {
height: 100%; /* this is wrong, but what do I do? */
}
div.img-container img {
max-height: 100%;
max-width: 100%;
height: auto;
width: auto;
opacity: 0.5;
}
/*
ADDED CODE BELOW
*/
/* optional, just to be safe */
.header {
height: 19px;
}
/* overrides .img-container from above */
.img-container {
height: calc(100% - 19px) !important;
}
<html>
<body>
<div class="container">
<div class="header">hieronymus bosch last judgement</div>
<div class="img-container"><img src="https://i.imgur.com/TT6drhn.jpg"></div>
</div>
<div class="rest">
<h1>blah blah blah</h1>
</div>
</body>
</html>
With Flex, you may use the flex property and overflow (or min-height). Example:
html, body {
height: 100vh;
margin: 0px;
display:flex;
flex-direction:column;
}
div.container {
flex:6;/* instead height:xx% */
border: 2px solid green;
box-sizing: border-box;
display: flex;
flex-direction: column;
overflow:hidden; /* or min-height:0 if scroll is needed */
}
div.rest {
flex:4;/* instead height:xx% */
border: 2px solid red;
box-sizing: border-box;
}
div.img-container {
flex: 1;
min-height:0; /* or overflow:hidden; */
}
div.header {
min-height:1.6em; /* if you need something alike ?? */
}
div.img-container img {
max-height: 100%;
opacity:0.5;
}
<html>
<body>
<div class="container">
<div class="header">hieronymus bosch last judgement</div>
<div class="img-container"><img src="https://i.imgur.com/TT6drhn.jpg"></div>
</div>
<div class="rest">
<h1>blah blah blah</h1>
</div>
</body>
</html>
Scenario :
I am having trouble getting an image to autofit a flexbox with a border around it. The image will be dynamically generated so sometimes the width or the height might be the longer side. Sometimes the image will be smaller or larger than the box it should be in, but it should automatically fit the size of the box and retain its proper proportions.
Tried Case :
The best I've come up with is to set both width and height of the image to 100%, and then use object-fit: contain.
However, object-fit: contain does not work well with borders. Instead of surrounding just the image the border is surrounding the entire parent div.
The Problem: If there is a tall skinny image it might enlarge or shrink to 30% width and 100% height. I would like the border to be also at the 30% and 100% region as well. However, the border is being placed at the 100% width and 100% height area which is not what I want.
What other method would work better for me here?
Here is a simplified look at my code:
<!DOCTYPE html>
<html>
<style>
html, body { width: 100%; height: 100% }
#outer {
width: 100%;
height: 100%;
display: flex;
background-color: green;
flex-direction: column
}
#top, #bottom {
flex: 1;
display: flex;
border: solid black 1px;
}
#first, #third {
flex: 1;
background-color: blue;
}
#second {
flex: 3;
background-color: yellow;
}
#second img {
border: solid black 5px;
object-fit: contain;
width: 100%;
height: 100%;
box-sizing: border-box;
}
</style>
<body>
<div id="outer">
<div id="top">
<div id="first">First</div>
<div id="second">
<img src="https://via.placeholder.com/350x800/faa">
</div>
<div id="third">Third</div>
</div>
<div id="bottom">
Bottom
</div>
</div>
</body>
</html>
If you run the above code snippet you will see the thick border is surrounding the entire parent region (shown in yellow), rather than just appearing around the image itself (pink area).
What can I do so that the border is only around the image itself?
Clarification
I need something that meets the following criteria:
Smaller images are scaled up to meet the size of the parent div
Larger images are scaled down to meet the size of the parent div
Images should be proportional (i.e. images must retain their aspect ratio and not become distorted)
The image should be centered within the parent div
The image should have a border only around the image and not the larger area
Code must work for both portrait and landscape images
In most cases only two sides of the image will touch the parent boundary, leaving the rest of the parent div empty (i.e. the yellow background in my code sample)
I'm actually quite surprised given how far CSS has come that there seems to be no simple solution for this.
Do you want only with height 100%? If not height 100% is depend on image's prop, you can use object-fit: fill; and height:auto;
<!DOCTYPE html>
<html>
<style>
html, body { width: 100%; height: 100% }
#outer {
width: 100%;
height: 100%;
display: flex;
background-color: green;
flex-direction: column
}
#top, #bottom {
flex: 1;
display: flex;
border: solid black 1px;
}
#first, #third {
flex: 1;
background-color: blue;
}
#second {
flex: 3;
background-color: yellow;
}
#second img {
border: solid black 5px;
object-fit: contain;
width: 100%;
height: auto;
box-sizing: border-box;
}
</style>
<body>
<div id="outer">
<div id="top">
<div id="first">First</div>
<div id="second">
<img src="https://picsum.photos/800/800">
</div>
<div id="third">Third</div>
</div>
<div id="bottom">
Bottom
</div>
</div>
</body>
</html>
Used object-fit: cover
so that the image will cover the entire parent.
Other solution will be inserting an image already having a border on it.Image can be edited online to attach a border to itself.
<!DOCTYPE html>
<html>
<style>
html, body { width: 100%; height: 100% }
#outer {
width: 100%;
height: 100%;
display: flex;
background-color: green;
flex-direction: column
}
#top, #bottom {
flex: 1;
display: flex;
border: solid black 1px;
}
#first, #third {
flex: 1;
background-color: blue;
}
#second {
flex: 3;
background-color: yellow;
}
#second img {
border: solid black 5px;
object-fit: cover;
width: 100%;
height: 100%;
box-sizing: border-box;
}
</style>
<body>
<div id="outer">
<div id="top">
<div id="first">First</div>
<div id="second">
<img src="https://via.placeholder.com/350x800/faa">
</div>
<div id="third">Third</div>
</div>
<div id="bottom">
Bottom
</div>
</div>
</body>
</html>
Updated Solution:
So, to achieve this, we can put image inside a container that will be
take height and width according to image. Put this image container div inside the main div container.
So, in this case, we have put the following code into #second conatiner, and adjusted the corresponding css to achieve the desired result.
html, body { width: 100%; height: 100% }
img {
max-width: 100%;
max-height: 100%;
width: auto;
height: auto;
transform: translate(-50%, -50%);
position: relative;
left: 50%;
top: 50%;
}
#testing {
display: inline-block;
/* text-align: center; */
}
#outer {
width: 100%;
height: 100%;
display: flex;
background-color: green;
flex-direction: column
}
#top, #bottom {
flex: 1;
display: flex;
border: solid black 1px;
}
#first, #third {
flex: 1;
background-color: blue;
}
#second {
flex: 3;
background-color: yellow;
display: flex;
margin: 0 auto;
justify-content: center;
}
#second img {
border: solid black 5px;
object-fit: contain;
box-sizing: border-box;
}
<!DOCTYPE html>
<html>
<body>
<div id="outer">
<div id="top">
<div id="first">First</div>
<div id="second">
<div id='testing'>
<img src="https://via.placeholder.com/1000x350/faa">
</div>
</div>
<div id="third">Third</div>
</div>
<div id="bottom">
Bottom
</div>
</div>
<div id="outer">
<div id="top">
<div id="first">First</div>
<div id="second">
<div id='testing'>
<img src="https://via.placeholder.com/350x1000/faa">
</div>
</div>
<div id="third">Third</div>
</div>
<div id="bottom">
Bottom
</div>
</div>
</body>
</html>
did you mean something like this?
changes are, move width: 100% and height: 100% to parent, add max-height: 100% on img, and add text-align: center on parent
update:
- add another div inside #second
- make #second display: flex; flex-direction: column; justify-content: center
- add max-width: 100% to img
- add max-height: 100%; max-width: 100%; height: fit-content; to the added div
html, body { width: 100%; height: 100% }
#outer {
width: 100%;
height: 100%;
display: flex;
background-color: green;
flex-direction: column
}
#top, #bottom {
flex: 1;
display: flex;
border: solid black 1px;
}
#first, #third {
flex: 1;
background-color: blue;
}
#second {
flex: 3;
background-color: yellow;
width: 100%;
height: 100%;
text-align:center;
display: flex;
flex-direction: column;
justify-content: center;
}
#second img {
border: solid black 5px;
box-sizing: border-box;
max-height: 100%;
max-width: 100%;
}
#vcenter{
max-height: 100%;
max-width: 100%;
height: fit-content;
}
<!DOCTYPE html>
<html>
<body>
<div id="outer">
<div id="top">
<div id="first">First</div>
<div id="second">
<div id="vcenter">
<img src="https://via.placeholder.com/350x800/faa">
</div>
</div>
<div id="third">Third</div>
</div>
<div id="bottom">
Bottom
</div>
</div>
</body>
</html>
same code for landscape images
html, body { width: 100%; height: 100% }
#outer {
width: 100%;
height: 100%;
display: flex;
background-color: green;
flex-direction: column
}
#top, #bottom {
flex: 1;
display: flex;
border: solid black 1px;
}
#first, #third {
flex: 1;
background-color: blue;
}
#second {
flex: 3;
background-color: yellow;
width: 100%;
height: 100%;
text-align:center;
display: flex;
flex-direction: column;
justify-content: center;
}
#second img {
border: solid black 5px;
box-sizing: border-box;
max-height: 100%;
max-width: 100%;
}
#vcenter{
max-height: 100%;
max-width: 100%;
height: fit-content;
}
<!DOCTYPE html>
<html>
<body>
<div id="outer">
<div id="top">
<div id="first">First</div>
<div id="second">
<div id="vcenter">
<img src="https://via.placeholder.com/1350x200/faa">
</div>
</div>
<div id="third">Third</div>
</div>
<div id="bottom">
Bottom
</div>
</div>
</body>
</html>
My goal was to get the footer to stay at the bottom of the page and to go further down when more content is added. In doing so, a div element on my page which follows the footer has stopped half way when there isn't enough content.
My question is, how do you get the middle-stripdiv to stretch to the footer and have the goal above still achievable.
Here is a simplified JSFiddle to show the issue.
html,
body {
margin: 0;
padding: 0;
height: 100%;
}
#container {
min-height: 100%;
position: relative;
}
#header {
background: #283343;
height: 50px;
}
#middle-strip {
padding-bottom: 100px;
background: #32cd32;
width: 500px;
margin: auto;
}
#content-area {
width: 400px;
height: 100%;
margin: auto;
}
#footer {
background: #283343;
position: absolute;
bottom: 0;
width: 100%;
height: 100px;
}
<div id="container">
<div id="header">
THIS IS THE HEADER
</div>
<div id="middle-strip">
<div id="content-area">
THIS IS WHERE THE CONTENT WILL GO
</div>
</div>
<div id="footer">
THIS IS THE FOOTER
</div>
</div>
You can use flexbox to achieve this:
#container {
display: flex;
min-height: 100vh;
flex-direction: column;
}
#middle-strip {
flex: 1;
}
https://philipwalton.github.io/solved-by-flexbox/demos/sticky-footer/
jsfiddle: https://jsfiddle.net/jefftg/1chmyppm/
The orange header columns and the white list rows scroll together horizontally, which is desired. However, I want the white list rows to scroll vertically with the orange header fixed at the top. They currently don't. I'm looking for this to work in modern browsers with HTML5/CSS3.
css
.container {
width: 800px;
height: 600px;
overflow-x: auto;
overflow-y: hidden;
}
.header-container {
display: flex;
}
.header-cell {
height: 40px;
min-width: 500px;
background-color: orange;
border: 1px solid red;
}
.data-container {
overflow-y: auto;
overflow-x: hidden;
display: inline-block;
}
.data-row {
overflow-x: hidden;
display: flex;
}
.data-row-cell {
height: 30px;
min-width: 500px;
background-color: white;
border: 1px solid black;
}
html
<div class="header-container">
<div class="header-cell">A</div>
<div class="header-cell">B</div>
<div class="header-cell">C</div>
<div class="header-cell">D</div>
</div>
<div class="data-container">
<div class="data-row">
<div class="data-row-cell">
A1
</div>
<div class="data-row-cell">
B1
</div>
<div class="data-row-cell">
C1
</div>
<div class="data-row-cell">
D1
</div>
</div>
......
</div>
This can be done with pure CSS and you don't need JavaScript.
I've modified your JSFiddle to work the way you are requesting: https://jsfiddle.net/48386nvn/3/
Essentially, .header-container needs to be positioned absolute relative to the .container element:
.container {
width: 800px;
height: 600px;
overflow-x: auto;
overflow-y: hidden;
/* added this: */
position: relative;
}
.header-container {
display: flex;
/* added these: */
position: absolute;
top: 0;
left: 0;
}
The above-mentioned CSS will stick the orange header where you want it and maintain the width you need it to be.
Next, you'll need to make the data scrollable, which is done by doing the following calculation:
height: heightOfParentContainer - heightOfHeaderRow;
The header cell height is 40px (42px when respecting the borders) It also needs a margin-top equal to the height of the header row:
.data-container {
overflow-y: auto;
overflow-x: hidden;
display: inline-block;
/* added these: */
margin-top: 40px;
height: 560px;
}
This should make sure that the header row is not overlapping the data container, and that the height of the data takes up the rest of the space of the overall container.
I was able to get the desired result by simply adding height: 558px to .data-container: jsfiddle.net/jefftg/1chmyppm/2
You don't need to add the overflow to every element, just the elements that need scrolling,
all I did is gave your .data-containera display:block and a certain height so that the overflow-y:auto can work, you can change the height with what you see fits in your page.
this here shows my solution, I hope it helps.
$(".header-container").scroll(function() {
var scrollPercentage = 100 * this.scrollLeft / (this.scrollWidth - this.clientWidth);
$(".data-container").scrollTop(scrollPercentage);
});
.container {
width: 800px;
height: 600px;
}
.header-container {
display: flex;
overflow-x: auto;
}
.header-cell {
height: 40px;
min-width: 500px;
background-color: orange;
border: 1px solid red;
}
.data-container {
overflow-y: auto;
overflow-x: hidden;
display: block;
height: 100px;
}
.data-row {
display: block;
}
.data-row-cell {
height: 50px;
min-width: 500px;
background-color: white;
display: block;
border: 1px solid black;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="header-container">
<div class="header-cell">A</div>
<div class="header-cell">B</div>
<div class="header-cell">C</div>
<div class="header-cell">D</div>
</div>
<div class="data-container">
<div class="data-row">
<div class="data-row-cell">
A1
</div>
<div class="data-row-cell">
B1
</div>
<div class="data-row-cell">
C1
</div>
<div class="data-row-cell">
D1
</div>
</div>
......
</div>
I have a design using some bootstrap styling which has a white column on the right. The height should be 100%, but it isn't rendering at 100%. It renders at 100% of the initial screen height, but when you scroll down it's no longer white.
I've looked at several other CSS solutions on this site. I've tried making all parent elements 100% height. I've tried making it a flexbox column. I've tried putting "position: relative;" in the body. Nothing has worked yet. I'd prefer not to use JS to achieve this.
Simplified version of my HTML:
<body>
<div class="container">
<div class="main">
<h1>This is the main content area</h1>
</div>
<div class="right pull-right">
<div class="content">
</div>
<div class="content">
</div>
<div class="content">
</div>
<div class="content">
</div>
</div>
</div>
</body>
The CSS:
body,html {
height: 100%;
background-color: #aaa;
}
body {
position: relative;
}
.main {
display: inline-block;
}
.container {
height: 100%;
}
.right {
display: inline-flex;
flex-direction: column;
background-color: #fff;
width: 350px;
height: 100%;
min-height: 100%;
border: 1px solid #E1E6E9;
margin-right: 100px;
position: absolute;
right: 100px;
}
.content {
height: 300px;
min-height: 300px;
margin: 10px 10px;
background-color: #ccc;
border: 1px solid #000;
}
Change your .right class to have height: auto;
It will size itself to fit with its content.
.right {
display: inline-flex;
flex-direction: column;
background-color: #fff;
width: 350px;
height: auto;
min-height: 100%;
border: 1px solid #E1E6E9;
margin-right: 100px;
position: absolute;
right: 100px;
}
http://codepen.io/smlariviere/pen/WrWgxQ