Aligning elements to the left in a variable width grid with centered alignment

Let's think about the structure below

<div class="container">
     <div class="grid">
         <div class="unit"></div>
         <div class="unit"></div>
         <div class="unit"></div>
         <div class="unit"></div>
         <div class="unit"></div>
         <div class="unit"></div>
          ....
      </div>
    </div>

Imagine this layout with images:

You can see that the green blocks and the container are currently aligned to the left.

What I am aiming for is this:

The .unit elements should have a fixed width

The .grid element should expand in width (allowing more unit elements on one line) while always remaining centered within .container.

Any ideas on how to achieve this using only CSS (and possibly some HTML wrappers if needed)?

Answer №1

Starting off, I found this question quite intriguing and initially thought that flexbox would be the perfect solution. Despite experimenting with various flexbox setups, I couldn't crack this particular problem. So, here's a unique approach using floating, clearing, and media queries.

In this scenario, I assumed each row contains a minimum of 3 and a maximum of 9 boxes. However, you can modify this solution to accommodate anywhere from 1 to over 9 boxes.

Below is the HTML code:

<div class="grid">
    <div></div>
    <div></div>
    ...
</div>

Here's the CSS code which includes a small reset to remove any default browser padding or margins that might interfere with sizing, as well as styling for the grid and its child div elements:

* {
    margin: 0;
    padding: 0;
}

.grid {
    display: table;
    outline: 1px solid blue;
    min-width: 330px;
    margin: 0 auto;
}

.grid > div {
    width: 100px;
    height: 61px;
    margin: 5px;
    background-color: teal;
    float: left;
}

The use of the container block was unnecessary due to displaying .grid as a table. By setting it up this way, .grid acts as a block wrapping around its children, while 'margin: 0 auto' centers it on the page. The min-width property ensures at least three blocks per line. Since floats don't collapse when used in a table element, there's no need for explicit float clearing (e.g., clearfix).

Each .grid div child occupies 110px horizontally (100px width + 10px margin on both sides), a crucial value for the upcoming media queries:

@media screen and (min-width: 330px) and (max-width: 439px) {
    .grid > div:nth-of-type(3n + 1) {
        clear: left;
    }
}
...

The media queries adjust the layout based on screen width to manage the number of blocks per line efficiently.

For more insight into the implementation and visuals, refer to this fiddle link: http://jsfiddle.net/5hWXw/. Make sure to resize the preview window to observe the changes.

Answer №2

Ensure your CSS includes the following: 1. Set text-align: center; in the .grid rule. 2. Set display: inline-block; in the .unit rule. The div element is typically displayed as a block-level element, causing each new element to be shown on a new line. By setting the display property to inline-block, all divs with the class of unit will display on the same line (until there is no more space). Additionally, remember that text-align: center; does not work with elements using display: block, as block-level elements default to display: block.

Answer №3

Simply assign values to your classes in this manner:

.container { align-items: center; }

.item { display: inline-block; }

Hopefully, this resolves the problem you are facing.

If not, kindly share your complete code through Jsfiddle for further assistance.

Answer №4

The solution provided by @DRD is effective, but it may require numerous media queries. However, if simplicity is what you seek, consider setting a padding-left/-right on your container...

.grid {
  padding: 0 5%;
}

If the uneven whitespace bothers you when the width isn't a perfect multiple of the .unit's entire box (padding, margin, border, width), utilizing a percentage-based width can resolve this issue.

For a demonstration, check out this fiddle. I've implemented a small amount of Javascript to dynamically adjust the padding, but removing it will showcase the CSS-only result. EDIT: @DRD has created a jQuery function that offers better functionality than my JavaScript solution. You can view it here (ensure to include jQuery if you choose to implement it).

Answer №5

It appears that a potential fix for this issue is similar to the one discussed here Flex-box: Align last row to grid

To address this, begin by setting .grid to inline, then insert additional divs with height: 0 until you have enough to match the maximum number of units in one line (minus one).

While this approach may seem cumbersome, it is still simpler than defining multiple @media queries as @DRD suggested and does not necessitate javascript or window resize handling.

<div class="container">
    <div class="grid">
        <div class="unit"></div>
        <div class="unit"></div>
        <div class="unit"></div>
        <div class="unit"></div>
        <div class="unit"></div>
        <div class="unit"></div>
        <div class="unit empty"></div>
        <div class="unit empty"></div>
        <div class="unit empty"></div>
        <div class="unit empty"></div>
        <div class="unit empty"></div>
        <div class="unit empty"></div>
        <div class="unit empty"></div>
    </div>
</div>


.container {
   display: block;
   text-align: center;
}

.empty {
   height: 0 !important;
}

.grid {
   display: inline;
}

I remain hopeful for a more streamlined solution using solely css

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

Is it possible for me to change the text direction from left to right?

Currently, I am facing a challenge involving adding Arabic text to my paragraphs in a right-to-left format. Despite attempting <HTML lang="ara">, and making adjustments through the .css file, I have not been successful. It's important ...

PHP encounters a Parse error due to a syntax error, where an unexpected character is present

In my new system, employees have the ability to check their leave status. I am currently working on a feature where this leave status will only be visible for logged-in users. One issue I encountered is that when user John Doe is logged in, I can still se ...

Finding the variance in the given situation is as simple as following these steps

To find the variance between the "Total Marks" in a question and the input texts for each answer, we need to consider specific scenarios. Firstly, if a question has only one answer, the text input should be displayed as readonly with the same value as the ...

Unable to see media queries on desktop by default, but can easily view them by inspecting the page

As I delved into a tutorial on media queries, I encountered a perplexing issue. Upon opening the HTML file in Chrome or Firefox, all I saw was a blank page with no content displayed. However, upon inspecting the page, the code appeared as expected and I co ...

JS-generated elements do not automatically wrap to the next line

For my first project, I've been working on a to-do list and encountered an issue. When I create a new div with user input, I expect it to start on a new line but it remains stuck on the same line. Can anyone point out where I might have gone wrong? I ...

Show the user's username on their profile page by retrieving the name from the database

Upon successful login/signup with various services, I want to display the username on the profile page. However, my database stores user data in different fields depending on the service used - user.twitter.name for Twitter logins, user.google.name for Goo ...

Adjusting the visibility and z-index of HTML5 video controls

Hello, I am facing an issue with a Bootstrap carousel that contains a video. The main problem is that the video controls cannot be clicked due to the carousel indicators overlaying them. I have tried adding margin and padding to the indicators, which worke ...

What makes it possible for Vue v3 to handle variables that are undefined?

We are in the process of developing a web application that monitors analytical changes and updates them in real time. While this may not be crucial information, we thought it would be worth mentioning. If you visit Vue.js's official website at https: ...

Applying CSS text-shadow to an input field can cause the shadow to be truncated

I've encountered an issue when applying text-shadow to an input field, where the shadow appears to clip around the text. Here is the CSS code I used: @import url('https://fonts.googleapis.com/css2?family=Jost:ital,wght@0,100..900;1,100..900& ...

Tips for creating a hover-activated dropdown menu

How can I create a drop-down menu in my horizontal navigation bar that appears when hovering over the Columns tab? The drop-down menu should include options such as Articles, Videos, Interview, and Fashion. To better illustrate what I am looking for, here ...

In order for the user to proceed, they must either leave the zip code field blank or input a 5-digit number. However, I am encountering a problem with the else if statement

/* The user must either leave the zip code field blank or input a 5-digit number */ <script> function max(){ /* this function checks the input fields and displays an alert message if a mistake is found */ ...

Text animation that rises smoothly within a concealed overflow region

I'm currently trying to replicate the effect seen in this example: Specifically, I am referring to the text that reads "CREATIVE AGENCY FOR DARING BRANDS" Although it appears simple, I am having trouble figuring out how to achieve it. I primarily wo ...

Unpredictable characters within CSS class titles

I've observed an interesting pattern on certain websites like tray.io, asana, and Facebook. When you inspect their CSS class names, you may come across random combinations of characters, such as: <header class="Header_XSDsdksdXKkSDD">..</Hea ...

The Zurb Foundation has a multitude of redundant CSS entries

I have been utilizing Zurb Foundation for a while now, with a bower + compass setup as outlined in the documentation here. Recently, I encountered an issue where a specific page was loading slowly. Upon investigating, I discovered that there were numerous ...

Struggling with implementing the group by feature in AngularJS?

Currently, I am trying to group a select-window by 2 different object arrays - subcategories and rootcategories. Each subcategory has a relation id that links to the rootcategory's id. My goal is to have the dropdown window group the subcategories bas ...

Adjusting the width of the progress bar without affecting the position of the elements within

Looking for ideas on how to adjust the display width of a progress bar without affecting the elements inside it. Here's what I'm aiming for: https://i.sstatic.net/1clkF.png Currently, the code for a player entry is as follows: <div class ...

Using CSS to display several images across the entire screen width

I need to display multiple images in a row that fill the screen width: <img src="1.jpg" style="max-width:25%"> <img src="2.jpg" style="max-width:25%"> <img src="3.jpg" style="max-width:25%"> <img src="4.jpg" style="max-width:25%"> ...

Shifting the pagination outside of the slider in ReactJS and SwiperJS seems to be tricky. Despite trying to adjust the margins and padding, the pagination

I've been struggling with this issue for a while now. I need to move the pagination outside of the slider, but using padding or margin doesn't seem to work. It always remains inside the slider, and if I try to position it outside, it gets hidden. ...

jQuery .click() only triggering upon page load

I've been searching all over the place and I just can't seem to find a solution to my specific situation. But here's what I'm dealing with: Instead of using inline HTML onclick, I'm trying to use jQuery click() like this $(docume ...

Combining Angular variables within HTML tags: A Guide to AngularJS

As a newcomer to AngularJS, I am truly impressed by its capabilities. One thing I am eager to learn is how to include an AngularJS binding within an HTML attribute, while also adding another string to it. I often use unique names like "thisform" and "thisd ...