What I am trying to do is have a fixed header, fixed footer with a section inbetween. The inbetween section would then get a scrollbar should the content not fit on screen. After much frustration I managed to get the main layout rendering correctly without using tables:
.main-container {
width: 50%;
height: 98vh;
flex-direction: column;
display: flex;
}
.main-container .main-view {
width: 100%;
overflow-y: scroll;
flex: 1 1 auto;
}
.main-container .top-bar {
width: 100%;
flex: 0 0 1em;
text-align: center;
}
.main-container .bottom-bar {
width: 100%;
flex: 0 0 1em;
}
.special {
display: inline;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
</head>
<body>
<div class="main-container">
<div class="main-container top-bar">
SOMETHING FIXED HERE
</div>
<div class="main-container main-view">
<span class="special">Lorem</span><span class="special">ipsum</span> dolor sit amet, consectetur adipiscing elit. Pellentesque magna tellus, dictum et luctus ac, laoreet vel justo. Cras at pretium lectus. Lorem ipsum dolor sit amet, consectetur
adipiscing elit. Suspendisse potenti. Maecenas tincidunt efficitur neque, eu elementum purus tincidunt vel. Nunc id dolor bibendum, pharetra erat in, pretium lorem. Donec vitae nulla et lacus porta scelerisque. Praesent blandit, nibh nec vulputate
semper, arcu odio scelerisque velit, at rhoncus lacus dui luctus sapien. Donec venenatis erat libero, vitae lobortis velit finibus ut.
</div>
<div class="main-container bottom-bar" id="bottom-bar">
SOMETHING FIXED HERE
</div>
</div>
</body>
</html>
However elements in the middle area only render correctly if they are not wrapped in any kind of tag. As soon as I wrap them in a div or span, the browser (Chrome at least) insists on having each tag take up the entire line. They do not appear side-by-side as I might expect.
I have tried creating a 'special' class, as noted in the example above, which I have applied to both div and span. Both give the same result: 'Lorem' and 'ipsum' appear on their own lines instead of side-by-side. I tried various things from other stack overflow questions on somewhat related topics including "float: left" and additional nesting using "display: flex".
I simply want to apply some styling and perhaps make some items clickable. To do that they need to be wrapped in something like a div or span. Anyone know how I can get it to render them side-by-side instead of each tag on its own line?
Your particular issue is because your .main-container class has display: flex; on it and then you've added that class to the top, center and bottom divs, this flex property changes the way that child elements are positioned.
As it sounds like you dont want to mess with the positioning of children elements of the main (middle) div, you dont want to add the 'main-container' class to that div.
Actually, you can achieve what you want much more simply:
body {
display: flex;
flex-direction: column;
height: 100vh;
}
.main-view {
flex-grow: 1;
overflow: scroll;
}
Here we're making the body always 100vh (100% viewport height) and changing the display to flex, direction column. Setting these flex properties allows us to tell the main-view container to flex-grow which means fill the remaining space of the parent, this pushes the footer down to the bottom of the body element (which is set to 100vh).
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<style>
body {
display: flex;
flex-direction: column;
height: 100vh;
}
.main-view {
flex-grow: 1;
overflow: scroll;
}
</style>
</head>
<body>
<div class="top-bar">
SOMETHING FIXED HERE
</div>
<div class="main-view">
<span class="special">Lorem</span><span class="special">ipsum</span> dolor sit amet, consectetur adipiscing elit. Pellentesque magna tellus, dictum et luctus ac, laoreet vel justo. Cras at pretium lectus. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse potenti. Maecenas tincidunt efficitur neque, eu elementum purus tincidunt vel. Nunc id dolor bibendum, pharetra erat in, pretium lorem. Donec vitae nulla et lacus porta scelerisque. Praesent blandit, nibh nec vulputate semper, arcu odio scelerisque velit, at rhoncus lacus dui luctus sapien. Donec venenatis erat libero, vitae lobortis velit finibus ut.
</div>
<div class="bottom-bar">
SOMETHING FIXED HERE
</div>
</div>
</body>
</html>
This is the nature of the flexbox. You gave the container the property of column for the flex-direction. The .special elements are being treated as flex items and getting arranged in a column. Simply wrap them all in a div so you have a single flex item so the inline display can kick in
.main-container {
width: 50%;
height: 98vh;
flex-direction: column;
display: flex;
}
.main-container .main-view {
width: 100%;
overflow-y: scroll;
flex: 1 1 auto;
}
.main-container .top-bar {
width: 100%;
flex: 0 0 1em;
text-align: center;
}
.main-container .bottom-bar {
width: 100%;
flex: 0 0 1em;
}
.special {
display: inline;
}
<div class="main-container">
<div class="main-container top-bar">
SOMETHING FIXED HERE
</div>
<div class="main-container main-view">
<div>
<span class="special">Lorem</span> <span class="special"> ipsum</span> dolor sit amet, consectetur adipiscing elit. Pellentesque magna tellus, dictum et luctus ac, laoreet vel justo. Cras at pretium lectus. Lorem ipsum dolor sit amet, consectetur
adipiscing elit. Suspendisse potenti. Maecenas tincidunt efficitur neque, eu elementum purus tincidunt vel. Nunc id dolor bibendum, pharetra erat in, pretium lorem. Donec vitae nulla et lacus porta scelerisque. Praesent blandit, nibh nec vulputate
semper, arcu odio scelerisque velit, at rhoncus lacus dui luctus sapien. Donec venenatis erat libero, vitae lobortis velit finibus ut.
</div>
</div>
<div class="main-container bottom-bar" id="bottom-bar">
SOMETHING FIXED HERE
</div>
</div>
Alternatively, you can utilize flex-direction: row on your flex container (in this case .main-view) so your flex items can display "side-by-side" instead of being stacked in a column. See sample below:
.main-container {
width: 50%;
height: 98vh;
flex-direction: column;
display: flex;
}
.main-container .main-view {
width: 100%;
overflow-y: scroll;
flex: 1 1 auto;
flex-direction: row;
}
.main-container .top-bar {
width: 100%;
flex: 0 0 1em;
text-align: center;
}
.main-container .bottom-bar {
width: 100%;
flex: 0 0 1em;
}
.special {
display: inline;
margin-right: 10px;
}
<div class="main-container">
<div class="main-container top-bar">
SOMETHING FIXED HERE
</div>
<div class="main-container main-view">
<span class="special">Lorem</span><span class="special">ipsum</span>Hello
</div>
<div class="main-container bottom-bar" id="bottom-bar">
SOMETHING FIXED HERE
</div>
</div>
Related
I've been working on how to rotate a div with number text and an ::after pseudo element styled into a line. Essentially I've gotten as far as arranging it horizontally (responding to screen width), but I want the text to rotate -90deg, stick to the left side of its container, and for the line to take up the remaining height of the container (but not go outside of the container).
Should look like this:
p {
display: flex;
align-items: center;
font-size: 10vw;
font-weight: bold;
margin: 0;
}
p::after {
content: '';
flex: 1;
margin-left: 1rem;
height: 2px;
background-color: #000;
}
<div class="container">
<div class="num">
<p>01</p>
</div>
</div>
I've tried adding a transform property with rotate and translate, messing with writing-mode properties, but can't seem to get the pseudo element to lengthen dynamically with the changing height (since the container's height changes with screen size). Any tips?
Figured it out, here's the solution (styled with flexbox) for anyone with this weirdly specific problem.
section {
display: flex;
background-color: blue;
}
.wrapper-section {
display: flex;
}
.section-sum {
height: 100%;
display: flex;
flex-flow: column nowrap;
}
.vt-line {
height: 100%;
width: 2px;
background-color: #262525;
margin: 0 auto;
}
.num p {
display: inline-block;
align-items: center;
font-size: 5em;
font-weight: bold;
margin: 0;
transform: rotate(-90deg);
}
.wrapper-aboutinfo {
display: flex;
align-items: center;
}
.container-aboutimg img {
display: block;
max-width: 100%;
margin: 0 auto;
}
<section id="about">
<div class="wrapper-section">
<div class="section-sum">
<div class="vt-line"></div>
<div class="num">
<p>01</p>
</div>
</div>
<div class="wrapper-aboutinfo">
<div class="container-aboutimg">
<img src="https://images.pexels.com/photos/3861964/pexels-photo-3861964.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=750&w=1260">
</div>
<div class="info-about">
<h2>Lorem Ipsum</h2>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam volutpat pretium pharetra. Aliquam non ultrices neque. Praesent rhoncus sapien vitae sem ultrices, ut malesuada magna consequat. Mauris eu laoreet justo. Integer tristique porta nibh vitae ultrices. Praesent porta ligula ut nisl pellentesque congue. Sed finibus ut est et lobortis. Pellentesque velit magna, sagittis non lorem at, pulvinar tempor sem. Nam iaculis nisi nec elit efficitur, non varius sapien feugiat.
<br>
<br>
Morbi justo arcu, rhoncus non sagittis eu, faucibus id ipsum. Vivamus augue lectus, venenatis a commodo eget, ullamcorper vel lorem. Vivamus posuere sagittis eros et consectetur. In feugiat gravida lectus sed pulvinar. Etiam dapibus luctus magna, fermentum dapibus mauris vulputate in. Aliquam at massa erat. In tincidunt dictum risus, vel eleifend sem tempor id. </p>
</div>
</div>
</div>
</section>
is it possible for a child inside a div to push down other divs outside based on its own height?
Given this simple HTML:
<!DOCTYPE html>
<html>
<head>
<title>Parcel Sandbox</title>
<meta charset="UTF-8" />
</head>
<body>
<div id="app">
<div class="main-section">
<div class="main-form">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi eget
sollicitudin urna. Duis congue mattis risus nec volutpat. Cras ut
risus et diam luctus consectetur. Phasellus aliquam dui nec vehicula
convallis. Donec sit amet nunc lacus. Praesent eget elit commodo,
ultricies felis non, tristique ex.
</div>
</div>
<div class="about-section">Hello World</div>
</div>
<script src="src/index.js"></script>
</body>
</html>
I have this CSS here, there are basically two divs (main-section and about-section) and the main-form is inside the main-section:
.main-section {
background-color: red;
padding: 10px 0 0 10px;
height: 100px;
min-width: 100%;
/* display: table; solution 1*/
/* overflow: auto; solution 2, it cuts off the yellow div, which is not the desired outcome */
}
.main-form {
background-color: yellow;
width: 120px;
min-height: 180px;
/* display: table-col; solution 1*/
}
.about-section {
background-color: blue;
}
The height of the parent .main-section should be fixed at 100px.
The height of the child .main-form varies depending on the length of the text on it, but should have a min-height of 180px.
The width of the .main-form should be fixed at 120px.
I have tried changing the overflow property of the parent but it cuts off the child element.
I have also tried using the display: table on the parent and display: table-col on the child, but this solution adjusts the height of the parent element.
Here is a code sandbox: https://codesandbox.io/s/romantic-wave-29f5f?fontsize=14&hidenavigation=1&theme=dark
Is there a way to do this?
Basically what I wanted to achieve looks something like this:
float and clear can do the job:
.main-section {
background-color: red;
padding: 10px 0 0 10px;
height: 100px;
}
.main-form {
background-color: yellow;
width: 120px;
float:left; /* here */
min-height: 180px;
}
.about-section {
background-color: blue;
clear:left; /* and here */
}
<div class="main-section">
<div class="main-form">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi eget sollicitudin urna. Duis congue mattis risus nec volutpat. Cras ut risus et diam luctus consectetur. Phasellus aliquam dui nec vehicula convallis. Donec sit amet nunc lacus. Praesent eget
elit commodo, ultricies felis non, tristique ex.
</div>
</div>
<div class="about-section">Hello World</div>
This question already has an answer here:
Fitting child into parent
(1 answer)
Closed 3 years ago.
I am trying to add two divs to an element. The first div should have a fixed height and position. The second div should take up the rest of the space (if needed), but never exceed it. I've prepared the following example, to display the desired output.
#container {
border: 1px solid black;
height: 200px;
width: 200px;
display: flex;
flex-direction: column;
}
#fixed {
flex: 0 0 50px;
background: red;
}
#free {
flex: 1;
}
#scroll {
max-height: 100%;
overflow-y: scroll;
background: blue;
}
<div id="container">
<div id="fixed">Should always appear</div>
<div id="free">
<span>Should always appear</span>
<div id="scroll">
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
</div>
</div>
</div>
This example displays the problem that arises when the contents of the second div are too large.
#container {
border: 1px solid black;
height: 200px;
width: 200px;
display: flex;
flex-direction: column;
}
#fixed {
flex: 0 0 50px;
background: red;
}
#free {
flex: 1;
}
#scroll {
max-height: 100%;
overflow-y: scroll;
background: blue;
}
<div id="container">
<div id="fixed">Should always appear</div>
<div id="free">
<span>Should always appear</span>
<div id="scroll">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse porta nec dolor a dignissim. Nunc auctor felis a turpis tincidunt auctor. Suspendisse venenatis volutpat sodales. Maecenas sodales est non quam vestibulum fermentum. Nulla venenatis
sapien sit amet augue ultricies molestie. Sed neque nulla, venenatis non est a, imperdiet dictum tortor. Nam at odio rutrum, convallis neque blandit, viverra urna. Maecenas scelerisque risus eu mollis ornare. Nullam tincidunt tempus vehicula. Aenean
at porttitor ex. Fusce tincidunt nulla velit, id gravida lacus vestibulum nec.
</div>
</div>
</div>
I would accept any answer that solves this problem regardless of what combination of css and html is used (that doesn't change the order of the elements), as long as no javascript and no more height properties are added (i.e top: 40px;, min-height: calc(100% - 40px); ...), with the exception of 0, auto and 100%.
Edit: Added min-height: 0 to div's css as well as an updated fiddle.
If I understand the question correctly, is this what you're looking for?
#free {
flex: 1;
min-height: 0;
display: flex;
flex-direction: column;
}
Jsfiddle: https://jsfiddle.net/nick_zoum/Lod38e9a/3/
I'm trying to design a section of HTML/CSS wherein I have a flexbox parent element that is the width and height of the starting viewport with 3 child text boxes.
My goal is to have all 3 elements on the page and visible without needing to scroll.
My goal is to have all 3 text boxes be legible and resize accordingly to the given viewport without getting shoved out.
Looking at the HTML, it seems the content is shoved off the viewport to the right despite trying to keep the width at 100%. Basically, how can I have 3 easily modifiable flexbox that stay legible and within the width and height of the viewport no matter what changes are made to them?
My code:
.intro_header {
display: flex;
width: 100%;
padding: 10% 10% 5% 10%;
background-position: center;
background-repeat: no-repeat;
height: 100vh;
flex-wrap: wrap;
justify-content: space-between;
}
/* Generic flexbox paragraph text div that can be used for one column display regardless of responsiveness */
/*can swap around elements using the order: style */
.oneColumnText {
width: 100%;
text-align: center;
}
<div class="intro_header" style="background-image: foo.jpg">
<div class="oneColumnText">
<p>Lorem ipsum dolor sit amet</p>
</div>
<div class="oneColumnText">
<p>Lorem ipsum dolor sit amet</p>
</div>
<div class="oneColumnText">
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse sodales nulla sed fermentum tempor. Maecenas eget posuere massa. Sed consequat, erat ac tincidunt porttitor, augue sapien feugiat ligula, id ultricies augue tortor id mauris. Duis mattis
felis non libero iaculis, nec varius turpis pharetra. Vivamus convallis nibh ac arcu condimentum porta. Ut tristique in erat quis lobortis. Etiam ut elit in sem placerat dapibus.
</p>
</div>
</div>
https://jsfiddle.net/eg14v3po/1/
Add this to your code:
* { box-sizing: border-box; }
body { margin: 0; }
.intro_header {
display: flex;
padding: 10% 10% 5% 10%;
background-position: center;
background-repeat: no-repeat;
height: 100vh;
flex-wrap: wrap;
justify-content: space-between;
}
.oneColumnText {
width: 100%;
text-align: center;
}
* { box-sizing: border-box; }
body { margin: 0; }
.oneColumnText {
border-bottom: 1px solid lightgray; /* for demo only */
}
<div class="intro_header" style="background-image: foo.jpg">
<div class="oneColumnText">
<p>Lorem ipsum dolor sit amet</p>
</div>
<div class="oneColumnText">
<p>Lorem ipsum dolor sit amet</p>
</div>
<div class="oneColumnText">
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse sodales nulla sed fermentum tempor. Maecenas eget posuere massa. Sed consequat, erat ac tincidunt porttitor, augue sapien feugiat ligula, id ultricies augue tortor id mauris. Duis mattis
felis non libero iaculis, nec varius turpis pharetra. Vivamus convallis nibh ac arcu condimentum porta. Ut tristique in erat quis lobortis. Etiam ut elit in sem placerat dapibus.
</p>
</div>
</div>
With the border-box value of the box-sizing property, the padding you have specified gets factored into the width / height calculations (more details).
With margin: 0 on the body element you are overriding the default margins set by the browser (more details).
How can we get Flexbox to stop equalizing space in sibling elements when both of the elements are using flex-grow: 1. This is difficult to explain upfront, so here is the code quickly followed by example screenshots of the issue, and desired behavior.
.Parent {
display: flex;
flex-direction: column;
background-color: lightcoral;
width: 400px;
min-height: 200px;
}
.Parent>div {
flex: 1;
}
.child1 {
background-color: lightblue;
}
.child2 {
background-color: lightgreen;
}
<div class="Parent">
<div class="child1">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam sagittis lorem at odio euismod tincidunt. Proin aliquet velit nec augue venenatis laoreet. Etiam nec metus mi. Aliquam sit amet velit non lectus porttitor accumsan sit amet egestas risus.</div>
<div class="child2">Lorem ipsum</div>
</div>
The issue:
Notice the equal space under the content of each div.
Desired:
When there is little content in the children divs, the divs should be of equal height:
When one of the divs has a lot of content, I would expect the div with more content to only be as tall as the content (if it passes the original flex grow allotment).
How can I get this behavior? Seems it should be easy using Flexbox.
flex-basis is the property you're looking for. https://developer.mozilla.org/en-US/docs/Web/CSS/flex-basis
The flex-basis CSS property specifies the flex basis which is the initial main size of a flex item. This property determines the size of the content-box unless specified otherwise using box-sizing.
By default, flex will take into account the content in the element when computing flex-grow - to disable that, just specify flex-basis: 0
.Parent {
display: flex;
flex-direction: column;
background-color: lightcoral;
width: 400px;
min-height: 200px;
}
.Parent>div {
flex-grow: 1;
flex-basis: 0;
}
.child1 {
background-color: lightblue;
}
.child2 {
background-color: lightgreen;
}
<div class="Parent">
<div class="child1">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam sagittis lorem at odio euismod tincidunt. Proin aliquet velit nec augue venenatis laoreet. Etiam nec metus mi. Aliquam sit amet velit non lectus porttitor accumsan sit amet egestas risus. Etiam nec metus mi. Aliquam sit amet velit non lectus porttitor accumsan sit amet egestas risus </div>
<div class="child2">Lorem ipsum</div>
</div>
By setting min-height on .Parent (along with setting the flex-direction to column), you're triggering the browser to fill the space with direct descendants of .Parent. It does so by distributing the space amongst all elements equally (that's the feature of Flexbox).
If you don't want that behavior, remove the min-height from .Parent and set a min-height on .Parent > div elements.
.Parent {
display: flex;
flex-direction: column;
background-color: lightcoral;
width: 400px;
}
.Parent>div {
flex: 1;
min-height: 100px;
}
.Parent > div:nth-child(odd) {
background-color: lightblue;
}
.Parent > div:nth-child(even) {
background-color: lightgreen;
}
<div class="Parent">
<div class="child1">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam sagittis lorem at odio euismod tincidunt. Proin aliquet velit nec augue venenatis laoreet. Etiam nec metus mi. Aliquam sit amet velit non lectus porttitor accumsan sit amet egestas risus. Nullam sagittis lorem at odio euismod tincidunt. Proin aliquet velit nec augue venenatis laoreet. Etiam nec metus mi. Aliquam sit amet velit non lectus porttitor accumsan sit amet egestas risus.</div>
<div class="child2">Lorem ipsum</div>
<div>Lorem ipsum doler sit amet</div>
<div>When there is little content in the children divs, the divs should be of equal height.</div>
</div>