2016-07-21 23 views
0

Ich versuche, eine horizontale Liste zentriert zu machen, mit seinen Elementen zu zentriert werden auch in Bezug auf die Hauptelternteil (das Fenster oder Körper); Und weil ich nicht weiß, welche Art und wie viele Elemente ich in diese Liste generiert habe, müsste ich die Elemente dynamisch in der Breite und die Liste scrollbar machen, damit ich sie alle durchsuchen kann.horizontal scrollbare Liste voll zentriert mit dynamischen Breite Elemente

Meine bisherigen Versuche sind gut, ich bekomme entweder: eine zentrierte Liste mit nicht zentrierten Elementen von dynamischer Breite; und eine vollständig zentrierte scrollbare Liste mit Elementen fester Breite.

ul { 
    width: 100%; 
    overflow-x: scroll; 
    overflow-y: hidden; 
    white-space: nowrap; 
} 

li { 
    display: inline-block; 
} 

Dann wird das Zentrieren wird durch Wickeln des <ul> in eine <div>, und macht die <div> scroll die <ul> anstelle des <ul> Scrollen der <li>:

Der Kerngedanke wird durch die Verwendung im wesentlichen erreicht. Es ermöglicht% basierend Margen der <ul>

div { 
    width: 100%; 
    overflow-x: scroll; 
    overflow-y: hidden; 
    white-space: nowrap; 
} 

ul { 
    margin: 0 50%; 
} 

li { 
    display: inline-block; 
} 

Für Elemente hinzufügen, indem Breite zentriert werden, ist die Idee, translateX(-50%) mit einem kleinen Twist zu verwenden: wie ich bei dem zusätzlichen Platz haben, nicht die Liste wollen Ende des Scrollens entferne ich das letzte Element aus dem Fluss, indem ich es am Ende absolut positioniere; Auf diese Weise sieht die Breite <ul> wie die Summe der Elemente Breite minus ein Element aus.

ul { 
    position: relative; 
    margin: 0 50%; 
} 

li { 
    display: inline-block; 
    width: some_number; 
    transform: translateX(-50%); 
} 

li:last-child { 
    position: absolute; 
    left: 100%; 
} 

Aber wie es so zu halten, ohne die Breite Einstellung ist mir ein Rätsel.
Irgendwelche Ideen da draußen?

Hier ist meine Geige mit einigen Kommentaren in dem CSS-Abschnitt: https://jsfiddle.net/11gkrju0/

Ich mag würde nicht Javascript zu verwenden überhaupt für das, wie es nur eine Frage des Styling ist, aber mit dem dom Messing ist eine absolut brauchbare Option.

Dank allen für das Lesen,

Antwort

0

Ok, so dass es ein bisschen schwierig ist. Die aufgelöste Geige ist hier mit Kommentaren, die ich auch hier beschreiben werde. https://jsfiddle.net/11gkrju0/7/

Das erste, was zu beachten ist, fügte ich eine vertical-align: top; zu meinem <li> s, um sicherzustellen, gibt es keine vertikale Lücke an einem Punkt.

Dann.

Grenzen für eine nicht zentrierte Liste sind leicht zu fangen:

+-----+---+---------+ 
| A | B | C | 
+-----+---+---------+ 
^     ^
a     b 

Für eine zentrierte Liste, sie ein wenig zu ändern:

+-----+---+---------+ 
| A | B | C | 
+-----+---+---------+ 
^^  ^^
a c   d b 

die Scroll richtig zu machen, müssen wir Ändern Sie die Breite des <ul> von A-> B nach C-> D. Da seine Breite dynamisch durch die Kinderbreite berechnet wird, müssen wir die Kinder ändern.

Wir können sehen, dass nur die ersten und letzten Kinder geändert werden.Da der Text die Breite der einzelnen untergeordneten Elemente definiert, können wir die Eigenschaft width nicht ändern, aber wir können die definierten Werte viel einfacher durch 2 teilen: font-size, padding.

li { 
    font-size: 12px; 
    padding: 0 50px; 
} 

li:first-child, li-last-child { 
    font-size: 6px; 
    padding: 0 25px; 
} 

Nun wird die Liste wie

+---+---+-----+ 
| a | B | c | 
+---+---+-----+ 
^^ ^^ 
a c  d b 

aussehen kann das Problem ist, aber dann, dass der Text und Polsterung jetzt kleiner ist. Was wir tun können, ist, die echten Knöpfe in einen :after mit dem kleinen Handel von einem Textattribut dem Li zu ersetzen, um die Eigenschaft content zu füttern.

<li text='A'>A</li> 
<li text='B'>B</li> 
<li text='C'>C</li> 

Damit im DOM, können wir diese Art von CSS erstellen gefälschte Tasten schreiben, die genau wie die reale sucht man (nicht zu vergessen die reale zu verstecken ...)

li { 
    position: relative; 
    background: transparent; 
    color: transparent; 
} 

li:after { 
    display: block; 
    overflow: hidden; 
    position: absolute; 
    left: 0; 
    top: 0; 
    width: 100%; 
    height: 100%; 
    content: attr(text); 
    color: #000; 
} 

Fast dort, fast dort ...

Die ersten und letzten Kinder wurden geändert, und so ihre Pseudo-Kind auch ... Nebeneffekt ist, dass die Breite für eine 6px Schriftgröße berechnet wird. Daher müssen wir die Breite auf die doppelte Größe zurücksetzen und die Schriftgröße zurücksetzen, um Vererbung zu verhindern.

li:first-child:after, #d li:last-child:after { 
    font-size: 12px; 
    width: 200%; 
} 

Schließlich (yay), pad das erste Element auf die Hälfte seiner Breite, um eine Kollision mit dem zweiten zu verhindern.

li:first-child:after { 
    left: -100%; 
} 

Wir könnten transform: translateX(-50%); auch verwendet, aber wir Manipulation bereits absolute Werte, so gibt es keine Notwendigkeit, eine andere Schicht der Berechnung auf, dass anzuwenden.

In der Hoffnung, es wird jemandem helfen.