“Önceki kardeş” seçici var mı?


1355

Artı işareti ( +) bir sonraki kardeş içindir.

Önceki kardeş için bir eşdeğer var mı?


18
OMG, html öğelerinin sırasını tersine çevirmenizi ve ardından geriye doğru görünmelerini sağlamak için CSS'yi kullanmanızı öneren tüm cevaplar gerçek bir esnektir. Elbette değil belirtmek Söz konusu ancak çoğu "Eğer CSS ile X yapabilirim" sorular yapısal HTML değiştiremezsiniz üstlenmelidir.
squarecandy

3
@squarecandy, çoğunlukla yorumunuza katılıyorum. Ancak, yetersiz olarak referansta bulunduğunuz çözümler yine de bazı durumlarda yararlıdır (yukarı oylara dikkat edin). Yani göndermeye değer. "Gerçek bir esneme" olarak gördüğünüz şey başkaları için "yaratıcı bir çözüm" olabilir.
Michael Benjamin

Yanıtlar:


839

Hayır, "önceki kardeş" seçicisi yok.

İlgili bir notta, ~genel halef kardeş (yani eleman bundan sonra gelir, ancak hemen sonra değil) anlamına gelir ve bir CSS3 seçicisidir. +bir sonraki kardeş içindir ve CSS2.1'dir.

Bkz . Seçici Seviye 3 ve 5.7'deki bitişik kardeş birleştirici . Basamaklı Stil Sayfaları Seviye 2 Revizyon 1 (CSS 2.1) Spesifikasyonundaki bitişik kardeş birleştirici .


14
CSS3 standardından: İki sekans tarafından temsil edilen elemanlar , doküman ağacında aynı ebeveyni paylaşır ve birinci sekans tarafından temsil edilen eleman, ikincisi tarafından temsil edilen elemandan önce (mutlaka gerekli değildir) önce gelir .
Yalan Ryan

26
@Lie Ryan: Evet, ama onun cevabını yapıyor noktası cletus sen kalmamasıdır seçmek önceki elemanı.
BoltClock

42
İşte bunun ne yapabileceğini ve yapamayacağını görmek için yaptığım bir örnek. jsfiddle.net/NuuHy/1
Abaküs

7
Bunun için yararlı jquery işlevi prev () işlevidir. Örneğin $ ("# the_element"). Prev (). Css ("arka plan rengi", "kırmızı")
Satbir Kira

1
İşaretlemenize bağlı olarak, bu yardımcı olabilir: stackoverflow.com/questions/42680881/…
samnau

234

~İhtiyacınıza bağlı olarak çalışabilecek tüm önceki kardeşleri (tersi ) şekillendirmenin bir yolunu buldum .

Diyelim ki bir bağlantı listeniz var ve bir tanesinin üzerine geldiğinizde, öncekilerin tümü kırmızıya dönmelidir. Bunu şöyle yapabilirsiniz:

/* default link color is blue */
.parent a {
  color: blue;
}

/* prev siblings should be red */
.parent:hover a {
  color: red;
}
.parent a:hover,
.parent a:hover ~ a {
  color: blue;
}
<div class="parent">
  <a href="#">link</a>
  <a href="#">link</a>
  <a href="#">link</a>
  <a href="#">link</a>
  <a href="#">link</a>
</div>


17
Nasıl çalıştığına dair bir açıklama ekleyebilirsiniz. (tüm öğelere ve aşağıdaki öğelere bir stil uyguladığınız anlaşılıyor, ancak açıkça tanımlanabilir)
AL

1
Müthiş bir çözüm. İşaretlemedeki veya oluşturmadaki (via float:right) öğeleri yeniden sıralamaya gerek yoktur . Birimler / sözcükler ve kenar boşlukları yerine dolgu arasında beyaz boşluk çökmesi gerektiriyordu, ancak aksi halde mükemmel çalışıyor!
Steven Vachon

7
Evet, ama tek bir önceki çoğu zaman TÜM önceki olanlar gerekli!
azerafati

41
Aralarındaki boşluğun üzerine gelirsem bağlantılar kırmızıya döner, benim için.
Lynn

3
@ Cevabı yanıtla, fareyle üzerine gelindiğinde önceki bağlantıları kırmızı yapmak için gereken kodu içerir. Ek stiller kullanım durumunuza bağlıdır. Bir yıldız derecelendirme bileşeni için (sanırım yaygın bir durumdur), bu alandan kurtulmanız ve vurgulanan bağlantıyı kırmızı yapmanız gerekir.
mantish

164

Seviye 4 seçiciler:has() (daha önce konu göstergesi !) ile daha önce bir kardeş seçmenize izin verir:

previous:has(+ next) {}

… Ancak yazma sırasında, tarayıcı desteği için kanayan kenarın ötesine biraz mesafe var.


51
"Tarayıcı desteği için hava alma kenarı" abartılı olabilir. Bunu yazarken, Chrome'un en son sürümü bile :has()sözde sınıfı kullanamaz .
Reed Martin

33
@ReedMartin - Bu yüzden kanayan kenarın ötesine biraz mesafe
Quentin

12
": işlevi, dinamik seçici profilinin bir parçası olarak işaretlenmediğinden, stil sayfalarında kullanılamaz; yalnızca document.querySelector () gibi işlevlerle kullanılabilir." - developer.mozilla.org/en-US/docs/Web/CSS/:has
Arch Linux Tux

1
@ArchLinuxTux: "Bu sınırlama artık kaldırıldı", bu nedenle bir zamanlar şu özelliği kullanabiliriz: D.
Jacob van Lingen

@JacobvanLingen - caniuse.com/#feat=css-has - Şu anda hiçbir tarayıcı desteklemiyor.
Quentin

153

orderEsnek ve ızgara düzenlerinin özelliklerini düşünün .

Aşağıdaki örneklerde flexbox'a odaklanacağım, ancak aynı kavramlar Grid için de geçerli.


Flexbox ile önceki bir kardeş seçici simüle edilebilir.

Özellikle, flex orderözelliği elemanları ekranın etrafında hareket ettirebilir.

İşte bir örnek:

B öğesi üzerine geldiğinde A öğesinin kırmızıya dönmesini istiyorsunuz.

<ul>
    <li>A</li>
    <li>B</li>
</ul>

ADIMLARI

  1. Make ula esnek konteyner.

    ul { display: flex; }

  1. İşaretlemede kardeşlerin sırasını ters çevirin.

    <ul>
       <li>B</li>
       <li>A</li>
    </ul>

  1. A Öğesini hedeflemek için bir kardeş seçici kullanın ( ~veya +yapacak).

    li:hover + li { background-color: red; }

  1. orderGörsel ekrandaki kardeşlerin sırasını geri yüklemek için flex özelliğini kullanın .

    li:last-child { order: -1; }

... ve voilà! Önceki bir kardeş seçici doğar (veya en azından simüle edilir).

İşte tam kod:

ul {
    display: flex;
}

li:hover + li {
    background-color: red;
}

li:last-child {
    order: -1;
}

/* non-essential decorative styles */
li {
    height: 200px;
    width: 200px;
    background-color: aqua;
    margin: 5px;
    list-style-type: none;
    cursor: pointer;
}
<ul>
    <li>B</li>
    <li>A</li>
</ul>

Flexbox özelliklerinden:

5.4. Görüntüleme Sırası: orderözellik

Esnek öğeler varsayılan olarak kaynak belgede göründükleri sırayla görüntülenir ve düzenlenir. orderMülkiyet Bu sıralamasını değiştirmek için kullanılabilir.

orderMülkiyet kontrolleri esnek ürün sıralı gruplara atayarak, esnek kap içinde görüntülendiği sıra. <integer>Esnek öğenin hangi sıralı gruba ait olduğunu belirten tek bir değer alır .

orderTüm esnek öğeler için başlangıç değeri 0'dır.

Ayrıca orderCSS Izgara Düzeni spesifikasyonlarına bakın .


Flex orderözelliğiyle oluşturulan "önceki kardeş seçici" örnekleri .

.container { display: flex; }

.box5 { order: 1; }    
.box5:hover + .box4 { background-color: orangered; font-size: 1.5em; }

.box6 { order: -4; }
.box7 { order: -3; }
.box8 { order: -2; }
.box9 { order: -1; }
.box9:hover ~ :not(.box12):nth-child(-1n+5) { background-color: orangered;
                                              font-size: 1.5em; }
.box12 { order: 2; }
.box12:hover ~ :nth-last-child(-1n+2) { background-color: orangered;
                                        font-size: 1.5em; }
.box21 { order: 1; }
.box21:hover ~ .box { background-color: orangered; font-size: 1.5em; }

/* non-essential decorative styles */
.container {
    padding: 5px;
    background-color: #888;
}
.box {
    height: 50px;
    width: 75px;
    margin: 5px;
    background-color: lightgreen;
    display: flex;
    justify-content: center;
    align-items: center;
    text-align: center;
    cursor: pointer;
}
<p>
Using the flex <code>order</code> property to construct a previous sibling selector
</p>

<div class="container">
    <div class="box box1"><span>1</span></div>
    <div class="box box2"><span>2</span></div>
    <div class="box box3"><span>3</span></div>
    <div class="box box5"><span>HOVER ME</span></div>
    <div class="box box4"><span>4</span></div>
</div>

<br>

<div class="container">
    <div class="box box9"><span>HOVER ME</span></div>
    <div class="box box12"><span>HOVER ME</span></div>
    <div class="box box6"><span>6</span></div>
    <div class="box box7"><span>7</span></div>
    <div class="box box8"><span>8</span></div>
    <div class="box box10"><span>10</span></div>
    <div class="box box11"><span>11</span></div>
</div>

<br>

<div class="container">
    <div class="box box21"><span>HOVER ME</span></div>
    <div class="box box13"><span>13</span></div>
    <div class="box box14"><span>14</span></div>
    <div class="box box15"><span>15</span></div>
    <div class="box box16"><span>16</span></div>
    <div class="box box17"><span>17</span></div>
    <div class="box box18"><span>18</span></div>
    <div class="box box19"><span>19</span></div>
    <div class="box box20"><span>20</span></div>
</div>

jsFiddle


Bir Yan Not - CSS Hakkında İki Eski İnanç

Flexbox, CSS hakkında uzun zamandır var olan inançları yıkıyor.

Böyle bir inanış, CSS'de önceki bir kardeş seçicinin mümkün olmadığıdır .

Bu inancın yaygın olduğunu söylemek yetersiz kalır. Aşağıda yalnızca Yığın Taşması ile ilgili soruların bir örneği verilmiştir:

Yukarıda açıklandığı gibi, bu inanç tamamen doğru değildir. Flex orderözelliği kullanılarak önceki bir kardeş seçici CSS'de simüle edilebilir .

z-indexMit

Uzun süredir devam eden bir başka inanç da z-indexsadece konumlandırılmış elemanlar üzerinde çalıştığıdır.

Aslında, spec'in en güncel sürümü - W3C Editörün Taslağı - bunun hala doğru olduğunu iddia ediyor:

9.9.1 Yığın seviyesini belirtme: z-index özellik

z-index

  • Değer: otomatik | | kalıt
  • İlk: otomatik
  • Şunun için geçerlidir: konumlandırılmış elemanlar
  • Kalıtsal: hayır
  • Yüzdeler: Yok
  • Medya: görsel
  • Hesaplanan değer: belirtildiği gibi

(vurgu eklendi)

Ancak gerçekte, bu bilgiler eski ve yanlıştır.

Olan elementler esnek ürün veya ızgara öğeler bile yığılan bağlamlar yaratabilir positionolduğunu static.

4.3. Esnek Ürün Z-Siparişi

Esnek öğeler, satır içi bloklarla tam olarak aynı şekilde boyanır, ancak ham belge sırası yerine siparişte değiştirilmiş belge sırası kullanılır ve olsa bile yığın içeriği oluşturmak z-indexdışındaki değerler kullanılır .autopositionstatic

5.4. Z ekseni Siparişi: z-indexözellik

Izgara öğeler boyama sırası tam ham belge düzenin yerine kullanılan bu sırayla modifiye edilmiş bir belge için hariç olmak üzere, içi blok ile aynıdır, ve z-indexdaha başka değerler autobile bir istifleme içeriğini oluşturmak positionolup static.

İşte z-indexkonumlandırılmamış esnek öğeler üzerinde çalışırken bir gösteri : https://jsfiddle.net/m0wddwxs/


15
orderO sadece değiştirmeye yönelik aldığı için tesisin çözüm değildir görsel o bu yüzden, düzeni değil orijinal geri semantik işten bu geçici çözüm için HTML değişikliği zorlanmaktadır sırasını.
Marat Tanalin

2
@Marat Tanalin: Kullanım durumlarının% 90'ı için tarayıcı desteğinin bir sorun olmadığını varsayarsak, bu işe yarayacaktır. Kullanım örneklerinin geri kalan% 10'u ya 1) görsel sırayı değiştirmenin bir çözüm olmadığı veya 2) CSS içermeyen vakalardır. Neyse ki, # 2 için selectors-4 şunları sağlar: has () ve bunu uygulamak için seçici kitaplık geliştiricilerine bağlı.
BoltClock

5
Alıntı yaptığınız CSS2.2 ED'nin özünde hala CSS2 olduğunu unutmayın. Ve CSS2'de flexbox ve grid düzeni mevcut değil, bu yüzden CSS2 söz konusu olduğunda, bu bilgiler kesinlikle doğru. En azından, metin, z-endeksinin gelecekteki CSS seviyelerindeki diğer eleman türleri için geçerli olabileceği, diğer özelliklerin opaklık gibi bir yığın bağlamı oluşturabileceğini söylediği şekilde güncellenebilir.
BoltClock

3
Durumda herkes sorun olduğunda anlamakta yaşıyor z-indexçalışacak dahi "OMG, hiçbir olduğunumu position, şartname kavramını bahseder belirtilmedi!" Bağlam istifleme ile güzel açıklanmıştır, MDN bu makalede
Rogier Spieker

3
@Michael_B rica ederim! Bundan habersiz birçok ön uçla başa çıktım. Bahsetmek istediğim başka bir şey, sahte önceki kardeş seçici de float: right(veya sıralamayı tersine çevirmek için flex/orderçok az (en az?) Yan etkisi olan başka bir yol) ile iyi çalışıyor. İki keman kadar çırpılmış: gösteren float: rightbir yaklaşım ve gösteridirection: rtl
Rogier Spieker

69

Aynı sorum vardı, ama sonra "duh" bir anım vardı. Yazmak yerine

x ~ y

yazmak

y ~ x

Açıkçası bu, "y" yerine "x" ile eşleşiyor, ancak "bir eşleşme var mı?" basit DOM geçişi sizi doğru öğeye javascript'te döngüden daha verimli bir şekilde götürebilir.

Orijinal sorunun bir CSS sorusu olduğunun farkındayım, bu yüzden bu cevap muhtemelen tamamen alakasız, ancak diğer Javascript kullanıcıları da benim yaptığım gibi arama yoluyla soruya rastlayabilirler.


18
İnanıyorum ki y kolayca bulunabiliyor. Sorun, eğer y yalnızca x'e göre bulunabiliyorsa ve tersine çevirirken y'yi bulamazsınız çünkü ilk önce x'i bulmanız gerekir. Bu elbette y'nin bir sonraki yerine bir önceki kardeş olma sorununa atıfta bulunur, ancak y'nin bir sonraki kardeş olması için de geçerli olabilir.
David

19
Biraz sert oluyorsun, Harsh. (özür dilerim, karşı koyamadım.) Mesele şu ki bazen "y var mı?" Diğer zamanlarda iki öğe arasına bir şey koymak için ": before" kullanabilirsiniz. Son olarak, jQuery'ye düşmeniz gerekiyorsa, find ("y ~ x"). Prev () yöntemini kullanmak birçok alternatiften daha kolaydır.
Bryan Larsen

156
Önceki bir kardeş seçicinin fikri, önceki öğeyi seçmesidir. Ne yazık ki, burada açıklandığı gibi geri döndürmek bu işlevi sağlamaz.
Zenexer

14
Bu cevabın orijinal soruya gerçek bir çözüm sağlamadığı için @Zenexer'e teşekkürler, kendimi y ~ xsorunumu nasıl çözebileceğimi aptalca düşünmeye başladım
Jaime Hablutzel

4
Bu cevabın arkasındaki fikri anlıyorum, ancak cevapta verilen mantık pek mantıklı değil. Seçici y ~ x"bir eşleşme var mı?" soru, çünkü burada verilen iki seçici tamamen farklı şeyler ifade ediyor. Örneğin y ~ x, alt ağaç verilen bir eşleşme üretmenin hiçbir yolu yoktur <root><x/><y/></root>. Soru "y var mı?" o zaman seçici basittir y. Eğer soru "herhangi bir keyfi konumda bir kardeş x verildiğinde y var mı?" her iki seçiciye de ihtiyacınız olacaktır . (Belki de sadece bu noktada
nitpicking

25

İki numara . Temel olarak HTML'de istediğiniz öğelerin HTML sırasını ters çevirme ve
~ Sonraki kardeşler operatörünü kullanma:

float-right + HTML öğelerinin sırasını tersine çevir

div{ /* Do with the parent whatever you know just to make the
  inner float-right elements appear where desired */
  display:inline-block;
}
span{
  float:right;  /* float-right the elements! */
}
span:hover ~ span{ /* On hover target it's "previous";) elements */
  background:red;
} 
<div>
  <!-- Reverse the order of inner elements -->
  <span>5</span>
  <span>4</span>
  <span>3</span>
  <span>2</span>
  <span>1</span>
</div>


İle Ana direction: rtl;iç elemanlarının sırası ters +

.inverse{
  direction: rtl;
  display: inline-block; /* inline-block to keep parent at the left of window */
}
span:hover ~ span{ /* On hover target it's "previous";) elements */
  background:gold;
}
Hover one span and see the previous elements being targeted!<br>

<div class="inverse">
  <!-- Reverse the order of inner elements -->
  <span>5</span>
  <span>4</span>
  <span>3</span>
  <span>2</span>
  <span>1</span>
</div>


25

+bir sonraki kardeş içindir. Önceki kardeş için bir eşdeğer var mı?

İki balta seçiciyi kullanabilirsiniz : !ve?

Orada 2 sonraki kardeş seçiciler geleneksel CSS'deki:

  • +olduğunu hemen sonraki kardeş seçicisi
  • ~olan herhangi bir müteakip kardeş seçici

Geleneksel CSS'de, daha önce bir kardeş seçici yoktur .

Ancak, ax CSS işlemci sonrası kitaplığında, önceki 2 kardeş seçici vardır :

  • ?olan hemen önceki Kardeş seçici (zıt +)
  • !olan herhangi bir önceki Kardeş seçici (zıt ~)

Çalışma Örneği:

Aşağıdaki örnekte:

  • .any-subsequent:hover ~ div sonraki herhangi birini seçer div
  • .immediate-subsequent:hover + div hemen sonrakini seçer div
  • .any-previous:hover ! div öncekileri seçer div
  • .immediate-previous:hover ? div hemen öncekini seçer div

div {
  display: inline-block;
  width: 60px;
  height: 100px;
  color: rgb(255, 255, 255);
  background-color: rgb(255, 0, 0);
  text-align: center;
  vertical-align: top;
  cursor: pointer;
  opacity: 0;
  transition: opacity 0.6s ease-out;
}

code {
  display: block;
  margin: 4px;
  font-size: 24px;
  line-height: 24px;
  background-color: rgba(0, 0, 0, 0.5);
}

div:nth-of-type(-n+4) {
  background-color: rgb(0, 0, 255);
}

div:nth-of-type(n+3):nth-of-type(-n+6) {
  opacity: 1;
}

.any-subsequent:hover ~ div,
.immediate-subsequent:hover + div,
.any-previous:hover ! div,
.immediate-previous:hover ? div {
  opacity: 1;
}
<h2>Hover over any of the blocks below</h2>

<div></div>
<div></div>

<div class="immediate-previous">Hover for <code>?</code> selector</div>
<div class="any-previous">Hover for <code>!</code> selector</div>
<div class="any-subsequent">Hover for <code>~</code> selector</div>
<div class="immediate-subsequent">Hover for <code>+</code> selector</div>

<div></div>
<div></div>

<script src="https://rouninmedia.github.io/axe/axe.js"></script>


3
Bir raylar projesinin içindeki sass üzerine uygulamaya çalıştığımda bu bana bir sözdizimi hatası veriyor.
alex

25
ax bir CSS post işlemcisidir. Sass, Less veya Stylus gibi CSS ön işlemcileri ile aynı sözdizimini kullanmaz.
Rounin

1
@Rounin bazı belge bağlantıları eklemeyi düşünür müsünüz? Balta sonrası işlemcisi bulamıyorum .
Dionys

@Dionys - İlginiz için teşekkürler. ax , ES2015'i bilmediğim ve JS'deki nesnelerin bile benim için çok yeni olduğu 2016'nın sonlarında başladığım bir proje. GitHub deposu burada: github.com/RouninMedia/axe . Ben çok bir noktada buna dönmek istiyoruz (ayrıca javascript olaylarının CSS eşdeğeri olan balta-bıçak denilen bir şey geliştirdim ), ama önce başka bir projede (kodlanmış ashiva ) işimi tamamlamak gerekiyor .
Rounin

17

Başka bir flexbox çözümü

HTML'deki öğelerin sırasını tersine kullanabilirsiniz. Daha sonra Michael_B'nin cevabındaorder olduğu gibi kullanmanın yanı sıra veya düzeninize bağlı olarak da kullanabilirsiniz .flex-direction: row-reverse;flex-direction: column-reverse;

Çalışma örnek:

.flex {
  display: flex;
  flex-direction: row-reverse;
   /* Align content at the "reversed" end i.e. beginning */
  justify-content: flex-end;
}

/* On hover target its "previous" elements */
.flex-item:hover ~ .flex-item {
  background-color: lime;
}

/* styles just for demo */
.flex-item {
  background-color: orange;
  color: white;
  padding: 20px;
  font-size: 3rem;
  border-radius: 50%;
}
<div class="flex">
  <div class="flex-item">5</div>
  <div class="flex-item">4</div>
  <div class="flex-item">3</div>
  <div class="flex-item">2</div>
  <div class="flex-item">1</div>
</div>


16

Şu anda bunu yapmanın resmi bir yolu yok, ancak bunu başarmak için küçük bir numara kullanabilirsiniz! Deneysel olduğunu ve bazı sınırlamaları olduğunu unutmayın ... ( navigatör uyumluluğu konusunda endişeleriniz varsa bu bağlantıyı kontrol edin )

Yapabileceğiniz şey bir CSS3 seçici kullanmaktır: sözde classe nth-child()

#list>* {
  display: inline-block;
  padding: 20px 28px;
  margin-right: 5px;
  border: 1px solid #bbb;
  background: #ddd;
  color: #444;
  margin: 0.4em 0;
}

#list :nth-child(-n+4) {
  color: #600b90;
  border: 1px dashed red;
  background: orange;
}
<p>The oranges elements are the previous sibling li selected using li:nth-child(-n+4)</p>

<div id="list">
  <span>1</span><!-- this will be selected -->
  <p>2</p><!-- this will be selected -->
  <p>3</p><!-- this will be selected -->
  <div>4</div><!-- this will be selected -->
  <div>5</div>
  <p>6</p>
  <p>7</p>
  <p>8</p>
  <p>9</p>
</div>

Sınırlamalar

  • Sonraki öğelerin sınıflarına göre önceki öğeleri seçemezsiniz
  • Bu sözde sınıflar için aynıdır

1
@Ian :nth-child(-n+4)düzgün çalışması için bir seçiciye uygulanması gereken sözde bir sınıf olduğu için. Eğer ikna değilseniz,
kemanımın

1
Aslında, düğmeyi bağımsız olarak *seçiciyi kullanarak gidebilirsiniz , ancak iğrenç derecede kötü bir uygulamadır.
Josh Burgess

1
Bu benim için işe yarayan cevap, neden daha yüksek oy kullanıldığından veya kabul edilmediğinden emin değil.
Jake Cattrall

1
Aslında, farklı düğümler için çalışır: jsfiddle.net/aLhv9r1w/316 . Lütfen cevabınızı güncelleyin :)
Jamie Barker

1
Karmaşık bir seçicim vardı, ancak diyelim li#someListItemve düğümü / düğümü hemen önce istedim (bu, "önceki" yi nasıl yorumladığım) - Verdiğiniz bilgilerin CSS yoluyla bunu ifade etmeme nasıl yardımcı olabileceğini görmüyorum. Sadece ilk n kardeşi seçiyorsun ve n'yi bildiğimi varsay. Bu mantığa dayanarak, herhangi bir seçici hile yapabilir ve ihtiyacım olan öğeleri seçebilir (örneğin: not ()).
bitoolean

4

Tam konumu biliyorsanız, :nth-child()aşağıdaki tüm kardeşlerin temelli bir hariç tutulması işe yarayacaktır.

ul li:not(:nth-child(n+3))

Hangi li3. s önce tüm s seçin (örneğin 1. ve 2.). Ancak, bence bu çirkin görünüyor ve çok sıkı bir kullanım alanına sahip.

Ayrıca, nci çocuğu sağdan sola seçebilirsiniz:

ul li:nth-child(-n+2)

Aynı şeyi yapar.


3

Hayır. CSS ile mümkün değildir. Kalp ;-) "Cascade" alır.


Ancak, sayfanıza JavaScript ekleyebiliyorsanız , biraz jQuery sizi hedefinize ulaştırabilir.
Sen jQuery en kullanabilirsiniz findhedef seçmek için geriye dönük izleme ardından, hedef element / sınıf / id bir "look-ahead" yerine getirmektir.
Sonra öğeniz için DOM (CSS) yeniden yazmak için jQuery kullanın.

Mike Brant'ın bu cevabına dayanarak , aşağıdaki jQuery snippet'i yardımcı olabilir.

$('p + ul').prev('p')

Bu önce hepsini seçer <ul> hemen a'yı izleyen<p> .
Sonra o <p>s kümesi önceki tüm seçmek için "geri izler" <ul>.

Etkili bir şekilde, "önceki kardeş" jQuery ile seçildi.
Şimdi, .cssbu öğe için CSS yeni değerlerinizi iletmek için işlevi kullanın.


Benim durumumda kimliğine sahip bir DIV seçmenin bir yolunu arıyordum #full-width, ama SADECE sınıfıyla (dolaylı) soyundan bir DIV varsa .companies.

Altında tüm HTML kontrol vardı .companies , ancak üstündeki HTML'nin hiçbirini değiştiremedim.
Ve çağlayan sadece 1 yöne gidiyor: aşağı.

Böylece TÜM seçebilirim #full-width.
Ya .companiesda sadece a #full-width.
Ama olabilir değil sadece seçmek #full-widtholduğunu s devam .companies .

Ve yine, .companiesHTML'de daha yüksek bir sayı ekleyemedim . HTML'nin bu kısmı harici olarak yazılmıştır ve kodumuzu tamamlamıştır.

Ama jQuery ile, ben yapabilirsiniz gerekli seçmek #full-widths, daha sonra uygun bir stil atamak:

$("#full-width").find(".companies").parents("#full-width").css( "width", "300px" );

Bu , CSS'de standarttaki belirli öğeleri hedeflemek için seçicilerin nasıl kullanıldığına benzer şekilde hepsini bulur #full-width .companiesve yalnızca bunları seçer .companies.
Sonra .parents"backtrack" için kullanır ve TÜM ebeveynleri seçer .companies,
ancak bu sonuçları sadece #fill-widthöğeleri tutmak için filtreler , böylece sonunda bir sınıf soyundan gelen
bir #full-widtheleman seçer .companies.
Son olarak, widthortaya çıkan öğeye yeni bir CSS ( ) değeri atar .

$(".parent").find(".change-parent").parents(".parent").css( "background-color", "darkred");
div {
  background-color: lightblue;
  width: 120px;
  height: 40px;
  border: 1px solid gray;
  padding: 5px;
}
.wrapper {
  background-color: blue;
  width: 250px;
  height: 165px;
}
.parent {
  background-color: green;
  width: 200px;
  height: 70px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<html>
<div class="wrapper">

  <div class="parent">
    "parent" turns red
    <div class="change-parent">
    descendant: "change-parent"
    </div>
  </div>
  
  <div class="parent">
    "parent" stays green
    <div class="nope">
    descendant: "nope"
    </div>
  </div>
  
</div>
Target <b>"<span style="color:darkgreen">parent</span>"</b> to turn <span style="color:red">red</span>.<br>
<b>Only</b> if it <b>has</b> a descendant of "change-parent".<br>
<br>
(reverse cascade, look ahead, parent un-descendant)
</html>

jQuery Referans Dokümanları:
$ () veya jQuery () : DOM öğesi.
. find : Seçili, jQuery nesnesi veya öğe tarafından filtrelenen geçerli eşleşen öğeler kümesindeki her öğenin torunlarını edinin.
. ebeveynler : Eşleşen öğeler kümesindeki her öğenin hemen önceki kardeşini edinin. Bir seçici sağlanırsa, yalnızca bu seçiciyle eşleşmesi durumunda önceki kardeşini alır (sonuçları yalnızca listelenen öğeleri / seçicileri içerecek şekilde filtreler).
. css : Eşleşen öğe kümesi için bir veya daha fazla CSS özelliği ayarlayın.


Bunun soru ile ilgisi yok. Tabii ki JS kullanmak mümkündür ve bunun için jQuery'ye bile ihtiyacınız yoktur ( previousElementSibling).
Fabian von Ellerts

1
@FabianvonEllerts OP'nin sorusunu doğrudan cevabımın ilk satırında cevapladım. Cevabımın da belirttiği gibi, CSS aracılığıyla kelimenin tam anlamıyla mümkün değil . Daha sonra , CSS kullanıcılarının aşina olabileceği ve erişebileceği bir teknoloji (JS | JQuery) kullanarak hedefe ulaşmak için 1 olası yol sağladım. Örneğin, birçok WordPress sitesinde JQuery de vardır, bu nedenle kolay bir giriş noktasıdır: kullanımı, hatırlanması ve genişletilmesi kolaydır. Sadece cevap vermek sorumsuzluk olur HAYIR hedefe ulaşmak için alternatif bir yol sağlamadan,. Aynı soruyu sorduğumda öğrendiklerimi ve kullandıklarımı paylaştım.
SherylHohman

previousElementSibling()yerel JS DOM işlevlerine daha aşina olanlar ileriye yönelik başka bir CSS dışı yol sağlayabilir .
SherylHohman

Diğer CSS HACKS'i çok ilginç buldum, ancak özel kullanım durumum için ya işe yaramadılar (uyarılar kategorisine düştüler) ya da çok kıvrıldılar. Aynı duruma giren diğerleri için, yukarıdaki çözümlerin başarısız olduğu veya uygulanması / sürdürülmesi çok zor olan, çalışabilen bu kullanımı kolay yöntemi paylaşmak adil olur. Birçok CSS HACKS paylaşıldı. Bu çalışma kapsamına girmedi. Yanıtlardan HİÇBİRİ +OP'nin özellikle istediği (var olmayan) seçiciyi kullanmaz. Bu yanıtı bir JS "hack" olarak düşünün. Bir çözüm bulmak için harcadığım zamanı kurtarmak için burada.
SherylHohman

2

Hiçbir "önceki" kardeş seçicisi maalesef, ama can muhtemelen hala konumlandırma (örn şamandıra hakkı) kullanarak aynı etkiyi elde. Ne yapmaya çalıştığınıza bağlıdır.

Benim durumumda, öncelikle CSS 5 yıldızlı derecelendirme sistemi istedim. Önceki yıldızları renklendirmem (veya simgeyi değiştirmem) gerekirdi. Her öğeyi doğru bir şekilde yüzerek, esasen aynı etkiyi elde ediyorum (yıldızlar için html 'geriye' yazılmalıdır).

Bu örnekte FontAwesome kullanıyorum ve fa-star-o ve fa-star unicodesları arasında geçiş yapıyorum http://fortawesome.github.io/Font-Awesome/

CSS:

.fa {
    display: inline-block;
    font-family: FontAwesome;
    font-style: normal;
    font-weight: normal;
    line-height: 1;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
}

/* set all stars to 'empty star' */
.stars-container {
    display: inline-block;      
}   

/* set all stars to 'empty star' */
.stars-container .star {
    float: right;
    display: inline-block;
    padding: 2px;
    color: orange;
    cursor: pointer;

}

.stars-container .star:before {
    content: "\f006"; /* fontAwesome empty star code */
}

/* set hovered star to 'filled star' */
.star:hover:before{
    content: "\f005"; /* fontAwesome filled star code */
}

/* set all stars after hovered to'filled star' 
** it will appear that it selects all after due to positioning */
.star:hover ~ .star:before {
    content: "\f005"; /* fontAwesome filled star code */
}

HTML: (40)

JSFiddle: http://jsfiddle.net/andrewleyva/88j0105g/


1
sağa doğru yüzer ve / +veya ~seçiciler bana en temiz iş olarak vurur.
Wylliam Judd

2

Kesin hedefinize bağlı olarak, bir ana seçici seçmeden bir tane kullanmadan faydalanmanın bir yolu vardır (biri olsa bile) ...

Diyelim ki:

<div>
  <ul>
    <li><a>Pants</a></li>
    <li><a>Socks</a></li>
    <ul>
      <li><a>White socks</a></li>
      <li><a>Blue socks</a></li>
    </ul>
  </ul>
</div>

Çorap bloğunu (çorap renkleri dahil) aralık kullanarak görsel olarak öne çıkarmak için ne yapabiliriz?

Güzel olan ama olmayan:

ul li ul:parent {
  margin-top: 15px;
  margin-bottom: 15px;
}

Ne var:

li > a {
  margin-top: 15px;
  display: block;
}
li > a:only-child {
  margin-top: 0px;
}

Bu, tüm bağlantı bağlantılarını üstte 15 piksel kenar boşluğuna sahip olacak şekilde ayarlar ve LI'lerde UL öğesi (veya başka etiketler) olmayanlar için 0'a sıfırlar.


2

Önceki kardeş tr seçmek için bir çözüm gerekiyordu. React ve Styled bileşenlerini kullanarak bu çözümü buldum. Bu benim kesin çözümüm değil (saatlerce sonra bellekten geliyor). SetHighlighterRow işlevinde bir kusur olduğunu biliyorum.

OnMouseOws üst üste satır dizinini duruma ayarlar ve önceki satırı yeni bir arka plan rengiyle yeniden oluşturur

class ReactClass extends Component {
  constructor() {
    this.state = {
       highlightRowIndex: null
    }
  }

  setHighlightedRow = (index) => {
    const highlightRowIndex = index === null ? null : index - 1;
    this.setState({highlightRowIndex});
  }

  render() {
    return (
       <Table>
        <Tbody>
           {arr.map((row, index) => {
                const isHighlighted = index === this.state.highlightRowIndex
                return {
                    <Trow 
                        isHighlighted={isHighlighted}
                        onMouseOver={() => this.setHighlightedRow(index)}
                        onMouseOut={() => this.setHighlightedRow(null)}
                        >
                        ...
                    </Trow>
                }
           })}  
        </Tbody>   
       </Table>
    )
  }
}

const Trow = styled.tr`
    & td {
        background-color: ${p => p.isHighlighted ? 'red' : 'white'};
    }

    &:hover {
        background-color: red;
    }
`;

-1

Benzer bir problemim vardı ve bu nitelikteki tüm problemlerin şu şekilde çözülebileceğini öğrendim:

  1. tüm öğelerinize bir stil verin.
  2. seçtiğiniz öğeye bir stil verin.
  3. sonraki öğelere + veya ~ kullanarak bir stil verin.

ve böylece mevcut, önceki öğelerinizi (geçerli ve sonraki öğelerle geçersiz kılınan tüm öğeler) ve sonraki öğelerinize stil uygulayabilirsiniz.

misal:

/* all items (will be styled as previous) */
li {
  color: blue;
}

/* the item i want to distinguish */
li.milk {
  color: red;
}

/* next items */
li ~ li  {
  color: green;
}


<ul>
  <li>Tea</li>
  <li class="milk">Milk</li>
  <li>Juice</li>
  <li>others</li>
</ul>

Umarım birine yardımcı olur.


1
temelde aynı iş parçacığının eski cevabı ile aynı hile: stackoverflow.com/a/27993987/717732
quetzalcoatl
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.