Adaptable Collection of 4 Images

I am facing a challenge in replicating eBay's 'Today' featured seller layout with 4 square images creating one box (refer to the image). I am using Bootstrap for this task, and I am finding it difficult to comprehend how to achieve this. I have managed to adjust the squares to look decent on lg, md, and sm breakpoints by setting fixed width and height for each square. However, this approach falls apart when it comes to mobile devices as the resizing needs to be responsive to window size.

https://i.sstatic.net/NGxD9.png

Currently, the HTML structure I have consists of a grid divided into 9 and 3 columns (col-xs-9 and col-xs-3) with predefined heights for each desktop and tablet width.

There will be instances where the images are squares, while other times they will be in portrait or landscape format. In such cases, the images should maintain their aspect ratio and expand to their maximum size within the container div.

My question is, can I achieve this layout using Bootstrap, or should I explore alternatives like incorporating JavaScript?

For reference, here is the code snippet:

HTML

<div id="featured-merchant-container">
  <div class="featured-merchant-listings">
    <div class="row">
      <div class="primary-img-container col-xs-9 col-sm-9 col-md-9 col-lg-9 no-padding-right">
        <div class="big-hero-image">
          <a ng-if="merchant.userListings[0].primaryImage" ng-href="/#!/users/{{merchant._id}}">
            <span class="thumb">
              <img ng-src="{{merchant.userListings[0].primaryImage}}" />
            </span>
          </a>
          <a ng-if="!merchant.userListings[0].primaryImage" ng-href="/#!/users/{{merchant._id}}">
            <span class="thumb">
              <img ng-src="img/placeholder.png" />
            </span>
          </a>
        </div>
      </div>
      <div class="secondary-img-container col-xs-3 col-sm-3 col-md-3 col-lg-3 no-padding-left">
        <div class="big-hero-images">
          <div class="first">
            <a ng-if="merchant.userListings[1].primaryImage" ng-href="/#!/users/{{merchant._id}}">
              <span class="thumb">
                <img ng-src="{{merchant.userListings[1].primaryImage}}" />
              </span>
            </a>
            <a ng-if="!merchant.userListings[1].primaryImage" ng-href="/#!/users/{{merchant._id}}">
              <span class="thumb">
                <img ng-src="img/placeholder.png" />
              </span>
            </a>
          </div>
          <div class="second">
            <a ng-if="merchant.userListings[2].primaryImage" ng-href="/#!/users/{{merchant._id}}">
              <span class="thumb">
                <img ng-src="{{merchant.userListings[2].primaryImage}}" />
              </span>
            </a>
            <a ng-if="!merchant.userListings[2].primaryImage" ng-href="/#!/users/{{merchant._id}}">
              <span class="thumb">
                <img ng-src="img/placeholder.png" />
              </span>
            </a>
          </div>
          <div class="last">
            <a ng-if="merchant.userListings[3].primaryImage" ng-href="/#!/users/{{merchant._id}}">
              <span class="thumb">
                <img ng-src="{{merchant.userListings[3].primaryImage}}" />
              </span>
            </a>
            <a ng-if="!merchant.userListings[3].primaryImage" ng-href="/#!/users/{{merchant._id}}">
              <span class="thumb">
                <img ng-src="img/placeholder.png" />
              </span>
            </a>
          </div>
        </div>
      </div>
      </div>
  </div>
</div>

CSS:

#featured-merchant-container {
    border: 1px solid green-grey;


    .big-hero-image {
            text-align:center;
            .thumb {
                display:block;
                border-right:1px solid green-grey;
                height:413px;
                display:table-cell;
                vertical-align:middle;
                text-align:center;
                img {
                    width:100%;
                    height:413px;
                }
            }
    }

    .big-hero-images {
            text-align:center;
            // border-left:1px solid green-grey;
            .thumb {
                display:block;
                height:137px;
                display:table-cell;
                vertical-align:middle;
                text-align:center;
                img {
                    width:100%;
                    height:137px;
                }
            }
            .first, .second {
                    border-bottom:1px solid green-grey;
                }
    }
}

I would greatly appreciate any assistance or guidance on this matter. Thank you for your help!

Answer №1

Is it possible to utilize the flex-box layout?

.cols {overflow: hidden;}
.cols .col {float: left; width: 25%;}
.cols .col:first-child {width: 75%;}
.cols .col img {width: 100%;}

.flex-container {
  display: -ms-flexbox;
  display: -webkit-flex;
  display: flex;
  -webkit-flex-direction: column;
  -ms-flex-direction: column;
  flex-direction: column;
  -webkit-flex-wrap: nowrap;
  -ms-flex-wrap: nowrap;
  flex-wrap: nowrap;
  -webkit-justify-content: flex-start;
  -ms-flex-pack: start;
  justify-content: flex-start;
  -webkit-align-content: stretch;
  -ms-flex-line-pack: stretch;
  align-content: stretch;
  -webkit-align-items: flex-start;
  -ms-flex-align: start;
  align-items: flex-start;
}

.flex-item {
  -webkit-order: 0;
  -ms-flex-order: 0;
  order: 0;
  -webkit-flex: 1 0 auto;
  -ms-flex: 1 0 auto;
  flex: 1 0 auto;
  -webkit-align-self: auto;
  -ms-flex-item-align: auto;
  align-self: auto;
}
<div class="cols">
  <div class="col">
    <img src="http://placehold.it/350x350" alt="" />
  </div>
  <div class="col">
    <div class="flex-container">
      <div class="flex-item"><img src="http://placehold.it/350x350" alt="" /></div>
      <div class="flex-item"><img src="http://placehold.it/350x350" alt="" /></div>
      <div class="flex-item"><img src="http://placehold.it/350x350" alt="" /></div>
    </div>
  </div>
</div>

Answer №2

If you have a variety of image dimensions, you have two options. One option is to utilize background images with the background-size property set to cover.

.flex-item
  background-size: cover;
  background-image: url(http://placehold.it/350x350);

Alternatively, you can use object-fit, which is fantastic but unfortunately lacks support in Internet Explorer.

.flex-item img
  object-fit: cover;

Answer №3

Appreciate all the input from everyone.

To achieve the desired layout, I opted to completely eliminate the use of Bootstrap for the grid structure. Instead, I constructed the grid based on percentages. I came across a useful tip online suggesting that setting a percentage as the value for padding-top can create a container with a specific aspect ratio. For instance, to maintain a 4:3 aspect ratio for a div, you can simply use

padding-top:75%; 

in the CSS for that particular div.

You can set the height of the div using the padding-top percentage trick as long as it has a defined width. For square divs in the grid, I applied

padding-top:100%;

to each of them. For the larger image within the grid, here is the CSS (stylus) snippet utilized:

.big-image {
        width: 75%;
        /* adjust width as needed */
        display: inline-block;
        position: relative;
        float: left;
        -moz-box-sizing: border-box;
        -webkit-box-sizing: border-box;
        -ms-box-sizing: border-box;
        box-sizing: border-box;
        font-size: 0;

        &:after {
            padding-top: 100%;
            /* 1:1 ratio for a square */
            display: block;
            content: '';
        }
}

It's important to note that the div must be relatively positioned and the padding should be specified within the :after CSS selector.

Hopefully, this information proves helpful to someone. Thank you.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Tips for resolving a flickering issue that occurs when switching to an input field with our default value / placeholder plugin

In the realm of web development, numerous plugins cater to the implementation of HTML5's placeholder attribute in older browsers. The plugin we have opted for can be found here. Unlike some other alternatives, this particular plugin, with a few modif ...

Encountered an undefined error while trying to read promises

I'm attempting to receive a response from a function in order to trigger another function, but I am not receiving the expected response. I encountered the following error message: "TypeError: Cannot read property 'then' of undefined." In my ...

Trouble with loading images on hbs/nodejs

I'm currently working on a web application using NodeJs and express-handlebars. However, I am facing an issue with images not displaying correctly on the HTML page that is being rendered using handlebars. Here is the structure of my app: The root fo ...

Content displayed in the center of a modal

Struggling to center the captcha when clicking the submit button. Check out the provided jsfiddle for more details. https://jsfiddle.net/rzant4kb/ <script src="https://cdn.jsdelivr.net/npm/@popperjs/<a href="/cdn-cgi/l/email-protection" class=" ...

JavaScript file encountering a Typescript issue with a property defined in a subclass

Currently, I am utilizing Typescript to validate my Javascript files. One issue I have encountered is that when I inherit from a class, Typescript does not recognize the types of the properties in the parent class. I am unsure if I am overlooking something ...

Creating a concise TypeScript declaration file for an established JavaScript library

I'm interested in utilizing the neat-csv library, however, I have encountered an issue with it not having a typescript definition file available. Various blogs suggest creating a basic definition file as a starting point: declare var neatCsv: any; M ...

Place a "sticky" button directly below a second "sticky" navigation bar

Within my app file, I have customized components like an appbar and various page elements: const styles = theme => ({ appBar: { width:'100%', }, }); class App extends Component { render() { const {classes} = this.props; ...

Tips for creating JavaScript event handlers for Laravel forms

Looking to create a form for my Laravel application that includes text input boxes, radio buttons, and optional values. Here is the basic structure of the form: <html> <head> <title>Form Generation</title> <body> <form act ...

Default close x button not functioning to close modal dialog

When I click the [X] button in my modal dialog box, it doesn't close. Here is an example of my code: $('#apply_Compensation_Leave').show(); This is the modal code: <div class="modal" id="apply_Compensation_Leave" tabindex="-1" role="di ...

Showing a pop-up dialog box once a value has been selected

When the ajax autocomplete value is selected in a certain textfield, I want to display a message box. To achieve this, I am utilizing the jquery-confirm JavaScript library which can be found here. Below is my code snippet: select: function( event, ui ) { ...

You cannot use the "this" keyword outside of a class body

I am facing an issue with my function, can someone help me? Here is the code: function remove_multi_leg(): void { if (Number($("#search_no_legs").val()) < 2) { return; } const removeId: number = Number($(this).attr("data-number")); const ...

Interactive image sliders in a Netflix-inspired style with live previews on hover, fully compatible with Bootstrap framework

I'm looking for suggestions on Twitter Bootstrap compatible jquery plugins that can create a Netflix-style continuously scrolling image carousel with mouse-over functionality. I've tried the carousel included in the Bootstrap JS library, but it r ...

Arrange elements in different directions to accommodate smaller screens

I need help aligning my brand and the links on opposite sides (brand on left, other links on the right) for mobile view. The issue I'm facing is that the links on the right end up moving to the next line. Any suggestions or advice would be greatly app ...

Integrating Flask with React for a cohesive frontend and backend connection

Recently, I decided to try my hand at setting up a webapp using Flask and React by following a YouTube tutorial. Despite encountering a few issues with virtual environments (which I ultimately resolved by not using one), I managed to closely follow the tut ...

Setting up a global CSS and SASS stylesheet for webpack, TypeScript, Phaser, and Angular: A step-by-step guide

A manual configuration has been set up to accommodate all the technologies mentioned in the title (webpack, typescript, phaser, and angular). While it works perfectly for angular component stylesheets, there seems to be an issue with including a global st ...

Titanium: Picture -> "automatically"

Imagine there is an image named hello.png with the dimensions of 200x100. A button is then created using this hello.png as shown below: var btn = Titanium.UI.createButton({ bottom : 50, backgroundImage : "images/hello.png", width:100, height:"auto"; }); w ...

React does not always remove event listeners when using the useEffect hook's return callback

I have a functionality in my component where it initializes a key event listener. This event is supposed to trigger an API call to fetch random data. useEffect(() => { const keyUpEvent = (event) => { if (event.code === "Enter") { ...

Tips on hiding specific table rows in two separate tables based on the chosen option from a dropdown menu

How do I hide table rows based on dropdown selection? The first table has a dropdown with two options: Current State and Future State. If I select Current State, I want to show or hide specific rows in the 2nd and 3rd tables. I am using IDs for these row ...

Issue: 'node' is not being recognized when attempting to execute the file using the package.json script

Currently diving into the world of Node.js, I encountered an issue stating "node is not recognized as an internal or external command" whenever I attempt to start my project using either npm start or npm run start. Strangely enough, running node index.js ...

The functionality of 'Access-Control-Allow-Origin': '*' is not operational

I attempted to address all inquiries pertaining to this tag, yet I encountered a hurdle. Where did I go wrong? $(document).ready(function () { $.ajax({ type: "GET", url: "http://www.tcmb.gov.tr/kurlar/today.xml", dataType: "xml ...