Top menu button customization in OutSystemsUIWeb (OutSystems 11), Part One
In this blog post I'm using CSS3 to animate the top menu in OutSystemsUIWeb. First, I'll explain how the classes for the top menu in the default BaseTheme are layered and strip them of their OutSystems-style. Then we get straight down to the customizing business in part two, and at the end, I'll share the full CSS modifications for you to apply to your own project. Buckle up, this is going to be a long one.
In order for OutSystems to be usable right out of the box, they have developed a basic HTML/CSS structure for us to build our apps on. I say 'basic' because it is the equivalent of pre-built IKEA furniture; it looks basic, but it fits in almost every common interior and is customizable with a lot of decorations. And much like IKEA furniture, the actual construction can be a bit confusing. It feels like it's is not really meant for us to break it apart in order to customize said actual construction, but we are welcome to try if we really want to. Counting from thetag as zero, our actual top menu button link is no less than fourteen layers deep. There are a lot of hidden style classes built inside those fourteen layers, and although most of them - if not all of them - can be found in the BaseTheme style sheet, it's not that easy to find what you're looking for. Fortunately, this amount of layers still is kind of manageable, so let's start breaking them down with the help of our browser's developer tools.
First, we have the html and body tags. There's not a lot of interesting stuff in the style sheet for those tags - some color-, font-, margin/padding- and box-sizing properties, and you'll have many of them overridden anyway. Next, there is a form tag. This is interesting if you want to learn more about how OutSystems works under the hood, but there are no particular styles associated with this tag, so it is not relevant for now.
Now we get to dive into the interesting stuff, CSS-wise; next up is a div with the class "layout layout-top". This makes sense, because we had to choose the 'Top Menu' web app template when we created our application in order to get a top menu in the first place. The only things specified in the layout-top class are -webkit-box-orient: vertical; and flex-direction: column;.*
*Fun fact: Side menu layouts have the layout-left style class and contain -webkit-box-orient: horizontal; and flex-direction: row;. This means that a side menu template just has its' layout boxes flipped sideways. Neat!
Underneath, we have a div with class "main". This class just flips everything inside our layout upright again (in case we had used a side menu), and sets the flex property to 1.
Next we finally get to our header tag (role="banner"). Here, we find a white background color, the box-shadow that's responsible for the shadow underneath the header, and some properties to ensure the header sticks to the top and stays visible (left: 0; top: 0; position: sticky; z-index: 100;). It's defined in the style sheet under .layout .header{} (without 'main'!)
Inside, there's the div with style class "ThemeGrid_Container", which is responsible for the margin, padding and width of the box the header contents are put into. (Note: it's more prevalent in the style sheet where the responsive behavior is defined.) Then there's a div with two style classes, "header-top" and "display-flex", where all "header-top" does is set the height of the header (standard 56px) and "display-flex" sets the display property to flex.
We're finally getting to some recognizable content within this div. In the Layout web block in Service Studio, we can see the 'Left' 'Center' and 'Right' placeholders in the header. There are four divs inside the "header-top" div, and three of them have id's ending in "Left", "Center" and "Right". The one div we don't recognize from our Layout web block is the one with the "menu-icon" class; this is not the icon OutSystems places into the Left placeholder, but a burger menu, only visible on phones or tablets (responsive). It contains three divs with the "menu-icon-line" class, which simply draws a line 3px high and sets the distance between itself and the next line.
For our menu button customization, we'll delve deeper into the div that has its' id end in "Center", because that's where we've placed our Common\Menu block in Service Studio. This div has four classes, "header-center display-flex align-items-center flex1", which simply applies padding to the center region, sets display to flex again, centers the content of its' boxes and sets flex to 1 again.
Drilling down again, we get to a nav tag (role="navigation") with classes "Application_Menu" and "OSInline". The "Application_Menu" class simply sets height and width to 100% in our browser, but is used often in conjunction with other style classes for responsive behavior. The "OSInline" class doesn't show up in the style sheet; it is a class which is added server-side to containers without a width property, setting display to inline-block and vertical-align to top.
Below, we find the "Menu_TopMenus" class on a regular div again. It doesn't do much in your browser, except setting display to flex and the height to 100% (again), and it has the "OSInline" class, too. (Note: the "Menu_TopMenus" class actually does a lot in OutSystems' responsive design.) Underneath, there's another div with a class that doesn't do much at the moment; "Menu_DropDownButton" (we have no submenu items). Of course, this gets more interesting once we actually have dropdowns in our menu, but all it does now is setting display to inline-block again. You'll see that there's a div with this class for each of your menu buttons, with more or less the same content.
Our next div has the "Menu_TopMenu Menu_TopMenuActive" classes. The TopMenu_TopMenuActive class isn't activated until the button is active (i.e. until we're actually on the page related to that button). This is where we really need to start paying attention. In the style sheet, .header .Menu_TopMenu:hover, .header .MenuTopMenuActive{} have a colored border bottom with your primary color as its' variable and bolden the font. The .header .Menu_TopMenu{} class contains a transition (all 150ms linear), some padding, and sets the top and bottom borders transparent.
This means that the current look and behavior of our buttons seems to be defined in two style classes with different pseudo-classes and pseudo-elements: .Menu_TopMenu{} and .MenuTopMenuActive{}. Now we can look into the BaseTheme style sheet to see what's actually in there, neutralize what we don't need, and proceed with our own customizations.
This is the BaseTheme top menu we start with:
Let's clean up the colored border bottom first:
.header .Menu_TopMenu:hover,
.header .Menu_TopMenu.Menu_TopMenuActive {
border-bottom: 0px;
}
This is what we get:
Now we'll clean up the highlight:
.Menu_TopMenu > div,
.Menu_TopMenuActive > div a,
.Menu_TopMenuActive > div a:visited,
.Menu_TopMenuActive > div a:hover,
.Menu_TopMenu:hover.Menu_TopMenuActive > div a {
color: var(--color-neutral-8);
font-weight: normal;
}
It looks better. Still, there's a pesky little animation going on when you hover on and off a menu button.
It's caused by border size in the .header .Menu_TopMenu class, so we can easily override this.
.header .Menu_TopMenu {
border-bottom: 0;
border-top: 0;
}
There's still a slight color difference on hover, but we've stripped the top menu bare. Let's fully customize it in the next post!
Geen reacties
Geef jouw mening
Reactie plaatsenReactie toevoegen