Travelplace / 0.21.0 – 26 aprile 2022

Organizzazione dei file

Il codice css di base (definizione colori, griglia, ecc.) è contenuto in tre file differenziati per i vari brand:

  • bluvacanze.[hash].css
  • going.[hash].css
  • bluwelfare.[hash].css

I file javascript e altri file css sono invece organizzati per pagina e sono condivisi tra i vari brand.

Nella documentazione e nei commenti dei file html la parte relativa al brand nei nomi dei file è a volte indicata genericamente con [*brand*] (es [*brand*]-home.incl.html)

La porzione [hash] dei nomi dei file indica una stringa generata dinamicamente che cambia in base alla versione del file allo scopo di evitare il caching del browser.

Nella pratica comunque non è necessario preoccuparsi di caricare i file js e css: è sufficiente includere gli snippet html specifici delle varie pagine così come indicato nei sorgenti delle pagine demo.

Ad esempio, visualizzando il codice della home page (https://travelplace-demo.bluvacanze.it/demo/home-bluvacanze.html), è sufficiente sostituire il blocco con l'include indicato nella seconda riga di commento, sostituendo la stringa [*brand*] con il brand desiderato (ad esempio per la home bluvacanze: https://cdn.bluvacanze.it/repository/includes/bluvacanze-home.incl.html)

  <!-- ******** SOSTITUIRE CON INCLUDE 'HOME' ******** -->
  <!-- (https://cdn.bluvacanze.it/repository/includes/[*brand*]-home.incl.html -->
  <link rel="preconnect" href="https://cdn.bluvacanze.it">
  <link rel="icon" href="https://cdn.bluvacanze.it/repository/favicons/bluvacanze/favicon.svg" type="image/svg+xml">
  <link rel="icon" href="https://cdn.bluvacanze.it/repository/favicons/bluvacanze/favicon.ico" sizes="any">
  <link rel="apple-touch-icon" href="https://cdn.bluvacanze.it/repository/favicons/bluvacanze/apple-touch-icon.png">
  <link rel="manifest" href="https://cdn.bluvacanze.it/repository/favicons/bluvacanze/manifest.webmanifest">
  <link rel="preload" href="https://cdn.bluvacanze.it/repository/js/icone.f4fa4c4218930b544639395a70ab7896.js" as="script" crossorigin>
  <link rel="preload" href="https://cdn.bluvacanze.it/repository/css/bluvacanze.ae5f5e2d47e6ebc436a7c8732b53ca4c.css" as="style" crossorigin>
  <link rel="preload" href="https://cdn.bluvacanze.it/repository/js/travelplace-home.min.accb5f9d5f16f81604765c3d4347e605.js" as="script" crossorigin>
  <script src="https://cdn.bluvacanze.it/repository/js/icone.f4fa4c4218930b544639395a70ab7896.js"></script>
  <link rel="preconnect" href="https://fonts.googleapis.com">
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
  <link rel="preload" href="https://fonts.googleapis.com/css2?family=Nunito:ital,wght@0,200..700;1,200..700&amp;display=swap" as="style" crossorigin>
  <link href="https://fonts.googleapis.com/css2?family=Nunito:ital,wght@0,200..700;1,200..700&amp;display=swap" rel="stylesheet" media="print" onload="this.media='all'">
  <link rel="stylesheet" href="https://cdn.bluvacanze.it/repository/css/bluvacanze.ae5f5e2d47e6ebc436a7c8732b53ca4c.css" type="text/css" media="all">
  <script async defer src="https://cdn.bluvacanze.it/repository/js/travelplace-home.min.accb5f9d5f16f81604765c3d4347e605.js"></script>
  <!-- /**************************************** -->

Eventuali file js o css contrassegnati come "SOLO PER DEMO" vanno ignorati in produzione:

<!-- ******** SOLO PER DEMO (non utilizzare in produzione) ******** -->
<link rel="stylesheet" ...>
<script src="..."></script>
<!-- /**************************************** -->

Oltre ai file js e css, l'include esegue i preload necessari, importa i font e le icone, imposta le favicons, ecc.

Tutti i file js e css le icone le favicons, ecc... vengono distribuiti tramite il cdn https://cdn.bluvacanze.it/repository.

NB: Gli snippet contenuti in questa pagina potrebbero non essere aggiornati con l'ultima release del codice: far sempre riferimento al codice html delle pagine demo per la versione definitiva.

Layout

Il layout è basato sulla griglia di Bootstrap 5 modificata in diversi punti.

Salvo pochi casi, le altri parti del framework non sono state utilizzate allo scopo di ridurre le dimensioni del css: se fosse necessario utilizzarle possono però essere incluse.

La griglia utilizzata è quella standard a 12 colonne, salvo che nel form di ricerca, dove è utilizzata anche una griglia a 16 colonne.

La griglia a 16 colonne viene attivata sostituendo alla classe row la classe bv-search-row.

La griglia a 16 colonne non ha tutte le opzioni della griglia standard (offset, row-cols, ecc..) ma solo le classi base col-1 ... col-16 e quelle legate ai breakpoints (col-md-*, col-lg-*, ...), ad eccezione del breakpoint sm.

Fa inoltre eccezione la classe row-cols-2 che, se utilizzata all'interno di un elemento bv-search-row, divide lo spazio in una o due parti in base al numero di elementi contenuti. È utilizzata nelle situazioni in cui, in base alla scelta dell'utente, uno dei due campi (ad esempio la data di arrivo nel caso di una ricerca.

Per semplificare la migrazione da Bootstrap 4, le classi utilità che nella versione 5 sono state rinominate con la logica start, end (https://getbootstrap.com/docs/5.1/migration/#rtl), sono state ripristinate alla forma precedente (ad esempio ml-2 o pr-1 invece di ms-2 o pe-1)

Headers e navigazione

Il markup di base dell'header comprensivo del menu di navigazione è il seguente:

<article class="bv-header">

  <!-- Immagine di sfondo -->
  <picture>
    <source srcset="[...]" media="[...]" type="image/webp">
    <source srcset="[...]" media="[...]">
    <!-- sources -->
    <img  src="[...]" srcset="[...] 2x" alt="alt text" fetchpriority="high">
  </picture>
  
  <div class="bv-header-inner overlay">

    <!-- info-bar -->
    <section class="bv-info-bar secondary-trasp">
      <div class="container-lg">
        [...info bar content...]
      </div>
    </section>
    <!-- /info-bar -->
    
    <!-- top-menu -->
    <header class="bv-header-menu">
      <!-- barra menu -->
      <div class="bv-top-menu-wrapper container">
        <div class="bv-header-menu-inner bv-menu-controls">
          <div class="bv-menu-trigger" role="button" aria-controls="extended-menu" aria-label="Menu">
            <span class="bv-menu-icon">
              <span></span>
            </span>
          </div>
          <a href="/" class="logo">
            <img src="https://cdn.bluvacanze.it/repository/media/bluvacanze.svg" alt="Logo Bluvacanze" class="bluvacanze">
          </a>
        </div>
        <div class="bv-header-menu-inner">
          <div role="button" aria-label="Accedi all'area riservata">
            <svg role="img" aria-hidden="true" class="icona mr-1">
              <use xlink:href="#icon-user"></use>
            </svg>
            <span class="d-none d-md-inline">Accedi</span>
          </div>
          <div role="button" aria-label="Carrello degli acquisti" class="cart-btn">
            <svg role="img" aria-hidden="true" class="icona">
              <use xlink:href="#icon-shopping-cart-simple"></use>
            </svg>
          </div>
        </div>
      </div>
      
      
      <!-- Menu esteso -->
      <div id="extended-menu" class="bv-extended-menu navigation-container"
        aria-label="Menu principale">
        <div class="container">
          <div class="row bv-m-accordion row-col-rules">
            
            <div class="col-lg-3 bv-accordion-item">
              <h2 id="ext-menu-1" class="bv-accordion-title">Speciali</h2>
              <div class="bv-accordion-content">
                <ul role="navigation" aria-labelledby="ext-menu-1">
                  <li>
                    <a href="__url__">Offerte della settimana</a>
                  </li>
                  <!-- altre voci menu -->
                </ul>
              </div>
            </div>

            <!-- altri blocchi `bv-accordion-item` -->

          </div>
        </div>
      </div>
    </header>
    
    
    <!-- contenuto header (tab ricerca o testo, ecc...) -->

  </div>
</article>
  • l'immagine varia in base alle dimensioni del viewport e va quindi inserita secondo le dimensioni indicate di seguito:
Breakpoint media query img width (px) img height (px) 2x
XXL (min-width: 1400px) 1920 602 No
XL (min-width: 1200px) and (max-width: 1399px) 1399 602 No
LG (min-width: 992px) and (max-width: 1199px) 1199 602 No
MD (min-width: 768px) and (max-width: 991px) 991 760
SM (min-width: 576px) and (max-width: 767px) 767 500
XS 575 900
  • L'elemento .bv-header-inner è posizionato sopra l'immagine e se l'immagine lo richiede, può avere una ulteriore classe overlay per aggiungere un div semitrasparante sopra l'immagine stessa.
  • Il logo può variare in base al sito di utilizzo, le opzioni possibili sono:
<!-- bluvacanze -->
<img src="https://cdn.bluvacanze.it/repository/media/bluvacanze.svg"  alt="Logo Bluvacanze" class="bluvacanze">

<!-- going -->
<img src="https://cdn.bluvacanze.it/repository/media/going4you.svg"  alt="Logo Going4You" class="going">

<!-- bluwelfare -->
<img src="https://cdn.bluvacanze.it/repository/media/bluwelfare.svg"  alt="Logo Bluvacanze" class="bluwelfare">
  • Il menu esteso può ovviamente variare e in base all'impaginazione desiderata è necessario intervenire sul markup interno:
    • Ogni blocco di voci del menu è indicato dalla classe bv-accordion-item
    • la suddivisione in colonne è ottenuta con le classi griglia standard di Bootstrap (ad esempio col-lg-3 per una suddiviosne in 4 colonne). La suddivisione in colonne va applicata solo per breakpoint da lg incluso in poi.

Home page - Sezioni orizzontali

Ogni porzione orizzontale della home page è un elemento bv-page-section che può contenere una serie di card o altri elementi.

Gli elementi bv-page-section hanno altezza prefissata ad eccezione di quelli con la classe aggiuntiva bv-page-section--auto che hanno altezza auto. In quest'ultimo caso, in presenza di immagini di sfondo, valutare l'altezza necessaria dell'immagine in base all dimensione finale della sezione.

Gli elementi possono avere sfondo trasparente, colorato o con immagine.

<!-- Sezione senza sfondo colorato o immagine -->
<article class="bv-page-section">
  [...]
</article>

<!-- Sezione con sfondo colorato -->
<article class="bv-page-section bg-sand">
  [...]
</article>

<!-- Sezione con immagine -->
<article class="bv-page-section text-white">
  
  <div class="bv-page-section--img">
    <picture>
      <source srcset="[...]" media="[...]" type="image/webp">
      <source srcset="[...]" media="[...]">
      <!-- ...sources... -->
      <img src="[...]" srcset="[...] 2x" alt="alt text" loading="lazy" decoding="async">
    </picture>
  </div>

  [...]

</article>

<!-- Il tag del contenitore può essere anche `section` o `aside` -->
<aside class="bv-page-section">
  [...]
</aside>

<!-- Dove necessario, il contenuto va inserito all'interno di un elemento `.container` -->
<article class="bv-page-section">
  <div class="container">
    [...]
  </div>
</article>

Lo sfondo colorato può essere ottenuto aggiungendo all'elemento bv-page-section una classe bg-* (le classi attualmente disponibili sono bg-sand, bg-azure e bg-dark-blue), mentre l'immagine viene inserita come elemento img (non come background css).

Devono essere presenti più versioni dell'immagine per i vari breakpoint, secondo le dimensioni riportate di seguito:

Breakpoint img width (px) img height (px) 2x
XXL 1920 550 No
XL 1399 550 No
LG 1199 550 No
MD 991 550
SM 767 550
XS 575 550

NB: Nel caso di sezione con immagine, all'elemento bv-page-section va aggiunta la classe text-white se l'immagine richiede un testo bianco.

NB: alle immagini di sfondo è applicato automaticamente un'overlay semitrasparente per ridurne la luminosità.

NB: le immagini di sfondo vanno caricate aggiungendo l'attributo loading="lazy"

Home Page - Cards

Cards wrapper

L'elemento .bv-card-wrapper (da inserire sempre dentro un elemento .bv-page-section) racchiude una serie di 2, 3 o 4 cards.

Il markup è il seguente:

<div class="bv-card-wrapper bv-cards-4">
  <div class="bv-card-scroll">
    <div class="bv-card-inner">
      [...cards...]
    </div>
  </div>
</div>

La classe .bv-cards-4 genera la griglia per il numero di card desiderato. I valori possibili sono 2, 3 e 4 (bv-cards-2, bv-cards-3, bv-cards-4).

Gli elementi .bv-card-wrapper vanno collocati all'interno di un elemento .page-section, mentre il titolo della sezione, dove necessario, va posizionato dentro un elemento .container:

<article class="bv-page-section">
  
  <div class="container">

    <div class="bv-card-main-title">
      <h2>Titolo sezione</h2>
      <a href="__url__">
        Vedi tutte
        <svg role="img" aria-hidden="true" class="icona">
          <use xlink:href="#icon-arrow-right"></use>
        </svg>
      </a>
    </div>

  </div>

  <div class="bv-card-wrapper bv-cards-4">
    <div class="bv-card-scroll">
      <div class="bv-card-inner">
        [...cards...]
      </div>
    </div>
  </div>

</article>

Contenitore cards con blocco di testo fisso

La presenza di testo fisso (non scorrevole) all'iterno di una riga card, richiede l'aggiunta della classe has-content al container e la presenza degli elementi .bv-card-content-wrapper e .bv-card-content. Quest'ultimo racchiude il contenuto personalizzato ed occupa circa la metà dello spazio disponibile.

Aggiungendo la classe .narrow-content a .bv-card-wrapper la larghezza viene ridotta.

La struttura delle card segue l'elemento .bv-card-content ed è identica a quella dello schema precedente.

Esempio con 4 cards:

<!-- se presente, la classe `narrow-content` riduce di circa la metà la larghezza del contenuto personalizzato -->
<div class="bv-card-wrapper bv-cards-4 has-content [narrow-content]"> 

  <div class="bv-card-content-wrapper">
    <div class="bv-card-content">
      [...contenuto...]
    </div>

    <div class="bv-card-scroll">
      <div class="bv-card-inner">
        [...cards...]
      </div>
    </div>

  </div>
</div>

Elementi card

Cards offerte:

<div class="bv-card">
  <a href="__url__" title="Vai a __titolo__">

    <picture>
      __img__
    </picture>

    <div class="bv-card--info">
      <div class="bv-card--info-tags">
        __tag_1__<br>
        ...
        __tag_n__
      </div>
      <div class="bv-card--info-prezzo">
        <div class="bv-card--info-durata">__durata__</div>
        <div class="bv-card--info-importo">
          <span class="bv-card--info-nota">da</span>
          __prezzo__
        </div>
        <div class="bv-card--info-nota">a persona</div>
      </div>
    </div>
    <div class="bv-card--loc">
      <svg role="img" aria-hidden="true" class="icona">
        <use
          xlink:href="#icon-map-pin"></use>
      </svg>
      Portofino
    </div>
    <div class="bv-card--title">__title__</div>
  </a>
</div>

Cards “categorie” (testo sopra la foto):

<div class="bv-card">
  <a href="__url__" title="Vai a __titolo__">

    <picture>
      __img__
    </picture>

    <div class="bv-card--category">
      <div class="bv-card--sommario">__sommario__</div>
      <div class="bv-card--title">__titolo__</div>
    </div>
  </a>
</div>

Dimensione delle immagini

Le dimensioni delle immagini delle card variano a secondo del numero di colonne. La seconda dimesnione nella colonna dell'altezza è riferita alle card di altezza ridotta

2 colonne

Breakpoint img width (px) img height (px) 2x
XXL 628 350 / 250 No
XL 538 350 / 250 No
LG 448 350 / 250 No
MD 350 350 / 250
XS-SM 300 350 / 250

3 colonne

Breakpoint img width (px) img height (px) 2x
XXL 408 350 / 250 No
XL 350 350 / 250 No
XS-LG 300 350 / 250

4 colonne

Breakpoint img width (px) img height (px) 2x
XS-XXL 300 350 / 250

Per tutte le combinazioni è necessario l'attributo loading="lazy".

Campi form standard

Markup standard Boostrap 5 con alcune modifiche

<!-- input text --> 
<div class="form-group">
  <label for="__id__" class="form-label">__label__</label>
  <input type="__text__" id="__id__" name="__name__" class="form-control">
</div>

<!-- input date / datetime --> 
<div class="form-group">
  <label for="__id__" class="form-label">__label__</label>
  <input type="date" id="__id__" name="__name__" class="form-control">
</div>

<div class="form-group">
  <label for="__id__" class="form-label">__label__</label>
  <input type="datetime-local" id="__id__" name="__name__" class="form-control">
</div>

<!-- select --> 
<div class="form-group form-group-select">
  <label for="__id__" class="form-label">__label__</label>
  <select id="__id__" name="__name__" class="form-select">
    <option value=""></option>
    <option value="__value__">__option__</option>
  </select>
</div>

<!-- checkbox --> 
<!-- in alcuni casi al tag label è aggiunta la classe `label-lg` --> 
<div class="form-check">
  <input class="form-check-input" type="checkbox" name="__name__" id="__id__" value="__value__">
  <label class="form-check-label label-lg" for="__id__">__label__</label>
</div>

<!-- radio --> 
<!-- aggiungere la classe `form-check-inline` per pulsanti radio inline --> 
<div class="form-check form-check-inline">
  <input class="form-check-input" type="radio" name="__name__"
    id="__id__" value="__value__">
  <label class="form-check-label" for="__id__">__label__</label>
</div>

Campi date e datetime correlati

È possibile correlare tra loro due campi date o datetime in modo c he siano reciprocamente vincolati e non sia possibile, ad esempio, inserire una data di arrivo precedente alla data di partenza.

Per attivare la funzionalità è necessario:

  • Aggiungere al campo della data iniziale l'attributo data-max il cui valore è l'id del secondo campo
  • Aggiungere al campo della data finale l'attributo data-min il cui valore è l'id del primo campo

Esempio:

<div class="form-group">
  <label for="data-1" class="form-label">Data partenza</label>
  <input type="date" id="data-1" name="__name__"
    class="form-control" data-max="data-2">
</div>
<div class="form-group">
  <label for="data-2" class="form-label">Data ritorno</label>
  <input type="date" id="data-2" name="__name__"
    class="form-control" data-min="data-1">
</div>

La correlazione viene ignorata se il secondo campo è disabilitato.

Widget viaggiatori

Mostra un pop-up per la selezione del numero di adulti, children o infant in base agli attributi data-* dell'elemento input[type="hidden"].bv-pax presenti all'interno di .pax-control:

<div class="pax-control">

  <div class="form-group">
    <label class="form-label">Viaggiatori</label>
    <div class="d-flex justify-content-between align-items-center">
      <span class="pax-summary">2</span>
    </div>
  </div>
  
  <input type="hidden" class="bv-pax" name="xxxxxx" data-xxxx="[...]" value="{...}">
  
</div>

Gli attributi data-* configurano il widget abilitando le varie opzioni e impostano eventuali vincoli:

  • data-max-rooms imposta il valore massimo di camere selezionabili. Se non presente, il valore è forzato su 1; se uguale a 0 o non valorizzato non vengono impostati limiti al numero di camere selezionabili
  • data-adt-max imposta l'eventuale valore massimo di adulti per ogni camera. Se non è presente o se uguale a 0 non vengono impostati limiti.
  • data-chd e data-inf attivano i controlli per bambini e infanti. Questi due attributi possono essere omessi se presente almeno uno tra data-***-max e data-***-age-range che impostano implicitamente i relativi controlli. In sostanza sono necessari solo nei casi in cui non volessero impostare limiti di età o di numero.
  • data-chd-max e data-inf-max impostano il numero massimo di bambini e infant per ogni camera, se non presenti o senza valore o se uguali a 0 non vengono impostati limiti.
  • data-chd-age-range e data-inf-age-range impostano il range di anni (chd) o mesi (inf) selezionabile per ogni viaggiatore aggiunto. Il valore è nella forma 'min-max' (es. '1-16', '0-12', ecc.). Se non presenti, non vengono impostati limiti

L'attributo name non viene utilizzato dal controllo e può essere impostato secondo le esigenze dell'applicazione.

Esempi:

Una camera, max 4 adulti, 3 bambini di età tra 1 e 16 anni e 1 infant tra 0 e 12 mesi:

<input type="hidden" class="bv-pax" 
  name="xxxxxx" 
  data-adt-max="4" 
  data-chd-max="3" 
  data-inf-max="1" 
  data-chd-age-range="1-16" 
  data-inf-age-range="0-12" 
  data-max-rooms="1" 
  value="[...]">

Una camera con adulti e bambini senza limiti di numero ed età:

<input type="hidden" class="bv-pax" 
  name="xxxxxx" 
  data-chd
  value="[...]">

Numero camere senza limitazioni, max 4 adulti per camera, 3 bambini di età tra 0 e 12 anni. Non viene mostrato il controllo infant:

<input type="hidden" class="bv-pax" 
  name="xxxxxx" 
  data-adt-max="4" 
  data-chd-max="3" 
  data-chd-age-range="0-12" 
  data-max-rooms="0" 
  value="[...]">

Valori restituiti

Il campo hidden viene valorizzato con un json corrispondente alle scelte dell'utente.

Il Json è un array contenente un oggetho per ogni camera definita (quindi almeno 1). In ogni oggetto-camera sono presenti le chiavi:

  • adt: numero di adulti
  • chd: array di età in anni dei bambini
  • inf: array di età in mesi anni degli infant

In base alle impostazioni, le chiavi chd e inf possono non essere presenti.

Esempi:

Una camera senza inf:

[
  {
    "adt": 2,        // due adulti
    "chd": [12, 8],  // due bambini di 12 e 8 anni
  }
]

Due camere con chd e inf:

[
  // camera 1
  {
    "adt": 2,        // due adulti
    "chd": [12, 8],  // due bambini di 12 e 8 anni
    "inf": [3]       // 1 infant di 3 mesi
  },

  // camera 2
  {
    "adt": 2,
    "chd": [6, 4],
    "inf": []
  }
]

In presenza di errori nei campi età (valori mancanti o non corretti), il corrispondente valore nel json è impostato su null (l'errore viene comunque segnalato all'utente e il pulsante submit del form contenente il widget viene disabilitato fino a correzione):

Errore nel campo età del secondo bambino:

[
  {
    "adt": 2, 
    "chd": [12, null], 
    "inf": []       
  }
]

Valori di default

È possibile impostare dei valori di default semplicemente inserendo nell'attributo value i parametri desiderati. Ad esempio, per preimpostare due adulti nella prima camera:

<input type="hidden" class="bv-pax" 
  name="xxxxxx" 
  data-adt-max="4" 
  data-chd-max="3" 
  data-chd-age-range="0-12" 
  data-max-rooms="0" 
  value="[{&quot;adt&quot;:2}]">

In mancanza di valori di default, il numero minimo degli adulti è sempre impostato a 1;

Widget cambio cittadinanza

Il widget cambio cittadinaza mostra un popup per la selezione della nazione dell'utente.

Il markup richiesto è il seguente:

<div class="ccitt-wrapper">
  <span class="small">Cittadinanza ospite: 
    <strong class="ccitt-lbl">Italia</strong>
  </span>
  <span class="small">/</span>
  <button type="button" class="small btn-link ccitt-trigger">Cambia</button>
  <input type="hidden" name="__name__" class="ccitt-val" value="IT">
</div>

La scelta dell'utente viene riportata nel campo hidden.ccitt-val (sigla nazione a due caratteri) e, contemporaneamente, la stessa nazione è riportata per esteso nell'ellemento ccitt-lbl.

I valori di default vanno impostati direttamente nel markup.

Widget selezione mese

Il widget selezione mese mostra un popup per la selezione di una coppia anno-mese.

Il markup richiesto è il seguente:

<div class="form-group">
  <label for="__id__" class="form-label">Periodo</label>
  <input type="month" id="__id__" name="__name__" class="form-control" min="2022-03" max="2025-06">
</div>

Il markup di base è un campo [type="month"] standard, che visto l'incompleto supporto da parte dei browser (e la scarsa usabilità dove lo è), viene sostituito in progressive enhancement con un picker personalizzato.

Il widget supporta gli attributi min e max del campo originale (se presenti) e l'eventuale presenza di un valore di default nell'attributo value.

In mancanza di min e max, questi vengono impostati di default al mese corrente per min e a dicembre del quarto anno successivo a quello corrente per max.

Pagine dei risultati delle ricerche

Le pagine dei risultati contengono un massimo di 7 card ognuna (6 per i voli) ed hanno un form di filtraggio aggiuntivo dei risultati posto sulla sinistra in visualizzazione desktop e off-canvas in quella mobile.

Immagini

Le dimensioni delle immagini associate ad ogni card sono indipendenti dalla tipologia ma variano in base al breakpoint:

Breakpoint Dimensioni 2x
xs-sm 508x225
md-lg 290x400
xl-xxl 290x300 No

Classi CSS

Classi specifiche del CSS Travelplace in aggiunta alle classi standard Bootstrap abilitate:

  • Testo colorato

    • .text-blue: color: #3555ff
    • .text-salmon: color: #fb6b6b
    • .text-cyan: color: #44d2ff
  • Formattazioni testo:

    • .sottotitolo: testo 1.5rem + font light
    • .fs-medium: testo medio (più di 2rem) + font light + line-heigth ridotta
    • .fs-big: testo grande (più di 3rem) + font light + line-heigth ridotta
    • .fs-base: forza la dimesnione di base del testo (1rem)
  • Buttons

    • .fg-btn: elemento button inserito in una blocco contenente elementi .form-group. La classe fa in modo che abbia la stessa altezza degli altri elementi della riga
    • .btn-grey: pulsante generico di colore grigio
    • .btn-primary, .btn-outline-primary, .btn-outline-secondary, .btn-link: classi bootstrap standard (NB: non è previsto .btn-secondary)
    • .btn-outline-white: bordi e testo bianchi
  • Forms

    • flex-label: modifica il display di un elemento label in flex. È utilizzato nelle pagine dei risultati di ricerca per mostrare il numero degli elementi corrispondenti ad un'opzione selezionabile tramite un checkbox.

TODO / problemi noti

  • integrare https://floating-ui.com (o in alternativa https://popper.js.org) per popup e visualizzazione itinerari
  • visualizzazione itinerari crociere (mappe)
  • safari: behavior smooth in scrollBy (card e tabs)
  • campi datetime: personalizzare messaggio errore
  • campi età, e date: testare su safari ios, potrebbero non funzionare min/max/step, esiste un controllo lato server?
  • radio-buttons: migliorare visualizzazione mobile
  • tabelle: visualizzazione mobile
  • fix visualizzazione header su mobile con contenuti più lunghi (bluwelfare)