How to display multiples images equally in a div - javascript

I am trying to create a photo gallery app and came across some obstacles. I want to have each image take equal portion of the div, for example if there are two images, each image takes up 50% of the div, and if there are three images, each images takes up 33.33% of the div, etc. Further, is there a way to format those images to be in square dimensions through css?
Also, I have the photos-gallery div that contains h2 and photos-gallery-content div. Currently, I am hardcoding the height for the photos-gallery-content div to fit inside the parent div, but is there a way to make that div take the remainder of the height of its parent div?
Eventually I want the pictures to render dynamically using React so any recommendations/advice on that would help a lot too.
Here is my code:
#photos {
width: 634px;
height: 339px;
}
.photos-gallery {
width: 634px;
height: 275.03px;
}
.photos-gallery-header {
font-size: 24px;
font-weight: bold;
line-height: 32px;
color: #333333;
border-bottom: 1px solid #E1E1E1;
padding-bottom: 16px;
margin: 0 0 16px 0;
display: flex;
justify-content: space-between;
}
.photos-gallery-content {
height: 200px;
}
.photos-gallery-layout {
height: 200px;
overflow: hidden;
float: left;
display: flex;
margin: 0;
padding: 0;
}
.photos-gallery-layout li {
height: auto;
float: left;
list-style: none;
display: flex;
}
.photo {
display: inline-flex;
white-space: nowrap;
}
.photo img {
max-width: 100%;
max-height: auto;
display: inline-block;
vertical-align: middle;
}
<div id="photos-gallery" class="photos content-block">
<h2 class="photos-gallery-header"> 2 Photos </h2>
<div class="photos-gallery-content">
<ul class="photos-gallery-layout">
<li class="photos-gallery-li">
<div class="photo">
<img src="https://i.imgur.com/8pTwPlXb.jpg" />
</div>
</li>
<li class="photos-gallery-li">
<div class="photo">
<img src="https://i.imgur.com/OPAR3PCb.jpg" />
</div>
</li>
<li class="photos-gallery-li">
<div class="photo">
<img src="https://i.imgur.com/A8eQsll.jpg" />
</div>
</li>
</ul>
</div>
<div>

I used your HTML and wrote a little CSS to demonstrate how to:
Have any amount of items fit at equal widths in one row using flexbox (display: flex on the parent and flex: 1 on the children)
Have <img> elements crop to the shape of the tallest element (in this case, a square) using object-fit: cover (note compatibility on CanIUse)
.photos-gallery-layout {
list-style: none;
padding: 0;
margin: 0;
display: flex;
}
.photos-gallery-li {
flex: 1;
}
.photo,
.photo img {
height: 100%;
}
.photo img {
width: 100%;
object-fit: cover;
}
<ul class="photos-gallery-layout">
<li class="photos-gallery-li">
<div class="photo">
<img src="https://i.imgur.com/8pTwPlXb.jpg" />
</div>
</li>
<li class="photos-gallery-li">
<div class="photo">
<img src="https://i.imgur.com/OPAR3PCb.jpg" />
</div>
</li>
<li class="photos-gallery-li">
<div class="photo">
<img src="https://i.imgur.com/A8eQsll.jpg" />
</div>
</li>
</ul>

Related

how can i make a padding keeps outside of my div

I'm not sure how i gonna ask this, but here it goes, i'm training css and i'm literally copying some random layout, and i find this website where he's using a padding outside the div (pic1, pic2), this way his content keeps centralized, what i want to know is how can i do this, my way (pic3, pic4) as you can see the padding keeps inside the div (which holds my section producs) making the section not centralized.
pic1
pic2
pic3
pic4
tsx
<div className={styles.sectionHeader}>
<h1>Top Picks</h1>
Ver todos
</div>
<div className={styles.sectionWithTopPicks}>
<div className={styles.eachItemSection}>
<Image src={img1} width={800} height={800} layout="responsive" />
<p>texto do produto</p>
<h5>R$ 50,00</h5>
</div>
<div className={styles.eachItemSection}>
<Image src={img1} width={800} height={800} layout="responsive" />
<p>texto do produto</p>
<h5>R$ 50,00</h5>
</div>
<div className={styles.eachItemSection}>
<Image src={img1} width={800} height={800} layout="responsive" />
<p>texto do produto</p>
<h5>R$ 50,00</h5>
</div>
<div className={styles.eachItemSection}>
<Image src={img1} width={800} height={800} layout="responsive" />
<p>texto do produto</p>
<h5>R$ 50,00</h5>
</div>
</div>
</div>
scss
.productBox {
display: block;
position: relative;
box-sizing: border-box;
height: 700px;
width: 100%;
background: saddlebrown;
padding: 0 40px 0 40px;
h1 {
font-size: 4rem;
}
}
.sectionHeader {
display:flex;
justify-content: space-between;
a {
font-size: 32px;
font-weight: 400;
font: sans-serif;
}
}
.eachItemSection{
width:25%;
height: 500px;
padding: 0 0 0 22px;
img{
align-self: center;
width:
}
}
.sectionWithTopPicks{
padding-top: 50px;
flex-wrap: wrap;
background: black;
display: flex;
justify-content: space-around;
p {
color: white
}
h5 {
color: white
}
}
I understand your objective, but you have to adjust the code.
With the flexbox approach, you can:
Use a flex-div to hold your items with: .sectionWithTopPick { display: flex; }
Inside it, use a div to hold the content, and tell the div how to fit the parent flex-box with flex-grow: 0; flex-shrink: 1; flex-basis: 25% (this tells to the inside div to never grow beyond 25%, but to shrink if necessary). This div also has the padding.
Select the first item with :fisrt-child and remove left-padding
Select the last item with :last-child and remove right-padding
Use another div to contain the item's contents, and make it's image fill 100% of the space.
Here a codepen with working solution
How you can see here the CSS box-model explain that padding and border are part of the html element.
You can also play here. So you can use margin if you want a space outside the div.
For align i can advise to use margin-left: auto; margin-right:auto;
I agree with Ale Macedo's answer but I'd make the following changes.
.eachItemSection {
flex-grow: 0;
flex-shrink: 1;
flex-basis: 25%;
display: flex;
flex-direction: column;
padding: 2vh .5vw;
&:first-child {
padding-left: 1vw;
} &:last-child {
padding-right: 1vw;
}

Add image below a certain class of element using css

What I want to do:
I want to add a "walkingMan" image under an element when its class is changed to activeCell. I know how to do it when the image is added to the front or back of the element using pseudo class, but as far as I know, there isn't something like :below that I can use to achieve the same effect. Is there a way in css I can use to micmic this?
What I have done:
I have added image below every upper cell and make it visible when the class is changed to activeCell. But I hope to find a more simple solution.
What it looks like:
Code: Simplified Code Example
You can use a single pseudo element on the .cell element and place a background image on it when it's active.
let activeIndex = 0;
const cells = [...document.querySelectorAll('.cell')];
setInterval(() => {
cells.forEach(cell => {
cell.classList.remove('activeCell')
});
cells[activeIndex].classList.add('activeCell');
activeIndex = activeIndex === cells.length - 1 ? 0 : (activeIndex + 1);
}, 300)
.cell {
display: inline-block;
border: 1px solid black;
margin-bottom: 1.2em;
}
.activeCell {
background-color: lightgrey;
position: relative;
}
.activeCell::after {
content: "";
position: absolute;
width: 1em;
height: 1em;
top: 1.3em;
left: calc(50% - .5em); /* Center the stickman. Position it half of its width before the parent center*/
background-image: url('https://www.shareicon.net/data/512x512/2016/01/17/704754_people_512x512.png');
background-size:cover; /* Scale the stickman to completely cover the background area. */
}
<div>
<div class='top'>
<a class='cell'>One</a>
<a class='cell'>One</a>
<a class='cell'>One</a>
<a class='cell'>One</a>
</div>
<div class='bottom'>
<a class='cell'>One</a>
<a class='cell'>One</a>
<a class='cell'>One</a>
<a class='cell'>One</a>
</div>
</div>
What about this: https://jsfiddle.net/147prwy5/3/
HTML
<div class="cell active">
<a>One</a>
<img src="https://www.shareicon.net/data/512x512/2016/01/17/704754_people_512x512.png" alt="walkingMan" />
</div>
<div class="cell">
<a>One</a>
<img src="https://www.shareicon.net/data/512x512/2016/01/17/704754_people_512x512.png" alt="walkingMan" />
</div>
<div class="cell">
<a>One</a>
<img src="https://www.shareicon.net/data/512x512/2016/01/17/704754_people_512x512.png" alt="walkingMan" />
</div>
<div class="cell active">
<a>One</a>
<img src="https://www.shareicon.net/data/512x512/2016/01/17/704754_people_512x512.png" alt="walkingMan" />
</div>
CSS
.cell {
display: inline-block;
}
.cell a {
border: 1px solid black;
}
.cell.active a {
background-color: lightgrey;
}
.cell img {
width: 20px;
height: 20px;
display: none;
}
.cell.active img {
margin-top: 5px;
width: 20px;
height: 20px;
display: block;
}
I've never been a fan of the ::before and ::after pseudo classes mainly because I've personally noticed some oddities when trying to position things in Chrome vs IE (damn it IE!). Since most people here are going to give a solution using these pseudo classes (because that's somewhat what you asked) I thought I'd give a different solution using flexbox and more divs.
Not the most optimal for download size but I do like that it's not absolute positioning elements and if the squares get bigger or smaller it's pretty easy to handle that as a scss variable at the top of the file. This all uses only two values, your padding between boxes and the size of the boxes so it should be easy to update and maintain.
Anyway, have fun! Awesome question by the way :-)
.blocks {
display: flex;
}
.block {
flex: 0 0 20px;
margin: 0px 5px;
display: flex;
flex-direction:column;
}
.block > .square {
flex: 0 0 20px;
margin: 5px 0px;
background: grey;
}
.block > .space {
flex: 0 0 20px;
margin: 5px 0px;
}
.block.activeCell > .space {
background: green;
}
<div class="blocks">
<div class="block activeCell"><div class="square"></div><div class="space"></div></div>
<div class="block"><div class="square"></div><div class="space"></div></div>
<div class="block"><div class="square"></div><div class="space"></div></div>
<div class="block"><div class="square"></div><div class="space"></div></div>
</div>
<div class="blocks">
<div class="block"><div class="square"></div></div>
<div class="block"><div class="square"></div></div>
<div class="block"><div class="square"></div></div>
<div class="block"><div class="square"></div></div>
</div>
Using jQuery you can toggle the class upon clicking with this:
$('.cell').click(function() { //catch clicks on .cell
$('.cell').removeClass('activeCell'); //remove class "activeCell" from all
$(this).addClass('activeCell'); //add class "activeCell" to .cell clicked
});
Apply position: relative; to .top and .bottom:
.top,
.bottom {
position: relative;
}
And use the psuedoclass :before to create a image under the .activeCell
.activeCell:before {
content: "";
position: absolute;
bottom: -20px;
height: 20px;
width: 20px;
background-image: url("https://www.shareicon.net/data/512x512/2016/01/17/704754_people_512x512.png");
background-size: 20px 20px;
}
And remove this:
.walkingMan {
width: 20px;
height: 20px;
display: inline-block
}
And this:
<img src="https://www.shareicon.net/data/512x512/2016/01/17/704754_people_512x512.png" alt="walkingMan" class='walkingMan'/>
And to add space between the divs .top and .bottom put a <br> between them.
$('.cell').click(function() {
$('.cell').removeClass('activeCell');
$(this).addClass('activeCell');
});
.cell {
display: inline-block;
border: 1px solid black;
cursor: pointer;
}
.top,
.bottom {
position: relative;
}
.activeCell {
background-color: lightgrey;
}
.activeCell:before {
content: "";
position: absolute;
bottom: -20px;
height: 20px;
width: 20px;
background-image: url("https://www.shareicon.net/data/512x512/2016/01/17/704754_people_512x512.png");
background-size: 20px 20px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<div>
<div class='top'>
<a class='cell activeCell'>One</a>
<a class='cell'>One</a>
<a class='cell'>One</a>
<a class='cell'>One</a>
</div>
<br>
<div class='bottom'>
<a class='cell'>One</a>
<a class='cell'>One</a>
<a class='cell'>One</a>
<a class='cell'>One</a>
</div>
</div>
add .RunManActive Class for Active element
//clicking add active Class
$(".RunMan").click(function() {
$(".RunMan").removeClass('RunManActive');
$(this).toggleClass('RunManActive');
});
//timing add active Class
var i=0;
var $elm=$(".Animate");
setInterval(function(){
$elm.removeClass('RunManActive');
$elm.eq(i).toggleClass('RunManActive');
i=$elm.length<=i?0:i+1;
}, 1000);
.RunMan{
width:35px;
height:35px;
background-color:lightgray;
border:3px solid #fff;
float:left;
position: relative;
}
.RunManActive{
background-color:#eee;
border:3px solid lightgray;
}
.RunManActive > div{
width:35px;
height:35px;
position: absolute;
background-image:url(http://www.iconsfind.com/wp-content/uploads/2013/11/Objects-Running-man-icon.png);
background-size:cover;
top:100%;
margin-top:5px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="RunMan"><div></div></div>
<div class="RunMan RunManActive"><div></div></div>
<div class="RunMan"><div></div></div>
<div class="RunMan"><div></div></div>
<div class="RunMan"><div></div></div>
<br><br><br><br><br><br>
<div style=" width:100%">
<div class="Animate RunMan"><div></div></div>
<div class="Animate RunMan "><div></div></div>
<div class="Animate RunMan"><div></div></div>
<div class="Animate RunMan"><div></div></div>
<div class="Animate RunMan"><div></div></div>
You can do something like this, using CSS only. With :target selector you can apply a style to the element you need to hide / show.
.container {
display: inline-block;
width: 100px;
height: 200px;
}
.link {
display: block;
width: 100px;
height: 100px;
background: #ccc;
}
.walking-man {
display: none;
width: 100px;
height: 100px;
background: red;
}
#p1:target {
display: block;
}
#p2:target {
display: block;
}
#p3:target {
display: block;
}
#p4:target {
display: block;
}
height: 90px;
float: left;
}
.walking-man img {
width: 100%;
}
.walkin-man:target {
display: block;
}
<div class="container">
<div id="p1" class="walking-man"></div>
</div>
<div class="container">
<div id="p2" class="walking-man"></div>
</div>
<div class="container">
<div id="p3" class="walking-man"></div>
</div>
<div class="container">
<div id="p4" class="walking-man"></div>
</div>

Set width of child div in flex container

I have 4 divs with the class .piece-slide that horizontally scroll across the page within the the div #work, which is a flex element. Within the third .piece-slide div the 3 nested elements are absolutely positioned, this renders the width of the third .piece-slide div to 0, so now I want to programmatically set the width of the third .piece-slide div so that it covers the 3 nested elements.
For some reason I am unable to set this width through CSS. I have also tried through jQuery. It would be much appreciated if some pointed me in the right direction as how to rectify this. Here is a jsfiddle as well as the embedded code below.
$("#third-div").outerWidth("100vw");
#wrapper {
display: flex;
flex-direction: column;
height: 100vh;
}
.content {
flex: 1;
}
#work {
height: 100%;
overflow-x: scroll;
display: flex;
background-color: red;
}
.piece-slide {
display: flex;
align-items: center;
position: relative;
padding-right: 5em;
box-sizing: border-box;
border-right: 1px solid black;
}
.piece {
width: 25vw;
margin: 10px;
}
.piece img {
max-width: 100%;
}
#third-div {
/* D0ES NOT WORK */
width: 100vw;
background-color: green;
}
#third-div a {
position: absolute;
}
#third-div a:nth-child(1) {
top: 0;
left: 0;
}
#third-div a:nth-child(2) {
top: 25vw;
left: 25vw;
}
#third-div a:nth-child(3) {
left: 60vw;
}
<div id="wrapper">
<div class="content">
<div id="work">
<div class="piece-slide">
<a class="piece">
<img src="https://athlonecommunityradio.ie/wp-content/uploads/2017/04/placeholder.png">
</a>
</div>
<div class="piece-slide">
<a class="piece">
<img src="https://dummyimage.com/hd1080https://dummyimage.com/hd1080">
</a>
<a class="piece">
<img src="https://dummyimage.com/hd1080https://dummyimage.com/hd1080">
</a>
</div>
<!-- THIRD DIV WHERE WIDTH SHOULD BE SET -->
<div id="third-div" class="piece-slide">
<a class="piece" num="1">
Nested Element 1<img src="http://i.stack.imgur.com/yZlqh.png">
</a>
<a class="piece" num="2">
Nested Element 2<img src="http://www.jennybeaumont.com/wp-content/uploads/2015/03/placeholder.gif">
</a>
<a class="piece" num="3">
Nested Element 3<img src="http://suplugins.com/podium/images/placeholder-02.jpg">
</a>
</div>
<div class="piece-slide">
<a class="piece">
<img src="https://athlonecommunityradio.ie/wp-content/uploads/2017/04/placeholder.png">
</a>
</div>
</div>
</div>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Try to remove
flex-direction: column;
from #wrapper.
Or change it to
flex-direction: row;

Positioning of elements in a horizontal timeline

I'm working on a custom timeline feature but I'm stuck on how to solve a certain positioning I want in edge-cases.
In the snippet below I have 3 timelines for demonstration:
The first is a timeline with many events. The timeline is supposed overflow the ones that don't fit. This is determined by a given min-width for li.
The second and third have few events. The positioning here needs to be so that they are equally spaced between eachother.
I also want the first and last events to be pulled to the left and right respectively, instead of centered.
What I have so far:
The width of each item is calculated based on the number of events. The min-width property prevents the size getting too small. The overflow is intended.
I thought I'd fix the spacing issue on the first and last event by pulling them left and right with left/right: XX % but the elements seem to behave as if they are positioned absolutely. I also tried float as well as using a fixed width and controlling the width by margin but that didn't work either.
.timeline-container {
overflow: hidden;
position: relative;
margin: 20px 0;
}
.timeline-container ol {
list-style: none;
width: 100%;
height: 2px;
white-space: nowrap;
margin: 30px 0 0;
padding: 0;
background: #EEE;
display: inline-block;
position: relative;
}
.timeline-container ol li {
display: inline-block;
position: relative;
height: 9px;
min-width: 150px;
}
.timeline-container ol li:before {
content: "";
cursor: pointer;
width: 12px;
height: 12px;
border: 2px solid #3598DC;
display: inline-block;
position: absolute;
bottom: 0;
left: 50%;
transform: translateX(-50%);
background: white;
z-index: 100;
}
.timeline-container ol li a {
position: relative;
bottom: 30px;
display: block;
text-align: center;
padding: 0;
}
<div class="timeline-container">
<ol>
<li style="width: 9.09091%;"><a>Feb 8</a></li>
<li style="width: 9.09091%;"><a>Feb 9</a></li>
<li style="width: 9.09091%;"><a>Feb 11</a></li>
<li style="width: 9.09091%;"><a>Feb 13</a></li>
<li style="width: 9.09091%;"><a>Feb 17</a></li>
<li style="width: 9.09091%;"><a>Feb 18</a></li>
<li style="width: 9.09091%;"><a>Feb 19</a></li>
<li style="width: 9.09091%;"><a>Feb 21</a></li>
<li style="width: 9.09091%;"><a>Feb 22</a></li>
<li style="width: 9.09091%;"><a>Feb 26</a></li>
<li style="width: 9.09091%;"><a>Feb 28</a></li>
</ol>
</div>
<div class="timeline-container">
<ol>
<li style="width: 50%;"><a>Feb 8</a></li>
<li style="width: 50%;"><a>Feb 28</a></li>
</ol>
</div>
<div class="timeline-container">
<ol>
<li style="width: 25%;"><a>Feb 8</a></li>
<li style="width: 25%;"><a>Feb 9</a></li>
<li style="width: 25%;"><a>Feb 11</a></li>
<li style="width: 25%;"><a>Feb 13</a></li>
</ol>
</div>
Desired behavior: (note the reduced margin left and right margin on the first and last item resp.)
A pure-css solution that would be preferable, but javascript is fine too. Thanks.
If you're alright with using flexbox, it could look something like this:
For many timeline items:
<div class="timeline many">
<div class="timeline__item"></div>
<div class="timeline__item"></div>
<div class="timeline__item"></div>
<div class="timeline__item"></div>
</div>
And CSS:
.timeline {
display: flex;
flex-direction: row;
}
.many .timeline__item {
flex: 1
}
For few items:
<div class="timeline few">
<div class="timeline__item"></div>
<div class="timeline__item"></div>
<div class="timeline__item"></div>
<div class="timeline__item"></div>
</div>
And CSS:
.timeline {
display: flex;
flex-direction: row;
}
.few .timeline__item {
justify-content: space-between;
}
For IE support you can use a tool like Gulp or Webpack to prefix your styles, or just paste them in an online one here: https://autoprefixer.github.io/

Responsive Equal height div without specifying the height

I am looking for some responsive equal height div by just using CSS. I don't want to specify the height. Looking somewhat similar to the image below but both the divs should adjust based on the other div height.
If the left side div is long then the right side div should adjust to the left side div and vice versa.
Also the right side div has 2 small divs which should also be of same height.
Can this be achieved using only CSS? Or should I make use of JS/jQuery?
Example here on the jsFiddle
img {
width: 100%;
border: 1px solid green;
}
.row {
display: table;
}
.column {
display: table-cell;
vertical-align: top;
}
.w100 {
width: 100%;
}
.w75 {
width: 75%;
}
.w50 {
width: 50%;
}
.w25 {
width: 25%;
}
<body>
<div class="row w100">
<div class="column w75">
<img src="http://placehold.it/500x500" alt="">
</div>
<div class="column w25">
<div class="col-row">
<img src="http://placehold.it/250x250" alt="">
</div>
<div class="col-row">
<img src="http://placehold.it/250x250" alt="">
</div>
</div>
</div>
You could use flex-box, for example:
.row {
display: flex;
flex-direction:row;
}
.column {
display: flex;
flex-direction:column;
}
And getting rid of the widths the browser does a great job aligning the items:
http://jsfiddle.net/2vLpx9k3/3/
You may need some prefixes for cross-browser support.
I've made something that might possibly be something that you are looking for.
http://jsfiddle.net/2vLpx9k3/4/
It adjusts the widht and height of the inner elements based on the outer element.
HTML:
<div class="outer">
<div class="left">
<div class="right"></div>
<div class="right bottom"></div>
</div>
</div>
CSS:
.outer {
height: 100vh;
}
.left {
background-color: red;
width: 100%;
height: 100%;
margin-right: 50%;
}
.right {
background-color: green;
height: 50%;
margin-left: 50%;
}
.right.bottom {
background-color: black;
}

Categories

Resources