使用 calc 缩进 CSS 网格的子元素与网格列准确对齐

Using calc to indent child element of CSS Grid accurately align with grid columns

我在 CSS 网格项目中有一个内容块,它工作正常。在某些情况下,我希望能够如此准确地缩进子元素 1 或 2 列,以便它与其父网格对齐。

我确实通过将相同的网格应用于子块(示例中的 storyblock__caption)实现了这一点,但是这导致元素跨越可用 space 的 100% 宽度,而我没有这样做想。所以我决定尝试使用 calc.

来解决它

我提供了一个乍一看实际上看起来正确的示例。示例中使用 calc 的段落似乎与网格的第二列对齐。但是,如果您要更改间距,使其与第 3 列的左边缘对齐,例如:margin-left: calc(((2 / 4) * 100%) - ((2 / 4) * 12px)); 您会看到数学不相加。

我认为这可能是因为网格没有考虑 storyblock__caption 的 12px left/right 填充。但是我已经尝试从计算中 add/subtract 24px 但我无法让它工作。

这是我的示例代码:

/* #BASE */

body  {color: white; margin: 0 auto;}
img   {width: 100%; max-width: 100%;}
h1    {margin-bottom: 15px;}
p     {margin-bottom: 15px;}
.btn  {background: white; color: black; display: inline-block; padding: 8px 24px; text-decoration: none;}

/* #CONTENT BLOCK */

.storyblock {
  display: grid;
  grid-column-gap: 12px;
  grid-template-columns: repeat(4, 1fr);
  margin: 0 auto;
  position: relative;
  max-width: 375px;
}

.storyblock--overlay {
  align-items: end;
}

.storyblock--overlay .storyblock__media,
.storyblock--overlay .storyblock__caption {
  grid-row: 1;
}

.storyblock__media,
.storyblock__caption {
  grid-column: 1/5;
}

.storyblock__caption {
  padding: 0 12px 24px;
}

.storyblock__caption p {
  margin-left: calc(((1 / 4) * 100%) - ((1 / 4) * 12px));
}
<div class="storyblock storyblock--overlay">
  <div class="storyblock__media">
    <img src="https://www.fillmurray.com/375/500" alt="ALT TEXT" />
  </div>
  <div class="storyblock__caption">
    <h1>Lorem Ipsum</h1>
    <p>Lorem ipsum dolor sit amet consectetur adipiscing.</p>
    <a href=" #" class="btn">Shop Now</a>
  </div>
</div>

我希望对其进行健全性检查,但我想我已经通过使用以下计算缩进 1 列并与父网格间距对齐来解决此问题...

1 列: margin-left: calc(((1 / 4) * (100% + 24px)) - ((3 / 4) * 12px));

然后,如果您想缩进 2 列,只需将分数更改为:

2 列: margin-left: calc(((2 / 4) * (100% + 24px)) - ((2 / 4) * 12px));

最后是 3 列。看起来很傻,但只是为了完成设置...

3 列: margin-left: calc(((3 / 4) * (100% + 24px)) - ((1 / 4) * 12px));

...将来我可能只是在子容器上设置相同的网格并将我不想拉伸 100% 宽的项目包裹在 div!

/* #BASE */

body  {color: white; margin: 0 auto;}
img   {width: 100%; max-width: 100%;}
h1    {margin-bottom: 15px;}
p     {margin-bottom: 15px;}
.btn  {background: white; color: black; display: inline-block; padding: 8px 24px; text-decoration: none;}

/* #CONTENT BLOCK */

.storyblock {
  display: grid;
  grid-column-gap: 12px;
  grid-template-columns: repeat(4, 1fr);
  margin: 0 auto;
  position: relative;
  max-width: 375px;
}

.storyblock--overlay {
  align-items: end;
}

.storyblock--overlay .storyblock__media,
.storyblock--overlay .storyblock__caption {
  grid-row: 1;
}

.storyblock__media,
.storyblock__caption {
  grid-column: 1/5;
}

.storyblock__caption {
  padding: 0 12px 24px;
}

.storyblock__caption p.indent-1 {
  margin-left: calc(((1 / 4) * (100% + 24px)) - ((3 / 4) * 12px));
}

.storyblock__caption p.indent-2 {
  margin-left: calc(((2 / 4) * (100% + 24px)) - ((2 / 4) * 12px));
}

.storyblock__caption p.indent-3 {
  margin-left: calc(((3 / 4) * (100% + 24px)) - ((1 / 4) * 12px));
}
<div class="storyblock storyblock--overlay">
  <div class="storyblock__media">
    <img src="https://www.fillmurray.com/375/500" alt="ALT TEXT" />
  </div>
  <div class="storyblock__caption">
    <h1>Default</h1>
    <p>Lorem ipsum dolor sit amet consectetur adipiscing.</p>
    <a href=" #" class="btn">Shop Now</a>
  </div>
</div>


<div class="storyblock storyblock--overlay">
  <div class="storyblock__media">
    <img src="https://www.fillmurray.com/375/500" alt="ALT TEXT" />
  </div>
  <div class="storyblock__caption">
    <h1>1 Col Indent</h1>
    <p class="indent-1">Lorem ipsum dolor sit amet consectetur adipiscing.</p>
    <a href=" #" class="btn">Shop Now</a>
  </div>
</div>

<div class="storyblock storyblock--overlay">
  <div class="storyblock__media">
    <img src="https://www.fillmurray.com/375/500" alt="ALT TEXT" />
  </div>
  <div class="storyblock__caption">
    <h1>2 Col Indent</h1>
    <p class="indent-2">Lorem ipsum dolor sit amet consectetur adipiscing.</p>
    <a href=" #" class="btn">Shop Now</a>
  </div>
</div>

<div class="storyblock storyblock--overlay">
  <div class="storyblock__media">
    <img src="https://www.fillmurray.com/375/500" alt="ALT TEXT" />
  </div>
  <div class="storyblock__caption">
    <h1>3 Col Indent</h1>
    <p class="indent-3">Lorem ipsum dolor sit amet consectetur adipiscing.</p>
    <a href=" #" class="btn">Shop Now</a>
  </div>
</div>

使用 CSS 变量,让您的生活更轻松。我已将间隙更改为 10px 以更好地识别值并避免与具有相同值的填充混淆。您还可以使用 CSS 变量作为填充和间隙

/* #BASE */

body  {color: white; margin: 0 auto;}
img   {width: 100%; max-width: 100%;}
h1    {margin-bottom: 15px;}
p     {margin-bottom: 15px;}
.btn  {background: white; color: black; display: inline-block; padding: 8px 24px; text-decoration: none;}

/* #CONTENT BLOCK */

.storyblock {
  display: grid;
  grid-column-gap: 10px;
  grid-template-columns: repeat(4, 1fr);
  margin: 0 auto;
  position: relative;
  max-width: 375px;
}

.storyblock--overlay {
  align-items: end;
}

.storyblock--overlay .storyblock__media,
.storyblock--overlay .storyblock__caption {
  grid-row: 1;
}

.storyblock__media,
.storyblock__caption {
  grid-column: 1/5;
}

.storyblock__caption {
  padding: 0 12px 24px;
}

.storyblock__caption p.indent {
  margin-left: calc(var(--n)*(100% + 2*12px + 10px)/4 - 12px);
}
<div class="storyblock storyblock--overlay">
  <div class="storyblock__media">
    <img src="https://www.fillmurray.com/375/500" alt="ALT TEXT" />
  </div>
  <div class="storyblock__caption">
    <h1>Default</h1>
    <p>Lorem ipsum dolor sit amet consectetur adipiscing.</p>
    <a href=" #" class="btn">Shop Now</a>
  </div>
</div>


<div class="storyblock storyblock--overlay">
  <div class="storyblock__media">
    <img src="https://www.fillmurray.com/375/500" alt="ALT TEXT" />
  </div>
  <div class="storyblock__caption">
    <h1>1 Col Indent</h1>
    <p class="indent" style="--n:1">Lorem ipsum dolor sit amet consectetur adipiscing.</p>
    <a href=" #" class="btn">Shop Now</a>
  </div>
</div>

<div class="storyblock storyblock--overlay">
  <div class="storyblock__media">
    <img src="https://www.fillmurray.com/375/500" alt="ALT TEXT" />
  </div>
  <div class="storyblock__caption">
    <h1>2 Col Indent</h1>
    <p class="indent" style="--n:2">Lorem ipsum dolor sit amet consectetur adipiscing.</p>
    <a href=" #" class="btn">Shop Now</a>
  </div>
</div>

<div class="storyblock storyblock--overlay">
  <div class="storyblock__media">
    <img src="https://www.fillmurray.com/375/500" alt="ALT TEXT" />
  </div>
  <div class="storyblock__caption">
    <h1>3 Col Indent</h1>
    <p class="indent" style="--n:3">Lorem ipsum dolor sit amet consectetur adipiscing.</p>
    <a href=" #" class="btn">Shop Now</a>
  </div>
</div>