News:

Bored?  Looking to kill some time?  Want to chat with other SMF users?  Join us in IRC chat or Discord

Main Menu

SMF 2.1: Full-width menu bar on default markup.

Started by Antechinus, September 15, 2021, 07:37:44 PM

Previous topic - Next topic

Antechinus

This is mainly a demonstration of CSS trickery, since if you were writing a custom theme the required markup change for a full-width menu bar is fairly trivial. However it does contain some interesting ideas

It shows a way of getting an unexpected result on default markup. If, for some reason, you cannot or do not want to edit the default template, tricks like this can be useful.

First take the basic case, with the menu bar contained within the default #wrapper div:

You cannot view this attachment.

This is obviously done by just having no background, border or box-shadow set on #wrapper, and with the eye candy set on the #upper_section div and/or its child elements. Pretty basic, especially for flat colours.

This theme does not actually use flat colours though. The backgrounds are a very subtle gradient, to give a slight highlighting effect to the top of each section with an overall flat look. The eye candy is done on #inner_section and .navigate_section, like this:

#inner_section {
    background: linear-gradient(#fff, #f6f8f8 3px);
    border-radius: 4px;
    box-shadow: 0 2px 3px #0002;
}
.navigate_section {
    background: linear-gradient(#fff, #f6f8f8 3px);
    border-top: 1px solid #d1d5d9;
}

Can this look be exactly duplicated, on default markup, responsive for any screen resolution, but with the menu bar running the full width of the screen?

Yes, it can. :D

You cannot view this attachment.

#upper_section {
    background: #f6f8f8;
    box-shadow: 720px 0 0 #f6f8f8, -720px 0 0 #f6f8f8,
                0 2px 3px #0002,
                1200px 2px 3px #0002, -1200px 2px 3px #0002;
}
#upper_section::before {
    display: block;
    height: 1px;
    content: '';
    background: #fdfdfd;
    box-shadow: 720px 0 0 #fdfdfd, -720px 0 0 #fdfdfd;
}
#inner_section::before {
    display: block;
    height: 1px;
    content: '';
    background: #fafbfb;
    box-shadow: 720px 0 0 #fafbfb, -720px 0 0 #fafbfb;
}
#inner_wrap::before {
    display: block;
    height: 1px;
    content: '';
    background: #f7f9f9;
    box-shadow: 720px 0 0 #f7f9f9, -720px 0 0 #f7f9f9;
}
.navigate_section::before {
    display: block;
    height: 1px;
    content: '';
    background: #d1d5d9;
    box-shadow: 720px 0 0 #d1d5d9, -720px 0 0 #d1d5d9,
                720px 1px 0 #fdfdfd, -720px 1px 0 #fdfdfd,
                720px 2px 0 #fafbfb, -720px 2px 0 #fafbfb,
                720px 3px 0 #f7f9f9, -720px 3px 0 #f7f9f9;
}

Which is a tad sneaky. :D It works because box-shadows do not trigger a scroll bar when they overflow the screen width. This means you can set a full opacity, zero blur, box-shadow with a large horizontal offset, and it will visually extend the width of the parent element as far as you like.

Box-shadows stack from last to first in the CSS, with the first shadow sitting on top of the others, so you can also use multiple stacked box-shadows to visually extend the width of a parent element that has a gradient background. A CSS gradient is only a series of flat colour lines on screen, because each pixel can only be one colour, so by offsetting the stacked box-shadows by 1px each time you can get exactly the same look as any gradient you like.

The gradient in this case is nominally from #fff to #f6f8f8, but because the first pixel is coloured as if a stop was set halfway across that pixel, the first row of pixels in the gradient as displayed on screen is actually #fdfdfd. So when using these tricks to emulate the look of the nominal gradient the relevant elements and pseudo elements, and their box-shadows, use the colours #fdfdfd, #fafbfb, and #f7f9f9, before proceeding to the flat background of #f6f8f8.

So #upper_section gets the flat background colour, along with five box-shadows: two to emulate the flat background and three to handle the box shadow for the necessary width.

#upper_section::before deals with the first line of pixels for the highlight gradient, and of course has two box-shadows to extend it horizontally.

#inner_section has no visible styling.

#inner_section::before deals with the second line of pixels for the highlight gradient (with two box-shadows to extend it horizontally).

#inner_wrap has no visible styling.

#inner_wrap::before deals with the third line of pixels for the highlight gradient (with two box-shadows to extend it horizontally).

After that the flat background from #upper_section takes over, until we get to the border and gradient between the #main_menu and .navigate_section divs. These are done solely on navigate_section::before, with the pseudo element itself and the first two box-shadows handling the grey 1px border. The remaining six stacked box-shadows handle the highlight gradient for that section.

So there you have it. A bit bonkers, but fun, and should give ideas for a range of further trickery. :)

ETA: This is for SMF 2.1, but similar tricks can be done on 2.0.x markup too.

Antechinus

Oh, there's obviously another way you can get the same visual result. CSS would not really be any more complicated, but the catch is you have to track your way through a range of media queries to deal wth the responsive side of things. The alternative approach would be to start with this:

#wrapper, #upper_section, #inner_section, #main_menu, .navigate_section {
    width: auto;
    max-width: 100%;
    margin: 0;
    padding: 0;
}

You would then have to use various child elements of #wrapper to handle the job #wrapper used to do, namely restricting content width and keeping it centred on larger screens:

#inner_wrap, #main_menu .menu_nav, .navigate_section ul {
    width: 90%;
    max-width: 1200px;
    margin: 0 auto;
}

After that, the eye candy could just be set on #upper_section for the main background (and any highlight gradient) of the menu bar. If wanting a border and/or gradient betwee #main_menu and .navigate_section, that would just be set on .navigate_section as a standard 1px border and gradient background.

The thing about doing it this way is that although the basic eye candy CSS is simple, there will be several conflcts to deal with in the default responsive.css, and you will have to change a few declarations here and there. Not a huge issue if you know what you are doing, but may be a bit much for some beginners. :)

Wellwisher

If that's a new theme ur making, you've nailed the colour scheme. Looks sexy af.


Mike66


Antechinus

Lol. I've done bugger all on it since then. I should make an effort to drag it out I suppose. :)

Wellwisher

#6
Quote from: Antechinus on March 09, 2022, 03:17:19 PMLol. I've done bugger all on it since then. I should make an effort to drag it out I suppose. :)

@Antechinus I want to run your theme until I finish my own custom one from scratch. Defo finish it, it looks gorgeous. Heck I would even purchase it, if you sold it at a theme store. :laugh:

Antechinus

Oh alright then. I'll dig it out and take another look at it. :D

Advertisement: