Grid and flexbox layout - flexbox header and image grid - front page

I am using grid and flexbox to layout site header and image gallery page

Please see below link

http://buildandtest.atspace.cc/

Behavior I am trying to achieve and current issues:

  1. Have header image, h1 and header nav centered and stack vertically without using media query when browser window gets resized to smaller sizes. In my previous layout it was achieved via media query with breakpoint and using flex-direction: column.

  2. I gave header navigation a width in order to be able to use justify-content: space-between; as justify content can only have effect if there’s extra space available in the container. Giving it a width seems to be an issue when the window is resized to smaller sizes

.header .topnav ul{
  display: flex;
  width: 41rem;
  justify-content: space-between;
  .........
}
  1. I am also wondering if its possible to implement sticky footer with this layout

  2. I put this as my last question however I guess it should actually be the first to ask myself: Considering site markup first I need to determine which elements should be laid out using grid and which using flexbox. Main criteria is if I need a one dimensional layout like header and footer flexbox would be first to consider (even though it is possible to do it with grid), when I need two dimensional layout like image gallery most appropriate would be grid.

That’s not fully possible without media queries although we can get quite close with some tweaks. You can lose the 41 rem width on the menu and use a max-width instead but you will need to use flex to make it expand.

Add the following rules after your original css as these are extra css rules that work with your existing rules. If all goes well then you can amalgamate them properly.

.header .topnav{flex:1 0 0%;}
.header .topnav ul {
padding:0 5px;
margin:1rem 0 1rem auto;
width:auto;
max-width:41rem;
min-width:300px;
}
.header h1 {margin:1rem auto;}
.logo {margin:auto;}

You are going to have to tweak padding rather than margins to get space around some of the elements.
I think that’s about as close as you can get on that top section without adding media queries.

Note how your images are squished in my screenshot. You need to add height:auto to the image css when you set their width to 100% and that will maintain the aspect ratio.

You can implement a position:sticky footer with the setup you already have like this.

footer{
position:-webkit-sticky;
position:sticky;
bottom:0;
background:rgba(0,0,0,0.5)
}

If you want an original sticky footer (footer sticks to the bottom of the viewport only when there is less content than viewport height) then you would need to do this instead:

 body{
display:flex!important;
flex-direction:column;
min-height:100vh;
}
footer{margin-top:auto;}

CSS tricks has a recent article about this which should help.

1 Like

the first two parameters are pretty much self-explanatory: flex-grow set to 1 means the item can grow if necessary, flex-shrink set to 0 means it can’t decrease in size. The interesting one is the last parameter flex-basis. I’ve checked CSS tricks and found "It specifies the initial size of the flex item, before any available space is distributed according to the flex factors. " Not sure I understand how it kicks in and why did you use percentage instead of just 0 zero?

It allows the text to wrap if needed whereas auto would keep them at the min-content length. It also distributes the free space in a different manner and usually its a matter of trial and error to work out what’s best for the task in hand.

That’s to counter a bug in IE11 where the element won’t take up the correct space if set to zero without a percent unit. (Not that I support ie11 anymore but it’s just habit).

1 Like

I’ve amalgamated your code and made some changes to my previous css as well
The above sticky footer portion with flex! important and direction column on the body messes up the image grid. My understanding this is happening because now with the above declarations all direct chidlren of the body become flex items so display:grid has no effect…

my changes:

I added max-width: 80%; to the body (just to keep it slightly narrower as next pages I am going to work on are blog, about and contact so it would keep things more compact I guess)

changed from grid-template-columns: repeat(3, 1fr); to grid-template-columns: repeat(auto-fill, minmax(380px, 1fr)); on main.home

I’ve updated my original link with above changes (please see post#1 in this thread)

I think I figured it out…just wrapped main.home with an extra div…seems fixed the issue…
Not sure…

I am curious to know why Flex and Grid are being used? Are you trying to learn how to use the two utilities?

For the simple demo site is the following adequate?

https://this-is-a-test-to-see-if-it-works.tk/sp-a/810311/index-002.php

Images are reduced to make it easier to show the responsiveness.

1 Like

You don’t need to do that just remove the margin:0 auto from main.home and that will allow the grid to use the full space available.

Live screenshot.

1 Like

Correct. Thanks for the demo @John_Betong

1 Like

It was new to me. So grid inside body with display: flex: still acts as grid and left and right auto margins were stocking images up…interesting

You can use grid inside flex or vice versa. You can also use flex inside flex and grid inside grid.

They will all still work. It’s no different to using a normal container in that the item (flex or grid) uses the space available as defined by its container. If a flex item is itself a grid then that just means the children will be children of a grid however the grid parent itself is a flex-item controlled by its flex parent.

It might be easier just to imagine if you put a grid inside a table-cell then the grid has to work within the confines of that table-cell. It doesn’t stop it being a grid or its children behaving like grid children :slight_smile:

Auto margins are now powerful things and effectively soak up the space on that side of the element. In grid and flex this can work both horizontally and vertically.

2 Likes

Page resizes perfectly if I manually resize browser window. I tried however testing the page via Chrome Dev Tools for different screen sizes and there’s some misaligntment with h1 and footer. I updated original link from post #1. I think partially it is happening because I am using minmax(380px, 1fr) which locks image to 380px. Also not using media queries makes it harder to achieve centering on smaller screens I think…

dev-tools-2

I am also wondering if I need to scale logo and navigation menu font for smaller screens…? I had my logo as png and converted it to svg using free online converter

As a variation to page design I am trying to swap h1 and logo so logo is actually in the center with h1 on the far left and nav on the far right (just to see how this header design would fit into overall site)…

Yes the 380px will break any devices that are smaller than 380px + 20%. the 20% is the fact that you have only an 80% body width and that is eating up a lot of space on small screens. Fore example on my iphone that equates to 64px on my 320px screen leaving only 256px room for any content!

The screen is also held wide by your menu which again at small widths is 354px wide so that will only fit on a screen that is 354px + 20% wider.

Yes of course it’s harder :slight_smile:

I assumed you were just doing this for a test and not for real life. There is no point in eschewing media queries just for the sake of it. It’s like painting yourself into a corner and you start to use unrealistic complicated techniques just to cater for the lack of a simple media query.

It’s good to have a component or components that can resize without media queries but you are never going to code any slightly complicated site without using media queries. After all that’s what they were designed for. :slight_smile:

The logo isn’t that big anyway but I would avoid making your navigation text any smaller as that makes it hard to hit the right item with fat fingers. Indeed on smaller screens you should be looking at slightly larger links and slightly larger readable text (not smaller and smaller).

Either re-arrange the navigation for smaller screens or do as 99% of the world does an implement a hamburger icon instead.

If I were you I would insert a media query at an appropriate point and change the minmax of the grid item to something that will fit on all smaller screens. I would also lose the width on the body at smaller widths and maybe just a 5px or 10px padding on the body edges instead.

Then once the menu starts to get squashed too much add another media query to activate the hamburger menu or if that is to much work make the menu vertical for each item instead.

2 Likes

No, its not for a test. Sorry if I was not clear at the beginning of this thread. I have WordPress backend on my localhost and front end layout which only uses flexbox ( you, Ron, Ray were helping me with it before). But because I never used grid I thought it would be a good learning experience for me to try re-build the whole layout using grid and flex. Once finished I would be moving the whole thing to Bluehost.

The reason I tried 80% on the body is because of blog page actually. If I make the whole site too wide, my blog posts would also stretch (I already have blog page and its using flexbox - no grid)

I am going to try re-build this page based on your suggestions Paul. Not sure how long it would take me :laughing: but I will try to do my best. Never implemented ham icons with pure CSS though (as I don’t know Javascript) but I will try google see if I can find some answers.

We can align these with flex property but in small devices we can adjust without media query.
Add the following rules that work with your existing rules. Add code:

.header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    color: #999;
    outline: 1px solid green;
}

.logo{
display:inline-block;
}

.h1{
display:inline-block;
}

.topnav{
display:inline-block;
}

We can sticky footer with by position code is:

<body>
  <div class="content">
    content
  </div>
  <footer class="footer"></footer>
</body>


html, body {
  height: 100%;
}
body {
  display: flex;
  flex-direction: column;
}
.content {
  flex: 1 0 auto;
}
.footer {
  flex-shrink: 0;
}

Try this!

1 Like

That issue has already been solved with a more reliable method thanks.

4 Likes

I usually just use a max-width instead because your 80% is still much to wide on my 27" imac and there are indeed much bigger screens about now.

Her’s an old example using CSS only (:target) for a hamburger menu.

There are other methods of toggling using the checkbox hack that are more persistent than :target but generally changing a class on the parent with js is an easier approach.

2 Likes

what max-width would you recommend considering I have a blog page which I don’t want to grow too wide as the blog entry text would be hard to read if it stretches too long…