Mosaic of images HTML/CSS
Asked Answered
O

10

21

I want to make an image layout with portrait images inside a div with a fixed aspect ratio of 3:2. The size of images is 327x491px.

The main issue is unwanted spaces between images. How do I align images as a mosaic using only HTML/CSS?

HTML :

<div id="pictures1" class="_pictures1 grid">
    <div class="_pictures1-01"><div style="width:125px;height: 188px; background: red;"><img src="" width="125" height="188" alt="" /></div></div>
    <div class="_pictures1-02"><div style="width:192px;height: 288px;background: green;"><img src="" width="192" height="288" alt="" /></div></div>
     ... SO ON ...
</div> 

CSS :

._pictures1 {
    width: 935px; height: 490px;
    margin: -26px 0 0 59px;
    float: left;
    top: 20%; left: 20%;
    position: absolute;
    border: 1px gray solid;
}
._pictures1 div {position: absolute;}
._pictures1-01 {top: 0px; left: 35px;}
._pictures1-02 {top: 200px; left: 0px;}
/* ... SO ON ... */

jsfiddle

Oversell answered 6/3, 2014 at 10:14 Comment(9)
I think the easiest way to do it, is to use a css grid framework.Hildie
Try setting width and heights on the divs containing the images, also add position: relative on those divs; for img add max-width:100%; max-height:100%Charitacharitable
How will you generate this markup? Server side? js, or just manually for an specific page?Sundog
its static markup in html nowOversell
@Aleks how to remove that spaces between div then?Oversell
@Sumit I do not understand what you want to achieve? You wrote the heights of the images are 491px. In your posted code you have 488px, but 188px + 288px = 476px! So you probably should get your math fixed first. Furthermore your code looks a bit like "Divitis" and overly complicated. When I understand what is your goal I will post an alternative solution.Viewable
@Viewable images pixels size is fixed 491 and 327 and vice versa ie. have ratio 3/2 and 2/3 vice versa so 325/488 = 2/3Oversell
With your layout it's not possible. Only if parts of the images are cut can it be achieved. It's because the smaller images are less wide if you maintain aspect ratio.Cronin
@HerrSerker Good point! I still do not understand what the OP wants to achieve!? And I still have the impression that there is an error in thinking ...Viewable
P
36

To make a proper answer, I am first going to clarify the requirements :

  1. images all have the same aspect ratio : 3/2
  2. images shouldn't be cropped
  3. no space between images
  4. make a mosaic of images

You can have thousands of possibilities to display your images. I am going to make a simple layout that should show you the way to build your own.

Here is a FANCY FIDDLE of what you can achieve and here is what it looks like :

Mosaic of images in html/css - example layout

Code :

body, html {
    width:100%;
    margin:0;
    padding:0;
}
#wrap {
    width:984px;
    height:492px;
}
.big_col, .medium_col, .small_col{
    height:492px;
    float:left;
}
img {
    display:block;
    margin:0;
    padding:0;
    border:none;
    float:left;
}
.big_col {
    width:328px;
}
.medium_col{
    width:164px;
}
.small_col{
    width:82px;
}
.big_img img {
    width:328px;
    height:492px
}
.medium_img img {
    width:164px;
    height:246px;
}
.small_img img {
    width:82px;
    height:123px;
}
<div id="wrap">
    <div class="big_col">
        <div class="small_img">
            <img src="https://picsum.photos/id/241/328/492" alt="" />
            <img src="https://picsum.photos/id/147/328/492" alt="" />
            <img src="https://picsum.photos/id/258/328/492" alt="" />
            <img src="https://picsum.photos/id/237/328/492" alt="" />
        </div>
        <div class="medium_img">
            <img src="https://picsum.photos/id/356/328/492" alt="" />
            <img src="https://picsum.photos/id/254/328/492" alt="" />
        </div>
        <div class="small_img">
            <img src="https://picsum.photos/id/156/328/492" alt="" />
            <img src="https://picsum.photos/id/175/328/492" alt="" />
            <img src="https://picsum.photos/id/132/328/492" alt="" />
            <img src="https://picsum.photos/id/197/328/492" alt="" />
        </div>
    </div>
    <div class="big_col">
        <img src="https://picsum.photos/328/492" alt="" />
    </div>
    <div class="small_col small_img">
        <img src="https://picsum.photos/id/210/328/492" alt="" />
        <img src="https://picsum.photos/id/152/328/492" alt="" />
        <img src="https://picsum.photos/id/142/328/492" alt="" />
        <img src="https://picsum.photos/id/189/328/492" alt="" />
    </div>
    <div class="medium_col medium_img">
            <img src="https://picsum.photos/id/254/328/492" alt="" />
            <img src="https://picsum.photos/id/111/328/492" alt="" />
    </div>
    <div class="small_col small_img">
            <img src="https://picsum.photos/id/198/328/492" alt="" />
            <img src="https://picsum.photos/id/201/328/492" alt="" />
            <img src="https://picsum.photos/id/286/328/492" alt="" />
            <img src="https://picsum.photos/id/145/328/492" alt="" />
    </div>
</div>

First step : think, calculate and think again

First : To make it simple let's say your images can have 3 sizes (I changed the image size by 1 px to make calculations easier) :

  1. big : 328*492px
  2. medium, 1/2 of big : 164*246px
  3. small, 1/4 of big : 82*123px

Second : As your images are all portraits and your container has the same height as the big image, you will have to work with 492px heigh columns that can have 3 widths :

  1. big : 328px wide, they can display all size images
  2. medium : 328/2 = 164px wide, they can display medium and small images
  3. small : 327/4 = 82px wide, they can only display small images

Third : How many columns and what image sizes? This is up to you, you will have to make a choice according to the total width of your container and the number of images you want to display.

But in your fiddle, the container (._pictures1) has a 935px width which will be impossible to achieve with the column widths chosen just before.

935/82 = 11.4024...

The closest you can get is 82*12 = 984px wide container.

You will either have to change the width of the container either change the sizes of images and columns to fit your initial width.


Or (spoiler) you can work with percentages, this can be an alternative especialy if you need your layout to be responsive but this can become complicated and I am trying to make things simple.

As I am sure you are curious and want to check it out, here is an example layout in a

Responsive mosaic of image fiddle

Code snippet :

body, html {
    width:100%;
    margin:0;
    padding:0;
}
#wrap {
    width:100%;
}
.big_col, .medium_col, .small_col{
    float:left;
}
img {
    height:auto;
    display:block;
    margin:0;
    padding:0;
    border:none;
    float:left;
}
.big_col {
    width:25%;
}
.medium_col{
    width:12.5%;
}
.small_col{
    width:6.25%;
}

.small_col img{
    width:100%;
}
.medium_col>img {
    width:100%;
}
.medium_col .small_img img {
    width:50%;
}
.big_col .small_img img {
    width:25%;
}
.big_col .medium_img img {
    width:50%;
}
.big_col img {
    width:100%;
}
<div id="wrap">
    <div class="big_col">
        <div class="small_img">
            <img src="https://picsum.photos/id/241/328/492" alt="" />
            <img src="https://picsum.photos/id/147/328/492" alt="" />
            <img src="https://picsum.photos/id/258/328/492" alt="" />
            <img src="https://picsum.photos/id/237/328/492" alt="" />
        </div>
        <div class="medium_img">
            <img src="https://picsum.photos/id/356/328/492" alt="" />
            <img src="https://picsum.photos/id/254/328/492" alt="" />
        </div>
        <div class="small_img">
            <img src="https://picsum.photos/id/156/328/492" alt="" />
            <img src="https://picsum.photos/id/175/328/492" alt="" />
            <img src="https://picsum.photos/id/132/328/492" alt="" />
            <img src="https://picsum.photos/id/197/328/492" alt="" />
        </div>
    </div>
    <div class="big_col">
        <img src="https://picsum.photos/328/492" alt="" />
    </div>
    <div class="small_col small_img">
        <img src="https://picsum.photos/id/210/328/492" alt="" />
        <img src="https://picsum.photos/id/152/328/492" alt="" />
        <img src="https://picsum.photos/id/142/328/492" alt="" />
        <img src="https://picsum.photos/id/189/328/492" alt="" />
    </div>
    <div class="medium_col medium_img">
            <img src="https://picsum.photos/id/254/328/492" alt="" />
            <img src="https://picsum.photos/id/111/328/492" alt="" />
    </div>
    <div class="small_col small_img">
            <img src="https://picsum.photos/id/198/328/492" alt="" />
            <img src="https://picsum.photos/id/201/328/492" alt="" />
            <img src="https://picsum.photos/id/145/328/492" alt="" />
            <img src="https://picsum.photos/id/198/328/492" alt="" />
    </div>
</div>

Next step : design the layout

Use a pen, photoshop, or any other tool that suits you, if you are realy good you can even use your brain to mentaly represent the layout you want.

I designed the image you can see at the bigininng of the answer.

As I said before there are many layout posibilities (number of columns and sizes of images in those columns) so for the example I chose 2 big columns 1 medium and 2 small ones

328*2+164+82*2 = 984px ( = width of container so it can fit!)

Last step : start coding!

You can see the result in this

FIDDLE

This layout is based on floats so we need to define in the width, height of container, columns, images so they can all fit next to each other nicely (as we have already thought about that with calculation and design, it's easy).

body, html {
    width:100%;
    margin:0;
    padding:0;
}
#wrap {
    width:984px;
    height:492px;
}
.big_col, .medium_col, .small_col{
    height:492px;
    float:left;
}
img {
    display:block;
    margin:0;
    padding:0;
    border:none;
    float:left;
}
.big_col {
    width:328px;
}
.medium_col{
    width:164px;
}
.small_col{
    width:82px;
}
.big_img img {
    width:328px;
    height:492px
}
.medium_img img {
    width:164px;
    height:246px;
}
.small_img img {
    width:82px;
    height:123px;
}
<div id="wrap">
    <div class="big_col">
        <div class="small_img">
            <img src="https://picsum.photos/id/241/328/492" alt="" />
            <img src="https://picsum.photos/id/147/328/492" alt="" />
            <img src="https://picsum.photos/id/258/328/492" alt="" />
            <img src="https://picsum.photos/id/237/328/492" alt="" />
        </div>
        <div class="medium_img">
            <img src="https://picsum.photos/id/356/328/492" alt="" />
            <img src="https://picsum.photos/id/254/328/492" alt="" />
        </div>
        <div class="small_img">
            <img src="https://picsum.photos/id/156/328/492" alt="" />
            <img src="https://picsum.photos/id/175/328/492" alt="" />
            <img src="https://picsum.photos/id/132/328/492" alt="" />
            <img src="https://picsum.photos/id/197/328/492" alt="" />
        </div>
    </div>
    <div class="big_col">
        <img src="https://picsum.photos/328/492" alt="" />
    </div>
    <div class="small_col small_img">
        <img src="https://picsum.photos/id/210/328/492" alt="" />
        <img src="https://picsum.photos/id/152/328/492" alt="" />
        <img src="https://picsum.photos/id/142/328/492" alt="" />
        <img src="https://picsum.photos/id/189/328/492" alt="" />
    </div>
    <div class="medium_col medium_img">
            <img src="https://picsum.photos/id/254/328/492" alt="" />
            <img src="https://picsum.photos/id/111/328/492" alt="" />
    </div>
    <div class="small_col small_img">
            <img src="https://picsum.photos/id/198/328/492" alt="" />
            <img src="https://picsum.photos/id/201/328/492" alt="" />
            <img src="https://picsum.photos/id/145/328/492" alt="" />
            <img src="https://picsum.photos/id/198/328/492" alt="" />
    </div>
</div>
Parity answered 14/3, 2014 at 18:19 Comment(4)
Congrats! This is the first real answer to what the OP presumably wants to achieve! Maybe it's worth to think about replacing the 'float' by display: table[-cell] or display: inline-block, but anyway a +1 from my side!Viewable
@Viewable thanks for your comment :). I thought about those alternative solutions but I think floats suit the OP's situation better because display:inline-block; whould create whitespace to deal whith and display:table-cell; isn't as crossbrower as floats.Parity
Sadly the lorempixum.com site is defunct, breaking these fiddles. Anyone volunteer to fix?Ton
@JeffAxelrod I changed the placeholder image provider and added code snippets ;)Parity
M
4

If you set one dimension or the other, but not both, the images should resize fluidly. Try setting just the width to a percentage unit.

Mesoblast answered 13/3, 2014 at 14:56 Comment(0)
O
2

First of all, to remove space between images, just remove set to '0' padding and margin.

Then to achive what you want, you can use or combine those strategies:

1) Assign a fixed size in pixel to one of the sizes: other one will scale automatically.

2) You can calculate the size you need via javascript and assign the value dinamically. For example with jQuery framework:

$(img).each(function(){
 var h = this.height();
 var w = this.width();


 if (w => h){
  this.attr('width', w*0.66);
}
else {
  this.attr('height',h*.066);
}
});

3) You can use css background-image for divs and background-size: cover or background-size: contain as you need, statically or dinamically (w3c docs

Oregano answered 13/3, 2014 at 15:10 Comment(0)
F
1

Absolute positioning doesn't seem to be the best choice if you want to dynamically keep the same positions and ratio.

Native HTML flow is usually the way to go. Absolute positioning is like vitamin tablets. You use it when you need it, but it's not your main food. ;)

What I would do is :

  1. simply position the container as wanted (centered for example) and size its width with percentage of the window/section it's in.

  2. Then you put your ._pictures1-xx divs inside it, and size the pics' width using percentage of the container. Height will keep ratio automatically (*)

  3. I would then make the ._pictures1-xx divs display "inline-block" and float "left". Then a little div with clear"both" after the last pic and close the container.

(*) reminder : the width or height default value is "auto", meaning any size that keeps the image ratio when the other is a px/% value. The horizontal margins natively become dynamic when your pics' height is defined, in order to keep your pics' ratios. If you define width and leave height auto, then the height is dynamic in order to keep the pics' ratio, and margins don't change.

I hope this was helpful.

Fils answered 15/3, 2014 at 1:44 Comment(0)
N
1

I would like to give simple solution.

You can simply wrap img tag with DIV. And you should apply CSS to this wrapped DIV.

Example Code

Instead of this
<img src='some_image.jpg'>
Use below kind of structure
<div class="img_wrapper">
     <img src='some_image.jpg'>
</div>


CSS

//  suggestion: target IMG with parent class / ID
.img_wrapper img{
    width: 100%; 
    height: auto;
} 

All images inside class .img_wrapper would have proper aspect ratio.

Nerynesbit answered 19/3, 2014 at 7:54 Comment(0)
C
0

wrap your image with a div. set width and height for the div according to ratio. Give only height for image. If you want the image to take only space they need use display:inline also

Captainship answered 13/3, 2014 at 17:6 Comment(0)
V
0

Try something like this

Styling

body{
    background: black;
    width:80%;
    margin:5em auto;
    display:block;
}
.wrapper{
    background:#FFF;
    float:left;
}   

.container{
    height:476px;
    width:192px;
    display:inline-block;
    float:left;
}
.small{
    height:188px;
    width:125px;
    display:block;
    margin:0 auto;
    background:#333;
}
.medium{
    background:#666;
    width:192px;
    height:288px;
}
.large{
    height:476px;
    width:200px;
    background:#999;
    display:inline-block;
    float:left;
}

This is HTML

<div class="wrapper">
    <div class="container">
        <div class="small">
            <div class="small_inner">
            </div>
        </div>        
        <div class="medium">
            <div class="medium_inner">
            </div>
        </div>
    </div>
    <div class="large">
        <div class="large_inner">
        </div>
    </div>
    <div class="container">
        <div class="medium">
            <div class="medium_inner">
            </div>
        </div>
        <div class="small">
            <div class="small_inner">
            </div>
        </div>  
    </div>
    <div class="large">
        <div class="large_inner">
        </div>
    </div>
    <div class="container">
        <div class="small">
            <div class="small_inner">
            </div>
        </div>        
        <div class="medium">

            <div class="medium_inner">
            </div>
        </div>
    </div>
</div>
Vasya answered 13/3, 2014 at 21:4 Comment(0)
B
0
img{
 height: auto;
 width: 50%
}
Bath answered 15/3, 2014 at 1:9 Comment(0)
S
0

aspectRatioResizeImg
This is a jQuery plugin that allows resizing of an image preserving its aspect ratio, fitting a container. Optionally the container can be resized to match the image aspect ratio.
https://github.com/stereoactivo/jquery.resize-image-aspect-ratio

Sukiyaki answered 18/3, 2014 at 20:7 Comment(0)
R
0

In my experience: if you only set the dimension of either height or the width (not both) the image will scale accordingly.

Rhodes answered 20/3, 2014 at 12:42 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.