This question already has answers here:
Percentage Height HTML 5/CSS
(7 answers)
Make div (height) occupy parent remaining height
(9 answers)
Closed 4 months ago.
I have React app that would like to make 20% app bar on top and 80% or the rest of the height fulfill with parent height.
<div>
//Like to make 20% height
<div>
<p>App bar</p>
</div>
//Like to make 80% height
<div>
<div>Content A</div>
<div>Content B</div>
<div>Content C</div>
</div>
</div>
Flex box makes it easiler than ever to scale the dom to fill the rest space.
<div class="parent">
<div class="app-bar">
<p>App bar</p>
</div>
<div class="rest">
<div>Content A</div>
<div>Content B</div>
<div>Content C</div>
</div>
</div>
.parent {
width: 100%;
height: 100%;
min-height: 400px;
display: flex;
flex-flow: column;
background-color: #cccccc;
border: 1 solid #aaaaaa;
}
.app-bar {
height: 20%;
background-color: #aaaaaa;
}
.rest {
flex: 1 1 auto;
background-color: yellow;
}
One of the solution is to try this:
<div style={{display:"flex", flexDirection:"column"}}>
<div style={{height: "20vh"}}>
<p>App bar</p>
</div>
<div style={{height: "80vh", border:"1px solid blue"}}>
<div>Content A</div>
<div>Content B</div>
<div>Content C</div>
</div>
</div>
Related
I'm trying to achieve this, where brown gets pushed down when pink is too long, and pink is dynamically sized based on its text content.
I was only able to achieve this using javascript and two templates, if pink length is over X use second template, but I'm wondering if there's a way to achieve this using CSS only?
I tried meddling with grid auto-fill/auto-fit with minmax, float, flex with wrap, but I couldn't get to the desired result with these.
.parent {
width: 170px;
}
.flex {
display: flex;
}
div {
outline: 2px solid rgba(255, 0,0, 0.3);
}
<div>
<p>scenario A</p>
<div class="parent flex">
<div>
<div class="one">A short title</div>
<div class="three">Some text here</div>
<div class="three">some more text</div>
</div>
<div>
<button>A button</button>
</div>
</div>
</div>
<div>
<p>scenario B</p>
<div class="parent">
<div class="one">Testing a very long title</div>
<div class="flex">
<div>
<div class="three">Some text here</div>
<div class="three">some more text</div>
</div>
<div>
<button>A button</button>
</div>
</div>
</div>
</div>
<p>can a component achieve both a and b with only css?
I found a solution, it requires having fixed height in the first row, and the right side button will basically overflow when needed.
Will wait a bit before accepting my own solution in case someone came with a better one.
.container {
width: 300px;
display: flex;
gap: 10px;
padding: 16px;
font-size: 14px;
font-family: Arial;
}
.text {
flex: 1;
min-width: 0;
}
.first-row {
height: 22px;
display: flex;
flex-wrap: wrap;
justify-content: flex-end;
gap: 8px;
}
.image {
width: 40px;
height: 40px;
border-radius: 50%;
background-color: #444;
}
.title {
flex-grow: 1;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
<h2>Long title</h2>
<div class="container">
<div class="image"></div>
<div class="text">
<div class="first-row">
<div class="title">Test title test title test title</div>
<button>Visit store</button>
</div>
<div class="three">in the stores</div>
<div class="three">sponsored</div>
</div>
</div>
<h2>Short title</h2>
<div class="container">
<div class="image"></div>
<div class="text">
<div class="first-row">
<div class="title">Short title</div>
<button>Visit place</button>
</div>
<div class="three">in the stores</div>
<div class="three">sponsored</div>
</div>
</div>
<h2>Very long title</h2>
<div class="container">
<div class="image"></div>
<div class="text">
<div class="first-row">
<div class="title">Test title test titleTest title test titleTest title test title</div>
<button>Visit place</button>
</div>
<div class="three">in the stores</div>
<div class="three">sponsored</div>
</div>
</div>
Could anyone please help me with this, How can I make the parent container flexible and make it reflow ready?
.container{
width: 350px;
border: 1px solid red;
}
.item{
margin-top:2px;
display: flex;
}
.line{
flex-grow:1;
}
<div class="container">
<div class="item">
<div class="line"><span>xyx</span></div>
<span>10 USD</span>
</div>
<div class="item">
<div class="line"><span>q</span></div>
<span>* 2</span>
</div>
<div class="item">
<div class="line"><span>total</span></div>
<span>20 USD</span>
</div>
</div>
Since you are referring reflow as browser width change and your default width for the container is 350px
just your change width: 350px to max-width: 350px. Your container is now responsive for smaller browser width
You can play around around here and change the browser here:
.container{
max-width: 350px;
border: 1px solid red;
}
.item{
margin-top:2px;
display: flex;
}
.line{
flex-grow:1;
}
<div class="container">
<div class="item">
<div class="line"><span>xyx</span></div>
<span>10 USD</span>
</div>
<div class="item">
<div class="line"><span>q</span></div>
<span>* 2</span>
</div>
<div class="item">
<div class="line"><span>total</span></div>
<span>20 USD</span>
</div>
</div>
I'm running into an issue with position: absolute and I can't find an answer anywhere that explains why it's happening.
I have a flexbox container inside a wrapper with two children that are each set to flex-basis: 50%. When I set position: absolute on the wrapper div, the wrapper shrinks in an unpredictable way.
See the code below:
.outer-wrapper {
position: relative;
width: 100%;
}
.outer-wrapper .wrapper {
position: absolute;
}
.outer-wrapper .wrapper .flex-container {
display: flex;
}
.outer-wrapper .wrapper .flex-container .flex-item {
flex-basis: 50%;
}
<div class="outer-wrapper">
<div class="wrapper">
<div class="flex-container">
<div class="flex-item">
Some Text That Is Long
</div>
<div class="flex-item">
Some Text
</div>
</div>
<div class="flex-container">
<div class="flex-item">
Some Text
</div>
<div class="flex-item">
Some Text
</div>
</div>
</div>
</div>
Removing line 6 in the CSS causes the flex-container to expand to the full width of the parent and each flex child takes up 50% of the width, as expected. However, when I set the wrapper div to position: absolute, the wrapper div shrinks to what seems like an arbitrary width and the text in the flex-children breaks onto multiple lines.
My questions:
Why does setting position: absolute on the wrapper div cause the wrapper div to shrink smaller than its content?
How does the browser determine what width to shrink the wrapper div to? It seems to me like it would either shrink to be as small as possible without introducing line breaks into the text, or would shrink as small as possible while still fitting the longest word, but instead it's shrinking to somewhere in the middle (it only introduces one line break in a string of short words).
Is there a way, while still using flexbox and position: absolute in this way, to force the browser to not shrink the wrapper smaller than its content (unless there is a max-width set on the wrapper)?
Really appreciate any help! This has been driving me crazy!
Why does setting position: absolute on the wrapper div cause the wrapper div to shrink smaller than its content?
How does the browser determine what width to shrink the wrapper div to?
The trick is the use of flex-basis::50%. You are in a situation where you are using a shrink-to-fit container (position:absolute element) and at the same time you are using percentage value inside the flex-basis. So the browser is first calculating the width of the container (ignoring the flex-basis) then the width calculated will be used as reference for the flex-basis.
Here is an illustration of what is happening:
.wrapper {
position: absolute;
border:1px solid red;
}
.wrapper .flex-container {
display: flex;
}
.wrapper .flex-container .flex-item {
/*flex-basis: 50%;*/
border:1px solid green;
}
<div class="wrapper">
<div class="flex-container">
<div class="flex-item">
Some Text That Is Long
</div>
<div class="flex-item">
Some Text
</div>
</div>
<div class="flex-container">
<div class="flex-item">
Some Text
</div>
<div class="flex-item">
Some Text
</div>
</div>
</div>
<div class="wrapper" style="top:100px;">
<div class="flex-container">
<div class="flex-item" style="flex-basis: 50%;">
Some Text That Is Long
</div>
<div class="flex-item" style="flex-basis: 50%;">
Some Text
</div>
</div>
<div class="flex-container">
<div class="flex-item" style="flex-basis: 50%;">
Some Text
</div>
<div class="flex-item" style="flex-basis: 50%;">
Some Text
</div>
</div>
</div>
Notice how in the first example (without flex-basis) the width is equal to the largest content. In the second example you will see that the total width didn't change but we made the flex items equal in width.
The same logic also happen with inline-block or float or any shrink-to-fit container.
.wrapper {
display:inline-block;
border:1px solid red;
}
.wrapper .flex-container {
display: flex;
}
.wrapper .flex-container .flex-item {
/*flex-basis: 50%;*/
border:1px solid green;
}
<div class="wrapper">
<div class="flex-container">
<div class="flex-item">
Some Text That Is Long
</div>
<div class="flex-item">
Some Text
</div>
</div>
<div class="flex-container">
<div class="flex-item">
Some Text
</div>
<div class="flex-item">
Some Text
</div>
</div>
</div>
<br><br>
<div class="wrapper">
<div class="flex-container">
<div class="flex-item" style="flex-basis: 50%;">
Some Text That Is Long
</div>
<div class="flex-item" style="flex-basis: 50%;">
Some Text
</div>
</div>
<div class="flex-container">
<div class="flex-item" style="flex-basis: 50%;">
Some Text
</div>
<div class="flex-item" style="flex-basis: 50%;">
Some Text
</div>
</div>
</div>
To get what you want it's clear that you need to not use flex-basis:50% and consider a different idea to get the same width.
Here is one using CSS grid as I think it would be tedious with flexbox:
.wrapper {
position:absolute;
border:1px solid red;
}
.wrapper .flex-container {
display: grid;
grid-template-columns:repeat(2,1fr);
}
.wrapper .flex-container .flex-item {
border:1px solid green;
}
<div class="wrapper">
<div class="flex-container">
<div class="flex-item">
Some Text That Is Long
</div>
<div class="flex-item">
Some Text
</div>
</div>
<div class="flex-container">
<div class="flex-item">
Some Text
</div>
<div class="flex-item">
Some Text
</div>
</div>
</div>
The reason it is shrinking is since you are setting position absolute without specifying a width.
Block element feature of having the full width of the parent's content area will not be honored when an element is absolute positioned.
If you want to retain the width (100% of the container) of a block element, then set the width of the absolute element .wrapper to 100% and problem solved.
.outer-wrapper {
position: relative;
width: 100%;
}
.wrapper {
position: absolute;
width:100%;
}
.flex-container {
display: flex;
}
.flex-item {
flex-basis: 50%;
}
I'm building a Carousel-type component, but am having some difficulty getting it to work just right.
My basic approach is a div (wrapper) with lots of other divs (items) in it. I want to display 4 items on the carousel at any one time. The items have various content heights, but the heights of the items should be equal (to the largest required).
I can't work out the CSS combination I need to get this to work correctly.
With this setup (HTML + CSS at bottom of post), the width: 25%; on each item-container is ignored.
If I add a fixed with to .item, then the 25% kicks in, but the item width is unknown -- it depends on the browsers size. Setting it to 1000px means you lose content from the item. Setting it to ~210px works, but when you start shrinking your browser, you lose content. On a large browser, you have excessive spacing.
Curiously, if I add flex-wrap: wrap to the CSS, then the 25% width is applied correctly -- but I can't do that, because then it's not a carousel! Example
The scenario is simple:
An unknown amount of items in a div with overflow: auto, which are equal heights should be displayed, with 4 of the children divs on the screen at any one time.
My HTML is structured as follows:
<div id="container">
<div id="wrapper">
<div class="item-container">
<div class="item">
<p>
Carousel Item #1 with some quite long text.
</p>
</div>
</div>
<div class="item-container">
<div class="item">
<p>
Carousel Item #2.
</p>
</div>
</div>
<div class="item-container">
<div class="item">
<p>
Carousel Item #3.
</p>
</div>
</div>
...
</div>
</div>
My CSS:
#container {
width: 100%;
background: #0f0;
overflow: auto;
}
#wrapper {
display: flex;
}
.item-container {
border: 1px solid #f00;
width: 25%;
}
Note, this is my MCVE. On my real component, I have buttons for scrolling left and right, the content is significantly more complex and stuff like that.
All you need is to add flex: 0 0 auto to .item-container elements.
* {
box-sizing: border-box;
}
#container {
width: 100%;
background: #0f0;
overflow: auto;
}
#wrapper {
display: flex;
}
.item-container {
border: 1px solid #f00;
flex: 0 0 auto;
width: 25%;
}
<div id="container">
<div id="wrapper">
<div class="item-container">
<div class="item">
<p>
Carousel Item #1 with some quite long text.
</p>
</div>
</div>
<div class="item-container">
<div class="item">
<p>
Carousel Item #2.
</p>
</div>
</div>
<div class="item-container">
<div class="item">
<p>
Carousel Item #3.
</p>
</div>
</div>
<div class="item-container">
<div class="item">
<p>
Carousel Item #4.
</p>
</div>
</div>
<div class="item-container">
<div class="item">
<p>
Carousel Item #5.
</p>
</div>
</div>
<div class="item-container">
<div class="item">
<p>
Carousel Item #6.
</p>
</div>
</div>
<div class="item-container">
<div class="item">
<p>
Carousel Item #7.
</p>
</div>
</div>
</div>
</div>
i coded a 6 divs beside each other
how can i make one div only to expand to take full width of wrapped div on hover and the other 5 divs get on bottom to the fully expanded div
html:
<div class="row">
<div class="col-md-2" id="discuss_block">
div1.....
</div>
<div class="col-md-2" id="discuss_block">
div2.....
</div>
<div class="col-md-2" id="discuss_block">
div3.....
</div>
<div class="col-md-2" id="discuss_block">
div4.....
</div>
<div class="col-md-2" id="discuss_block">
div5.....
</div>
<div class="col-md-2" id="discuss_block">
div6.....
</div>
</div>
css:
#discuss_block{
background: #FFBC2F;
color: #FFF;
z-index: 30;
top: 0px;
}
#discuss_block:hover{
width:100%;
}
You can use float:left http://jsfiddle.net/sfnxkav5/1/
#discuss_block{
width:50px;
float:left;
background: #FFBC2F;
color: #FFF;
z-index: 30;
top: 0px;
}