How to ensure empty span matches height of sibling

2019-08-08 15:14发布

问题:

On codepen I'm testing some frame classes on span button input and an empty span. In order to ensure the empty span matches the height of the others I'm using calc math give it min-height but this calculation seems to require knowing line-height. Is there a way to ensure the min-height without needing to know the line-height? Also I don't understand why the vertical-align middle aligns the empty one with the others while baseline doesn't. If anyone can explain that or suggest alternative that'd be awesome

.frame-apply {
  --sum-border: calc(2 * var(--frame-border-width, 0));
  --sum-padding-y: calc(2 * var(--frame-padding-y));

  border-image: none;
  border-radius: var(--radii-medium);
  border-style: solid;
  border-width: var(--frame-border-width, 0);
  display: inline-block;

  /* Using middle aligns the empty one with the others
     I don't understand why it doesn't align correctly as baseline */
  vertical-align: middle;

  /* min-height only seems necssary to fill the empty one
     It'd be better to avoid needing to know line-height */
  min-height: calc(
    var(--sum-padding-y) +
    var(--sum-border) + 
    1em * var(--test-line)
  );

  min-width: 0;
  padding:
    var(--frame-padding-y)
    var(--frame-padding-x);  
}

.frame-dense {
  --frame-padding-y: 3px;
  --frame-padding-x: 11px;
  --frame-border-width: 1px;
}

.frame-basic {
  --frame-padding-y: 7px;
  --frame-padding-x: 15px;
  --frame-border-width: 1px;
}

.frame-plush {
  --frame-padding-y: 11px;
  --frame-padding-x: 23px;
  --frame-border-width: 1px;
}

/* Test values ideally all scale */
:root {
  --test-size calc(1rem * 14px / 16px);
  --test-line: 1.5;
}

.font-test {
  font-size: var(--test-size);
  line-height: var(--test-line); 
}

回答1:

The easiest way to fix all the issue (min-height and alignment) is to rely on flexbox where all the elements will by default stretch to fill the height of their line:

figure {
  display:flex;
  flex-wrap:wrap;
}
figcaption {
  width:100%;
}

figure > * {
 margin-right:4px!important; /*to replace the default whitespace*/
}
<link rel="stylesheet" href="https://unpkg.com/@plangrid/structure@0.36.0/main.css">
<link rel="stylesheet" href="https://unpkg.com/@plangrid/structure@0.36.0/root.css">
<link rel="stylesheet" href="https://unpkg.com/@plangrid/paint@0.34.0/blending.css">

<link rel="stylesheet" href="https://unpkg.com/@plangrid/paint@0.34.0/live.css">
<style>
/*
Preset classes in HTML are from
https://unpkg.com/@plangrid/structure@0.36.0/main.css
https://stackoverflow.com/q/48469414/770127
*/

.frame-apply {
  --sum-border: calc(2 * var(--frame-border-width, 0));
  --sum-padding-y: calc(2 * var(--frame-padding-y));
  border-image: none;
  border-radius: var(--radii-medium);
  border-style: solid;
  border-width: var(--frame-border-width, 0);
  min-width: 0;
  padding:
    var(--frame-padding-y)
    var(--frame-padding-x);  
}

.frame-dense {
  --frame-padding-y: 3px;
  --frame-padding-x: 11px;
  --frame-border-width: 1px;
}

.frame-basic {
  --frame-padding-y: 7px;
  --frame-padding-x: 15px;
  --frame-border-width: 1px;
}

.frame-plush {
  --frame-padding-y: 11px;
  --frame-padding-x: 23px;
  --frame-border-width: 1px;
}

/* Test values ideally all scale */
:root {
  --test-size calc(1rem * 14px / 16px);
  --test-line: 1.5;
}

.font-test {
  font-size: var(--test-size);
  line-height: var(--test-line); 
}
</style>
<figure class="preset-box mb3">
  <figcaption class="font-os mb1">frame-dense</figcaption>
  <span class="font-os font-test preset-box frame-apply frame-dense">span</span>
  <button class="font-os font-test preset-button frame-apply frame-dense ccc-black ggg-transparent bbb-black" type="button" disabled>button</button>
  <input class="font-os font-test preset-input frame-apply frame-dense ccc-black ggg-transparent bbb-black" value="input" disabled>
  <span class="font-os font-test preset-box frame-apply frame-dense "></span>
  <span class="font-os">&larr; empty</span>
</figure>
<figure class="preset-box mb3">
  <figcaption class="font-os mb1">frame-basic</figcaption>
  <span class="font-os font-test preset-box frame-apply frame-basic">span</span>
  <button class="font-os font-test preset-button frame-apply frame-basic ccc-black ggg-transparent bbb-black" type="button" disabled>button</button>
  <input class="font-os font-test preset-input frame-apply frame-basic ccc-black ggg-transparent bbb-black" value="input" disabled>
  <span class="font-os font-test preset-box frame-apply frame-basic"></span>
  <span class="font-os">&larr; empty</span>
</figure>
<figure class="preset-box mb3">
  <figcaption class="font-os mb1">frame-plush</figcaption>
  <span class="font-os font-test preset-box frame-apply frame-plush">span</span>
  <button class="font-os font-test preset-button frame-apply frame-plush ccc-black ggg-transparent bbb-black" type="button" disabled>button</button>
  <input class="font-os font-test preset-input frame-apply frame-plush ccc-black ggg-transparent bbb-black" value="input" disabled>
  <span class="font-os font-test preset-box frame-apply frame-plush"></span>
  <span class="font-os">&larr; empty</span>
</figure>