Verwenden Sie CSS, um „A“ am unteren Ende von „B“ auszurichten, wobei „B“ eine unbekannte Breite und einen unbekannten Textumbruch aufweist

9

Ich habe eine "sortierbare" Tabelle, in der die Kopfzeile der aktuell sortierten Spalte ein Symbol anzeigt:

Geben Sie hier die Bildbeschreibung ein

Das Sortiersymbol soll am Ende des Textes angezeigt werden (dh wir unterstützen LTR / RTL). Ich benutze gerade display:flex. Wenn jedoch die Tabellenbreite kleiner wird und der Text der Spaltenüberschrift zu umbrechen beginnt, stoße ich auf mehrdeutige Zustände, in denen nicht klar ist, welche Spalte sortiert ist:

Geben Sie hier die Bildbeschreibung ein

Stattdessen möchte ich folgende Anforderungen erfüllen:

  1. Das Symbol ist immer "eng" am "Ende" der längsten Textzeile ausgerichtet (auch wenn die Umbruchzelle / -schaltfläche breiter ist).
  2. Das Symbol sollte auch unten an der letzten Textzeile ausgerichtet sein.
  3. Das Symbol sollte niemals in eine eigene Zeile eingeschlossen werden.
  4. Die Schaltfläche muss vorhanden sein und sich über die gesamte Breite der Zelle erstrecken. (Das interne Design und das Markup können sich nach Bedarf ändern.)
  5. CSS und HTML nur wenn möglich.
  6. Es kann sich nicht auf bekannte / festgelegte Spaltenbreiten oder Kopfzeilentexte verlassen.

Zum Beispiel:

Geben Sie hier die Bildbeschreibung ein

Ich habe mit einer Reihe von verschiedenen Kombinationen zu experimentieren display: inline/inline-block/flex/grid, position, ::before/::afterund sogar float(!), Kann aber nicht das gewünschte Verhalten bekommen. Hier ist mein aktueller Code, der das Problem demonstriert:

.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>

Irgendwelche Ideen, wie man diese Benutzeroberfläche erreicht? Dies hat wahrscheinlich wenig mit dem Tisch- oder Knopfmaterial zu tun. Wirklich, ich muss Thing A"fest" unten / am Ende ausgerichtet sein Thing B(von einer flexiblen Breite und die Text umbrochen haben kann), Thing Akann aber nicht auf eine eigene Linie umbrechen.

Ich habe versucht, mit den flexWerten herumzuspielen , aber bei jeder Kombination wird der Text entweder vorzeitig oder nicht früh genug umbrochen.

robertwbradford
quelle
Ich habe versucht , das Problem mit Ihrem aktuellen CSS zu beheben und html jedoch die Taste und das span - Element kombiniert , wo Kopfschmerzen so dass ich font-awesome mit CSS zu verwenden , entschieden und html hier ist ein Beispiel , es hilft
stan chacon
@stanchacon danke für den Blick. Ich hätte es erwähnen sollen, aber ich werde nicht den Luxus haben, Spaltenbreiten festzulegen oder zu wissen, wie der Kopfzeilentext im Voraus aussehen wird. Ich habe # 6 zu den Anforderungen hinzugefügt.
Robertwbradford
1
@ Stanchacon ... und ich könnte jetzt für ein Ribeye gehen :)
robertwbradford
@robertwbradford Ist das schon angesprochen? Oder suchen Sie noch nach einer Lösung?
Furqan Rahamath
@MohammedFurqanRahamathM, dies wurde noch nicht beantwortet. Immer noch auf der Suche ...
Robertwbradford

Antworten:

1

Denken Sie, Sie brauchen JS dafür. Hier ist eine Antwort, die alle Bedingungen außer 5 erfüllen sollte.

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>

Sol
quelle
1

Ich denke, hier gibt es überhaupt kein Problem außer der visuellen Mehrdeutigkeit. Hier sind meine Beobachtungen.

  • Die Gegenstände sind tatsächlich fest gebunden. Standardmäßig folgt jedes Element einem anderen, sofern nicht anders angegeben.
  • Warum gibt es einen Abstand? Es gibt zwei Variationen davon
    • Erstens: Wenn sich der Text nicht in einem Umbruchelement befindet (der Zustand, in dem er sich gerade befindet). In diesem Szenario wird, da sowohl für Text als auch für die Spanne keine explizite Breite erwähnt wird, die Breite automatisch zugewiesen, und der Text versucht, die gesamte Breite mit Ausnahme der 1,25-fachen Breite zu erfassen, die das span-Element annimmt. Und gemäß der w3c-Dokumentation existieren die Regeln nur, um die Haltepunkte in einer bestimmten Zeichenfolge und nicht im Abstand zu identifizieren, da die Textausrichtung ein völlig anderes Problem darstellt. Bitte beziehen Sie sich auf dieses Problem, um zu verstehen, wie es gemacht wird. Es ist eine Standardfrage zur dynamischen Programmierung, die am College untersucht wurde. Während der Begründung ist natürlich ein Abstand vorhanden. Bitte beachten Sie die verfügbare Breite, die der Browser nicht reduzieren wird.
    • Zweitens: Wenn sich der Text in einem Umbruchelement befindet , kann dies span, p, div usw. sein. Auch in diesem Fall erfolgt die automatische Zuweisung der Breite, da keine Breite explizit angegeben wird. In diesem Fall können Sie im Inspect-Element tatsächlich sehen, dass das Element versucht, den gesamten Platz mit Ausnahme der Breite 1,25rem des Sortiersymbols einzunehmen.

Es gibt so enge Grenzen, dass nur der dynamische Abstand die visuelle Mehrdeutigkeit verursacht.

Wenn wir nun zur Lösung kommen, ist die nächste Lösung, die ich ohne JavaScript-Intervention finden könnte , obwohl sie nicht perfekt ist,

  • Wickeln Sie den Text in ein Element, möglicherweise eine Spanne
  • Begrenzen Sie die Breite dieses Textes, indem Sie eine maximale Breite angeben:

    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
    }

Hinweis: Das text-align: centerist nur die Wirkung des fehlenden Raum zu reduzieren, es sei denn , Sie strenge Anforderung habe nicht mit diesem zu gehen.

Bitte lassen Sie mich wissen, wenn dies Ihre Frage beantwortet.

So würde der Effekt sein: Geben Sie hier die Bildbeschreibung ein

Furqan Rahamath
quelle
Danke für die Antwort. Dafür müssen wir am Ende sein.
Robertwbradford
@robertwbradford Ich habe meine Antwort geändert und das mögliche Problem erläutert, mit dem Sie konfrontiert sind, und eine Lösung vorgeschlagen. Bitte lassen Sie mich wissen, wenn dies Ihre Frage beantwortet.
Furqan Rahamath
0

Ich denke du bist fast gut und vermisst die (3), was ein bisschen Trick ist. Eine Idee ist, das Symbolelement mit einer Breite gleich dem 0Leerzeichen zwischen dem Text und dem Sortiersymbol zu machen und zu deaktivieren. Dafür verwende ich einen zusätzlichen Wrapper für den Text und habe die Verwendung von Flexbox entfernt.

Sie werden einen gewissen Überlauf haben, aber dies ist kein Problem, da Sie Polster anwenden. Sie können auch erhöhen, padding-rightwenn Sie möchten

.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>

Temani Afif
quelle
Danke für die Antwort. Einige gute Punkte, aber ich sehe, dass es nicht die "Anforderung 1" erfüllt, bei der der Pfeil am Ende der längsten Textzeile ausgerichtet werden müsste. Im Fall von "Lieblingsfarbe" sollte das Symbol beim Umbrechen von "Farbe" in die zweite Zeile horizontal am Ende von "Favorit" ausgerichtet sein, wie im letzten Screenshot gezeigt.
Robertwbradford
1
@ Robertwbradford ah verstand es nicht so .. Ich dachte, es sollte eng mit dem letzten sein. Ich denke, Sie haben
kein
0

Wenn dein Thead-Titel nicht dynamisch ist, habe ich eine sehr einfache Lösung.

Dazu müssen Sie das letzte Wort des Titels und das SVG-Symbol in span zusammenfügen

zB: -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>

Entfernen Sie display: flex aus der .button-Klasse und geben Sie der hinzugefügten Spanne die Stilanzeige: inline-block

Da die Spanne ein Inline-Block ist, befindet sich das SVG-Symbol niemals in einer separaten Zeile. Es wird mindestens ein Wort davor stehen

Shirish Maharjan
quelle
Danke für Ihre Antwort. Ich
baue
Sie können Js verwenden, um das letzte Wort in span zu setzen. Es sollte nicht so schwer sein
Shirish Maharjan
0

Sie könnten es so versuchen:

<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>

Hoffe, diese Antwort wird Ihnen helfen. Ich habe kein CSS für die mobile Ansicht erstellt!

Krishna Savani
quelle