Widget cards aspect ratio

I want ask regarding size of my widget cards
Actually I can see, that on the screen I have 3 cards ( width of each is 33% of the screen), but height isn’t the same:

Height of each is also randomly changing if side panel is on or off.

So question is, if it’s possible set (or fix) aspect ration of the cards, to have stable size for all.

Thanks

You can set the height of the card using the height style.

You can also explicitly set the aspect ratio of a card using the aspect-ratio style. Just be aware that Safari was the last to really implement this, so if you have older iOS devices they may not respect that setting, but any up to date iOS should be fine.

OK, If I will use height: 370px, widget height will stay fixed - doesn’t make sense which resolution has a display.
Much better looks aspect-ration : 1.8. Only small problem is, that white space is inserted (to keep ratio) always down of the card. So widget isn’t centered on the card.

If you want to center the card’s content, the easiest method is probably to change the card to a flexbox and set the alignment that way by adding:

    display: flex
    align-items: center
    justify-content: center

to the card style.

So I added into card style this :

    display: flex
    align-items: center
    justify-content: center
    aspect-ratio: 1.7

now it’s ok.
thanks

let me ask one more question.
I’m using weather widget :

uid: Weather_Card
tags: []
props:
  parameters:
    - description: <b>Optional prefix</b> for item names
      label: Item prefix
      name: itemPrefix
      required: false
      type: TEXT
      groupName: general
    - description: <b>Additional prefix</b> for item names that belongs to another Things channel (valid for 'StationName' as it might differ)
      label: Additional item prefix
      name: itemPrefix2
      required: false
      type: TEXT
      groupName: general
    - description: The number of hours you want to forecast (<u>default:</u> <b>12</b>)
      label: Number of hours to forecast
      name: forecastHours
      required: false
      type: TEXT
      groupName: general
    - description: The number of days you want to forecast (<u>default:</u> <b>3</b>)
      label: Number of days to forecast
      name: forecastDays
      required: false
      type: TEXT
      groupName: general
    - description: Set a background-image which will be shown during the day (if empty it will fall back to the linear-gradient)
      label: Background image-url (day-cycle)
      name: backgroundUrlDay
      required: false
      type: TEXT
      groupName: lookandfeel
    - description: Set a background-image which will be shown during the night (if empty it will fall back to the linear-gradient)
      label: Background image-url (night-cycle)
      name: backgroundUrlNight
      required: false
      type: TEXT
      groupName: lookandfeel
    - description: Activate day & night Indication on hourly forecast (background color & sunrise / sunset indicator icon)
      label: Show sunrise & sunset
      name: sunIndicator
      required: false
      type: BOOLEAN
      groupName: lookandfeel
    - description: Overwrite the global font-color as rgb (<u>default:</u> <b>255,255,255<b>)
      label: Font color (rgb)
      name: fontColor
      required: false
      type: TEXT
      groupName: lookandfeel
    - description: Overwrite the global text shadow color as rgb (<u>default:</u> <b>0,0,0<b>)
      label: Text shadow color(rgb)
      name: textShadowColor
      required: false
      type: TEXT
      groupName: lookandfeel
    - label: Daytime background indication color
      name: sunIndicatorColorDay
      required: false
      type: TEXT
      groupName: lookandfeel
      advanced: true
    - label: Nighttime background indication color
      name: sunIndicatorColorNight
      required: false
      type: TEXT
      groupName: lookandfeel
      advanced: true
    - description: Overwrite the station location name
      label: Location title
      name: locationTitle
      required: false
      type: TEXT
      groupName: localization
    - description: Format of the timestamp below the location-name (<u>default:</u> <b>DD. MMMM YYYY</b>)<br>Visit <a 'https://day.js.org/docs/en/display/format'>https://day.js.org/docs/en/display/format</a> for more informations.
      label: Timestamp format
      name: dateScheme
      required: false
      type: TEXT
      groupName: localization
    - description: Acitvate 24-hour time-format (<u>default:</u> <b>12-hour clock-format</b>)
      label: 24h hour-format
      name: dateFormat
      required: false
      type: BOOLEAN
      groupName: localization
    - description: Add suffix to the hourly-forecast timestamp
      label: Custom hour suffix
      name: timestampSuffix
      required: false
      type: TEXT
      groupName: localization
    - label: Translation 'Feel'
      name: wordingFeel
      required: false
      type: TEXT
      groupName: localization
    - label: Translation 'Hourly'
      name: wordingForecastHours
      required: false
      type: TEXT
      groupName: localization
    - label: Translation 'Daily'
      name: wordingForecastDays
      required: false
      type: TEXT
      groupName: localization
    - label: Translation '%-Precipitation'
      name: wordingForecastPrecib
      required: false
      type: TEXT
      groupName: localization
    - label: Translation 'Now'
      name: wordingNow
      required: false
      type: TEXT
      groupName: localization
    - label: Translation 'Today'
      name: wordingToday
      required: false
      type: TEXT
      groupName: localization
    - label: Translation 'Sunrise at'
      name: wordingSunrise
      required: false
      type: TEXT
      groupName: localization
    - label: Translation 'Sunset at'
      name: wordingSunset
      required: false
      type: TEXT
      groupName: localization
  parameterGroups:
    - name: general
      label: General settings
    - name: lookandfeel
      label: Look & Feel
      description: Everything that influences the look & feel of the widget
    - name: localization
      label: Localization settings
      description: Set alternative wordings & date pattern
timestamp: May 10, 2024, 8:21:32 PM
component: f7-card
config:
  style:
    aspect-ratio: 1.7
    --weather-card-text-color: rgba(var(--weather-card-color),1)
    --weather-font-size-date: =(device.desktop)?('0.8vw'):('3vw')
    --weather-font-size-descr: =(device.desktop)?('1.1vw'):('4vw')
    --weather-font-size-feel: =(device.desktop)?('1.0vw'):('3vw')
    --weather-font-size-hum-wind: =(device.desktop)?('0.8vw'):('3vw')
    --weather-font-size-icon: =(device.desktop)?('3vw'):('12vw')
    --weather-font-size-slider-text: =(device.desktop)?('0.8vw'):('2.5vw')
    --weather-font-size-slider-text-temp-max-min-pr: =(device.desktop)?('0.9vw'):('3vw')
    --weather-font-size-temper: =(device.desktop)?('2.5vw'):('8vw')
    --weather-font-size-title: =(device.desktop)?('1.3vw'):('4vw')
    --weather-icon-size-slider: =(device.desktop)?('1.5vw'):('7vw')
    --weather-text-transform-time: uppercase
    border-radius: var(--f7-card-expandable-border-radius)
    box-shadow: 5px 5px 10px 1px rgba(0,0,0,0.3)
    color: var(--weather-card-text-color)
    margin-left: 5px
    margin-right: 5px
    noShadow: false
    padding: 0px
slots:
  content:
    - component: f7-block
      config:
        style:
          background: "=dayjs().format() >= items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'ForecastToday_Sunrise'].state && dayjs().format() < items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'ForecastToday_Sunset'].state ? 'no-repeat 100% / cover url(' + props.backgroundUrlDay + ')' : 'no-repeat 100% / cover url(' + props.backgroundUrlNight + ')'"
          margin: 0
          padding: 0
      slots:
        default:
          - component: f7-row
            slots:
              default:
                - component: f7-col
                  config:
                    class:
                      - text-align-center
                    style:
                      width: 40%
                  slots:
                    default:
                      - component: Label
                        config:
                          style:
                            font-size: var(--weather-font-size-title)
                            font-weight: 600
                            letter-spacing: .75px
                            overflow: hidden
                            text-overflow: ellipsis
                            white-space: nowrap
                          text: "=!props.locationTitle ? items[(!props.itemPrefix2 ? (!props.itemPrefix ? '' : props.itemPrefix) : props.itemPrefix2) + 'StationName'].state : props.locationTitle"
                      - component: f7-icon
                        config:
                          f7: "=(items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Current_IconId'].state === '01d') ? 'sun_max_fill' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Current_IconId'].state === '01n') ? 'moon_stars_fill' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Current_IconId'].state === '02d') ? 'cloud_sun_fill' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Current_IconId'].state === '02n') ? 'cloud_moon_fill' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Current_IconId'].state === '03d') ? 'cloud_fill' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Current_IconId'].state === '03n') ? 'cloud_fill' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Current_IconId'].state === '04d') ? 'cloud_fill' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Current_IconId'].state === '04n') ? 'cloud_fill' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Current_IconId'].state === '09d') ? 'cloud_heavyrain_fill' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Current_IconId'].state === '09n') ? 'cloud_heavyrain_fill' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Current_IconId'].state === '10d') ? 'cloud_sun_rain_fill' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Current_IconId'].state === '10n') ? 'cloud_moon_rain_fill' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Current_IconId'].state === '11d') ? 'cloud_sun_bolt_fill' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Current_IconId'].state === '11n') ? 'cloud_moon_bolt_fill' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Current_IconId'].state === '13d') ? 'cloud_snow_fill' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Current_IconId'].state === '13n') ? 'cloud_snow_fill' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Current_IconId'].state === '50d') ? 'cloud_fog_fill' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Current_IconId'].state === '50n') ? 'cloud_fog_fill' : '?'"
                          style:
                            font-size: var(--weather-font-size-icon)
                      - component: Label
                        config:
                          style:
                            font-size: var(--weather-font-size-descr)
                            overflow: hidden
                            text-overflow: ellipsis
                            white-space: nowrap
                          text: "=items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Current_Weather_Condition'].state"
                - component: f7-col
                  config:
                    style:
                      width: 20%
                - component: f7-col
                  config:
                    style:
                      align-self: center
                      width: 40%
                  slots:
                    default:
                      - component: Label
                        config:
                          style:
                            font-size: var(--weather-font-size-temper)
                            font-weight: 600
                            line-height: var(--weather-font-size-temper)
                            overflow: hidden
                            text-align: center
                            text-overflow: ellipsis
                            white-space: nowrap
                          text: "=Math.round(items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Current_Temperature'].state.split(' ')[0] * 10) / 10 + '°'"
                      - component: Label
                        config:
                          style:
                            font-size: var(--weather-font-size-feel)
                            overflow: hidden
                            text-align: center
                            text-overflow: ellipsis
                            white-space: nowrap
                          text: "=((!props.wordingFeel) ? 'Feel: ' : props.wordingFeel + ': ') + Math.round(items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Current_Apparent_Temperature'].state.split(' ')[0]) + '°'"
                      - component: f7-row
                        config:
                          style:
                            font-size: var(--weather-font-size-hum-wind)
                        slots:
                          default:
                            - component: f7-col
                              config:
                                style:
                                  width: 38%
                              slots:
                                default:
                                  - component: Label
                                    config:
                                      style:
                                        overflow: hidden
                                        text-align: right
                                        text-overflow: ellipsis
                                        white-space: nowrap
                                      text: "=Math.round(items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Current_Humidity'].state.split('.')[1]) + ' %'"
                                      tooltip: Humidity
                            - component: f7-col
                              config:
                                style:
                                  width: 10%
                              slots:
                                default:
                                  - component: Label
                                    config:
                                      style:
                                        color: rgba(var(--weather-card-color),.25)
                                        text-align: center
                                      text: =" | "
                            - component: f7-col
                              config:
                                style:
                                  width: 52%
                              slots:
                                default:
                                  - component: Label
                                    config:
                                      style:
                                        overflow: hidden
                                        text-align: left
                                        text-overflow: ellipsis
                                        white-space: nowrap
                                      text: "=Math.round(items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Current_Windspeed'].state.split(' ')[0]) + ' ' + items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Current_Windspeed'].state.split(' ')[1]"
                                      tooltip: Windspeed
    - component: f7-block
      config:
        class:
          - no-padding
          - no-margin
          - align-items-space-between
      slots:
        default:
          - component: f7-segmented
            config:
              strong: true
              style:
                --f7-button-active-text-color: rgba(var(--weather-card-color),1)
                --f7-button-border-radius: 0
                --f7-button-raised-box-shadow: none
                --f7-button-text-color: rgba(var(--weather-card-color),.5)
                --f7-segmented-strong-button-active-bg-color: transparent
                --f7-segmented-strong-button-active-box-shadow: 0px 4px 0 -1px rgba(var(--weather-card-color),1)
                --f7-segmented-strong-button-active-text-color: rgba(var(--weather-card-color),1)
                --f7-segmented-strong-padding: 3px
                --f7-segmented-strong-text-color: rgba(var(--weather-card-color),.5)
                align-items: flex-end
                background: transparent
                padding-top: 2%
                width: =calc(100% - 38px)
              textColor: white
            slots:
              default:
                - component: oh-button
                  config:
                    action: variable
                    actionVariable: tab
                    actionVariableValue: hourly_forecast
                    active: =vars.tab === 'hourly_forecast'
                    color: var(--weather-card-text-color)
                    style:
                      --f7-button-font-size: =(device.desktop)?('0.8vw'):('2.5vw')
                      height: =(device.desktop)?('1.8vw'):('7vw')
                    text: "=(!props.wordingForecastHours) ? 'Hourly' : props.wordingForecastHours"
                - component: oh-button
                  config:
                    action: variable
                    actionVariable: tab
                    actionVariableValue: daily_forecast
                    active: =vars.tab === 'daily_forecast'
                    color: var(--weather-card-text-color)
                    style:
                      --f7-button-font-size: =(device.desktop)?('0.8vw'):('2.5vw')
                      height: =(device.desktop)?('1.8vw'):('7vw')
                    text: "=(!props.wordingForecastDays) ? 'Daily' : props.wordingForecastDays"
                - component: oh-button
                  config:
                    action: variable
                    actionVariable: tab
                    actionVariableValue: precip_forecast
                    active: =vars.tab === 'precip_forecast'
                    color: var(--weather-card-text-color)
                    style:
                      --f7-button-font-size: =(device.desktop)?('0.8vw'):('2.5vw')
                      height: =(device.desktop)?('1.8vw'):('7vw')
                    text: "=(!props.wordingForecastPrecib) ? '%-Precipitation' : props.wordingForecastPrecib"
          - component: f7-block
            config: {}
          - component: f7-swiper
            config:
              navigation: true
              params:
                breakpoints:
                  "0":
                    slidesPerView: 1
                  "240":
                    slidesPerView: 2
                  "320":
                    slidesPerView: 4
                  "480":
                    slidesPerView: 5
                  "640":
                    slidesPerView: 5
                grabCursor: true
                initalSlide: 0
                keyboard: true
                mousewheel: true
                observeSlideChildren: true
                observer: true
                runCallbacksOnInit: true
                spaceBetween: 0
                updateOnWindowResize: true
                watchOverflow: true
              style:
                width: 100%
                --swiper-navigation-color: var(--weather-card-text-color)
                --swiper-navigation-size: 30px
              visible: =vars.tab === 'hourly_forecast' || !vars.tab
            slots:
              default:
                - component: oh-repeater
                  config:
                    for: hour
                    fragment: true
                    rangeStart: 0
                    rangeStop: "=(!props.forecastHours) ? 12 : Number(props.forecastHours)"
                    sourceType: range
                  slots:
                    default:
                      - component: f7-swiper-slide
                        config:
                          expandable: true
                          style:
                            background: "=(props.sunIndicator) ? ((dayjs().add(loop.hour,'hour').format() >= items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Forecast' + (dayjs().add(loop.hour,'hour').startOf('day').format() === dayjs().startOf('day').format() ? 'Today' : (dayjs().add(loop.hour,'hour').startOf('day').format() === dayjs().startOf('day').add(1,'day').format() ? 'Tomorrow' : 'Day2')) + '_Sunrise'].state && dayjs().add(loop.hour,'hour').format() <= items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Forecast' + (dayjs().add(loop.hour,'hour').startOf('day').format() === dayjs().startOf('day').format() ? 'Today' : (dayjs().add(loop.hour,'hour').startOf('day').format() === dayjs().startOf('day').add(1,'day').format() ? 'Tomorrow' : 'Day2')) + '_Sunset'].state) ? (!props.sunIndicatorColorDay ? 'rgba(255,255,255,.2)' : props.sunIndicatorColorDay) : (!props.sunIndicatorColorNight ? 'rgba(41,109,152,.2)' : props.sunIndicatorColorNight)) : 'none'"
                            border-radius: 5px
                        slots:
                          default:
                            - component: f7-icon
                              config:
                                f7: sun_max_fill
                                size: 17px
                                style:
                                  color: var(--weather-card-text-color)
                                  cursor: pointer
                                  position: absolute
                                  right: 3px
                                  top: 3px
                                  z-index: 998
                                tooltip: "=((!props.wordingSunrise) ? 'Sunrise at ' : props.wordingSunrise + ' ') + ((!props.dateFormat) ? dayjs(items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Forecast' + (dayjs().add(loop.hour,'hour').startOf('day').format() === dayjs().startOf('day').format() ? 'Today' : (dayjs().add(loop.hour,'hour').startOf('day').format() === dayjs().startOf('day').add(1,'day').format() ? 'Tomorrow' : 'Day2')) + '_Sunrise'].state).format('h:mm A') : dayjs(items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Forecast' + (dayjs().add(loop.hour,'hour').startOf('day').format() === dayjs().startOf('day').format() ? 'Today' : (dayjs().add(loop.hour,'hour').startOf('day').format() === dayjs().startOf('day').add(1,'day').format() ? 'Tomorrow' : 'Day2')) + '_Sunrise'].state).format('H:mm') + (!props.timestampSuffix ? '' : ' ' + props.timestampSuffix) ) + '<br><b>' + dayjs(items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Forecast' + (dayjs().add(loop.hour,'hour').startOf('day').format() === dayjs().startOf('day').format() ? 'Today' : (dayjs().add(loop.hour,'hour').startOf('day').format() === dayjs().startOf('day').add(1,'day').format() ? 'Tomorrow' : 'Day2')) + '_Sunrise'].state).fromNow() + '</b>'"
                                visible: "=(dayjs().add(loop.hour,'hour').startOf('hour').format() === dayjs(items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Forecast' + (dayjs().add(loop.hour,'hour').startOf('day').format() === dayjs().startOf('day').format() ? 'Today' : (dayjs().add(loop.hour,'hour').startOf('day').format() === dayjs().startOf('day').add(1,'day').format() ? 'Tomorrow' : 'Day2')) + '_Sunrise'].state).startOf('hour').format() && props.sunIndicator === true)"
                            - component: f7-icon
                              config:
                                f7: moon_fill
                                size: 17px
                                style:
                                  color: var(--weather-card-text-color)
                                  cursor: pointer
                                  position: absolute
                                  right: 3px
                                  top: 3px
                                  z-index: 998
                                tooltip: "=((!props.wordingSunset) ? 'Sunset at ' : props.wordingSunset + ' ') + ((!props.dateFormat) ? dayjs(items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Forecast' + (dayjs().add(loop.hour,'hour').startOf('day').format() === dayjs().startOf('day').format() ? 'Today' : (dayjs().add(loop.hour,'hour').startOf('day').format() === dayjs().startOf('day').add(1,'day').format() ? 'Tomorrow' : 'Day2')) + '_Sunset'].state).format('h:mm A') : dayjs(items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Forecast' + (dayjs().add(loop.hour,'hour').startOf('day').format() === dayjs().startOf('day').format() ? 'Today' : (dayjs().add(loop.hour,'hour').startOf('day').format() === dayjs().startOf('day').add(1,'day').format() ? 'Tomorrow' : 'Day2')) + '_Sunset'].state).format('H:mm') + (!props.timestampSuffix ? '' : ' ' + props.timestampSuffix) ) + '<br><b>' + dayjs(items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Forecast' + (dayjs().add(loop.hour,'hour').startOf('day').format() === dayjs().startOf('day').format() ? 'Today' : (dayjs().add(loop.hour,'hour').startOf('day').format() === dayjs().startOf('day').add(1,'day').format() ? 'Tomorrow' : 'Day2')) + '_Sunset'].state).fromNow() + '</b>'"
                                visible: "=(dayjs().add(loop.hour,'hour').startOf('hour').format() === dayjs(items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Forecast' + (dayjs().add(loop.hour,'hour').startOf('day').format() === dayjs().startOf('day').format() ? 'Today' : (dayjs().add(loop.hour,'hour').startOf('day').format() === dayjs().startOf('day').add(1,'day').format() ? 'Tomorrow' : 'Day2')) + '_Sunset'].state).startOf('hour').format() && props.sunIndicator === true)"
                            - component: f7-row
                              config:
                                class:
                                  - justify-content-center
                              slots:
                                default:
                                  - component: Label
                                    config:
                                      style:
                                        color: var(--weather-card-text-color)
                                        font-size: var(--weather-font-size-slider-text)
                                        font-weight: 700
                                        text-transform: var(--weather-text-transform-time)
                                      text: "=(loop.hour === 0) ? ((!props.wordingNow) ? 'Now' : props.wordingNow) : ((!props.dateFormat) ? dayjs().add(loop.hour,'hour').startOf('hour').format('h A') : dayjs().add(loop.hour,'hour').startOf('hour').format('H')) + (!props.timestampSuffix ? '' : ' ' + props.timestampSuffix)"
                            - component: f7-col
                              config:
                                class:
                                  - text-align-center
                              slots:
                                default:
                                  - component: f7-icon
                                    config:
                                      f7: "=(items[((!props.itemPrefix) ? '' : props.itemPrefix) + ((loop.hour === 0) ? 'Current' : 'ForecastHours_' + ((loop.hour_idx < 10 ? '0'+(loop.hour_idx) : loop.hour_idx))) + '_IconId'].state === '01d') ? 'sun_max_fill' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + ((loop.hour === 0) ? 'Current' : 'ForecastHours_' + ((loop.hour_idx < 10 ? '0'+(loop.hour_idx) : loop.hour_idx))) + '_IconId'].state === '01n') ? 'moon_stars_fill' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + ((loop.hour === 0) ? 'Current' : 'ForecastHours_' + ((loop.hour_idx < 10 ? '0'+(loop.hour_idx) : loop.hour_idx))) + '_IconId'].state === '02d') ? 'cloud_sun_fill' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + ((loop.hour === 0) ? 'Current' : 'ForecastHours_' + ((loop.hour_idx < 10 ? '0'+(loop.hour_idx) : loop.hour_idx))) + '_IconId'].state === '02n') ? 'cloud_moon_fill' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + ((loop.hour === 0) ? 'Current' : 'ForecastHours_' + ((loop.hour_idx < 10 ? '0'+(loop.hour_idx) : loop.hour_idx))) + '_IconId'].state === '03d') ? 'cloud_fill' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + ((loop.hour === 0) ? 'Current' : 'ForecastHours_' + ((loop.hour_idx < 10 ? '0'+(loop.hour_idx) : loop.hour_idx))) + '_IconId'].state === '03n') ? 'cloud_fill' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + ((loop.hour === 0) ? 'Current' : 'ForecastHours_' + ((loop.hour_idx < 10 ? '0'+(loop.hour_idx) : loop.hour_idx))) + '_IconId'].state === '04d') ? 'cloud_fill' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + ((loop.hour === 0) ? 'Current' : 'ForecastHours_' + ((loop.hour_idx < 10 ? '0'+(loop.hour_idx) : loop.hour_idx))) + '_IconId'].state === '04n') ? 'cloud_fill' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + ((loop.hour === 0) ? 'Current' : 'ForecastHours_' + ((loop.hour_idx < 10 ? '0'+(loop.hour_idx) : loop.hour_idx))) + '_IconId'].state === '09d') ? 'cloud_heavyrain_fill' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + ((loop.hour === 0) ? 'Current' : 'ForecastHours_' + ((loop.hour_idx < 10 ? '0'+(loop.hour_idx) : loop.hour_idx))) + '_IconId'].state === '09n') ? 'cloud_heavyrain_fill' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + ((loop.hour === 0) ? 'Current' : 'ForecastHours_' + ((loop.hour_idx < 10 ? '0'+(loop.hour_idx) : loop.hour_idx))) + '_IconId'].state === '10d') ? 'cloud_sun_rain_fill' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + ((loop.hour === 0) ? 'Current' : 'ForecastHours_' + ((loop.hour_idx < 10 ? '0'+(loop.hour_idx) : loop.hour_idx))) + '_IconId'].state === '10n') ? 'cloud_moon_rain_fill' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + ((loop.hour === 0) ? 'Current' : 'ForecastHours_' + ((loop.hour_idx < 10 ? '0'+(loop.hour_idx) : loop.hour_idx))) + '_IconId'].state === '11d') ? 'cloud_sun_bolt_fill' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + ((loop.hour === 0) ? 'Current' : 'ForecastHours_' + ((loop.hour_idx < 10 ? '0'+(loop.hour_idx) : loop.hour_idx))) + '_IconId'].state === '11n') ? 'cloud_moon_bolt_fill' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + ((loop.hour === 0) ? 'Current' : 'ForecastHours_' + ((loop.hour_idx < 10 ? '0'+(loop.hour_idx) : loop.hour_idx))) + '_IconId'].state === '13d') ? 'cloud_snow_fill' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + ((loop.hour === 0) ? 'Current' : 'ForecastHours_' + ((loop.hour_idx < 10 ? '0'+(loop.hour_idx) : loop.hour_idx))) + '_IconId'].state === '13n') ? 'cloud_snow_fill' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + ((loop.hour === 0) ? 'Current' : 'ForecastHours_' + ((loop.hour_idx < 10 ? '0'+(loop.hour_idx) : loop.hour_idx))) + '_IconId'].state === '50d') ? 'cloud_fog_fill' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + ((loop.hour === 0) ? 'Current' : 'ForecastHours_' + ((loop.hour_idx < 10 ? '0'+(loop.hour_idx) : loop.hour_idx))) + '_IconId'].state === '50n') ? 'cloud_fog_fill' : '?'"
                                      size: var(--weather-icon-size-slider)
                                      style:
                                        color: var(--weather-card-text-color)
                                        padding-bottom: 0px
                                        padding-top: 0px
                                  - component: Label
                                    config:
                                      style:
                                        color: var(--weather-card-text-color)
                                        font-size: var(--weather-font-size-slider-text-temp-max-min-pr)
                                        font-weight: 400
                                      text: "=Math.round(items[((!props.itemPrefix) ? '' : props.itemPrefix) + ((loop.hour === 0) ? 'Current' : 'ForecastHours_' + ((loop.hour_idx < 10 ? '0'+(loop.hour_idx) : loop.hour_idx))) + '_Temperature'].state.split(' ')[0]) + '°'"
          - component: f7-swiper
            config:
              navigation: true
              params:
                breakpoints:
                  "0":
                    slidesPerView: 1
                  "210":
                    slidesPerView: "=(!props.forecastDays) ? 4 : ((props.forecastDays < 2) ? Math.round(Number(props.forecastDays) + 1) : 2)"
                  "480":
                    slidesPerView: "=(!props.forecastDays) ? 4 : ((props.forecastDays < 3) ? Math.round(Number(props.forecastDays) + 1) : 3)"
                  "640":
                    slidesPerView: "=(!props.forecastDays) ? 4 : ((props.forecastDays < 4) ? Math.round(Number(props.forecastDays) + 1) : 4)"
                grabCursor: true
                initalSlide: 0
                keyboard: true
                mousewheel: true
                observeSlideChildren: true
                observer: true
                spaceBetween: 0
                updateOnWindowResize: true
                watchOverflow: true
              style:
                --swiper-navigation-color: var(--weather-card-text-color)
                --swiper-navigation-size: 30px
              visible: =vars.tab === 'daily_forecast'
            slots:
              default:
                - component: oh-repeater
                  config:
                    for: day
                    fragment: true
                    rangeStart: 0
                    rangeStop: "=(!props.forecastDays) ? 3 : Number(props.forecastDays)"
                    sourceType: range
                  slots:
                    default:
                      - component: f7-swiper-slide
                        config:
                          class: text-align-center
                        slots:
                          default:
                            - component: f7-row
                              config:
                                class:
                                  - justify-content-center
                                  - align-items-center
                              slots:
                                default:
                                  - component: Label
                                    config:
                                      style:
                                        color: var(--weather-card-text-color)
                                        font-size: var(--weather-font-size-slider-text)
                                        font-weight: 700
                                        text-transform: var(--weather-text-transform-time)
                                      text: "=(loop.day === 0) ? ((!props.wordingToday) ? 'Today' : props.wordingToday) : dayjs().add(loop.day,'day').startOf('day').format('dddd')"
                            - component: f7-icon
                              config:
                                f7: "=(items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Forecast' + (((loop.day === 0) ? 'Today' : ((loop.day === 1) ? 'Tomorrow' : 'Day' + loop.day_idx))) + '_IconId'].state === '01d') ? 'sun_max_fill' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Forecast' + (((loop.day === 0) ? 'Today' : ((loop.day === 1) ? 'Tomorrow' : 'Day' + loop.day_idx))) + '_IconId'].state === '01n') ? 'moon_stars_fill' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Forecast' + (((loop.day === 0) ? 'Today' : ((loop.day === 1) ? 'Tomorrow' : 'Day' + loop.day_idx))) + '_IconId'].state === '02d') ? 'cloud_sun_fill' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Forecast' + (((loop.day === 0) ? 'Today' : ((loop.day === 1) ? 'Tomorrow' : 'Day' + loop.day_idx))) + '_IconId'].state === '02n') ? 'cloud_moon_fill' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Forecast' + (((loop.day === 0) ? 'Today' : ((loop.day === 1) ? 'Tomorrow' : 'Day' + loop.day_idx))) + '_IconId'].state === '03d') ? 'cloud_fill' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Forecast' + (((loop.day === 0) ? 'Today' : ((loop.day === 1) ? 'Tomorrow' : 'Day' + loop.day_idx))) + '_IconId'].state === '03n') ? 'cloud_fill' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Forecast' + (((loop.day === 0) ? 'Today' : ((loop.day === 1) ? 'Tomorrow' : 'Day' + loop.day_idx))) + '_IconId'].state === '04d') ? 'cloud_fill' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Forecast' + (((loop.day === 0) ? 'Today' : ((loop.day === 1) ? 'Tomorrow' : 'Day' + loop.day_idx))) + '_IconId'].state === '04n') ? 'cloud_fill' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Forecast' + (((loop.day === 0) ? 'Today' : ((loop.day === 1) ? 'Tomorrow' : 'Day' + loop.day_idx))) + '_IconId'].state === '09d') ? 'cloud_heavyrain_fill' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Forecast' + (((loop.day === 0) ? 'Today' : ((loop.day === 1) ? 'Tomorrow' : 'Day' + loop.day_idx))) + '_IconId'].state === '09n') ? 'cloud_heavyrain_fill' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Forecast' + (((loop.day === 0) ? 'Today' : ((loop.day === 1) ? 'Tomorrow' : 'Day' + loop.day_idx))) + '_IconId'].state === '10d') ? 'cloud_sun_rain_fill' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Forecast' + (((loop.day === 0) ? 'Today' : ((loop.day === 1) ? 'Tomorrow' : 'Day' + loop.day_idx))) + '_IconId'].state === '10n') ? 'cloud_moon_rain_fill' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Forecast' + (((loop.day === 0) ? 'Today' : ((loop.day === 1) ? 'Tomorrow' : 'Day' + loop.day_idx))) + '_IconId'].state === '11d') ? 'cloud_sun_bolt_fill' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Forecast' + (((loop.day === 0) ? 'Today' : ((loop.day === 1) ? 'Tomorrow' : 'Day' + loop.day_idx))) + '_IconId'].state === '11n') ? 'cloud_moon_bolt_fill' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Forecast' + (((loop.day === 0) ? 'Today' : ((loop.day === 1) ? 'Tomorrow' : 'Day' + loop.day_idx))) + '_IconId'].state === '13d') ? 'cloud_snow_fill' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Forecast' + (((loop.day === 0) ? 'Today' : ((loop.day === 1) ? 'Tomorrow' : 'Day' + loop.day_idx))) + '_IconId'].state === '13n') ? 'cloud_snow_fill' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Forecast' + (((loop.day === 0) ? 'Today' : ((loop.day === 1) ? 'Tomorrow' : 'Day' + loop.day_idx))) + '_IconId'].state === '50d') ? 'cloud_fog_fill' : (items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Forecast' + (((loop.day === 0) ? 'Today' : ((loop.day === 1) ? 'Tomorrow' : 'Day' + loop.day_idx))) + '_IconId'].state === '50n') ? 'cloud_fog_fill' : '?'"
                                size: var(--weather-icon-size-slider)
                                style:
                                  color: var(--weather-card-text-color)
                                  padding-bottom: 5px
                                  padding-top: 5px
                            - component: f7-row
                              config:
                                class:
                                  - justify-content-center
                              slots:
                                default:
                                  - component: Label
                                    config:
                                      style:
                                        color: var(--weather-card-text-color)
                                        font-size: var(--weather-font-size-slider-text-temp-max-min-pr)
                                        font-weight: 400
                                      text: "=Math.round(items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Forecast_' + ((loop.day === 0) ? 'Today' : ((loop.day === 1) ? 'Tomorrow' : 'Day' + (loop.day_idx))) + '_Maxtemperature'].state.split(' ')[0])+'°'"
                                  - component: Label
                                    config:
                                      style:
                                        color: var(--weather-card-text-color)
                                        font-size: var(--weather-font-size-slider-text-temp-max-min-pr)
                                      text: =" | "
                                  - component: Label
                                    config:
                                      style:
                                        color: var(--weather-card-text-color)
                                        font-size: var(--weather-font-size-slider-text-temp-max-min-pr)
                                        font-weight: 400
                                      text: "=Math.round(items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Forecast_' + ((loop.day === 0) ? 'Today' : ((loop.day === 1) ? 'Tomorrow' : 'Day' + (loop.day_idx))) + '_Mintemperature'].state.split(' ')[0])+'°'"
          - component: f7-swiper
            config:
              navigation: true
              params:
                breakpoints:
                  "0":
                    slidesPerView: 1
                  "240":
                    slidesPerView: 2
                  "320":
                    slidesPerView: 4
                  "480":
                    slidesPerView: 5
                  "640":
                    slidesPerView: 5
                grabCursor: true
                initalSlide: 0
                keyboard: true
                mousewheel: true
                observeSlideChildren: true
                observer: true
                runCallbacksOnInit: true
                spaceBetween: 0
                updateOnWindowResize: true
                watchOverflow: true
              style:
                --swiper-navigation-color: var(--weather-card-text-color)
                --swiper-navigation-size: 30px
              visible: =vars.tab === 'precip_forecast'
            slots:
              default:
                - component: oh-repeater
                  config:
                    for: hour
                    fragment: true
                    rangeStart: 0
                    rangeStop: "=(props.forecastHours === undefined) ? 12 : Number(props.forecastHours)"
                    sourceType: range
                  slots:
                    default:
                      - component: f7-swiper-slide
                        config:
                          expandable: true
                          id: =loop.hour_idx
                          style:
                            background: "=(props.sunIndicator) ? ((dayjs().add(loop.hour,'hour').format() >= items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Forecast' + (dayjs().add(loop.hour,'hour').startOf('day').format() === dayjs().startOf('day').format() ? 'Today' : (dayjs().add(loop.hour,'hour').startOf('day').format() === dayjs().startOf('day').add(1,'day').format() ? 'Tomorrow' : 'Day2')) + '_Sunrise'].state && dayjs().add(loop.hour,'hour').format() <= items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Forecast' + (dayjs().add(loop.hour,'hour').startOf('day').format() === dayjs().startOf('day').format() ? 'Today' : (dayjs().add(loop.hour,'hour').startOf('day').format() === dayjs().startOf('day').add(1,'day').format() ? 'Tomorrow' : 'Day2')) + '_Sunset'].state) ? (!props.sunIndicatorColorDay ? 'rgba(255,255,255,.2)' : props.sunIndicatorColorDay) : (!props.sunIndicatorColorNight ? 'rgba(41,109,152,.2)' : props.sunIndicatorColorNight)) : 'none'"
                            border-radius: 5px
                        slots:
                          default:
                            - component: f7-icon
                              config:
                                f7: sun_max_fill
                                size: 17px
                                style:
                                  color: var(--weather-card-text-color)
                                  cursor: pointer
                                  position: absolute
                                  right: 3px
                                  top: 3px
                                  z-index: 998
                                tooltip: "=((!props.wordingSunrise) ? 'Sunrise at ' : props.wordingSunrise + ' ') + ((!props.dateFormat) ? dayjs(items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Forecast' + (dayjs().add(loop.hour,'hour').startOf('day').format() === dayjs().startOf('day').format() ? 'Today' : (dayjs().add(loop.hour,'hour').startOf('day').format() === dayjs().startOf('day').add(1,'day').format() ? 'Tomorrow' : 'Day2')) + '_Sunrise'].state).format('h:mm A') : dayjs(items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Forecast' + (dayjs().add(loop.hour,'hour').startOf('day').format() === dayjs().startOf('day').format() ? 'Today' : (dayjs().add(loop.hour,'hour').startOf('day').format() === dayjs().startOf('day').add(1,'day').format() ? 'Tomorrow' : 'Day2')) + '_Sunrise'].state).format('H:mm') + (!props.timestampSuffix ? '' : ' ' + props.timestampSuffix) ) + '<br><b>' + dayjs(items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Forecast' + (dayjs().add(loop.hour,'hour').startOf('day').format() === dayjs().startOf('day').format() ? 'Today' : (dayjs().add(loop.hour,'hour').startOf('day').format() === dayjs().startOf('day').add(1,'day').format() ? 'Tomorrow' : 'Day2')) + '_Sunrise'].state).fromNow() + '</b>'"
                                visible: "=(dayjs().add(loop.hour,'hour').startOf('hour').format() === dayjs(items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Forecast' + (dayjs().add(loop.hour,'hour').startOf('day').format() === dayjs().startOf('day').format() ? 'Today' : (dayjs().add(loop.hour,'hour').startOf('day').format() === dayjs().startOf('day').add(1,'day').format() ? 'Tomorrow' : 'Day2')) + '_Sunrise'].state).startOf('hour').format() && props.sunIndicator === true)"
                            - component: f7-icon
                              config:
                                f7: moon_fill
                                size: 17px
                                style:
                                  color: var(--weather-card-text-color)
                                  cursor: pointer
                                  position: absolute
                                  right: 3px
                                  top: 3px
                                  z-index: 998
                                tooltip: "=((!props.wordingSunset) ? 'Sunset at ' : props.wordingSunset + ' ') + ((!props.dateFormat) ? dayjs(items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Forecast' + (dayjs().add(loop.hour,'hour').startOf('day').format() === dayjs().startOf('day').format() ? 'Today' : (dayjs().add(loop.hour,'hour').startOf('day').format() === dayjs().startOf('day').add(1,'day').format() ? 'Tomorrow' : 'Day2')) + '_Sunset'].state).format('h:mm A') : dayjs(items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Forecast' + (dayjs().add(loop.hour,'hour').startOf('day').format() === dayjs().startOf('day').format() ? 'Today' : (dayjs().add(loop.hour,'hour').startOf('day').format() === dayjs().startOf('day').add(1,'day').format() ? 'Tomorrow' : 'Day2')) + '_Sunset'].state).format('H:mm') + (!props.timestampSuffix ? '' : ' ' + props.timestampSuffix) ) + '<br><b>' + dayjs(items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Forecast' + (dayjs().add(loop.hour,'hour').startOf('day').format() === dayjs().startOf('day').format() ? 'Today' : (dayjs().add(loop.hour,'hour').startOf('day').format() === dayjs().startOf('day').add(1,'day').format() ? 'Tomorrow' : 'Day2')) + '_Sunset'].state).fromNow() + '</b>'"
                                visible: "=(dayjs().add(loop.hour,'hour').startOf('hour').format() === dayjs(items[((!props.itemPrefix) ? '' : props.itemPrefix) + 'Forecast' + (dayjs().add(loop.hour,'hour').startOf('day').format() === dayjs().startOf('day').format() ? 'Today' : (dayjs().add(loop.hour,'hour').startOf('day').format() === dayjs().startOf('day').add(1,'day').format() ? 'Tomorrow' : 'Day2')) + '_Sunset'].state).startOf('hour').format() && props.sunIndicator === true)"
                            - component: f7-row
                              config:
                                class:
                                  - justify-content-center
                                  - align-items-center
                              slots:
                                default:
                                  - component: Label
                                    config:
                                      style:
                                        color: var(--weather-card-text-color)
                                        font-size: var(--weather-font-size-slider-text)
                                        font-weight: 700
                                        text-transform: var(--weather-text-transform-time)
                                      text: "=(loop.hour === 0) ? ((!props.wordingNow) ? 'Now' : props.wordingNow) : ((!props.dateFormat) ? dayjs().add(loop.hour,'hour').startOf('hour').format('h A') : dayjs().add(loop.hour,'hour').startOf('hour').format('H')) + (!props.timestampSuffix ? '' : ' ' + props.timestampSuffix)"
                            - component: f7-col
                              config:
                                class:
                                  - justify-content-center
                                  - align-items-center
                                  - text-align-center
                              slots:
                                default:
                                  - component: f7-icon
                                    config:
                                      f7: umbrella_fill
                                      size: var(--weather-icon-size-slider)
                                      style:
                                        color: var(--weather-card-text-color)
                                        padding-bottom: 5px
                                        padding-top: 5px
                                  - component: Label
                                    config:
                                      style:
                                        color: var(--weather-card-text-color)
                                        font-size: var(--weather-font-size-slider-text-temp-max-min-pr)
                                        font-weight: 400
                                      text: "=Math.round(items[((!props.itemPrefix) ? '' : props.itemPrefix) + ((loop.hour === 0) ? 'Current_Rain' : 'ForecastHours' + ((loop.hour_idx < 10 ? '0'+(loop.hour_idx) : loop.hour_idx))) + '_Precipprobability'].state.split(' ')*100) + ((loop.hour === 0) ? ' min' : '%')"

into f7-card I inserted aspect-ratio: 1.7
but if I will add also :

    display: flex
    align-items: center
    justify-content: center

complete layout is lost
I think problem is s7-segmented and s7-swiper used ?
thanks
Alex

As the widgets become more complex, keeping track of all the parameters that can go into the flexbox calculations can be difficult.

In this case I believe the issue is entirely the swiper. The flex parameters that worked before don’t work here, because they impose no width constraint down the tree and so the swiper can grow to be as wide as it wants with no regard for the actual width of the containing elements.

The quickest fix here would be to use the following instead on the f7-card:

    display: flex
    flex-direction: column
    align-items: stretch
    justify-content: center

That would be the quickest and the easiest, but you may find that it’s not the best because it’s going to leave a bunch of space above and below the content.

If you want to also change the shape of the f7-blocks so that they fill the space better then you will get a better looking result but it will be a lot more work because you will have to change some of the styling for the internal elements as well.

f7-card modification

    display: flex
    flex-direction: column
    align-items: stretch
    justify-content: center

works quite good. White space above and below is quite ok, but I’m also interested about more difficult way, because maybe it will help me learn more…
Can you please explain this more difficukt way ?
Thank you

There’s no one more difficult way. There are dozens of options. My point was that this complex widget already has detailed styling for its basic layout. You are changing the fundamental style philosophy (forcing an aspect ratio rather than let the contents determine the shape of the container). There’s nothing wrong with that but, such a fundamental change to the base components is going to have consequences all the way down the tree, and if you want to make your new style comprehensive then you will likely also have to make changes to most of the components all the way down the tree.

Ok, I understand. I want do it step by step. But I’m not sure how to start with this change. Maybe first of all I need to understand how layout building is working and how aspect ration + display flex in the card style is working, because right now isn’t compatible with s7-swiper.

edit: What I have problem is understand layout philosophy. What is container (s7-card or s7-block or ??) and what is item in the container. Is it oh-label, oh-button or s7-row, s7-col etc… ?

There are lots of different ways to use css to arrange html elements so one of the hardest parts is often selecting the basic method that fits the job at hand the most closely. If you’re really interested in exploring more about the basics and building up your understanding, then I recommend taking a look at any one of the many CSS tutorials/introductions that can be found on the web. One example would be:

but there are hundreds of good free options to choose from.

The way swiper card is included in the weather widget, it is going to expand its width to fit as many slides as possibile until it reachers some maximum width defined by one of the elements above it. When you move the card over to a flexbox display it turns out that you are removing the that limit, so the swiper expands to its full width even though that is much larger than the width of the card. There’s no one way to fix this, there’s no best way to fix this. But learning how each element uses the sizes of its children and/or parents to determine its size is one parts of CSS that often takes people the longest to really get comfortable with.

One of the most general terms for each piece of an html page is element (you will also see node as an even more general term because that extends to many tag based markup languages). In a tree based structure such as html, each element is going to have one parent (unless it is the root node of the tree) and zero or more child nodes.

<parent>
  <element>
    <child1>
    <child2>

Container is often synonymous with parent but doesn’t have to be. If you are talking about some element, say a text paragraph (a <p> element) then container would be a less precise term that just refers to any element above that <p> in the tree that is controlling some of the styling of the <p> element.

<div> <- this div is acting as a container for the importantText p and the uselessText p
  <div> <- this div is a container only for the importantText p
    <p id="importantText">...</p>
  </div>
  <div> <- this div is a container only for the uselessText p
    <p id="uselessText">...</p>
  </div>
</div>