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 BThing A、それ自体の行に折り返すことができません。

私はflex値をいじってみましたが、どのような組み合わせでもテキストの折り返しが時期尚早になるか、十分に早くなりません。


私はあなたの現在のCSSやHTMLを使用して問題を解決しようとしたが、ボタンと私はここにCSSでフォント-awesomeが使用することを決めたとhtmlので、頭痛がある組み合わせspan要素の例には役立ちます希望が
スタンチャコン

@stanchacon見てくれてありがとう。私は言及すべきでしたが、列幅を設定したり、ヘッダーテキストが事前にどうなるかを知る余裕はありません。要件に#6を追加しました。
robertwbradford

1
@stanchacon ...そして私は今すぐリブアイに行くことができました:)
robertwbradford '27

@robertwbradfordこれはすでに対処されていますか?または、まだ解決策を探していますか?
Furqan Rahamath

@MohammedFurqanRahamathM、これはまだ答えられていません。まだ探しています...
robertwbradford '11 / 12/19

回答:


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

視覚的な曖昧さ以外は何も問題はないと思います。ここに私の観察があります。

  • 実際のアイテムはしっかりと拘束されています。デフォルトでは、特に指定のない限り、要素は別の要素の後に続きます。
  • なぜ間隔があるのですか?これらの2つのバリエーションがあります
    • 最初:テキストが折り返し要素の内部にない場合(現在の状態)。このシナリオでは、幅だけでなくテキストも明示されていないため、テキストとスパンの両方に幅の自動割り当てがあり、テキストは、スパン要素が使用している1.25rem幅を除くすべての幅にしようとしています。また、w3cのドキュメントによると、テキストの位置揃えはまったく別の問題であるため、ルールは特定の文字列のブレークポイントを識別するためにのみ存在し、スペースではありません。この問題を参照して、それがどのように行われるかを理解してください。これは、大学で研究されている標準的な動的プログラミングの質問です。そのため、当然、位置合わせを行っている間はスペースが存在します。ブラウザが折りたたまない、利用可能な幅を覚えておいてください。
    • 2番目:テキストがラッピングエレメント内にある場合、 span、p、divなどが考えられます。この場合も、幅が明示的に指定されていないため、幅の自動割り当てが行われます。そして、この場合、要素がsortアイコンの1.25rem幅以外のすべてのスペースを占有しようとすることを実際にinspect要素で確認できます。

非常に厳しい境界が存在します。その動的な間隔が視覚的なあいまいさを引き起こしているというだけです。

ソリューションになりました。完璧ではありませんJavaScriptの介入なしに思いつくことができる最も近いソリューションは、

  • 要素、おそらくスパン内にテキストをラップします
  • max-widthを指定して、このテキストの幅を制限します。

    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、テキストと並べ替えアイコンの間の空白を無効にすることをお勧めします。このために、テキスト用の追加のラッパーを使用し、フレックスボックスの使用を削除しました。

オーバーフローが発生しますが、パディングを適用しているため、問題にはなりません。あなたも増やすことができます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」を満たしていないようです。「お気に入りの色」の場合、「色」が2行目に折り返されると、アイコンは、最後のスクリーンショットに示すように、「お気に入り」の端に水平に揃うはずです。
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>

.buttonクラスからdisplay:flexを削除し、追加されたスパンにスタイルdisplay:inline-blockを付与します

スパンがインラインブロックであるため、svgアイコンが別の行になることはありません。その前に少なくとも1つの単語があるでしょう


返信してくれてありがとう。これをコンポーネントとして構築しているので、タイトルテキストは動的になります:(
robertwbradford

Jsを使用して、最後の単語をスパンに入れることができます。それほど難しくはないはずです
Shirish Maharjan

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.