Sử dụng CSS, làm thế nào để chặt chẽ và sắp xếp chặt chẽ, sắp xếp một cách chặt chẽ và sắp xếp văn bản


9

Tôi có một bảng "có thể sắp xếp" trong đó tiêu đề của cột hiện được sắp xếp sẽ hiển thị một biểu tượng:

nhập mô tả hình ảnh ở đây

Biểu tượng sắp xếp sẽ được hiển thị ở cuối văn bản (nghĩa là chúng tôi đang hỗ trợ LTR / RTL). Tôi hiện đang sử dụng display:flex. Tuy nhiên, nếu chiều rộng bảng co lại và văn bản tiêu đề cột bắt đầu bao bọc, tôi chạy vào trạng thái mơ hồ nơi không rõ cột nào được sắp xếp:

nhập mô tả hình ảnh ở đây

Thay vào đó tôi muốn đáp ứng các yêu cầu sau:

  1. Biểu tượng luôn được căn chỉnh "chặt chẽ" với "kết thúc" của dòng văn bản dài nhất (ngay cả khi ô / nút gói rộng hơn).
  2. Biểu tượng cũng phải được căn dưới cùng với hàng văn bản cuối cùng.
  3. Biểu tượng không bao giờ nên quấn vào một dòng của riêng nó.
  4. Nút phải có mặt và phải trải rộng toàn bộ chiều rộng của ô. (Đó là kiểu dáng bên trong và đánh dấu có thể thay đổi khi cần thiết.)
  5. CSS và HTML chỉ khi có thể.
  6. Nó không thể dựa vào độ rộng cột đã biết / đặt hoặc tiêu đề văn bản.

Ví dụ:

nhập mô tả hình ảnh ở đây

Tôi đã thử nghiệm với một loạt các kết hợp khác nhau của display: inline/inline-block/flex/grid, position, ::before/::after, và thậm chí float(!) Nhưng không thể có được những hành vi mong muốn. Đây là mã hiện tại của tôi chứng minh vấn đề:

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

Bất kỳ ý tưởng về làm thế nào để thực hiện giao diện người dùng này? Điều này có lẽ ít liên quan đến bảng hoặc công cụ nút. Thực sự tôi cần Thing Ađáy / cuối "chặt chẽ" được căn chỉnh theo Thing B(có chiều rộng linh hoạt và có thể có văn bản được bọc) nhưng Thing Akhông thể quấn vào một dòng của chính nó.

Tôi đã cố gắng làm rối tung các flexgiá trị nhưng bất kỳ sự kết hợp nào cũng làm cho văn bản bị gói sớm hoặc không đủ sớm.


Tôi đã cố gắng khắc phục sự cố của bạn với css và html hiện tại của bạn, tuy nhiên nút và phần tử span kết hợp với nhau gây đau đầu nên tôi quyết định sử dụng font-awesome với css và html ở đây là một ví dụ hy vọng nó sẽ giúp
stan chacon

@stanchacon cảm ơn bạn đã xem. Tôi nên đã đề cập, nhưng tôi sẽ không có sự xa xỉ trong việc thiết lập độ rộng cột hoặc biết văn bản tiêu đề nào sẽ đi trước thời đại. Tôi đã thêm # 6 vào các yêu cầu.
robertwbradford

1
@stanchacon ... và tôi có thể đi lấy ribeye ngay bây giờ :)
robertwbradford

@robertwbradford Điều này đã được giải quyết chưa? Hay bạn vẫn đang tìm kiếm một giải pháp?
Furqan Rahamath

@MohammedFurqanRahamathM, điều này chưa được trả lời. Vẫn đang tìm kiếm ...
robertwbradford

Câu trả lời:


1

Hãy nghĩ rằng bạn cần JS cho việc này. Đây là một câu trả lời phải đáp ứng tất cả các điều kiện ngoại trừ 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

Tôi nghĩ rằng không có vấn đề nào ở đây ngoại trừ sự mơ hồ về thị giác. Dưới đây là những quan sát của tôi.

  • Các mặt hàng trong thực tế bị ràng buộc chặt chẽ. Theo mặc định, bất kỳ yếu tố nào cũng sẽ theo sau trừ khi có quy định khác.
  • Tại sao có một khoảng cách? Có hai biến thể của
    • Đầu tiên: Nếu văn bản không nằm trong bất kỳ phần tử bao bọc nào (trạng thái mà nó đang ở ngay bây giờ). Trong kịch bản này, vì không có chiều rộng được đề cập rõ ràng, cho cả văn bản cũng như khoảng thời gian, có tự động gán chiều rộng và văn bản đang cố gắng cho tất cả chiều rộng ngoại trừ chiều rộng 1,25rem mà phần tử span đang lấy. Và theo tài liệu của w3c, các quy tắc chỉ tồn tại để xác định các điểm dừng trên một chuỗi nhất định và không có khoảng cách, bởi vì chứng minh văn bản là một vấn đề hoàn toàn khác. Vui lòng tham khảo vấn đề này để hiểu cách nó được thực hiện, một câu hỏi lập trình động tiêu chuẩn được nghiên cứu ở trường đại học. Vì vậy, tất nhiên khoảng cách sẽ tồn tại trong khi thực hiện biện minh và xin vui lòng nhớ chiều rộng có sẵn, mà trình duyệt sẽ không sụp đổ.
    • Thứ hai: Nếu văn bản nằm trong phần tử gói , có thể là span, p, div, v.v. Trong trường hợp này cũng vậy, việc tự động gán chiều rộng xảy ra vì không có chiều rộng được chỉ định rõ ràng. Và trong trường hợp này, bạn thực sự có thể thấy trong phần tử kiểm tra phần tử đó cố gắng chiếm toàn bộ không gian ngoại trừ chiều rộng 1,25rem của biểu tượng sắp xếp.

Vì vậy, giới hạn chặt chẽ , không tồn tại, chỉ khoảng cách động đó là gây ra sự mơ hồ thị giác.

Bây giờ đến với giải pháp, giải pháp gần nhất mà tôi có thể đưa ra mà không cần sự can thiệp của JavaScript , mặc dù không hoàn hảo, là,

  • Gói văn bản bên trong một phần tử, có thể là một khoảng
  • Giới hạn chiều rộng của văn bản này bằng cách cho chiều rộng tối đa:

    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
    }

Lưu ý: Điều text-align: centernày chỉ để giảm ảnh hưởng của không gian bị thiếu, trừ khi bạn yêu cầu nghiêm ngặt không đi kèm với điều này.

Xin vui lòng cho tôi biết nếu điều này giải quyết câu hỏi của bạn.

Đây là cách hiệu ứng sẽ là: nhập mô tả hình ảnh ở đây


Cảm ơn vi đa trả lơi. Đối với điều này, chúng tôi có một yêu cầu cho nó là ở cuối.
robertwbradford

@robertwbradford Tôi đã thay đổi câu trả lời của mình để giải thích vấn đề có thể bạn gặp phải và đề xuất giải pháp. Xin vui lòng cho tôi biết nếu điều này trả lời câu hỏi của bạn.
Furqan Rahamath

0

Tôi nghĩ rằng bạn gần như tốt và thiếu (3) đó là một mẹo nhỏ. Một ý tưởng là làm cho phần tử biểu tượng có chiều rộng bằng 0và vô hiệu hóa bất kỳ khoảng trắng nào giữa văn bản và biểu tượng sắp xếp. Đối với điều này, tôi sử dụng một trình bao bọc thêm cho văn bản và loại bỏ việc sử dụng flexbox.

Bạn sẽ có một số tràn nhưng đó không phải là vấn đề vì bạn đang áp dụng phần đệm. Bạn cũng có thể tăng padding-rightnếu bạn muốn

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


Cảm ơn vi đa trả lơi. Một số điểm tốt, nhưng tôi thấy nó không đáp ứng "yêu cầu 1" trong đó mũi tên sẽ cần được căn chỉnh với phần cuối của hàng văn bản dài nhất. Trong trường hợp "Màu yêu thích", khi "Màu" kết thúc ở dòng thứ hai, biểu tượng sẽ được căn chỉnh theo chiều ngang với phần cuối của "Yêu thích" như trong ảnh chụp màn hình cuối cùng.
robertwbradford

1
@robertwbradford ah không hiểu nó theo cách đó .. Tôi nghĩ rằng nó nên chặt chẽ với cái cuối cùng. Tôi nghĩ rằng bạn đã hết may mắn cho yêu cầu này ...
Temani Afif

0

Nếu tiêu đề thead của bạn không năng động thì tôi có sửa chữa rất dễ dàng.

để làm điều này, bạn sẽ phải đặt từ cuối cùng của tiêu đề và biểu tượng svg trong khoảng

ví dụ: -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>

xóa display: flex từ lớp .button và đưa kiểu hiển thị: block-inline vào khoảng được thêm vào

do span là chặn nội tuyến, biểu tượng svg sẽ không bao giờ nằm ​​trong dòng riêng biệt. ít nhất sẽ có một từ ở phía trước của nó


Cảm ơn bạn đã trả lời. Tôi đang xây dựng nó như là một thành phần, vì vậy văn bản tiêu đề sẽ động :(
robertwbradford 6/12/19

Bạn có thể sử dụng Js để đặt từ cuối cùng trong khoảng. Nó không quá khó
Shirish Maharjan 7/12/19

0

Bạn có thể thử như thế này:

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

Hy vọng câu trả lời này sẽ hữu ích cho bạn. Tôi đã không tạo css cho chế độ xem trên điện thoại di động!

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.