Header layout


#1

I was wondering if using display: table for header layout would work in this case.
Please find three layouts attached that I would be trying to achieve

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width">
  <link rel="stylesheet" href="css/style.css">
  <title>Lorem Ipsum </title>
</head>
<body>
  <header>
    <img src="/images/test-logo.png" alt="site logo">
    <h1>Lorem Ipsum</h1>
    <nav>
        <ul>
          <li><a href="page-1.html">menu-1</a></li>
          <li><a href="page-2.html">menu-2</a></li>
          <li><a href="page-3.html">menu-3</a></li>
        </ul>
    </nav>
  </header>
  
  <main>
      <img src="https://images.pexels.com/photos/373543/pexels-photo-373543.jpeg" alt="">
      <img src="https://images.pexels.com/photos/908284/pexels-photo-908284.jpeg" alt="">
      <img src="https://images.pexels.com/photos/546819/pexels-photo-546819.jpeg" alt="">
      <img src="https://images.pexels.com/photos/373543/pexels-photo-373543.jpeg" alt="">
      <img src="https://images.pexels.com/photos/908284/pexels-photo-908284.jpeg" alt="">
      <img src="https://images.pexels.com/photos/546819/pexels-photo-546819.jpeg" alt="">

  </main>

<footer>&copy; Lorem Ipsum. Copyright 2018.</footer>

</body>
</html>
* {box-sizing: border-box;}

body {
  max-width: 60%;
  margin: 0 auto;
  font: normal 100% Arial, sans-serif;
  color: #999999;
}
main img {max-width: 100%;}

header {
  display: table;
  table-layout: fixed;
  width: 100%;
  padding: 1em 0;
  outline: 1px dotted green;
}


header img {
  display: table-cell; 
  vertical-align: middle;
  outline: 1px dotted blue;

}

header h1 {
  display: table-cell;
  vertical-align: middle;
  outline: 1px dotted blue;

} 

header nav {
  display: table;
} 

header nav ul {
  display: table-row;
  text-align: right;
}

header nav ul li {
  display: table-cell;
  outline: 1px dotted blue;
}

I am not sure if display: table could be a solution here for the header. Ronpat helped with my site layout in the past and he used display: table. Thanks again Ronpat I still have copy of your code and actually was reviewing it recently to understand if I can take anything from that layout and incorporate it into this layout.


#2

Display:table will do what you want but of course there are many variables to consider which will depend on the exact look you want. You’ve made a good start so why not try adding some real content to see if it does what you want.

I would consider changing the display:table on the nav element to display:table-cell because the siblings are table-cell elements so you can’t really have a table as a sibling of a cell (although I believe that html will generate the anonymous table-cell to make it work anyway but why leave it to chance).

I would change it to this:

header {
  display: table;
  width: 100%;
  padding: 1em 0;
  outline: 1px dotted green;
}

header img {
  display: table-cell;
  vertical-align: middle;
  outline: 1px dotted blue;
}

header h1 {
  display: table-cell;
  vertical-align: middle;
  outline: 1px dotted blue;
}

header nav {
  display: table-cell;
  vertical-align: middle;
  text-align: right;
}

header nav ul {
  display: table;
  width: 100%;
  margin: 0;
  padding: 0;
  list-style: none;
}

header nav ul li {
  display: table-cell;
  outline: 1px dotted blue;
}

(Note the repetition in the above rules could be amalgamated into a comma separated list (or separate class if required)).

I also removed the table-layout:fixed from the header rule otherwise you get three equal cells rather than letting content dictate the space available (to some degree). It all depends on what happens next and the exact dynamics required.

You can of course do the same with flexbox if only modern browsers support is required (or grid if you want to be clever). As usual with CSS there is not one definitive answer as you can often do the same thing in hundreds of different ways but only one may be right for the job in hand.

@ronpat needs top answer that :slight_smile:


#3

Just to make sure I understand this part correctly: header (parent), img, h1, nav (siblings because they have the same parent ‘header’ and they are also ‘header’ children)…

Also what was new to me is that we can nest ‘table’ within ‘table-cell’ as in

header nav {
  display: table-cell;
  vertical-align: middle;
  text-align: right;
}

header nav ul {
  display: table;
  width: 100%;
  margin: 0;
  padding: 0;
  list-style: none;
}

I came across this here, tried Google it further but wasn’t able to find any further explanation. Is that becase both display: table and display: table-cell generate block-level boxes?


#4

I don’t think I am ready to jump into flexbox or grid at my level. I totally agree with your opinion about flexbox/grid as mentioned here which is to only “use them if there’s no simpler way to do things”


#5

Hi, Sergiy. Haven’t heard from you in about 5 years. Hope you’ve been well. smile

I’m working on your issue now. It would be helpful if you could either attach a copy of the logo image or at least give its size. Content matters when planning a layout so the more you can show, the easier our job becomes.


#6

:+1:


#7

I think it may be preferable to try flex or grid rather than get very deep into nesting with CSS display table* rules

Under https://www.w3.org/TR/CSS2/tables.html#table-display

Is https://www.w3.org/TR/CSS2/tables.html#anonymous-boxes

Any table element will automatically generate necessary anonymous table objects around itself, consisting of at least three nested objects corresponding to a ‘table’/‘inline-table’ element, a ‘table-row’ element, and a ‘table-cell’ element. Missing elements generate anonymous objects (e.g., anonymous boxes in visual table layout) according to the following rules:

  1. Remove irrelevant boxes:
  2. Generate missing child wrappers:
  3. Generate missing parents:

Maybe you’ll do better at understanding the rules than I. But I don’t exactly feel comfortable trusting browsers to do what I expect when I see words such as “automatically”, “remove” and “generate”


#8

Hi Ron,

Good to hear from you. I am doing OK. True I didn’t visit Sitepoint forums for some time. Got a few books on web development so been reading those and practicing when I had time + a full time job.

The logo image size is 70 x 70, the gallery thumbnails 300 x 225 (desktop view, please see attached mock ups). I’ve adjusted the CSS, however, the gap between logo and h1 is a little bit too wide. Let me try finishing the HTML portion to incorporate the gallery and then I will try post a link with what I come up with.


#9

Great. Looking forward to seeing it. If it is significantly different than your wish, you might include a made-up screen shot showing the intent.


#10

Yes they are direct siblings of the parent and as such they all need to be table-cells otherwise it doesn’t make sense (just as if you had a real html table and had 3 tds followed immediately by a table element as a sibling).

Its the same as a normal html table and a td or th can contain (almost) any element that you want (e.g. a div or indeed another table).

In css you can often short-circuit the table structure by leaving out table rows (tr and other table elements) but the browser will still construct an anonymous table-row for you. The same would have applied when you went straight to a display:table and the browser would have constructed an anonymous table-cell around it in order to make the structure sound.

The problem with letting the browser do it is that they you cannot target an anonymous element and you won’t be able to style the content as expected.

(As an aside even when you use an html table and if you look in devtools you will see that the browser has constructed tbody elements for you automatically; which is why if you said something like table >tr > td {} it would fail to target that element because there is a tbody in the way.)


#11

I hear you Mittineague. I read through those in the past - the part about anonymous boxes is not that easy to understand. I’ll keep in mind your suggestion with regards to flex and grid.


#12

got it


#13

Hi, Sergiy.

This is my “flexy” version of your page. The menu items are loosely arranged. I was waiting for a “make believe” screen shot to help me visualize how the items should be arranged, but without it, I just left them “loose”. The spacing can be changed later if the content portion (and the flex code) is OK with you.

Feedback please.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="css/style.css">
    <title>header-layout3=ronpat</title>
<!--
https://www.sitepoint.com/community/t/header-layout/305103
810311
Aug 23,2018 10:49 PM
Some References:
https://css-tricks.com/snippets/css/a-guide-to-flexbox/
https://css-tricks.com/snippets/css/a-guide-to-flexbox/#article-header-id-4  {flex-wrap:}
https://css-tricks.com/snippets/css/a-guide-to-flexbox/#article-header-id-6  {justify-content:}
-->
    <style>
html {
    box-sizing:border-box;
}
*,*::before,*::after {
    box-sizing:inherit;
}
body {
    font:normal 100% Arial, sans-serif;
    color:#999;
    margin:0;
}
header,
footer {
    background-color:#333;
    padding:1rem 0;
}
header > div,
main,
footer > div {
    width:94%;
    max-width:1200px;
    margin:0 auto;
    outline:1px dashed green;  /* TEST Outline. To Be Deleted. */
}
header > div {
    display:flex;
    flex-wrap:wrap;
    justify-content:space-evenly;  /* See reference above for other values */
    align-items:center;
}
header .logo {
    outline:1px dotted yellow;
}
header img {
    display:block;
    width:70px;
    height:auto;
}
header h1 {
    display:inline-block;
    vertical-align:middle;
    outline:1px dotted yellow;
}
header nav {
    display:inline-block;
    vertical-align:middle;
}
header nav ul {
    display: table;
    width: 100%;
    margin: 0;
    padding: 0;
    list-style:none;
}
header nav ul li {
    display:table-cell;
    outline:1px dotted yellow;
}

main {
    display:flex;
    flex-wrap:wrap;  /* flex items do not wrap by default */
    justify-content:space-evenly;  /* In this layout, this affects the last row if it has fewer content boxes than the preceeding rows.  Comment out to test; try other values. */
    margin:0 auto;
}
main > div {
    flex-basis:33.33%;  /* similar to width except more flexible */
    display:flex;  /* flex items can be flex boxes, too. */
    padding:3px;  /* padding around the image is best assigned to its parent container */
}
main img {
    display:block;
    width:100%;
    height:auto;
}
@media screen and (max-width:900px) {
    main > div {flex-basis:50%}
}
@media screen and (max-width:500px) {
    main > div {flex-basis:100%}
}

    </style>
</head>
<body>

<header>
    <div>
        <div class="logo">
            <img src="https://via.placeholder.com/70x70" alt="site logo" width="70" height="70">  <!-- It is good practice to include the actual dimensions of each image even if changed in CSS. -->
        </div>
        <h1>Lorem Ipsum</h1>
        <nav>
            <ul>
                <li><a href="page-1.html">menu-1</a></li>
                <li><a href="page-2.html">menu-2</a></li>
                <li><a href="page-3.html">menu-3</a></li>
            </ul>
        </nav>
    </div>
</header>
<!--
The first image below has an aspect ratio of 9:7.  Other images have an aspect ratio of *approximately* 3:2.
The 3:2 images in the top row are distorted (stretched taller) to match the 9:7 aspect ratio image.
Using this method, these images should have exactly the same aspect ratio. Sizes can vary.
NOTE: The last image below is commented out to demo the odd last row.  Restore it to see matched columns.
-->
<main>
    <div><img src="http://www.prygara.com/images/rennie_craigg_sm.jpg" alt="" width="450" height="350"></div>
    <div><img src="images/pexels-photo-908284.jpeg" alt="" width="2500" height="1669"></div>
    <div><img src="images/pexels-photo-546819.jpeg" alt="" width="4288" height="2848"></div>
    <div><img src="images/pexels-photo-373543.jpeg" alt="" width="2999" height="1999"></div>
    <div><img src="images/pexels-photo-908284.jpeg" alt="" width="2500" height="1669"></div>
<!--
    <div><img src="images/pexels-photo-546819.jpeg" alt="" width="4288" height="2848"></div>
-->
</main>
<footer>
    <div>&copy; Lorem Ipsum. Copyright 2018.</div>
</footer>

</body>
</html>

#14

Hi Ron,

Thanks for the flex layout. Its gonna take me some time to fully understand it. I looked through it very briefly and already noticed few things which I don’t understand. I will check those links in the comments that you are refering to. May be it would be a good idea for me to go through some basic tutorials for flex…So can’t promise on a very quick feedback…:slightly_smiling_face:

I’ve attached “make believe” (mockups) screens at the bottom. The desktop version is the one with 3 images in a row, tablet with 2 and mobile with 1. I am trying to re-build my current portfolio website into responsive version and thought I would stick with the most basic layout ( as you can see from my mockups).

The behavior I am trying to achieve is that the layout would change at different break points. Sticky footer may be…? (not sure about this part though because I don’t know if this is something that can be used for tablet and mobile…).

I still have to figure out how “hamburger menu” is built as I was thinking to use it for tablet and mobile verison.

As you suggested I tried to use inline-block for thumbnails gallery and here’s where I am at right now…

http://buildandtest.atspace.cc/


#15

Sergiy,

Whatever time you spend studying it will be worthwhile. smile

In case you did not do so, please copy the code that I posted to a new file, give it an html suffix and open it in your favorite browser, then drag the width of the browser window from wide to narrow (and v.v.) to see how the layout behaves. I focussed on the content section rather than the menu, as explained.

Several aids have been developed to help one grasp the concepts and new behaviors within flex. You can probably find more.

Wes Bos offers a free flex tutorial:


This is another popular free flex course:


 
Here are a couple of games:

https://www.flexboxdefense.com/
(The server timed out when I tried it just now so it may be down.)
 

A good quick reference: (shown in post #13)


 
Since you are steadfastly looking for a solution that uses inline-blocks to hold the thumbs, try the next “working page”. Just as above, copy the code to a new file and see how it behaves. THEN compare the flex code that for the main section to this inline-block code. Once you learn the few flex properties being used, I think you’ll agree that flex is easier to manage in this layout.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="css/style.css">
    <title>main layout inline-block</title>
<!--
https://www.sitepoint.com/community/t/header-layout/305103
810311
Aug 23,2018 10:49 PM
-->
    <style>
html {
    box-sizing:border-box;
}
*,*::before,*::after {
    box-sizing:inherit;
}
body {
    font-size:100%;
    color:#999;
    margin:0;
}
header,
footer {
    background-color:#333;
    padding:1rem 0;
}
header > div,
main,
footer > div {
    width:94%;
    max-width:1200px;
    margin:0 auto;
    outline:1px dashed green;  /* TEST outline. To Be Deleted. */
}
.table {
    display:table;  /* required to eliminate space between inline boxes */
    width:100%;     /* required */
    background-color:#bdf;
    border:2px solid transparent;  /* space around inside edge of table */
    font-family:sans-serif;  /* required */
    word-spacing:-.5em;      /* required */
    text-align:center;
    margin:0 auto;
}
.table div {
    display:inline-block;
    vertical-align:top;
    width:33.33%;
    word-spacing:0;  /* required to restore normal word spacing */
    border:2px solid transparent;  /* space around outside of images */
}
main img {
    display:block;
    width:100%;
    height:auto;
}
@media screen and (max-width:900px) {
    .table div {width:50%}
}
@media screen and (max-width:500px) {
    .table div {width:100%}
}
    </style>
</head>
<body>

<header>
    <div>
        <div class="logo">
            <img src="https://via.placeholder.com/70x70" alt="site logo" width="70" height="70">  <!-- It is good practice to include the actual dimensions of each image even if changed in CSS. -->
        </div>
        <h1>Lorem Ipsum</h1>
        <nav>
            <ul>
                <li><a href="page-1.html">menu-1</a></li>
                <li><a href="page-2.html">menu-2</a></li>
                <li><a href="page-3.html">menu-3</a></li>
            </ul>
        </nav>
    </div>
</header>
<main>
    <div class="table">
        <div><img src="https://via.placeholder.com/600x400/888888/ffffff" alt="" width="600" height="400"></div>
        <div><img src="https://via.placeholder.com/600x400/888888/ffffff" alt="" width="600" height="400"></div>
        <div><img src="https://via.placeholder.com/600x400/888888/ffffff" alt="" width="600" height="400"></div>
        <div><img src="https://via.placeholder.com/600x400/888888/ffffff" alt="" width="600" height="400"></div>
        <div><img src="https://via.placeholder.com/600x400/888888/ffffff" alt="" width="600" height="400"></div>
<!--
        <div><img src="https://via.placeholder.com/600x400/888888/ffffff" alt="" width="600" height="400"></div>
-->
    </div>
</main>
<footer>
    <div>&copy; Lorem Ipsum. Copyright 2018.</div>
</footer>

</body>
</html>

In this post, I did not give any attention to the header.
Do you want the hamburger menu to have any animation?


#16

I would start with the most basic one with no animation.

P.S. Thanks for those links to flexbox resources. Definitely going to bookmark them.


#17

Sure will give it a try. You guys have more experience with this so if you suggest flex for this layout then will try my best to get an idea of how it works.


#18

Hi Ron,

  1. How did you calculate those aspect aspect ratios 9:7 and 3:2? Why they are important?

  2. Should I replace last four links with my own images of same size?


#19

Sergiy,

To be clear, please realize that that quote refers to the images in my test page. The first image is different from your first image.

Do you know how to reduce fractions to their lowest form?
The first image has a real width of 450px and a real height of 350px.
This can be written as width/height or 450/350. The fraction can be reduced to 9/7 or 9:7. This is the aspect ratio of that image. If the image were larger, say 8100px wide by 6300px tall, the aspect ratio would still be 9:7.

The fourth image on your page is 2999w : 1999h. As a fraction, that cannot be reduced any smaller. BUT if I add one px to each side, it becomes 3000w by 2000h which is easily reduced to 3/2 or 3:2. So I state that the aspect ratio of the 2999 x 1999 image is approximately 3:2. I used a similar method to approximate the aspect ratios of your other images. Because the actual aspect ratios are not exactly 3:2, some distortion of the image (stretching or shrinking) can be introduced by forcing them to fit into a 3:2 box. (There are ways to avoid that distortion by cropping the image, but that does not involve flexbox so I am no going to talk about that.) For this time being the images need to be exactly the same aspect ratio to avoid distortion.

Does this make sense?

To minimize loading time, images are usually no larger than the largest size that they will be displayed in a browser window (there can be exceptions).
A width of 600px by a height of 400px might be OK, but you should make that determination as you write your page. Heck, you might prefer square or tall images :wink:

Hope this helps


#20

Sorry can you provide the math for this? How are you getting 9/7 or 9:7? or 3/2 or 3:2 ? Also why aspect ratio is important in this case?