I am trying to implement a Flexbox container for an image gallery. I would like this gallery to not require the use of a scrollbar and instead adjust the size of the images to fit the screen.
<!DOCTYPE html>
<html>
<head>
<style>
* {
box-sizing: border-box;
}
html, body {
height: 100%;
margin: 0;
}
#flex-container {
display: flex;
flex-wrap: wrap;
justify-content: center;
align-items: center;
background-color: blue;
height: 90%;
}
.img-wrap {
width: 25%;
height: 25%;
display: flex;
align-items: center;
justify-content: center;
}
.img-wrap img {
max-width: 100%;
max-height: 100%;
height: auto;
width: auto;
}
</style>
</head>
<body>
<div class="text-wrap">This should always be visible</div>
<div id="flex-container">
<div class="img-wrap"><img src="https://picsum.photos/200"></div>
<div class="img-wrap"><img src="https://picsum.photos/300/200"></div>
<div class="img-wrap"><img src="https://picsum.photos/400/800"></div>
<div class="img-wrap"><img src="https://picsum.photos/500/250"></div>
<div class="img-wrap"><img src="https://picsum.photos/450/505"></div>
<div class="img-wrap"><img src="https://picsum.photos/350/520"></div>
<div class="img-wrap"><img src="https://picsum.photos/250/300"></div>
<div class="img-wrap"><img src="https://picsum.photos/550/200"></div>
<div class="img-wrap"><img src="https://picsum.photos/200"></div>
<div class="img-wrap"><img src="https://picsum.photos/300/200"></div>
<div class="img-wrap"><img src="https://picsum.photos/400/800"></div>
<div class="img-wrap"><img src="https://picsum.photos/500/250"></div>
<div class="img-wrap"><img src="https://picsum.photos/450/505"></div>
<div class="img-wrap"><img src="https://picsum.photos/350/520"></div>
<div class="img-wrap"><img src="https://picsum.photos/250/300"></div>
<div class="img-wrap"><img src="https://picsum.photos/550/200"></div>
</div>
<div class="text-wrap">This should always be visible, even without using a scrollbar</div>
</body>
</html>
The problem is that when the window is small enough (vertically), the bottom text gets cut off and the user needs to scroll to see it.
I would like to have both sections of text always visible. The images should always get smaller until both sections of text are touching, at which point a scrollbar is acceptable.
Add position fixed on text-wrap class, it will fix the position of top and bottom heading.
.text-wrap {
postion:fixed;
}
Related
I am trying to create a split screen scroll.
I need to position the image from the first column exactly parallel to the image from the second column.
It has to start and finish with both images completly visible on the screen.
My problem is that when it starts and finishes the images are not aligned (a bit of one image is not visible).
It only works randomly on some resolutions.
The left column works with the default native browser scroll.
The second column which is fixed positioned is working by taking the the number of pixels scrolled then multiplied by minus one.
https://codepen.io/victoreugen2002/pen/QWdJzdB
$(window).on('scroll', function() {
$(".column-right").css('bottom', $(window).scrollTop() * -1);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="full-page">
<div class="column-left">
<div class="image">
<img src="https://picsum.photos/200/300">
</div>
<div class="image">
<img src="https://picsum.photos/200/300">
</div>
<div class="image">
<img src="https://picsum.photos/200/300">
</div>
</div>
<div class="column-right">
<div class="image">
<img src="https://picsum.photos/200/300">
</div>
<div class="image">
<img src="https://picsum.photos/200/300">
</div>
<div class="image">
<img src="https://picsum.photos/200/300">
</div>
</div>
</div>
<style>
.full-page .column-left {
margin-top: 0;
display: flex;
flex-direction: column;
justify-content: space-between;
width: 100%;
box-sizing: border-box;
}
.full-page .column-right {
justify-content: space-between;
width: 100%;
box-sizing: border-box;
padding-left: 30px;
padding-right: 30px;
width: 50%;
left: 50%;
position: fixed;
display: flex;
flex-direction: column-reverse;
bottom: 0;
}
.image {
width:496px;
}
.image img {
width: 100%;
}
</style>
I have a page I'm trying fill some content with and then the remainder of the page fill with a background color. I've kind of been able to achieve this using min-height: 100vh but the problem is now my page scroll get's extended significantly. Is it possible just to color the visible space on the screen without increasing scrollable area on the page.
Here's a simple example with a jsfiddle:
If you remove the min-height: 100vh from .footer notice that the colored square gets much smaller and now the scroll area isn't very large either. How do I only fill that area that's visible when not using the min-height style.
.body {
margin-left: 50px;
}
.footer {
background-color: grey;
min-height: 100vh;
z-index: -100;
margin-top: -150px;
}
img {
z-index: 100;
margin-left: 200px;
}
h1 {
text-align: center;
}
<div class="body">
<div class="row justify-content-center text-centerr">
<h1>
This is my page heading
</h1>
</div>
<div class="row justify-content-center text-center">
<p>
This is some information about this page.
</p>
</div>
<div class="row justify-content-center text-centerr">
<div class="justify-content-center">
<img src="https://cdn.vox-cdn.com/thumbor/RkBHz5tPuCNQOG0a6FooNwiqQyw=/0x0:939x704/1820x1213/filters:focal(0x0:939x704):format(webp)/cdn.vox-cdn.com/uploads/chorus_image/image/49610677/homersimpson.0.0.jpg"
width="300px"
height="300px"
</div>
</div>
<div class="footer">
<br />
</div>
</div>
This is what I came up with, using flexbox and flex-grow: 1 to force the element to grow and take up the remaining space and flex-shrink: 0 to prevent the img and other elements from shrinking.
I had to add a new class to he footer's parent element, to add the flexbox class to it. note the footer-parent class.
<div class="body">
<div class="row justify-content-center text-center">
<h1>
This is my page heading
</h1>
</div>
<div class="row justify-content-center text-center">
<p>
This is some information about this page.
</p>
</div>
<div class="row footer-parent justify-content-center text-center">
<div class="justify-content-center">
<img src="https://cdn.vox-cdn.com/thumbor/RkBHz5tPuCNQOG0a6FooNwiqQyw=/0x0:939x704/1820x1213/filters:focal(0x0:939x704):format(webp)/cdn.vox-cdn.com/uploads/chorus_image/image/49610677/homersimpson.0.0.jpg" width="300px" height="300px" />
</div>
<div class="footer">
<br />
</div>
</div>
</div>
Here's the CSS
body {
margin: 0;
}
.body {
display: flex;
flex-flow: column nowrap;
margin-left: 50px;
height: 100%;
min-height: 100vh;
}
.footer {
background-color: grey;
flex-grow: 1;
z-index: -100;
margin-top: -150px;
}
.footer-parent {
display: flex;
flex-grow: 1;
flex-flow: column nowrap;
}
img {
z-index: 100;
flex-shrink: 0;
margin-left: 200px;
}
h1 {
flex-shrink: 0;
text-align: center;
}
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 have a div with two contents: an image (on top) and text (on bottom).
Height of image plus height of the text is bigger than the height of the parent.
I want an image to shrink, so the whole text will be visible.
So - now it looks like this:
And I want it to look like this:
How to achieve this?
I tried it with display: flex and flex-shrink or flex-grow, but it's not working.
Solution with flex will be much appreciated :)
Here's a codepen with an example:
https://codepen.io/anon/pen/zQXyLb
And here's code used:
<html>
<head></head>
<body style="background: yellow;">
<div style="
width: 150px;
height: 150px;
background: #ddd;
overflow: hidden;
display: flex;
flex-direction: column;
">
<div>
<img src="https://emojipedia-us.s3.dualstack.us-west-1.amazonaws.com/thumbs/120/apple/198/skull_1f480.png">
</div>
<div>
<div>Here i have some text</div>
<div>which is multiline</div>
<div>and it should make</div>
<div>the skull smaller</div>
</div>
</div>
</body>
</html>
Instead of img tag try div with background-image.
flex: is short form of: flex-grow, flex-shrink, flex-basis.
0 0 auto means that element will take just as much space as needed.
1 1 auto means that element will take all available space — so image takes box size minus text size. And text is always visible.
.box {
display: flex;
flex-direction: column;
margin-bottom: 20px;
width: 150px;
height: 150px;
background: #ddd;
}
.image {
flex: 1 1 auto;
background: url(https://emojipedia-us.s3.dualstack.us-west-1.amazonaws.com/thumbs/120/apple/198/skull_1f480.png) 0 0 no-repeat;
background-size: contain;
}
.text {
flex: 0 0 auto;
}
<div class="box">
<div class="image"></div>
<div class="text">
<div>Here I have some text</div>
<div>which is multiline</div>
<div>and it should make</div>
<div>the skull smaller</div>
</div>
</div>
<div class="box">
<div class="image"></div>
<div class="text">
<div>Here I have small text</div>
</div>
</div>
You can also keep image in the HTMl if you inbricate flex boxes to allow img container to shrink and img understand max-height:100%;
body {
background-color: #a3d5d3;
}
[class],
[class]>div {
display: flex;
flex-direction: column;
overflow: hidden;
}
img {
max-height: 100%;
margin-right: auto;
}
[class]>div[id] {
flex-grow: 1;
flex-shrink: 0;
}
<div class style="
width: 150px;
height: 150px;
background: #ddd;
">
<div>
<img src="https://emojipedia-us.s3.dualstack.us-west-1.amazonaws.com/thumbs/120/apple/198/skull_1f480.png">
</div>
<div id>
<div>Here i have some text</div>
<div>which is multiline</div>
<div>and it should make</div>
<div>the skull smaller</div>
</div>
</div>
Resize the image using css.
img{
max-width:50px;
}
The above code should make the image flexible and allow it to be smaller.
Also you can put variable height to the parent div, i.e.
<div style="
width: 150px;
max-height: 250px; //added this part
background: #ddd;
overflow: hidden;
display: flex;
flex-direction: column;
">
But this way the image will stay large but the parent's height will increase. Allowing the text to appear in the enlarged div.
I have a site header and I would like to use flexbox for this.
I use justify-content: space-between; to evenly divide the free space between the div's but when I add my svg and scale it down to the size of the header bar flexbox reserves the same amount of space as if the svg was displayed at 100%.
I made a example to show what I mean:
#wrapper {
width: 700px;
height: 100px;
display: flex;
justify-content: space-between;
background: blue;
}
.child {
flex: content;
background: red;
}
<div id="wrapper">
<div class="child">
<img src="https://s.cdpn.io/3/kiwi.svg" height="100%" alt="">
</div>
2
3
</div>
<br>
<div id="wrapper">
<div class="child">
<img src="https://picsum.photos/200/300/?random" height="100%" alt="">
</div>
2
3
</div>
And a JSiddle:
https://jsfiddle.net/03r8vzkn/6/
Is there a way I can avoid this or should I make the svg smaller? This feels a bit hacky because I don't want to make every svg the right size; the scalability is one of its biggest advantages.
You can do it with the display: inline-flex for the .child divs, then they will only take the content's width, of course you also need to make your imgs responsive:
#wrapper {
width: 700px;
height: 100px;
display: flex;
justify-content: space-between;
background: blue;
}
.child {
display: inline-flex; /* only takes the content's width */
background: red;
}
img {
display: block; /* removes bottom margin/whitespace */
max-width: 100%; /* horizontally responsive */
max-height: 100vh; /* vertically responsive */
}
<div id="wrapper">
<div class="child">
<img src="https://s.cdpn.io/3/kiwi.svg" alt="">
</div>
2
3
</div>
<br>
<div id="wrapper">
<div class="child">
<img src="https://picsum.photos/300/400/?random" alt="">
</div>
2
3
</div>
<br>
<div id="wrapper">
<div class="child">
<img src="https://picsum.photos/200/300/?random" alt="">
</div>
2
3
</div>
<br>
<div id="wrapper">
<div class="child">
<img src="https://picsum.photos/100/200/?random" alt="">
</div>
2
3
</div>