使用CSS,如何“紧密”对齐“ A”与“ B”的底部/末端,其中“ B”的宽度和文字环绕未知


9

我有一个“可排序”表,其中当前排序列的标题显示一个图标:

在此处输入图片说明

排序图标将显示在文本的末尾(即,我们支持LTR / RTL)。我目前正在使用display:flex。但是,如果表的宽度缩小并且列标题文本开始换行,则我将进入不清楚的状态,即不清楚对哪一列进行排序:

在此处输入图片说明

相反,我想满足以下要求:

  1. 图标始终与最长文本行的“结尾”“紧密”对齐(即使换行单元格/按钮较宽)。
  2. 图标也应与文本的最后一行在底部对齐。
  3. 该图标绝对不能缠绕在自己的一行上。
  4. 该按钮必须存在并且应跨越单元的整个宽度。(它的内部样式和标记可以根据需要更改。)
  5. 仅在可能的情况下使用CSS和HTML。
  6. 它不能依赖已知/设置的列宽或标题文本。

例如:

在此处输入图片说明

我一直在尝试了一堆的不同组合display: inline/inline-block/flex/gridposition::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来解决您的问题,但是按钮和span元素组合在一起令人头疼,所以我决定在CSS和html中使用font-awesome是一个希望对您有帮助的示例
stan chacon

@stanchacon感谢您的关注。我应该提到,但是我不会奢侈地设置列宽或提前知道标题文本。我在要求中添加了#6。
robertwbradford

1
@stanchacon ...而且我现在可以去找
肋眼

@robertwbradford这已经解决了吗?还是您仍在寻找解决方案?
Furqan Rahamath

@MohammedFurqanRahamathM,这尚未得到回答。还在寻找...
robertwbradford

Answers:


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

我认为除了视觉上的歧义,这里根本没有问题。这是我的观察。

  • 实际上,这些项目是紧密绑定的。默认情况下,除非另有说明,否则任何元素都会跟随另一个元素。
  • 为什么会有间距?这些有两种变体
    • 第一:如果文本不在任何换行元素内(当前处于这种状态)。在这种情况下,由于没有明确提到宽度,因此对于文本和跨度,都自动分配宽度,并且文本将尝试使用所有宽度,但span元素采用的1.25rem宽度除外。而且根据w3c文档,存在规则仅是为了确定给定字符串上的断点而不是空格,因为文本对齐是完全不同的问题。请参考此问题以了解如何完成此问题,这是大学学习的标准动态编程问题。因此,在进行对齐时当然会存在间距,请记住可用宽度,浏览器不会崩溃。
    • 第二:如果文本在包装元素内,则可以是span,p,div等。在这种情况下,由于未明确指定宽度,因此会自动分配宽度。在这种情况下,您实际上可以在inspect元素中看到该元素试图占据除排序图标的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 '19

0

我认为您几乎不错,并且缺少(3)的技巧。一个想法是使图标元素的宽度等于0并禁用文本和排序图标之间的任何空格。为此,我为文本使用了一个额外的包装,并删除了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”,在该要​​求中,箭头需要与最长的文本行的末尾对齐。对于“收藏夹颜色”,当“颜色”换行到第二行时,图标应与“收藏夹”的末尾水平对齐,如最后一个屏幕截图所示。
robertwbradford

1
@robertwbradford啊不这样理解..我认为最后一个应该紧。我认为您对此要求不高...
Temani Afif

0

如果您的thead标题不是动态的,那么我有非常简单的解决方法。

为此,您必须将标题的最后一个单词和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>

从.button类中删除display:flex,并为显示的样式内联显示块:

由于跨度是inline-block,因此svg图标将永远不在单独的行中。前面至少有一个字


感谢您的答复。我将其构建为组件,因此标题文本将是动态的:(
robertwbradford

您可以使用Js将最后一个单词放入跨度。不应该那么难
Shirish Maharjan '19

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!

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.