Visualizzazione dei risultati da 1 a 7 su 7
  1. #1

    Effetto collaterale di offset su link interno alla pagina

    Salve, pubblico in CSS poiché il problema in questione si presenta risolvendone via CSS un altro, ma andiamo per ordine.
    Ho il layout di un sito dove uso Bootstrap, con navbar fissa in alto, avente height=86px.
    Sotto la navbar c'è il menù interno della pagina che, puntando semplicemente ai riferimenti locali (es.: <a href="#link">Personaggi</a>), li porta in cima alla finestra del browser, che come detto è occupata dalla navbar.
    Per risolvere, ho inserito nel CSS questo codice, adattato da un altro mio sito senza Bootstrap:
    codice HTML:
    :target:before {
    	content: "";
    	display: block;
    	height: 86px;
    	margin: -86px 0 0;
    }
    Il "trucchetto" funziona, se non fosse che il corrispondente riferimento/segnalibro (es.: <a name="link">Personaggi</a>, si trova in un <h2></h2> dallo sfondo rosso il quale risponde al click sul link nel menù aumentando la propria altezza di 86px, e coprendo le ultime righe del blocco superiore!

    Evidentemente il codice CSS non va bene allo scopo, quindi vorrei sapere come fare a dare un offset desiderato ai link locali.

  2. #2
    Moderatore di CSS L'avatar di KillerWorm
    Registrato dal
    Apr 2004
    Messaggi
    4,728
    L'hack che stai usando in effetti è usato spesso, in varie salse. Forse con qualche accorgimento si può risolvere ma così su due piedi non mi vengono particolari idee; ti chiedo quindi se puoi postare il link della pagina in questione, così magari posso fare qualche prova diretta per verificare se la cosa può essere risolta col solo CSS. L'alternativa forse è l'uso di JavaScript.
    Prima di postare considera che tra i link utili puoi trovare il 75% delle risposte alle tue domande; il 20% tra i post del forum; il 15% sul web.
    Ti resta... humm spè

    Le cattive domande sono quelle che non meritano risposta, le buone domande sono quelle che non hanno risposta
    L'Itailano non e nu'opnioine. E' improntate uslaro correattemtne sul froum. Garize!

  3. #3
    Il problema è presente su tutte le pagine dato che il layout è grosso modo lo stesso, ea considera che il sito è in costruzione quindi non badare a link non funzionanti o immagini che non si caricano...
    Questa pagina è pressoché completa: http://pugniespinaci.altervista.org/autori.php Se scorri i titoli H2 si vedono bene, ma se usi il menù interno e poi sali un po', noti che l'H2 è cresciuto verso sopra.

  4. #4
    Moderatore di CSS L'avatar di KillerWorm
    Registrato dal
    Apr 2004
    Messaggi
    4,728
    Ho fatto un po' di ricerche e provato diverse soluzioni, applicabili e non, ognuna con i suoi pro e contro.

    Prima di indicarti alcune possibili soluzioni faccio una piccola premessa perché mi preme chiarire alcuni punti.
    Per creare le ancore stai usando una tecnica obsoleta, con una struttura del genere:
    codice:
    <h2>
        <a name="nome-ancora"></a>
        Titolo
    </h2>

    In HTML5 l'uso dell'attributo "name", applicato agli elementi <a> per creare delle ancore interne, è obsoleto, anche se i vari browser possono riuscire a digerirlo; dovresti invece usare l'id (col relativo nome dell'ancora) applicandolo direttamente agli <h2> in questo modo:
    codice:
    <h2 id="nome-ancora">Titolo</h2>

    Altra cosa, ho provato su Edge e IE11, e vedo che il sistema del target, da te usato, non funziona. Non ho approfondito ma è giusto per fartelo presente. Fai tu eventuali verifiche.

    ---

    Qui le varie possibili strade:

    A) Uso di scroll-padding-top. Togli il trick :target:before e applica giusto questa regola:
    codice:
    html, body {
        scroll-padding-top: 86px;
    }

    PRO: questa è la soluzione più semplice e pulita che ho trovato e provato, supportata dalle versioni più recenti dei diversi browser.

    CONTRO: non è supportata da qualche browser non proprio recente. Su caniuse puoi vedere l'attuale supporto dei vari browser e valutare tu se usarla.

    B) Usando il trick :target:before (che già hai) applica overflow:hidden al div che contiene l'elemento <h2>. Nella tua specifica situazione, ogni <h2> è contenuto dentro un <div class="col-12"> per cui potresti fare una cosa del genere:
    codice:
    .col-12 {
        overflow: hidden;
    }

    Dal momento che il div non subisce l'alterazione della sua altezza, anche se l'altezza dell'elemento <h2> viene maggiorata, quel overflow:hidden non fa altro che "confinare" il contenuto stesso all'interno dell'area del div, che resta sostanzialmente invariata.

    PRO: di facile applicazione nella tua situazione attuale, dato che si appoggia al corrente trick.

    CONTRO: si comporta in modo differente a seconda del browser. Funziona perfettamente su FF66, su cui l'ho testato, mentre su CH vedo che la pagina viene portata al target ma senza considerare quell'offset relativo al contenuto nascosto, creato col :before (può essere che allo stesso modo non funzioni su versioni più recenti di FF, attualmente la 75). Su ED/IE non è possibile verificare dato che il trick :target:before non funziona.
    Boccerei comunque questa soluzione dato che fallisce su recenti browser, come CH81 su cui sto testando.


    C) Uso di background:linear-gradient e pointer-events:none per <h2>.

    Sostanzialmente creo per <h2> uno sfondo a due fasce, di cui quella di sopra è trasparente, quindi lo rendo "immune" agli eventi mouse.

    In questo caso va aggiustato l'HTML come indicato nella premessa, cioè vanno rimossi tutti quegli <a name="..."> (che comunque risultano obsoleti) e va impostato un relativo id su ciascun <h2>. Questa mi pare comunque una cosa che dovresti fare per avere un codice perfettamente valido, a prescindere dalla risoluzione del problema in oggetto.

    Per farlo in modo veloce e automatico, può essere utile usare un editor con la funzione trova/sostituisci che supporti le espressioni regolari.

    Io l'ho fatto con Notepad++ impostando la sostituzione in questo modo:
    codice:
    Trova: <(.+?)>([\s]*?)<a name="(.+?)"></a>
    Sostituisci con: <$1 id="$3">$2

    A questo punto dovrai chiaramente togliere la regola :target:before e quindi sostituire la regola definita per h2, con questa:
    codice:
    h2 {
        font-size: 20px;
        font-weight: bold;
        text-align: center;
        color: #ffffff;
        padding-top: 86px; /* valore per l'offset */
        margin-top: -76px; /* riposizionamento rispetto all'offset. I 10px che mancano sono per il normale margin */
        pointer-events: none; /* lo rendo inattivo agli eventi mouse per risolvere il problema della sovrapposizione */
        background: -webkit-linear-gradient(transparent 86px, #f75740 86px);
        background: -o-linear-gradient(transparent 86px, #f75740 86px);
        background: linear-gradient(transparent 86px, #f75740 86px); /* applico la trasparenza per l'altezza dell'offset */
    }

    I commenti mi sembrano abbastanza chiari, ad ogni modo riassumo ciò che avviene:

    - in sostanza il padding serve a estendere l'altezza di h2 in riferimento al valore di offset da considerare;

    - il margin negativo "azzera" lo spostamento dovuto a questo sovradimensionamento, così come più o meno avviene per quel trick :target:before;

    - il pointer-events:none disabilita gli eventi del mouse su questo elemento, in modo che anche se questo viene a trovarsi sopra altri elementi, non vada ad impedire l'interazione del mouse con loro;

    - il linear-gradient impostato per il background crea lo sfondo con due fasce di cui quella sopra, alta quanto il valore dell'offset, è trasparente, mentre quella sotto è del colore impostato normalmente per lo sfondo di h2.

    PRO: soluzione abbastanza pulita e funziona perfettamente sui vari browser, recenti e un po' meno recenti (come IE11). Risolve peraltro il mancato funzionamento su ED/IE che attualmente hai con quel trick. E cosa importante, ti costringe a sistemare le ancore interne così da avere un HTML perfettamente valido.

    CONTRO: va impiegato un po' di tempo per aggiustare l'HTML ma penso ne valga la pena. Eventuali elementi cliccabili (ad esempio link) contenuti in <h2>, restano "insensibili" agli eventi mouse dal momento che è applicato pointer-events:none; ad ogni modo, se si vuole renderli nuovamente sensibili, è sufficiente applicare, a questi, pointer-events:auto, in modo che tale proprietà sovrascriva quella del genitore h2 (il quale manterrà comunque la sua giusta "insensibilità").

    D) Usare una soluzione JavaScript/jQuery. Non ne ho da proporti ma sono facilmente reperibili con qualche ricerca.
    Ultima modifica di KillerWorm; 29-04-2020 a 08:10
    Prima di postare considera che tra i link utili puoi trovare il 75% delle risposte alle tue domande; il 20% tra i post del forum; il 15% sul web.
    Ti resta... humm spè

    Le cattive domande sono quelle che non meritano risposta, le buone domande sono quelle che non hanno risposta
    L'Itailano non e nu'opnioine. E' improntate uslaro correattemtne sul froum. Garize!

  5. #5
    Wow, grazie mille per le varie alternative, peraltro commentate!
    Nelle ultime ore mi sono dedicato prevalentemente alla parte PHP/SQL del sito (il grosso del sito), e ho dato un'occhiata tra le mie cartelle per i JavaScript che avevi già suggerito: ho trovato qualcosa che però non ho testato se e come funziona in questo caso, è un mio codice piuttosto lungo che risale a un paio di anni fa, commentato ma che devo ristudiare.

    La soluzione ottimale è sempre quella compatibile con tutti i browser aggiornati, per pc come per dispositivi mobili, ma se non c'è bisogna fare compromessi.

    Ora che l'hai scritto, ho ricordato che in HTML5 i link si fanno con l'id e non coi name... Sono stato fuori dai codici per qualche tempo e mi era passato di mente, andando in automatico coi vecchi codici...

  6. #6
    Ispirandomi alla soluzione C, siccome ho link interni sia verso titoli <h2> che verso paragrafi <p>, ho introdotto la classe offset aggiunta agli id cui puntano i link interni, ma temo di dover differenziare i due tipi di link perché il risultato non va bene graficamente, a meno di giocarmi la compatibilità con Internet Explorer e i browser integrati in Android.

    Soluzioni JS non ne ho trovate risolutive.

  7. #7
    Moderatore di CSS L'avatar di KillerWorm
    Registrato dal
    Apr 2004
    Messaggi
    4,728
    Soluzioni JS non ne ho trovate risolutive.
    Vedi la mia risposta e l'edit qui: https://forum.html.it/forum/showthre...1#post25552242

    Buon proseguimento
    Prima di postare considera che tra i link utili puoi trovare il 75% delle risposte alle tue domande; il 20% tra i post del forum; il 15% sul web.
    Ti resta... humm spè

    Le cattive domande sono quelle che non meritano risposta, le buone domande sono quelle che non hanno risposta
    L'Itailano non e nu'opnioine. E' improntate uslaro correattemtne sul froum. Garize!

Tag per questa discussione

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2020 vBulletin Solutions, Inc. All rights reserved.