Design Studio CSS Investigations Vol 1.
I’ve had the opportunity recently to work quite a lot with Design Studio, specifically during the development of course material for BI Clients and Applications on SAP HANA at openSAP. In the exercise for Week 3 Unit 3, we use CSS to format a crosstab and dimension filter in Design Studio 1.3. The outcome looks like this:
When I wrote the exercise, I pretty much just fumbled around blindly using this handy document as a reference:
Design Studio 1.1 Full List of CSS classes (?)
I came out with the following CSS, which, for the dimension filter at least, is pretty clunky:
.sapzenfilterpanel-Container, .sapzenfilterpanel-Container .sapUiBorderLayoutTop, .sapzenfilterpanel-Container .sapUiBorderLayoutTop, .sapzenfilterpanel-HeaderText, .sapzenfilterpanel-HeaderText.sapUiTv, .sapzenfilterpanel-HeadLine, .sapzenfilterpanel-Container .sapUiRrRow .sapzenfilterpanel-RowRepeaterRow div { font-size: 10px !important; color: white !important; background-image: linear-gradient( red, #f06d06 ); top: 1px !important; bottom: 1px !important; margin: 1px 1px 1px 1px !important; align-items: flex-end !important; } .sapzencrosstab-ColumnHeaderArea .sapzencrosstab-HeaderCellDefault, .sapzencrosstab-DimensionHeaderArea .sapzencrosstab-HeaderCellDefault { color: blue !important; text-shadow: none !important; background-image: none !important; background-color: blue !important; }
At the root of my efforts with the dimension filter, was the borderline OCD obsession with aligning the vertical space required by the dropdown boxes and the dimension filter. The Design Studio application designer doesn’t allow you to set the height of a dropdown box when using the Mobile theme. It is hard-coded to auto, which amounts to a value of 31:
Perhaps a small part of me hoped that this would get picked up and fixed in DS 1.4, but since it didn’t, I’ve now convinced myself that this was a decision made in order to optimize the dropdown button for touch events, on mobile devices.
Now that we’ve settled that (or have we?) the only remaining task is to size the dimension filter that shares real estate on the header section of the application with the dropdown boxes to an equivalent height of 31. Perhaps it’s trivial, but I would argue that in order to deliver consistency in our visual design approach, it is important nonetheless. Borrowing a line from the visual design basics site, this is a component of unity:
- Unity has to do with all elements on a page visually or conceptually appearing to belong together. Visual design must strike a balance between unity and variety to avoid a dull or overwhelming design.
OK, so my approach to unity in this little application is to normalize all of the filtering components on a single x-axis, and to have them render with the same height.
This should be easy right?
I’ll just set the height of the dimension filter to 31 and forge happily ahead…
Wait a minute, that can’t be right … the bottom of the dimension filter is cut off, and there’s a scroll bar on the side of the component! Even in a pinch, I couldn’t very well deliver my openSAP exercises with something looking this unprofessional. So I played around with the classes I knew about at the time and delivered a filter bar that we can have a closer look at:
It is clear that the dimension filter is bigger than the other components, even though the font size has been reduced. Unfortunately, due to the fact that my deadline was looming and that I enjoyed playing with the linear-gradient property so much, I went ahead and published this as-is. Story over right?
Not quite. A couple of weeks ago a student asked in the discussion forums whether it was possible to apply word-wrap to header cells in a Design Studio crosstab (it is btw:
.sapzencrosstab-HeaderCellContentDiv { word-break: break-all !important; white-space: normal !important; }
) and I mused in an SCN comment that I’d like to know how people knew which CSS classes to use:
Mike’s comment was pointed enough … but initially I wasn’t completely certain what he meant. I’d used the developer tools before but how could I use this to sort out all of my ailing CSS? What follows is the process I used to identify the classes and properties needed to take control of the dimension filter and make it look correct at a height of 31px.
Let’s start with an unformatted application:
I’ll execute the application locally and have it launch in Chrome. Once it’s up, press F12 on your keyboard to bring up the developer tools. Your screen will now look something like this:
You want to be in the Elements tab and you should see the Styles tab on the right. There is unfortunately a lot of noise to sift through here, and I’m going to use that as an excuse for why I didn’t stumble across this initially. However, thanks to Mike’s comment, I knew there was some magic here somewhere if I could find it. In the image above, you can see a div set to 100% of the page body … this is the root div that the rest of the application is contained within. Expand a few levels and find the root element from which the mobile theme is inherited. :
Once you expand the body element you can see where the magic takes place:
There you have it! The div inside of the comments above contains all of the components in our application. In this case, my application was called WORDBREAK, so that shows up in the Start/End template body comments. Expand a few more levels and we finally locate the element containing our dimension filter:
It’s quite helpful that Chrome highlights the entity on the browser as you mouse-over it. It would have taken me a lot longer to figure out where the dimension filter was otherwise. Now it’s important to note that we aren’t really interested in this container as an absolute object. We simply need to identify the CSS classes underneath it … so let’s expand a few levels more (it really is like peeling an onion … it was 6 levels down from here for me):
At last we can identify a CSS class that looks familiar from the 1.1 reference! We can also tell that the sapzenfilterpanel-Container class has correctly inherited the height property we set to 31 in the designer. Since that seems OK, we continue our downward spiral until we find sapzenfilterpanel-RowRepeaterRow:
Finally, the culprit starts to surface. This row container is setting a height of 47px and ignoring the value I set on my application … for shame! We now know that the class:
.sapzenfilterpanel-Container .sapzenfilterpanel-RowRepeaterRow
Has priority here. It is also superseding another incorrect value of 45px set on the individual class .sapzenfilterpanel-RowRepeaterRow. We can change this right here in Chrome to see how it will look after we fix it:
The scrollbar is gone, and the container is drawn correctly, but we still need to adjust the text components inside of the dimension filter.
The remaining changes are in the same vein.
The text components are structured as an HTML unordered list with list items inside. I assume this is because the Dimension Filter and Filter Panel components leverage the same underlying UI5 component.
First, .sapUiTv.sapzenfilterpanel-HeaderText shows up with a default line-height of 45px. We also want to adjust the font-size to 10px so that we can see the entire string:
You can type directly into the properties and see the changes live in the browser window above! Something similar is happening to the .sapUiTv.sapzenfilterpanel-SelectionMemberText class, but here we need to update both line-height and height:
And last but not least, we have the .sapzenfilterpanel-RightArrowImage class which seems to get a relative top property set at around 1/3 the height of the container object (which was 43px originally. The top property below is initially set to 14px. 14/43 = .325):
So we can set the top value to 10px. Now we have a filter panel that looks and feels consistent with the dropdown box:
All that’s left to do is apply the CSS. The final CSS looks like this:
.myDimFilter .sapzenfilterpanel-Container .sapzenfilterpanel-RowRepeaterRow, .myDimFilter .sapUiTv.sapzenfilterpanel-SelectionMemberText, .myDimFilter .sapUiTv.sapzenfilterpanel-HeaderText { font-size: 10px !important; height: 31px !important; line-height: 31px !important; } .myDimFilter .sapzenfilterpanel-RightArrowImage { top: 10px !important; }
I preface the properties with my own custom class called myDimFilter so that I can apply it to the components individually. Without this qualifier, the default styles are changed and it messes up the filter panel component. This validated my theory that the underlying UI5 components are the same.
I hope you’ve found this investigation helpful!
New NetWeaver Information at SAP.com
Very Helpfull