F7 - row, F7 - col and text aligment

I’m still fighting with text aligment.
So I made a test code :

uid: test
tags: []
props:
  parameters:
    - context: item
      description: test
      label: test
      name: TC_auto_on_off
      required: true
      type: TEXT
    - context: item
      description: Switch
      label: Switch
      name: TC_on_off
      required: true
      type: TEXT
  parameterGroups: []
timestamp: May 29, 2023, 10:17:50 PM
component: f7-card
config:
  style:
    background-color: "=props.bgcolor ? props.bgcolor : ''"
    border-radius: var(--f7-card-expandable-border-radius)
    box-shadow: 5px 5px 10px 1px rgba(0,0,0,0.1)
    margin-left: 5px
    margin-right: 5px
    noShadow: false
    padding: 0px
slots:
  content:
    - component: f7-block
      config:
        style:
          --f7-theme-color: var(--f7-text-color)
          margin: 0
          padding: 0
      slots:
        default:
          - component: f7-row
            config: {}
            slots:
              default:
                - component: Label
                  config:
                    style:
                      margin-top: 0px
                    text: LINE1
          - component: f7-row
            config:
              style:
                margin-top: 7%
            slots:
              default:
                - component: Label
                  config:
                    style:
                      text-align: left
                    text: LINE 2 Left
                - component: Label
                  config:
                    style:
                      text-align: left
                    text: LINE 2 Right
          - component: f7-row
            config:
              style:
                margin-top: 7%
            slots:
              default:
                - component: Label
                  config:
                    text: LINE 3 Left
                - component: Label
                  config:
                    text: LINE 3 Right

A now I’m trying to get all text into center like this:

 - component: f7-row
            config: {}
            slots:
              default:
                - component: Label
                  config:
                    style:
                      text-align: center
                      margin-top: 0px
                    text: LINE1

but it isn’t workig :

so what I’m doing wrong
Is necessary add into each f7-row next f7-col for each label ?

In situations like this, it is always helpful to open up the developer tools in your browser to see how the widget is actually being rendered into html. In this case, starting from the f7-block you get this:

<div class="block" style="--f7-theme-color:var(--f7-text-color); margin: 0px; padding: 0px;">
  <div class="row" slot="default">
    <div slot="default" class="" style="margin-top: 0px;">LINE1</div>
  </div>
  <div class="row" slot="default" style="margin-top: 7%;">
    <div slot="default" style="text-align: left;">LINE 2 Left</div>
    <div slot="default" style="text-align: left;">LINE 2 Right</div>
  </div>
  <div class="row" slot="default" style="margin-top: 7%;">
    <div slot="default">LINE 3 Left</div>
    <div slot="default">LINE 3 Right</div>
  </div>
</div>

What you see is that each Label is actually its own <div> and one that is sized just to the text. So, adjusting the alignment of the text in the Label element has no significant impact. What you are looking to do is to adjust the the position of the label elements within the f7-row. The f7 rows, cols, and blocks all use flexbox for determining the alignment of the child elements:

Thanks,
I read, but not clear for me.
I modified code for my better understanding :

uid: test
tags: []
props:
  parameters:
    - context: item
      description: test
      label: test
      name: TC_auto_on_off
      required: true
      type: TEXT
    - context: item
      description: Switch
      label: Switch
      name: TC_on_off
      required: true
      type: TEXT
  parameterGroups: []
timestamp: May 29, 2023, 10:17:50 PM
component: f7-card
config:
  style:
    background-color: "=props.bgcolor ? props.bgcolor : ''"
    border-radius: var(--f7-card-expandable-border-radius)
    box-shadow: 5px 5px 10px 1px rgba(0,0,0,0.1)
    margin-left: 5px
    margin-right: 5px
    noShadow: false
    padding: 0px
slots:
  content:
    - component: f7-block
      config:
        style:
          --f7-theme-color: var(--f7-text-color)
          margin: 0
          padding: 0
      slots:
        default:
          - component: f7-row
            config: {}
            slots:
              default:
                - component: f7-col
                  config:
                  slots:
                    default:
                      - component: Label
                        config:
                          style:
                            text-align: left
                          text: LINE1
                - component: f7-col
                  config:
                  slots:
                    default:
                      - component: Label
                        config:
                          style:
                            text-align: right
                          text: LINE 2 Left
                      - component: Label
                        config:
                          style:
                            text-align: left
                          text: LINE 2 Right


result of this code is :

so now I can adjust aligment, but must be so complicated ?
Is my actual definition like this ? :

I’m most of the time also struggling with the layout, it’s just a bit difficult and abstract way of designing. What I do when i’m lost is using a different (just Red, Blue, Green etc.) background color per row and col. I mostly makes it a lot clearer what happens when you change certain values.

Yes and no. HTML and CSS are the tools that produce the nearly infinite variation of webpages that you can find across the whole internet. Any tool that provides that much control must, by definition, be exceedingly complex because of the number of different choices you have to be able to specify. A low-code system such as the custom widgets in OH remove complexity by removing many of the choices that you can specify directly. For each choice you want to have back, you must add some of that complexity back in.

Close, but you’re actually missing one level of structure. If you look back at the html in my first post, you’ll see that the “block” is just a div element with the block class added to it and the “row” just a <div> with the row class. “Columns” are similarly just div elements with the col class added. Your image represents each of those <div> elements of the tree. However,

and this means that in the left “col” there is an additional <div> element that contains the text “LINE 1” and in the right “col” there are two more <div> elements that contain the text “LINE 2 Left” and “LINE 2 Right” respectively.

This is important because the way CSS works is that every style that is applied must be applied to some element, so you need to have every single thing that is going to be styled differently (font, color, position, animation, etc.) inside a container. In this case you want “LINE 2 Left” and “LINE 2 Right” to be positioned differently, so they must be inside their own containers (elements). That element doesn’t have to be a <div> element, but that’s the way OH has defined the Label component so that’s what you get. You want the container (in this case the column <div>) that holds those two labels to be positioned differently (on the right) than the column that holds the other Label (on the left) so each of those columns are their own <div> element. This pattern of thinking goes all the way back up the HTML tree to the root element of the page. If you look at the full html of even a fairly simple webpage these days you see a bewildering array of elements in that page. Each one of those elements (assuming that the page is well constructed) is there because there is at least one specific style that distinguishes it from any other combination of elements on that page.

In your previous code, you couldn’t see any difference when trying to justify the text of the labels to the left or the right, so the standard assumption is that the style is not actually being applied. What I tried to indicate in my previous post is that this assumption is not correct. The style was being applied, you just couldn’t see any difference because the <div> element that contained the label text was exactly the same width as the text itself. This means that the text was already touching both the left and right sides of it’s container and therefore left- and right- justification placed the text in the exact same location on the rendered page. Those <div> elements were sized to their text, in part, because they were inside a <div> element withe the row class which because of the way it spaces its child elements constrains their width by default.

When you then moved those child <div> elements inside a col class <div>, the width constraints are different and the <div> elements holding the label text are now as wide as the column itself. Because these elements are now wider than the text they contain, you can see the different effects of the left- and right- justification.

What this boils down to in the end is this: there are really two different ways to determine where some text will appear on the screen. You can have that text inside a big element and try to move that text by defining how the element places it’s own text or you can place that text inside a small element and define how that element is placed on the page. When first approaching webdsign, it is natural for us to choose the first option. After all we’re all used to using wysiwyg text editors and it that what you appear to do with those (it’s not actually, but it’s what it looks like to the user). In the long run, you will be much better off if you shift your point of view to the second option because that is the philoshophy that HTML and CSS are really designed around and therefore it will eventually be easier and give better results when you get used to it.

Here’s an example of what I mean. If I want three labels spaced evenly, the f7-row already does that for me automatically. So I just need the elements with no extra styling at all:

    - component: f7-block
      config:
        style:
          --f7-theme-color: var(--f7-text-color)
          margin: 0
          padding: 0
      slots:
        default:
          - component: f7-row
            config: {}
            slots:
              default:
                - component: Label
                  config:
                    text: Left
                - component: Label
                  config:
                    text: Center
                - component: Label
                  config:
                    text: Right

image

But what if I want the first to elements next to each other? Well, I could try to make the middle element so big that is stretches across the entire space in the middle and then move it’s text all the way to the left, but then I have to know how big to make that element which depends on the size of the row and the length of the text in the other labels…etc. It’s gets very messy very quickly. On the other hand, I can just tell the html that I want the first two labels to be on one side and the third to be on the other by just adding an addition level of html around those two elements:

    - component: f7-block
      config:
        style:
          --f7-theme-color: var(--f7-text-color)
          margin: 0
          padding: 0
      slots:
        default:
          - component: f7-row
            config: {}
            slots:
              default:
                - component: f7-row
                  config: {}
                  slots:
                    default:
                    - component: Label
                      config:
                        text: Left1
                    - component: Label
                      config:
                        text: Left 2
                - component: Label
                  config:
                    text: Right

image
But that doesn’t look quite right, because now the row element that contains the two left labels is squishing them together. Well, I could try and change the position of the “Left2” text by making it’s container bigger and then then moving the text around, or I could just use one style directive to tell the row to leave a gap between it’s child elements:

    - component: f7-block
      config:
        style:
          --f7-theme-color: var(--f7-text-color)
          margin: 0
          padding: 0
      slots:
        default:
          - component: f7-row
            config: {}
            slots:
              default:
                - component: f7-row
                  config:
                    style:
                      gap: 10px <------ Flexbox based style - see the flexbox link I provided in the previous comment
                  slots:
                    default:
                    - component: Label
                      config:
                        text: Left1
                    - component: Label
                      config:
                        text: Left 2
                - component: Label
                  config:
                    text: Right

image

That’s a great way to start to see the structure of the page and how to manipulate it to what you want. I sometimes add borders around each of my elements for the same reason. But you can also get a visualization of this information from the developers tool in most browsers. In chrome, if you click on the image button at the top of the dev tools panel you can hover over each elements in the windows and its boundaries, and padding will be highlighted.

2 Likes

Thank you very much for your reply and explanation. Now a lot of my questions is clarified.