2016-05-05 38 views
10

Questa domanda espande il numero "Separators For Navigation" chiedendo come sia possibile rimuovere i separatori alle interruzioni di linea, in base alla dimensione del viewport.Separatore reattivo per l'elenco orizzontale

Ampia Finestra
->  Item 1 | Item 2 | Item 3 | Item 4 | Item 5  <- 
Piccolo viewport
-> Item 1 | Item 2 | Item 3 <- 
->  Item 4 | Item 5  <- 

Ecco un violino che mostra come un tubo rimane sulla linea di rottura:

Fiddle.

Sono interessato a una soluzione solo CSS, ma javascript è accettabile se fornisce l'unica soluzione possibile.

+0

Possibile duplicato di [CSS: Last element on line] (http://stackoverflow.com/questions/9847663/css-last-element-on-line) – dippas

+0

Non ho trovato questa domanda prima di scrivere il mio domanda. Tuttavia, ritengo che questa domanda abbia come obiettivo risposte leggermente diverse e casi d'uso. Inoltre, questo potrebbe non fornire soluzioni che si allineano con le specifiche attuali. – roydukkey

risposta

6

È possibile sfruttare fatto che finale e la linea di trailing spazio bianco automaticamente crolla: https://jsfiddle.net/vnudrsh6/7/

nav { 
 
    text-align: center; 
 
    padding-right: 1em; /* = li::[email protected] */ 
 
} 
 
ul { 
 
    display: inline; 
 
    margin: 0; 
 
    padding: 0; 
 
} 
 
li { 
 
    display: inline; 
 
    /* white-space: nowrap should be moved to child A because IE fails to wrap resulting list completely */ 
 
} 
 
li::before { 
 
    content: ' '; 
 
    /* 
 
    this content is important only for Crome in case the HTML will be minified with no whitespaces between </li><li> 
 
    */ 
 
} 
 
li::after { 
 
    content: ' '; 
 
    white-space: normal; 
 
    word-spacing: 1em; /* = [email protected] - this actually makes width */ 
 
    background-image: radial-gradient(circle, black, black 7%, transparent 15%, transparent 35%, black 45%, black 48%, transparent 55%); 
 
    background-size: 1em 1em; 
 
    background-repeat: no-repeat; 
 
    background-position: center center; 
 
    opacity: 0.5; 
 
} 
 
/* 
 
no need to unset content of li:last-child, because it will be the trailing whitespace so it will collapse 
 
*/ 
 
a { 
 
    white-space: nowrap; /* here */ 
 
    display: inline-block; /* to allow padding */ 
 
    padding: 1em; 
 
    text-decoration: none; 
 
    color: black; 
 
    transition-property: background-color; 
 
    transition-duration: 500ms; 
 
} 
 
a:hover { 
 
    background-color: #ccc; 
 
}
<nav> 
 
    <ul> 
 
    <li><a href="#">Item 1</a></li><li><a href="#">Item 2</a></li><li><a href="#">Item 3</a></li><li><a href="#">Item 4</a></li><li><a href="#">Item 5</a></li><li><a href="#">Item 6</a></li><li><a href="#">Item 7</a></li><li><a href="#">Item 8</a></li><li><a href="#">Item 9</a></li><li><a href="#">Item 10</a></li><li><a href="#">Item 11</a></li><li><a href="#">Item 12</a></li><li><a href="#">Item 13</a></li><li><a href="#">Item 14</a></li><li><a href="#">Item 15</a></li><li><a href="#">Item 16</a></li><li><a href="#">Item 17</a></li><li><a href="#">Item 18</a></li><li><a href="#">Item 19</a></li><li><a href="#">Item 20</a></li> 
 
    </ul> 
 
</nav> 
 
<p>(Content)</p>

Questa proof-of-concept background-image usa di "fine colapsing" CSS generated content spazio dopo ogni <li>. Testato su Firefox, Chrome e IE11 attuali.

+0

Hummm ... Mi piace. Vediamo cosa possono fare gli altri. – roydukkey

+0

Sarebbe bello avere una soluzione che funzioni con altri personaggi (ad esempio proiettili, quote ad angolo retto, ecc.). – roydukkey

+0

Il mio funziona con JS aggiungendo/rimuovendo le classi, quindi potresti voler verificarlo. –

0

Se si dispone di una larghezza statica dell'elemento, è possibile calcolare dallo schermo del supporto. Se non utilizzare lo script

body { 
    text-align: center; 
} 

ul { 
    margin: 0; 
    padding: 0; 
    list-style: none; 
} 

li { 
    display: inline-block; 

    &:not(:last-child):after { 
    content: ' |'; 
    } 
} 
@media screen and (max-width: 265px) { 
    li { 
    display: inline-block; 

    &:not(:last-child):after { 
    content: ''; 
    } 
} 

} 
+0

No. L'elemento su cui alla fine utilizzerò questa tecnica avrà solo una larghezza massima. – roydukkey

0

Nizza domanda. Per la vita di me, non riesco a pensare a una soluzione unica CSS a prova d'acqua temo ...

Ho modificato una vecchia soluzione a una domanda simile postata qualche tempo fa: CSS: Last element on line. Stranamente, stavo cercando una soluzione per un altro problema che avevo da un po 'di tempo e mi sono imbattuto in questo: da allora ho fatto un segnalibro!

Ecco un violino con i miei aggiornamenti: https://jsfiddle.net/u2zyt3vw/1/

HTML:

<ul> 
    <li>Item 1</li> 
    <li>Item 2</li> 
    <li>Item 3</li> 
    <li>Item 4</li> 
    <li>Item 5</li> 
</ul> 

CSS:

body { 
    text-align: center; 
} 

ul { 
    margin: 0; 
    padding: 0; 
    list-style: none; 
} 

li { 
    display: inline-block; 

    &:not(:last-child):after { 
    content: ' |' 

    } 

} 
li.remove:after { 
    content: none; 
} 

jQuery:

$(window).on("resize", function() { 
    var lastElement = false; 
    $("ul > li").each(function() { 
     if (lastElement && lastElement.offset().top != $(this).offset().top) { 
      lastElement.addClass("remove"); 
     } 
     lastElement = $(this); 
    }).last().addClass("remove"); 
}).resize(); 

NOTA - funziona meglio onload al momento, il ridimensionamento causa alcuni problemi anche se utilizzo toggleClass(). Quindi continua a premere "Esegui" ogni volta che ridimensiona la vista. Ci lavorerò e tornerò da te ..

+0

Bello! il problema con questo non è fluido, il che significa che non apparirà dopo diciamo portrait to mobile (sor instance) ma se non è un problema gg! – Riskbreaker

+0

@Riskbreaker buon punto. Ci sono molte eventualità da tenere in considerazione con questo ... Una domanda molto interessante. –

1

Una soluzione diversa da quella stessa CSS: Last element on line sembra che funzionerebbe qui.

HTML:

<div> 
<ul> 
<li>Item 1</li> 
<li>Item 2</li> 
<li>Item 3</li> 
<li>Item 4</li> 
<li>Item 5</li> 
</ul> 
</div> 

CSS:

div {overflow: hidden; margin: 1em; } 
div ul { list-style: none; padding: 0; margin-left: -4px; } 
div ul li { display: inline; white-space: nowrap; } 
div ul li:before { content: " | "; } 

(Fiddle)

+0

Non funziona quando gli elementi sono allineati al centro. :/ – roydukkey

0

La mia applicazione con JavaScript: https://jsfiddle.net/u2zyt3vw/5/

Hit "Run" di nuovo dopo aver ridimensionato la finestra.

È anche possibile aggiungere listener di eventi come onresize. Ecco il JS:

var listItems = document.getElementsByTagName("li"); 
var listItemsWidth = []; 
var listItemsDistance = []; 

for (let i = 0; i < listItems.length; i++) { 
    listItemsWidth[i] = listItems[i].offsetWidth; 
    listItemsDistance[i] = listItems[i].getBoundingClientRect().right; 
} 

for (let i = 0; i < listItems.length; i++) { 
    if (listItemsDistance[i] == Math.max.apply(null, listItemsDistance)) { 
    listItems[i].classList -= "notLast"; 
    } else { 
    listItems[i].classList = "notLast"; 
    } 
} 

ho aggiunto la classe notLast a tutti i vostri elementi, ed è quello che contiene la :after pseudo-elemento con il tubo. Questo script rimuove questa classe da quelli più vicini al bordo destro del contenitore.

Ho anche scherzato con lo pseudoelemento e lo ho reso position:absolute; per motivi bui.