Making gallery responsive with css - javascript

I am trying to build simple gallery.
What I would like to achieve is this:
However, what I am actually achieving is this:
There is basically too much space between images and I can't find a way how to solve it. I understand that is because of justify-content: space-between; but perhaps there's another option that will put less space between the images?
Html
<div class="photoContainer>
<div class="ant-image">
...
</div>
</div>
Css
.photosContainer {
width: 80%;
height: 100%;
overflow: auto;
overflow-x: hidden;
display: flex;
align-content: space-between;
flex-wrap: wrap;
align-items: center;
justify-content: space-between;
padding: 10px;
}
.ant-image {
height: fit-content;
flex-shrink: 0;
position: relative;
display: inline-block;
width: 200px;
}

With the space-between rule you cannot have the control of the space between the images.
My suggestion is to:
make the image gallery container smaller because you have a small number of photos
to have more control over the images you can use also for the single image a % width as you have done for the container.
hint: use property object-fit for the single images

you can use grid display instead of flex and solve your problem:
.photosContainer{
display:grid;
grid-template-columns:repeat(4 , 1fr);
}

Related

Using a media query with viewheight to fix footer

I am trying to create my own website with a basic structure (header, main and footer) but when there are not enough elements to fill the height of the screen, footer is not placed at the bottom.
To fix that problem I used these lines:
footer {
display: flex;
align-items: center;
justify-content: center;
flex-direction: row;
position: fixed;
bottom: 0;
left: 0;
width: 100%;
}
but now that there are enough elements and should be scroll, the footer still fixed (what is obvious) so I am trying to create a media query to change footer's css when the height of the body is larger than 100vh - and it is not working and I do not know why. How can I fix it?
#media screen and (min-width: 100vh) {
footer {
display: flex;
align-items: center;
justify-content: center;
flex-direction: row;
}
}
I know that I could choose any of them depending on the final structure but meanwhile I would like to forget about having to change the footer's css manually.
Thank you in advance.
I understand what you need to make and I offer you to use flex on container.
<div class="container">
<header></header>
<main></main>
<footer></footer>
</div>
If you use this structure, add below styles then you will never need to add position fixed and media query to footer.
.container {
display: flex;
flex-direction: column;
min-height: 100vh;
}
main {
flex: 1;
}
To make <body> fill the whole page vertically:
html {
height: 100% /*of viewport's height*/;
}
body {
/* At least 100%;
* allows vertical scrollbars if content overflows
*/
min-height: 100%;
/* Reset margin:
* Margins don't count towards size.
* If wanted, you'd need to explicitly subtract
* them from size declarations.
*/
margin: 0;
}
To distribute <body>'s space, you can use CSS Grid:
body {
display: grid;
grid-template-rows:
auto /*First row: Take up required space*/
1fr /*Middle row: Take up remaining space, after required space is allotted*/
auto /*Last row: Take up required space*/;
}
/*Previous rules*/
html {height: 100%}
body {
margin: 0;
min-height: 100%;
}
/*Ignore; for presentational purposes*/
header, main, footer {
min-height: 4rem;
}
header {background-color: cornflowerblue}
main {background-color: brown}
footer {background-color: darkkhaki}
<html>
<body>
<header></header>
<main></main>
<footer></footer>
</body>
</html>
just write a property for the parent element of the entire site:
min-height: 100%;
and for the section before the footer, you need to register the following property:
flex-grow: 1;
Its default value for 'flex' is 0 1 auto , which means. flex-grow: 0; flex-shrink: 1; flex-basis: auto;

Tidying container boxes borders with CSS [duplicate]

This question already has answers here:
Preventing "double" borders in CSS
(19 answers)
Closed 2 years ago.
Relatively new to Javascript/HTML5 etc. I'm often in awe of how many different ways there are to do the same thing. In trying to develop a dashboard app, I'm trying to visually fine tune the CSS to get rid of the double boarder boxes interior to the main div container. (Later these subcontainers will be reaching out to various different APIs.)
I'm pretty sure there is a property I can put onto shared that will overlap the boxes giving a nice even clean look but I wasn't able to find one. What are some other ways to handle this situation? Is there some automated way to do it? Or does one need to specify the borders individually on each sub-containers?
.container {
border: 3px solid black;
display: flex;
position: relative;
flex-direction: column;
margin: 0;
padding: 0;
height: 400px;
}
.shared {
min-height: 100%;
display: flex;
flex-direction: column;
flex: 1;
display: flex;
flex-direction: column;
justify-content: center;
border: 0;
}
.sub-container {
border: 3px solid black;
margin: 0;
padding: 0;
align-items: stretch;
height: 100%;
}
<div class="container shared" id="D">
<div class="sub-container">
<h2>Section Sub D1</h2>
<p id="D1-values">D1 Values</p>
</div>
<div class="sub-container">
<h2>Section Sub D2</h2>
<p id="D2-values">D2 Values</p>
</div>
<div class="sub-container">
<h2>Section Sub D3</h2>
<p id="D3-values">D3 Values</p>
</div>
</div>
Add a negative margine for the bottom.
in this case for the .sub-container class
like this:
.sub-container {
border: 3px solid black;
margin-bottom: -3px;
padding: 0;
align-items: stretch;
height: 100%;
}
This happens because of the margins.
In evey element inside is the content, as we go outside, the next one is the padding,
then comes the border, but after that we got a margine. So the borders will
always be separated. Except if you add a negative margine for the bottom, with equal pixels as the border. This way the elements will overlap eachother.
allways remember this
We can use a :not and :first-of-type selector to do this neatly.
.sub-container:not(.sub-container:first-of-type) {
border-top: none;
}

Odd behavior when changing CSS Grid elements' order with a transition, how to fix that?

I want to change the order of elements inside a grid container by clicking on a button. I simply gave the child element a transition property and the result was so strange.
First of all, the timing is completely wrong between the transition's timing value and the actual time that it takes to achieve that, also it happens on many stages in a strange and random order, finally and most importantly there is no transition effect or what so ever.
Here's a snippet of my code:
function changeOrder(){
var elmnts = document.querySelectorAll(".container>div");
elmnts.forEach((item, i) => {
item.style.order = 5 - i;
});
}
.container{
max-width: 1000px;
margin: 0 auto;
display: grid;
grid-template-columns: repeat(auto-fill, 150px);
grid-column-gap: 4px;
grid-row-gap: 24px;
justify-content: center;
padding: 25px;
}
.container > div {
width: 150px;
height: 150px;
background: red;
color: white;
display: flex;
flex-flow: column nowrap;
justify-content: center;
align-items: center;
transition: order 20s;
}
<div class="container">
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
</div>
<button type="button" name="button" onclick="changeOrder()">Change order</button>
So is there a way to achieve that, to give a sense of motion when the element moves from a position to another due to changes in its order value?

Space between in desktop, stacked on mobile how to?

At the moment I'm using flex with justify-content: center; and padding left on B component. Is a temporary hack. How can I do it to work properly?
When the container is big, I want them centred but with a space in the middle. When is small, I would like to have them to go on top of each other.
Note:
On the large screen the 2 items are centred and have a gap between.
Should not be based on the screen size because the wrapper can be small on a desktop for example.
No JS solution like component media query;
One of the solutions could be something like this: https://www.npmjs.com/package/react-element-query but uses JS.
Media query doesn't work because https://jsfiddle.net/t4j6z7og/
Why not simply make use of a media query to swap to flex-direction: column at the smaller width, and swap the margin for B from margin-left to margin-top?
This can be seen in the following example
(hit 'Run code snippet' then 'Full page' for the side-by-side view):
.container {
display: flex;
justify-content: center;
align-items: center;
}
.a, .b {
width: 300px;
height: 100px;
border: 1px solid black;
}
.b {
margin-left: 20px;
}
#media screen and (max-width: 768px) {
.container {
flex-direction: column;
}
.b {
margin-left: 0;
margin-top: 20px;
}
}
<div class="container">
<div class="a">A</div>
<div class="b">B</div>
</div>
Hope this helps! :)

Remove a class when two divs overlap

I have used flexbox to center my content vertically inside of 'main' tag, however when too much content is added it spills over into the 'header'. Is there a way I can calculate that if the div goes above a certain vertical position on screen (256px - height set as header), it removes a class from the 'main' (currently set to .vertical).
I know that the .removeClass() removes the class, but I dont know where to start with the vertical position calculation.
HTML
<header>Nav</header>
<main class="vertical">A lot of text here</main>
CSS
body, html{margin:0; height:100%}
header{width:100%; height:256px; background:red;}
main{width:100%; height: calc(100% - 256px); background:#fff;}
.vertical{
display: flex;
flex-direction: column;
justify-content: center;
}
Fiddle
I do hope that makes sense.
Many thanks Thanks.
I may misunderstand your goal, but it doesn't seem like you need to calculate the position on the screen. Since you have a Nav bar, it should always be visible and the content shouldn't overlap. I made a few changes to your code that allows the content to always sit underneath the header using justify-content: flex-start.
body, html {
margin: 0;
height: 100%
}
header {
display: block;
width: 100%;
height: 256px;
background: red;
}
main {
width: 100%;
height: 100%;
background: #fff;
}
.vertical{
display: flex;
flex-direction: column;
justify-content: flex-start;
}
If you still want to align the text differently, you could nest the content within another tag inside .vertical. Like so:
<header>Nav</header>
<main class="vertical">
<p class="content">all the text...</p>
</main>
And then add vertical styles to the .content section.

Categories

Resources