I have 2 divs. In the div on the right has a text. This text has to to be allways in the middle of the screen. Also the text is never allowed to leave the box. I want it responsive. So it works on pc / tablet / phone, etc.
Here my jsfiddle:
https://jsfiddle.net/ourn15f8/106/
.screen-1 {
width: 500px;
display: flex;
}
.div-1 {
background-color: green;
width: 100px;
}
.div-2 {
background-color: red;
width: 400px;
text-align: center;
}
Total Width = Screen Width
<br><br>
Situation:
<div class="screen-1">
<div class="div-1">logo</div>
<div class="div-2">text</div>
</div>
Wanted:
<div class="screen-1">
<div class="div-1" style="position: absolute">logo</div>
<div class="div-2" style="width: 500px">text</div>
</div>
<div class="screen-1" style="width: 400px">
<div class="div-1" style="position: absolute">logo</div>
<div class="div-2" style="width: 300px">text</div>
</div>
<div class="screen-1" style="width: 300px">
<div class="div-1" style="position: absolute">logo</div>
<div class="div-2" style="width: 200px">text</div>
</div>
Text in the middle of screen
<br><br>
Also when screen to small, I want this:
<div class="screen-1" style="width: 150px">
<div class="div-1">logo</div>
<div class="div-2" style="width: 50px">text</div>
</div>
"text" is never allowed to leave the div
<br><br>
Info:<br>
I dont want to use position absolute. The divs have to by dynamic so it works on pc and phone.
You can use grid to make 3 boxes, each 1fr so they're evenly spaced then put your logo in the left one and the content in the middle one. You can then use flexbox to put the text div in to the middle of the centre div which is essentially the centre of the screen.
.container {
display: grid;
grid-template-columns: repeat(3, 1fr);
background-color: red;
}
.logo {
background-color: green;
width: 200px;
margin-left: 0;
margin-right: auto;
}
.textcontainer {
display: flex;
justify-content: center;
}
.container>div>div {
padding: 0.5rem 0.25rem;
}
<div class='container'>
<div class='logocontainer'>
<div class='logo'>
Logo
</div>
</div>
<div class='textcontainer'>
<div>
<!-- Put your text here -->
Text
</div>
</div>
<div></div>
<!-- this is a dummy container to push the text container to the middle of the screen -->
</div>
Related
I'm aware of CSS Subgrid being able to solve a layout like this, but what I'm looking to achieve is a list of containers with content inside. The content inside the containers is aligned right in the containers, but all the content is aligned (left) to the longest content.
Is this possible with flex? Are there any strategies to achieve this?
I suppose the HTML structure would be something like:
<div class="container">
<div class="content" style="100px"></div>
</div>
<div class="container">
<div class="content" style="300px"></div>
</div>
<div class="container">
<div class="content" style="400px">All other content aligned to this longest content</div>
</div>
<div class="container">
<div class="content" style="200px"></div>
</div>
It is most definitely doable with flex.
What I've done is create 2 columns inside the .container element. Column 2 will be right aligned inside the container, and your .content will be left aligned inside .column2.
All you need to do to adjust the alignment of the content inside the containers, is to play around with the widths of .column1 and .column2 in the snippet below:
* {
font-family: sans-serif;
}
.container {
display: flex;
background: lightgray;
align-items: center;
border-radius: 5px;
margin-bottom: 10px;
padding: 7px;
}
.content {
display: flex;
align-items: center;
padding: 0 10px;
background: #666;
border-radius: 5px;
color: white;
height: 50px;
}
.column1 {
width: 30%;
}
.column2 {
width: 70%;
}
<div class="container">
<div class="column1">Container</div>
<div class="column2">
<div class="content" style="width: 100px"></div>
</div>
</div>
<div class="container">
<div class="column1">Container</div>
<div class="content" style="width: 250px"></div>
</div>
</div>
<div class="container">
<div class="column1">Container</div>
<div class="column2">
<div class="content">All other content aligned to this longest content</div>
</div>
</div>
<div class="container">
<div class="column1">Container</div>
<div class="column2">
<div class="content" style="width: 200px"></div>
</div>
</div>
I had to change the logo's resolution to at least be able to see the logo (format was 3400x1716) to 99x50 for overlapping the picture and added a text with the logo.
I set the pictures that are supposed to get superimposed to 300 height and 100% width to fill out the rest of the page, but that is shown in my code.
The end product will be that I will be able to hover over the picture/logo and the text appears.
My problem is that I can't see the logo nor the text that should superimpose the picture.
In total for 12 pictures with 12 different text's but the same logo.
.portfolio-items-wrapper {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
}
.portfolio-item-wrapper {
position: relative;
}
.portfolio-img-background {
height: 300px;
width: 100%;
background-size: cover;
background-position: center;
background-repeat: no-repeat;
}
.img-text-wrapper {
position: absolute;
top: 0;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
height: 100%;
text-align: center;
padding-left: 100%;
padding-right: 100%;
}
<div class="content-wrapper">
<div class="portfolio-items-wrapper">
<div class="portfolio-item-wrapper">
<div class="portfolio-img-background" style="background- image:url(images/portfolio1.jpg)"></div>
<div class="img-text-wrapper">
<div class="logo-wrapper">
<img src="images/logos/thought.png">
</div>
<div class="subtitle">
Using a different approach than the NORM!
</div>
</div>
</div>
<div class="portfolio-item-wrapper">
<div class="portfolio-img-background" style="background- image:url(images/portfolio2.jpg)"></div>
<div class="img-text-wrapper">
<div class="logo-wrapper">
<img src="images/logos/thought.png">
</div>
<div class="subtitle">
Everything starts with a THOUGHT!
</div>
</div>
</div>
</div>
</div>
You can use the approach you started using, that is setting a background-image to your parent container element, and then you can position the text and logo elements using flexbox.
img {
width:50px;height:50px;
}
div {
background-image:url('https://static-cse.canva.com/image/1578/RoyalBlue_Set1_23.5dfc6872.png');
background-size:contain;
background-repeat:no-repeat;
background-position:center center;
width:300px;height:300px;
display:flex;align-items:center;flex-direction:column;justify-content:center;
color:#FFF;font-size:36px;
}
<div>
<img src="https://assets.codepen.io/5200861/internal/avatars/users/default.png">
<h3>some text here</h3>
</div>
I'm programming a web application with collapsible sidebar inside a CSS grid. The CSS grid divides the whole UI into sections, and the sidebar panel is a sub-component of one of those sections.
The issue I am running into is that I want the side panel to automatically shrink to the minimum size of it's contents, which it does fine until it's added to a CSS grid cell, at which point it expands to fill the entire cell.
Here is a quick example of the issue:
<style>
#myGrid{
display: grid;
grid-template-areas:
"g1 g2";
}
#panel{
grid-area: g2;
display: inline-block;
background: #FFAAAA;
height: 100%;
width: auto;
min-width: minmax(0, 1fr);
}
#panelContents{
display: flex;
flex-direction: row;
height: 100%;
}
#collapseArrow{
align-self: center;
right: 0;
top: 50%;
}
#block{
grid-area: g1;
width: 200px;
height: 100%;
background: #AAAAFF;
}
</style>
<body>
<div id="myGrid">
<div id="block">
Contents
</div>
<div id="panel">
<div id="panelContents">
<div id="collapseContents">
<div class="item">
Item1
</div>
<div class="item">
Item2
</div>
<div class="item">
Item3
</div>
<div class="item">
Item4
</div>
<div class="item">
Item5
</div>
</div>
<div id="collapseArrow"><</div>
</div>
</div>
</div>
</body>
Any idea how to solve this? I am trying to get the red panel to shrink to fit it's contents. I tried changing the min-width to 0, but that didn't seem to help.
EDIT: This is a more complex UI for an HTML5 game engine. The left grid cell is an asset browser, and the red panel is a simple properties panel for the right editor window (right grid cell), which I'm trying to display only on the left portion of the cell, so the rest of the right cell can be the editor window.
Use the other column to squeeze the panel down to its content width.
#myGrid {
display: grid;
grid-template-columns: 1fr auto; /* 1fr consumes all free space on the row */
grid-template-areas: "g1 g2";
}
#block {
grid-area: g1;
background: #AAAAFF;
}
#panel {
grid-area: g2;
background: #FFAAAA;
}
#panelContents {
display: flex;
}
#collapseArrow {
align-self: center;
}
<div id="myGrid">
<div id="block">
Contents
</div>
<div id="panel">
<div id="panelContents">
<div id="collapseContents">
<div class="item">Item1</div>
<div class="item">Item2</div>
<div class="item">Item3</div>
<div class="item">Item4</div>
<div class="item">Item5</div>
</div>
<div id="collapseArrow"><</div>
</div>
</div>
</div>
I have a flex container which contains an img flex item.
I want this img to disregard its intrinsic height (90px) so that the height may shrink to match the sibling's flex item height (as per the default align-items: stretch style).
.container {
border: 1px solid;
display: flex;
}
.item {
border: 1px solid;
}
.content {
width: 200px;
height: 50px;
background-color: hotPink;
}
<div class="container">
<img class="item" src="https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRu-3yBSd2b6JCOMcGVSOFf8X49QB3Ik-OI87gKEMwWLrdJxP5qOErmZQ">
<div class="item">
<div class="content"></div>
</div>
</div>
We can see the desired behaviour if we swap the img for a div:
.container {
border: 1px solid;
display: flex;
}
.item {
border: 1px solid;
}
.dynamicHeightContent {
width: 120px;
height: 100%;
background-color: green;
}
.content {
width: 200px;
height: 50px;
background-color: hotPink;
}
<div class="container">
<div class="item">
<div class="dynamicHeightContent"></div>
</div>
<div class="item">
<div class="content"></div>
</div>
</div>
I have tried min-height: 0 on the img, to no avail.
What is the special behaviour that applies to img but not div?
How can we opt out of img's special behaviour so that it behaves like other flex items (such as div)? If there isn't a way to opt-out, is there a recommended workaround?
Note that whilst the img won't shrink its height, it does appear to grow:
.container {
border: 1px solid;
display: flex;
}
.item {
border: 1px solid;
}
.content {
width: 200px;
height: 300px;
background-color: hotPink;
}
<div class="container">
<img class="item" src="https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRu-3yBSd2b6JCOMcGVSOFf8X49QB3Ik-OI87gKEMwWLrdJxP5qOErmZQ">
<div class="item">
<div class="content"></div>
</div>
</div>
Note: I'm happy to disregard the img's aspect ratio. I plan to avoid skewing the img via object-fit: cover.
Note that in your example, the item is the flex item and not content - you should check the strech behaviour of item here.
How can we opt out of img's special behaviour so that it behaves like
other flex items (such as div)?
It behaves like other flex items - <img> may not be very useful as a flex item but the stretch behaviour works fine:
if the image has more height than item, the item stretches to the height of the image
if the image has less height than item, the image stretches to the height of the content breaking its aspect ratio.
See demo below:
.container {
border: 1px solid;
display: flex;
}
.item {
background: cadetblue;
}
.content {
width: 200px;
background-color: hotPink;
}
img {
display: block;
}
<h2>Small content</h2>
<div class="container">
<img src="https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRu-3yBSd2b6JCOMcGVSOFf8X49QB3Ik-OI87gKEMwWLrdJxP5qOErmZQ">
<div class="item">
<div class="content">some text here some text here some text here </div>
</div>
</div>
<br/>
<h2>Large Content</h2>
<div class="container">
<img src="https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRu-3yBSd2b6JCOMcGVSOFf8X49QB3Ik-OI87gKEMwWLrdJxP5qOErmZQ">
<div class="item">
<div class="content">some text here some text here some text here some text here some text here some text here some text here some text here some text here some text here some text here some text here some text here some text here some text here some text here </div>
</div>
</div>
I have tried min-height: 0 on the img, to no avail.
The min-height: 0 is given to a column flexbox along the flex direction to override the default auto behaviour (for row direction the property is min-width) - this doesn't work in the cross axis.
You can see details and some examples of this below:
Flexbox affects overflow-wrap behavior
Flexbox resize and scrollable overflow
Why don't flex items shrink past content size?
Wrapping image in a container
Now wrap the <img> in a div and see the same situation - the stretch behaviour is again good:
.container {
border: 1px solid;
display: flex;
}
.item {
background: cadetblue;
}
.content {
width: 200px;
background-color: hotPink;
}
img {
display: block;
}
<h2>Small content</h2>
<div class="container">
<div class="item">
<img src="https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRu-3yBSd2b6JCOMcGVSOFf8X49QB3Ik-OI87gKEMwWLrdJxP5qOErmZQ"></div>
<div class="item">
<div class="content">some text here some text here some text here </div>
</div>
</div>
<br/>
<h2>Large Content</h2>
<div class="container">
<div class="item">
<img src="https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRu-3yBSd2b6JCOMcGVSOFf8X49QB3Ik-OI87gKEMwWLrdJxP5qOErmZQ"></div>
<div class="item">
<div class="content">some text here some text here some text here some text here some text here some text here some text here some text here some text here some text here some text here some text here some text here some text here some text here some text here </div>
</div>
</div>
The difference now is that you can use object-fit successfully on the image now (this does not work properlly if it is a flex item):
.container {
border: 1px solid;
display: flex;
}
.item {
background: cadetblue;
}
.content {
width: 200px;
background-color: hotPink;
}
img {
display: block;
width: 100%;
height: 100%;
object-fit: cover;
}
<h2>Small content</h2>
<div class="container">
<div class="item">
<img src="https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRu-3yBSd2b6JCOMcGVSOFf8X49QB3Ik-OI87gKEMwWLrdJxP5qOErmZQ"></div>
<div class="item">
<div class="content">some text here some text here some text here </div>
</div>
</div>
<br/>
<h2>Large Content</h2>
<div class="container">
<div class="item">
<img src="https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRu-3yBSd2b6JCOMcGVSOFf8X49QB3Ik-OI87gKEMwWLrdJxP5qOErmZQ"></div>
<div class="item">
<div class="content">some text here some text here some text here some text here some text here some text here some text here some text here some text here some text here some text here some text here some text here some text here some text here some text here </div>
</div>
</div>
I want this img to disregard its intrinsic height (90px) so that the
height may shrink to match the sibling's flex item height
The only way to disregard the image height is to use positioning on the image wrapper:
position the image absolutely with respect to its wrapper,
you can either give a width to the image wrapper or give flex: 1 on item to get half of the available width horizontally.
See demo below:
.container {
border: 1px solid;
display: flex;
}
.item {
background: cadetblue;
flex: 1; /* equal width for items */
}
.content {
width: 200px;
background-color: hotPink;
}
.item:first-child { /* image container */
position: relative;
}
img {
display: block;
width: 100%;
height: 100%;
object-fit: cover;
position: absolute; /* position absolutely */
top: 0;
left: 0;
}
<h2>Small content</h2>
<div class="container">
<div class="item">
<img src="https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRu-3yBSd2b6JCOMcGVSOFf8X49QB3Ik-OI87gKEMwWLrdJxP5qOErmZQ"></div>
<div class="item">
<div class="content">some text here some text here some text here </div>
</div>
</div>
<br/>
<h2>Large Content</h2>
<div class="container">
<div class="item">
<img src="https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRu-3yBSd2b6JCOMcGVSOFf8X49QB3Ik-OI87gKEMwWLrdJxP5qOErmZQ"></div>
<div class="item">
<div class="content">some text here some text here some text here some text here some text here some text here some text here some text here some text here some text here some text here some text here some text here some text here some text here some text here </div>
</div>
</div>
I think you are looking at this the wrong way.
The image itself is 90px high which means the content of the flex item has a height of 90px(because your image is the flex item). So your div on the right side is matching the image height because it is higher than the div's height and not the other way around.
Think of it as if you have set the height of the flex item(image) to 90px. So it won't shrink pass it unless you set it to a smaller height. Even though you didn't explicitly set the image height to 90px but it is 90px naturally so it is implicitly set which causes the confusion. So while it will stretch beyond 90px in height it won't go under it because that's the height of the flex item content.
In the case where you swapped it for a div and it works like you imagined is because there is no height set on the .item div which is the flex item.
while this is not the answer you are asking, but the div and img actually behave the same, that is if there is content taller than the height, it grows the height
example:
.container {
border: 1px solid;
display: flex;
}
.item {
border: 1px solid;
}
.dynamicHeightContent {
width: 120px;
height: 100%;
background-color: green;
}
.content {
width: 200px;
height: 50px;
background-color: hotPink;
}
<div class="container">
<div class="item">
<div class="dynamicHeightContent">
akhsdjahskd<br>
ajkhsdkjhasd<br>
ajshdkahsd<br>
ajsgdjgad<br>
ajshdasjdh<br>
</div>
</div>
<div class="item">
<div class="content"></div>
</div>
</div>
since you insist that object-fit should solve it, you can try this, as you can see, object-fit only works if we set the height and width, otherwise the browser will try to make it "keep aspect ratio", just try to remove the height or width from the css (one at a time), you will see this effect
.container {
border: 1px solid;
display: flex;
}
.item {
border: 1px solid;
}
img.item {
height: 50px;
width: 200px;
object-fit: cover;
}
.content {
width: 200px;
height: 50px;
background-color: hotPink;
}
<div class="container">
<img class="item" src="https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRu-3yBSd2b6JCOMcGVSOFf8X49QB3Ik-OI87gKEMwWLrdJxP5qOErmZQ">
<div class="item">
<div class="content"></div>
</div>
</div>
I have 3 columns
.bookingTotals.middleRow {
height: 315px;
bottom: 400px;
}
.bookingTotals.row {
height: 400px;
bottom: 0;
margin-left: 920px;
/*margin-right: 55px;*/
}
<div id "myParent">
<div style="float: left; width: 400px;">
//some stuff
<div>
<div style="float: left; width: 400px;">
//some stuff
<div>
<div style="float: left; width: 400px;">
<div style="height:50px;">
//top stuff
</div>
<div class="bookingTotals middleRow">
//middle stiff that fills the gap
</div>
<div class="bookingTotals row">
//bottom stuff that i want fixed to the bottom
</div>
</div>
</div>
</div>
</div>
</div>
</div>
I want to split the last column into 3 layers where the top and bottom div heights are known. So I want the middle div to fill the space between.
What actually happens is that this footer div is displayed outside myParent as if it had no relation to it. What am I doing wrong?
I took some liberty with your height so it would show better.
Use CSS for everything, not put in the markup. Use classes for that.
I make the assumption you want the text in the last one at the bottom so I added a span around it and used align-self: flex-end; at the flex end for the row.
Background color added for clarity of the solution.
#myParent {
width: 100px;
}
.rowthing {
width: 410px;
}
.holder {
display: flex;
flex-direction: column;
min-height: 350px;
border: solid 1px red;
}
.things {
display: flex;
}
.topstuff {
height: 50px;
background-color: #ddeeee;
}
.bookingTotals.middleRow {
flex-grow: 1;
background-color: #dddddd;
justify-content: space-evenly;
}
.bookingTotals.middleRow span {
align-self: center;
}
.bookingTotals.bottom {
height: 100px;
background-color: #eeeedd;
justify-content: center;
}
.bookingTotals.bottom span {
align-self: flex-end;
}
<div id "myParent">
<div class="rowthing">
//some stuff1
</div>
<div class="rowthing">
//some stuff2
</div>
<div class="rowthing holder">
<div class="things topstuff">
//top stuff
</div>
<div class="things bookingTotals middleRow">
<span> //middle stiff that fills the gap<span>
</div>
<div class="things bookingTotals bottom">
<span>bottom stuff that i want fixed to the bottom<span>
</div>
</div>
</div>
If you use the bottom property you also need to specify position.
I used calc to fill the space. In this way, the height of the middle row will depend on the screen size.
.top-row {
height: 50px;
background: red;
}
.bookingTotals.middleRow {
height: calc(100vh - 400px);
background: orange;
}
.bookingTotals.row {
height: 290px;
background: yellow;
}
<div id="myParent">
<div>
some stuff
<div>
<div style="width: 400px;">
some stuff
<div>
<div style="width: 400px;">
<div class="top-row">
top stuff
</div>
<div class="bookingTotals middleRow">
middle stiff that fills the gap
</div>
<div class="bookingTotals row">
bottom stuff that i want fixed to the bottom
<div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>