A column of DIV's centered horizontally

I have a column of DIV’s that I want to center horizontally. This is the CSS for the parent container

width: 100%;
    display: flex;
    flex-direction: column;
    align-content: center;

The CSS for the first item

position: absolute;
    top: 5%;
    height: 10%;
    width: 30%;

The first item is aligning left. What am I doing wrong?

position: absolute takes items out of the document flow, so the alignments will be off. It will also be farther off because it’s based on the closest parent position anchor.

position:absolute should be the last resort for positioning in most cases.

If you want to center a container, use and auto margin on it.

/* applies a margin of 2rem top/bottom and centers horizontally */
.example { max-width: 50%; margin: 2rem auto; }

For flex, which you use depends on the flex direction. justify-content deals with the direction of the flex. align-items is the opposite access. So in flex-direction: column, you need to use align-items:center to center it horizontally.

Here’s a quick and dirty example which shows the same justify-content and align-items, but each use a different flex-direction.

1 Like

Mainly the use of absolute positioning. That’s something only to be used in special cases, and when you know how it works.
But without the corresponding HTML that goes with it, there isn’t much advice that can be given.

1 Like

Sorry I couldn’t resist.:slight_smile:

From this thread:

Joking aside, it should be clear by now that absolute positioning isn’t going to help with your task and layout techniques such as flexbox or grid should be your first stop in laying out your page. I know flex/grid are harder to learn that placing things absolutely but its well worth the effort and will allow to do almost anything you need.

Also be careful with your fixed heights.

What is that supposed to be 10% of?

10% of the document or 10% of the section or 10% of the viewport or 10% of the parent?

Suffice to say percentage heights don’t work like that anyway and in most cases will collapse to zero unless there is an unbroken chain of uninterrupted parents all the way back to the root element all having a fixed height defined (other than auto).

These days you can use vh units (viewport height) and so you could say height:10vh which will give 10% height of the viewport. However, should your content in that element exceed the height specified it will overflow and indeed if someone zooms text only it will overflow. With that in mind it would be better to say min-height:10vh instead of height and in that way the element can grow if needed. Better still just let the content control the height unless its just a series of fixed height images or similar.

(The 10% will work for absolute elements but only if they have a context and you will get 10% the height of the nearest positioned ancestor assuming that ancestor has a height defined otherwise you get zero. If there is no such ancestor then you will get 10% height of the viewport as in your example.)

These are all common mistakes that many people make.:slight_smile:

@DaveMaxwell has given a good example of how to approach this.:wink:

HTML

 <div id="Header">
                Registration
            </div>

            <div id="Verify">
                <p style="font-size: 40px; text-align: center;">Email Verification</p>
                <fieldset style="width: 100%;">
                    <label for="Email" style="width: 10%;">Email</label> <input type="text" name="Email" style="width: 75%; border-radius: 10px; border: solid;" id="Email" >
                    <input type="button" value="Enter" style="border-radius: 10px; width: 10%;">
                </fieldset>
                <p id="VerifyText" style="text-align: center;">An email has been sent to <span id="JobseekerEmail">/email address/</span>. <br>Copy the 6 digit PIN and paste it into box below</p>
                <fieldset style="width: 20%; margin: auto;">
                    <label for="PIN" style="width: 50%;">PIN</label><input type="text" name="PIN" id="PIN" style="width: 50%;">
                </fieldset>
            </div>

CSS

.container{
    width: 100%;
    display: flex;
    justify-content: flex-start;
    flex-direction: column;
    align-items: center;
    gap: 1rem;
    width: 75%; 
    margin: 2rem auto;
    padding: 2rem 0;
    height: 100%;
}

#Header{
    width: 200px;
    font-size: 40px;
    border: solid;
}


#Verify{
    height: 400px;
    width: 600px;
    border: solid;
}

The verification DIV is centered horizontally, but the header DIV isn't.

This is very rough but should give you the idea.

Sorry i was replying to the problem in the original post.
Didn’t notice that things had moved on. :rolleyes:

Is it possible to have a fixed vertical gap between DIV’s? I have the next DIV centered horizontally, but its too low, five times the gap between the first two DIV’s.

Do you mean you’ve added another div with some more content?

If so then it needs to be inside the container div if you want it aligned with the rest of that form. You can then just give the div a top margin to space it out a little

I’m not sure that’s what you are doing though so I may need to see the new code :slight_smile:

All content is within the container DIV, which is essentially the body. The horizontal gap between the first two DIV’s is small, about 20-30px, the gap between the 2nd and 3rd is about 5 times bigger. I want the gaps to be the same, say 50px. Is this achieved with margin, top & bottom?

In my example I just used a margin bottom on the header to space it from the div below.

If you are following the same code you would do the same for the Verify div to push the element after it downwards.

However you say there is 5 times the space at present which means you have some other rules in effect because there would be no gap otherwise.

I’d need to see your code again I’m afraid:)

The DIV (3rd of many) has a fixed height and width,

<div id="Personal">
                <fieldset >
                    <label for="Name" style="width: 15%;">Name</label><input type="text" name="Name" id="Name" style="width: 60%;">
                </fieldset>
                <fieldset>
                    <label for="Address" style="width: 15%;">Address</label><input type="text" name="Address" id="Address" style="width: 80%;">
                </fieldset>
                <fieldset>
                    <label for="Town" style="width: 15%;">Town</label><input type="text" name="Town" id="Town" style="width: 50%;">
                </fieldset>
                <fieldset>
                    <label for="City" style="width: 15%;">City</label><input type="text" name="City" id="City" style="width: 30%;">
                </fieldset>
<fieldset>
                    <label for="Phone" style="width: 15%;">Phone</label><input type="tel" name="Phone" style="width: 30%;">
                </fieldset>
</div>

CSS

#Personal{
    height: 450px;
    width: 600px;
    margin: 0 0 3rem;
}

Same margin as Verify, yet the gap is much bigger.

That’s a bottom margin you are applying there so will make no difference to the top margin. If you are doing this as per my example there should be no gap at all so you most liekely have other rules at play that are interfering that we have not been shown.

To show what I mean I have added your div after my code and given it a top margin and it displays exactly as I would expect.

Note that I removed your multiple fieldsets as that is incorrect. Not every label and input is a fieldset. The whole address section is just one fieldset. Use a div around each pair inside if you need to separate items or group them.

Also note that you have set labels to be 15% wide which means n a mobile that will be 15% of 320px (smallest mobile) which will not be wide enough for the text. better to set a min-width in px or em/rem instead in order for there to always be enough room for the text (or use a grid layout).

Don’t use inline styles either as that just makes it 100 times harder to control and to read and to work out what’s going on. Keep the css in the css and not in the html.

Lastly and most importantly stop using fixed heights for you divs holding variable content. You don’t know what the height will be on any users system so let the content control the height.

Unfortunately most of those points above will not help with your issue unless you use the code I have given as there is obviously something else in your code that is spacing elements awkwardly. For instance you could have a justify content space-between adjusting the space or an auto margin which will push the element away to the limit of its container in the opposite direction to its auto setting (depending on axis used).

If none of that helps then try to adapt my codepen to show what you actually have in place. There are so many little things that can change a layout that its hard to pinpoint without a full example :slight_smile:

I used your code and it displays exactly as per your codepen. Cheers.

2 Likes