CSS kullanarak, “A” nın “B” nin bilinmeyen genişliği ve metin kaydırması olduğu “A” nın “B” altına / sonuna nasıl “sıkıca” hizalanması


9

Şu anda sıralanmış sütunun başlığının bir simge görüntülediği bir "sıralanabilir" tablo var:

resim açıklamasını buraya girin

Sıralama simgesi metnin sonunda görüntülenecektir (yani, LTR / RTL'yi destekliyoruz). Şu anda kullanıyorum display:flex. Ancak, tablo genişliği küçülürse ve sütun başlığı metni sarılmaya başlarsa, hangi sütunun sıralandığı net olmayan belirsiz durumlara girerim:

resim açıklamasını buraya girin

Bunun yerine aşağıdaki gereksinimleri karşılamak istiyorum:

  1. Simge her zaman metnin en uzun satırının "ucu" ile "sıkıca" hizalanır (kaydırma hücresi / düğmesi daha geniş olsa bile).
  2. Simge ayrıca metnin son satırıyla aşağıya hizalanmalıdır.
  3. Simge asla kendi çizgisine sarılmamalıdır.
  4. Düğme mevcut olmalı ve hücrenin tüm genişliğini kaplamalıdır. (İç tasarım ve işaretleme gerektiğinde değişebilir.)
  5. CSS ve HTML yalnızca mümkünse.
  6. Bilinen / ayarlanan sütun genişliklerine veya başlık metnine güvenemez.

Örneğin:

resim açıklamasını buraya girin

Ben farklı kombinasyonları bir grup ile deneme oldum display: inline/inline-block/flex/grid, position, ::before/::afterve hatta float(!) Ancak istenen davranışı elde edemezsiniz. İşte benim mevcut kod sorunu gösteren:

.table {
  border-collapse: collapse;
  width: 100%;
}

.thead {
  border-bottom: 3px solid #d0d3d3;
}

.thead .tr {
  vertical-align: bottom;
}

.button {
  padding: 1rem;
  text-align: start;
  font-family: Arial, "noto sans", sans-serif;
  font-size: 0.875rem;
  border: 0;
  background-color: transparent;
  width: 100%;
  display: flex;
  align-items: flex-end;
  font-weight: bold;
  line-height: 1.4;
}

.sort {
  width: 1.25rem;
  height: 1.25rem;
}
<table class="table">
  <thead class="thead">
    <tr class="tr">
      <th class="th">
        <button class="button">
          Age
          <span class="sort"></span>
         </button>
      </th>
      <th class="th">
        <button class="button">
          Favorite Food
          <span class="sort"></span>
        </button>
      </th>
      <th class="th" aria-sort="ascending">
        <button class="button">
          Favorite Color
          <span class="sort">
            <svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" role="presentation" style="width: 1.25rem; height: 1.25rem;"> <path d="M11.4709 4.2136C11.7638 3.92071 12.2386 3.92071 12.5315 4.2136L17.1277 8.8098C17.4206 9.10269 17.4206 9.57756 17.1277 9.87046C16.8348 10.1633 16.3599 10.1633 16.0671 9.87046L12.7512 6.55459V19.25C12.7512 19.6642 12.4154 20 12.0012 20C11.587 20 11.2512 19.6642 11.2512 19.25V6.55459L7.93533 9.87046C7.64244 10.1633 7.16756 10.1633 6.87467 9.87046C6.58178 9.57756 6.58178 9.10269 6.87467 8.8098L11.4709 4.2136Z"> </path></svg>
          </span>
        </button>
      </th>
      <th class="th">
        <button class="button">
          Likes Neil Diamond?
          <span class="sort"></span>
        </button>
      </th>
    </tr>
  </thead>
</table>

Bu kullanıcı arayüzünü nasıl gerçekleştireceğiniz hakkında bir fikriniz var mı? Bu muhtemelen tablo veya düğme şeyler ile ilgisi yoktur. Gerçekten ( Thing Asıkı Thing Bbir genişlik ve sarılmış metin Thing Aolabilir ) hizalanmış "sıkı" alt / uç gerekir ama kendi bir çizgi üzerine sarın olamaz.

Ben flexdeğerleri ile karışıklık denedim ama herhangi bir kombinasyon ya metin sargı erken yapar ya da yakında değil.


Mevcut css ve html ile sorununuzu düzeltmeye çalıştım, ancak düğme ve span öğesi bir baş ağrısının birleştiği bir yerde, bu yüzden css ve html ile font-awesome kullanmaya karar verdim, yardımcı olan bir örnek umut
stan chacon

@stanchacon Bir göz attığınız için teşekkürler. Bahsetmeliydim, ancak sütun genişliklerini ayarlama veya başlık metninin önceden ne olacağını bilmeme lüksüne sahip olmayacağım. Gereksinimlere # 6 ekledim.
robertwbradford

1
@stanchacon ... ve şu an bir ribeye için gidebilirim :)
robertwbradford

@robertwbradford Bu zaten ele alınmış mı? Yoksa hala bir çözüm mü arıyorsunuz?
Furqan Rahamath

@MohammedFurqanRahamathM, bu henüz cevaplanmadı. Hala bakıyor ...
robertwbradford

Yanıtlar:


1

Bunun için JS'ye ihtiyacınız olduğunu düşünün. İşte 5 dışındaki tüm koşulları karşılaması gereken bir cevap.

const debounce = fn => {
  let frame;

  return (...params) => {
    if (frame) {
      cancelAnimationFrame(frame);
    }
    frame = requestAnimationFrame(() => {
      fn(...params);
    });
  };
};

const text = [...document.querySelectorAll(".text")];
const iconWidth = "1.25rem";

const positionIcon = () => {
  if (!text) return;
  
  text.forEach(t => {
    const width = t.getBoundingClientRect().width;

    const icon = t.nextElementSibling;
    if (!icon) return;
    
    icon.style.left = `calc(${width}px + ${iconWidth})`;
  });
};

positionIcon();
window.addEventListener("resize", debounce(positionIcon));
.table {
  border-collapse: collapse;
  width: 100%;
}

.thead {
  border-bottom: 3px solid #d0d3d3;
}

.thead .tr {
  vertical-align: bottom;
}

.button {
  padding: 1rem;
  text-align: start;
  font-family: Arial, "noto sans", sans-serif;
  font-size: 0.875rem;
  border: 0;
  background-color: transparent;
  width: 100%;
  font-weight: bold;
  line-height: 1.4;
  position: relative;
}

.sort {
  width: 1.25rem;
  height: 1.25rem;
  position: absolute;
  bottom: 1rem;
  left: 100%; /* no js fallback */
}

.sort svg {
  height: 1.25rem;
  width: 1.25rem;
}
<svg xmlns="http://www.w3.org/2000/svg" style="display: none;">
   <svg id="arrow" viewBox="0 0 24 24" role="presentation"> <path d="M11.4709 4.2136C11.7638 3.92071 12.2386 3.92071 12.5315 4.2136L17.1277 8.8098C17.4206 9.10269 17.4206 9.57756 17.1277 9.87046C16.8348 10.1633 16.3599 10.1633 16.0671 9.87046L12.7512 6.55459V19.25C12.7512 19.6642 12.4154 20 12.0012 20C11.587 20 11.2512 19.6642 11.2512 19.25V6.55459L7.93533 9.87046C7.64244 10.1633 7.16756 10.1633 6.87467 9.87046C6.58178 9.57756 6.58178 9.10269 6.87467 8.8098L11.4709 4.2136Z"> </path></svg>
</svg>
<table class="table">
  <thead class="thead">
    <tr class="tr">
      <th class="th">
        <button class="button">
          <span class="text">Age</span>
          <span class="sort">
            <svg>
              <use xlink:href="#arrow">
            </svg>
          </span>
         </button>
      </th>
      <th class="th">
        <button class="button">
          <span class="text">Favourite Food</span>
          <span class="sort">
          <svg>
              <use xlink:href="#arrow">
            </svg>
          </span>
        </button>
      </th>
      <th class="th" aria-sort="ascending">
        <button class="button">
          <span class="text">Favorite Color</span>
          <span class="sort">
            <svg>
              <use xlink:href="#arrow">
            </svg>
          </span>
        </button>
      </th>
      <th class="th">
        <button class="button">
          <span class="text">Likes Neil Diamond?</span>
          <span class="sort">
            <svg>
              <use xlink:href="#arrow">
            </svg>
          </span>
        </button>
      </th>
    </tr>
  </thead>
</table>


1

Sanırım burada görsel belirsizlik dışında hiçbir sorun yok. İşte benim gözlemlerim.

  • Aslında öğeler sıkı sıkıya bağlıdır. Varsayılan olarak, aksi belirtilmedikçe herhangi bir öğe diğerini izler.
  • Neden boşluk var? Bunların iki varyasyonu vardır
    • İlk olarak: Metin herhangi bir sarma öğesinin (şu anda bulunduğu durum) içinde değilse . Bu senaryoda, açıkça belirtilen genişlik olmadığından, hem metin hem de span için otomatik genişlik ataması vardır ve metin, span öğesinin aldığı 1.25rem genişlik hariç tüm genişliğe çalışır. Ve w3c belgelerine göre, kurallar yalnızca belirli bir dizgideki kesme noktalarını tanımlamak için kullanılır, boşluk bırakmaz, çünkü metin yaslaması tamamen farklı bir sorundur. Nasıl yapıldığını anlamak için lütfen bu probleme bakın, bu üniversitede incelenen standart bir Dinamik programlama sorusu. Tabii ki, gerekçelendirme yaparken boşluk kalacak ve lütfen tarayıcının çökmeyeceği mevcut genişliği unutmayın.
    • İkincisi: Metin bir kaydırma öğesinin içindeyse , yayılma alanı, p, div vb. Olabilir. Bu durumda, genişlik otomatik olarak atanması, açıkça bir genişlik belirtilmediğinden gerçekleşir. Ve bu durumda, aslında inceleme öğesinde, öğenin sıralama simgesinin 1.25rem genişliği dışında tüm alanı işgal etmeye çalıştığını görebilirsiniz.

Çok sıkı sınırlama var, sadece dinamik boşluk görsel belirsizliğe neden oluyor.

Şimdi çözüme gelince , mükemmel olmasa da, JavaScript müdahalesi olmadan karşılaşabileceğim en yakın çözüm ,

  • Metni bir öğenin içine sarın, belki bir açıklık
  • Maksimum genişlik vererek bu metnin genişliğini sınırlayın:

    button.button > span {
        max-width: 60%; // I saw this to be decent enough
        text-align: center; // This is to offset the visual effect of spacing
    }

Not: Bununla text-align: centerbirlikte gitmemek için katı bir gereksiniminiz yoksa, sadece eksik alanın etkisini azaltmaktır.

Bunun sorunuza yanıt verip vermediğini lütfen bildirin.

Etkisi şöyle olur: resim açıklamasını buraya girin


Yanıtınız için teşekkürler. Bunun için sonunda olması şarttır.
robertwbradford

@robertwbradford Karşılaştığınız olası sorunu açıklayarak cevabımı değiştirdim ve bir çözüm önerdim. Bunun sorunuza cevap verip vermediğini lütfen bize bildirin.
Furqan Rahamath

0

Sanırım neredeyse iyi ve biraz hile olan (3) eksik. Bir fikir, genişliğe sahip simge öğesini 0metin ve sıralama simgesi arasındaki boşluğa eşit yapmak ve devre dışı bırakmaktır. Bunun için metin için ekstra bir sargı kullanıyorum ve flexbox kullanımını kaldırdım.

Biraz taşacaksınız, ancak dolgu uyguladığınız için bu bir sorun değil. Ayrıca artırabilir padding-rightİstersen

.table {
  border-collapse: collapse;
  width: 100%;
}

.thead {
  border-bottom: 3px solid #d0d3d3;
}

.thead .tr {
  vertical-align: bottom;
}

.button {
  padding: 1rem;
  text-align: start;
  font-family: Arial, "noto sans", sans-serif;
  font-size:0;
  border: 0;
  background-color: transparent;
  width: 100%;
  font-weight: bold;
  line-height: 1.4;
}
.button > span {
  font-size: 0.875rem;
}
.sort {
  width: 0;
  height: 1.25rem;
  display: inline-block;
  vertical-align: bottom;
}
<table class="table">
  <thead class="thead">
    <tr class="tr">
      <th class="th">
        <button class="button">
          <span>Age</span>
          <span class="sort"></span>
         </button>
      </th>
      <th class="th">
        <button class="button">
          <span>Favorite Food</span>
          <span class="sort"></span>
        </button>
      </th>
      <th class="th" aria-sort="ascending">
        <button class="button">
          <span>Favorite Color</span>
          <span class="sort">
            <svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" role="presentation" style="width: 1.25rem; height: 1.25rem;"> <path d="M11.4709 4.2136C11.7638 3.92071 12.2386 3.92071 12.5315 4.2136L17.1277 8.8098C17.4206 9.10269 17.4206 9.57756 17.1277 9.87046C16.8348 10.1633 16.3599 10.1633 16.0671 9.87046L12.7512 6.55459V19.25C12.7512 19.6642 12.4154 20 12.0012 20C11.587 20 11.2512 19.6642 11.2512 19.25V6.55459L7.93533 9.87046C7.64244 10.1633 7.16756 10.1633 6.87467 9.87046C6.58178 9.57756 6.58178 9.10269 6.87467 8.8098L11.4709 4.2136Z"> </path></svg>
          </span>
        </button>
      </th>
      <th class="th">
        <button class="button">
          <span>Likes Neil Diamond?</span>
          <span class="sort"></span>
        </button>
      </th>
    </tr>
  </thead>
</table>


Yanıtınız için teşekkürler. Bazı iyi noktalar, ama okun en uzun metin satırının sonuna hizalanması gereken "gereksinim 1" karşılamayan görüyorum. "Sık Kullanılan Renk" durumunda, "Renk" ikinci satıra sarıldığında, simge son ekran görüntüsünde gösterildiği gibi "Sık Kullanılan" ın sonuna yatay olarak hizalanmalıdır.
robertwbradford

1
@robertwbradford ah bu şekilde anlamadı .. Sonuncusu ile sıkı olması gerektiğini düşündüm. Sanırım bu gereksinim için şansın yok ...
Temani Afif

0

senin başlık başlığı dinamik değilse o zaman ben çok kolay düzeltme var.

bunun için başlık ve svg simgesinin son kelimesini açıklığa koymanız gerekir

örneğin: -HTML

<button>
 Long 

<span> title 
 <svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" role="presentation" style="width: 1.25rem; height: 1.25rem;"> <path d="M11.4709 4.2136C11.7638 3.92071 12.2386 3.92071 12.5315 4.2136L17.1277 8.8098C17.4206 9.10269 17.4206 9.57756 17.1277 9.87046C16.8348 10.1633 16.3599 10.1633 16.0671 9.87046L12.7512 6.55459V19.25C12.7512 19.6642 12.4154 20 12.0012 20C11.587 20 11.2512 19.6642 11.2512 19.25V6.55459L7.93533 9.87046C7.64244 10.1633 7.16756 10.1633 6.87467 9.87046C6.58178 9.57756 6.58178 9.10269 6.87467 8.8098L11.4709 4.2136Z"> </path></svg>
</span>
</button>

display'i kaldır: .button sınıfından flex ve style display ver: eklenen açıklığa satır içi blok

span inline-block olduğundan svg simgesi asla ayrı satırda olmayacaktır. önünde en az bir kelime olacak


Cevabınız için teşekkür ederim. Bunu bir bileşen olarak inşa ediyorum, bu yüzden başlık metni dinamik olacak :(
robertwbradford

Son kelimeyi yayına koymak için Js tuşunu kullanabilirsiniz. O kadar zor olmamalı
Shirish Maharjan

0

Böyle deneyebilirsiniz:

<style>

.table {
  border-collapse: collapse;
  width: 100%;
}

.thead {
  border-bottom: 3px solid #d0d3d3;
}

.thead .tr {
  vertical-align: bottom;
}


.button {
  padding: 1rem;
  text-align: start;
  font-family: Arial, "noto sans", sans-serif;
  font-size: 0.875rem;
  border: 0;
  background-color: transparent;
    
 /* display: flex;
  align-items: flex-end;*/
  font-weight: bold;
  line-height: 1.4;
  float: left;
}
@media only screen and (min-width:502px)
{.button {
    width: calc(192px - 89px);
  }
  .button.food {
    width: calc(214px - 89px);
}
}

.sort {
  width: 1.25rem;
  height: 1.25rem;
  position: relative;
}
.sort svg {
  position: absolute;
}
</style>
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <table class="table">
  <thead class="thead">
    <tr class="tr">
      <th class="th">
        <button class="button">
          Age
          <span class="sort"></span>
         </button>
      </th>
      <th class="th">
        <button class="button food">
          Favorite Food
          <span class="sort"></span>
        </button>
      </th>
      <th class="th" aria-sort="ascending">
        <button class="button">
          Favorite Color
          <span class="sort">
            <svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" role="presentation" style="width: 1.25rem; height: 1.25rem;"> <path d="M11.4709 4.2136C11.7638 3.92071 12.2386 3.92071 12.5315 4.2136L17.1277 8.8098C17.4206 9.10269 17.4206 9.57756 17.1277 9.87046C16.8348 10.1633 16.3599 10.1633 16.0671 9.87046L12.7512 6.55459V19.25C12.7512 19.6642 12.4154 20 12.0012 20C11.587 20 11.2512 19.6642 11.2512 19.25V6.55459L7.93533 9.87046C7.64244 10.1633 7.16756 10.1633 6.87467 9.87046C6.58178 9.57756 6.58178 9.10269 6.87467 8.8098L11.4709 4.2136Z"> </path></svg>
          </span>
        </button>
      </th>
      <th class="th">
        <button class="button">
          Likes Neil Diamond?
          <span class="sort"></span>
        </button>
      </th>
    </tr>
  </thead>
</table>

Umarım bu cevap size yardımcı olacaktır. Mobil görünüm için css yapmadım!

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.