ใช้ CSS วิธีการ“ จัดแน่น” จัด“ A” ไปที่ด้านล่าง / สิ้นสุดของ“ B” โดยที่“ B” มีความกว้างและการตัดข้อความที่ไม่รู้จัก


9

ฉันมีตาราง "sortable" ที่ส่วนหัวของคอลัมน์เรียงปัจจุบันแสดงไอคอน:

ป้อนคำอธิบายรูปภาพที่นี่

ไอคอนการเรียงจะแสดงที่ท้ายข้อความ (เช่นเรากำลังสนับสนุน LTR / RTL) display:flexฉันกำลังใช้ อย่างไรก็ตามหากความกว้างของตารางลดลงและข้อความส่วนหัวของคอลัมน์เริ่มล้อมรอบฉันทำงานในสถานะที่ไม่ชัดเจนซึ่งไม่ชัดเจนว่าจะเรียงคอลัมน์ใด:

ป้อนคำอธิบายรูปภาพที่นี่

ฉันต้องการที่จะปฏิบัติตามข้อกำหนดต่อไปนี้แทน:

  1. ไอคอนจะถูก "ชิด" เสมอกับ "จุดสิ้นสุด" ของบรรทัดข้อความที่ยาวที่สุด (แม้ว่าเซลล์ / ปุ่มตัดจะกว้างขึ้น)
  2. ไอคอนควรจัดเรียงชิดล่างสุดกับแถวสุดท้ายของข้อความ
  3. ไอคอนไม่ควรพันบนบรรทัดของมันเอง
  4. ปุ่มต้องมีอยู่และควรขยายความกว้างเต็มของเซลล์ (เป็นสไตล์ภายในและมาร์กอัปสามารถเปลี่ยนแปลงได้ตามต้องการ)
  5. CSS และ HTML เฉพาะในกรณีที่เป็นไปได้ทั้งหมด
  6. ไม่สามารถพึ่งพาความกว้างของคอลัมน์ที่ทราบ / ชุดหรือข้อความส่วนหัว

ตัวอย่างเช่น:

ป้อนคำอธิบายรูปภาพที่นี่

ฉันได้รับการทดสอบด้วยพวงของการรวมกันของdisplay: inline/inline-block/flex/grid, position, ::before/::afterและแม้กระทั่งfloat(!) แต่ไม่สามารถรับพฤติกรรมที่ต้องการ นี่คือรหัสปัจจุบันของฉันแสดงให้เห็นถึงปัญหา:

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

ความคิดใด ๆ เกี่ยวกับวิธีการบรรลุ UI นี้? สิ่งนี้อาจมีส่วนเกี่ยวข้องกับตารางหรือปุ่มเล็กน้อย จริง ๆ แล้วฉันต้องการThing A"แน่นหนา" ด้านล่าง / สิ้นสุดจัดชิดกับThing B(ของความกว้างที่ยืดหยุ่นและซึ่งสามารถมีข้อความที่ห่อ) แต่Thing Aไม่สามารถห่อลงบนบรรทัดของตัวเอง

ฉันได้ลองทำล้อเล่นกับflexค่าต่างๆ แต่การรวมกันใด ๆ ก็ทำให้การห่อข้อความก่อนกำหนดหรือไม่เร็วพอ


ผมพยายามที่จะแก้ไขปัญหาของคุณกับ CSS ปัจจุบันของคุณและ HTML แต่ปุ่มและบรรยากาศช่วงรวมที่ปวดหัวดังนั้นผมจึงตัดสินใจที่จะใช้ตัวอักษรที่น่ากลัวด้วย CSS และ HTML ที่นี่เป็นตัวอย่างความหวังว่ามันจะช่วย
สแตน Chacon

@statacon ขอบคุณสำหรับการดู ฉันควรจะพูดถึง แต่ฉันจะไม่มีความหรูหราในการตั้งค่าความกว้างของคอลัมน์หรือรู้ว่าส่วนหัวของข้อความจะเป็นล่วงหน้า ฉันเพิ่ม # 6 เข้ากับข้อกำหนด
robertwbradford

1
@stanchacon ... และฉันจะไปหาริบอายได้แล้ว :)
robertwbradford

@robertwbradford นี่พูดถึงแล้วหรือยัง หรือคุณยังมองหาวิธีแก้ปัญหาอยู่?
Furqan Rahamath

@MohammedFurqanRahamathM ยังไม่ได้รับคำตอบ ยังคงมองหา ...
robertwbradford

คำตอบ:


1

คิดว่าคุณต้องการ JS สำหรับสิ่งนี้ นี่คือคำตอบที่ควรตรงตามเงื่อนไขทั้งหมดยกเว้น 5

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

ฉันคิดว่าไม่มีปัญหาเลยยกเว้นความกำกวมทางสายตา นี่คือข้อสังเกตของฉัน

  • รายการในความเป็นจริงจะถูกผูกไว้แน่น โดยค่าเริ่มต้นองค์ประกอบใด ๆ จะตามมาอีกเว้นแต่จะระบุไว้เป็นอย่างอื่น
  • ทำไมจึงมีระยะห่าง มีสองรูปแบบของสิ่งเหล่านี้
    • ครั้งแรก: หากข้อความไม่ได้อยู่ในองค์ประกอบห่อ (สถานะที่อยู่ในตอนนี้) ในสถานการณ์นี้เนื่องจากไม่มีความกว้างที่กล่าวถึงอย่างชัดเจนสำหรับทั้งข้อความและการขยายจึงมีการกำหนดความกว้างโดยอัตโนมัติและข้อความพยายามที่จะความกว้างทั้งหมดยกเว้นความกว้าง 1.25rem ที่องค์ประกอบการขยายกำลังดำเนินการ และตามเอกสาร w3c กฎมีอยู่เพื่อระบุจุดพักบนสตริงที่กำหนดและไม่เว้นวรรคเนื่องจากการจัดข้อความเป็นปัญหาที่แตกต่างกันโดยสิ้นเชิง โปรดอ้างอิงปัญหานี้เพื่อทำความเข้าใจวิธีการทำคำถามการเขียนโปรแกรมแบบไดนามิกมาตรฐานที่เรียนในวิทยาลัย ดังนั้นการเว้นวรรคของหลักสูตรจะเกิดขึ้นในขณะที่ให้เหตุผลและโปรดจำความกว้างที่มีอยู่ซึ่งเบราว์เซอร์จะไม่ยุบ
    • ข้อที่สอง: หากข้อความอยู่ในองค์ประกอบการตัดอาจเป็น span, p, div ฯลฯ ในกรณีนี้การกำหนดความกว้างอัตโนมัติจะเกิดขึ้นเนื่องจากไม่มีการระบุความกว้างอย่างชัดเจน และในกรณีนี้คุณสามารถเห็นองค์ประกอบตรวจสอบว่าองค์ประกอบพยายามครอบครองพื้นที่ทั้งหมดยกเว้นความกว้าง 1.25rem ของไอคอนการเรียงลำดับ

มีขอบเขตที่แน่นอยู่เพียงระยะห่างแบบไดนามิกทำให้เกิดความกำกวมทางสายตา

ตอนนี้มาถึงทางออกทางออกที่ใกล้ที่สุดที่ฉันสามารถทำได้โดยไม่มีการแทรกแซง JavaScriptแม้ว่าจะไม่สมบูรณ์ก็คือ

  • ล้อมรอบข้อความภายในองค์ประกอบอาจเป็นช่วง
  • จำกัดความกว้างของข้อความนี้โดยให้ความกว้างสูงสุด:

    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
    }

หมายเหตุ:text-align: centerเป็นเพียงเพื่อลดผลกระทบของพื้นที่หายไปจนกว่าคุณจะได้ความต้องการที่เข้มงวดจะไม่ไปกับเรื่องนี้

โปรดแจ้งให้เราทราบหากสิ่งนี้ตอบคำถามของคุณ

นี่คือผลกระทบที่เกิดขึ้น: ป้อนคำอธิบายรูปภาพที่นี่


ขอบคุณสำหรับการตอบกลับ. สำหรับสิ่งนี้เรามีความต้องการที่จะเป็นที่สุด
robertwbradford

@robertwbradford ฉันได้เปลี่ยนคำตอบของฉันเพื่ออธิบายปัญหาที่เป็นไปได้ที่คุณเผชิญและเสนอวิธีแก้ปัญหา โปรดแจ้งให้เราทราบหากนี่เป็นคำตอบสำหรับคำถามของคุณ
Furqan Rahamath

0

ฉันคิดว่าคุณเกือบดีและหายไป (3) ซึ่งเป็นเคล็ดลับเล็กน้อย แนวคิดคือการทำให้องค์ประกอบไอคอนมีความกว้างเท่ากับ0และปิดช่องว่างใด ๆ ระหว่างข้อความและไอคอนการเรียงลำดับ สำหรับเรื่องนี้ฉันใช้ wrapper พิเศษสำหรับข้อความและลบการใช้ flexbox

คุณจะมีบางอย่างที่ล้น แต่ก็ไม่เป็นปัญหาเนื่องจากคุณกำลังใช้การเติมเต็ม คุณสามารถเพิ่มpadding-rightถ้าคุณต้องการ

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


ขอบคุณสำหรับการตอบกลับ. บางจุดที่ดี แต่ฉันเห็นมันไม่ตรงกับ "ความต้องการ 1" ซึ่งลูกศรจะต้องสอดคล้องกับจุดสิ้นสุดของข้อความที่ยาวที่สุด ในกรณีของ "Favorite Color" เมื่อ "Color" ตัดไปยังบรรทัดที่สองไอคอนควรจัดแนวในแนวนอนกับส่วนท้ายของ "Favorite" ตามที่แสดงในภาพหน้าจอล่าสุด
robertwbradford

1
@robertwbradford อาไม่เข้าใจอย่างนั้น .. ฉันคิดว่ามันควรจะแน่นกับอันสุดท้าย ฉันคิดว่าคุณไม่มีโชคสำหรับข้อกำหนดนี้ ...
Temani Afif

0

หากชื่อเรื่องของคุณไม่ได้เป็นแบบไดนามิกแล้วฉันมีการแก้ไขที่ง่ายมาก

สำหรับสิ่งนี้คุณจะต้องใส่คำสุดท้ายของชื่อและไอคอน svg ในการรวมกัน

เช่น: -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>

ลบจอแสดงผล: งอจากคลาส. ปุ่มและแสดงสไตล์: บล็อกแบบอินไลน์เพื่อเพิ่มช่วง

เนื่องจากการขยายเป็นแบบอินไลน์บล็อกไอคอน svg จะไม่อยู่ในบรรทัดที่แยกออกจากกัน อย่างน้อยจะมีหนึ่งคำที่อยู่ข้างหน้า


ขอบคุณสำหรับการตอบกลับ. ฉันกำลังสร้างสิ่งนี้เป็นส่วนประกอบดังนั้นข้อความไตเติ้ลจะเป็นแบบไดนามิก :(
robertwbradford

คุณสามารถใช้ Js เพื่อใส่คำสุดท้ายในช่วง ไม่ควรยากนัก
Shirish

0

คุณสามารถลองสิ่งนี้:

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

หวังว่าคำตอบนี้จะเป็นประโยชน์กับคุณฉันไม่ได้ทำ CSS สำหรับมุมมองมือถือ!

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.