【问题标题】:Is it possibly to keep vertical rhythm using only css?是否可以仅使用 css 来保持垂直节奏?
【发布时间】:2011-06-26 14:17:02
【问题描述】:

我正在开发一个面向排版的 wordpress 主题[1],但我在使用内嵌图像时遇到了问题。

我可以控制每个元素并调整它的行高、下边距、ecc,以保持垂直节奏。但是由于通过编辑器粘贴的图像可以有任意高度,它们显然会破坏以下所有内容。

所以问题是是否可以使用边距、填充、两者或其他解决方案,以确保独立于图像大小,它将调整到基线。

我知道有一些替代方法,比如让所有图像变成行高的倍数,这样我可以保持节奏。其他选项是使用 javascript,不理想,但如果没有 css 解决方案,我将不得不考虑它。

[1] 如您所见,这是一个与 css 相关的问题,而不是 wordpress 问题,这就是我在这里发布这个问题的原因。

【问题讨论】:

  • 图像默认排列在它们的基线上。我不知道你在问什么。
  • 唯一的选择是使用 javascript 并缩放图像以适应节奏 - 或者如果这足够了 - 应用边距/填充以匹配节奏,这样您就不会将图像压缩/拉伸通过 css/js 进行缩放可能非常可怕)
  • 我不明白。也许 "vertical-align: middle" 和 "display: inline-block" 可以帮助你
  • 对于那些不明白他所说的“垂直节奏”是什么意思的人:webtypography.net/Rhythm_and_Proportion/Vertical_Motion/2.2.2
  • 有点不相关,但超级酷:lamb.cc/typograph

标签: javascript css typography vertical-rhythm


【解决方案1】:

(已编辑——新的和改进的解决方案)

我不知道 WordPress 是否提供任何方法来生成围绕图像的包装 div,但如果提供,那么这应该可以。面对不同的文本比例和图像大小,它相当健壮,尽管您可能需要根据图像的高低来调整交替空格和不间断空格的生成内容字符串的长度。

它的工作方式是它使用负边距使外部图像包装器比内部包装器足够宽,以便在发生换行之前一个不间断的空间将适合一行,然后它生成一串交替的不间断和正常空间,在右边缘一次填充一行,然后溢出到下面的行。最后,等于 1 行高的负边距抵消了图像下方部分填充的空间行。

<!DOCTYPE html>
<html>
  <style>
    html {
        line-height: 1.25em;
    }
    .p {
        margin: 0;
        padding: 0;
    }
    .section,
    .imginner {
        width: 20em;
    }
    .section {
        float: left;
        margin: 0.5em;
        background-color: #eeeeff;
    }
    .fakeimage {
        background-color: #ffeeee;
    }
    .imgouter {
        margin-right: -0.5em;
        background-color: #eeffee;
        margin-bottom: -1.25em; /* minus 1 line-height */
    }
    .imgouter:after {
        content:'\00a0  \00a0  \00a0  \00a0  \00a0  \00a0  \00a0  \00a0  \00a0  \00a0  \00a0  \00a0  \00a0  \00a0  \00a0  \00a0  \00a0  \00a0  \00a0  \00a0  \00a0  \00a0  \00a0  \00a0'
    }
    .imginner {
        float: left;
        background-color: #ffffdd;
    }
  </style>
<head>
</head>
<body>
  <div class='section'>
    Some text text text text text text.
    Some text text text text text text.
    <div class='imgouter'>
      <div class='imginner'>
        <div class='fakeimage' style="width:145px; height:92px">
          (image here)
        </div>
      </div>
    </div>
    Some text text text text text text.
    Some text text text text text text.
    Some text text text text text text.
  </div>
  <div class='section'>
    Some text text text text text text.
    Some text text text text text text.
    Some text text text text text text.
    Some text text text text text text.
    Some text text text text text text.
    Some text text text text text text.
    Some text text text text text text.
    Some text text text text text text.
    Some text text text text text text.
    Some text text text text text text.
    Some text text text text text text.
    Some text text text text text text.
    Some text text text text text text.
    Some text text text text text text.
  </div>
</body>
</html>

【讨论】:

  • 我已经读了几遍了,但仍然不明白它是如何工作的......因此不明白如何实现它 D:
  • 内层随图片垂直展开,所以高度相同。内包装也具有与容器相同的宽度。外包装有一个负边距,使其稍大,在内部的右侧留下空白空间,仍然在外部。外部:后内容是交替的断行和非断行空格,它们沿右侧空间换行,然后溢出到下面的行上。最后,负边距将下面的内容抬高 1 行高,覆盖底部的空格。这有意义吗?
  • outer:after 内容填充了内部包装右侧的许多短文本行,直到它溢出内部包装的底部,然后填充下面的部分行。外包装具有与 1 行高相同大小的负底边距,有效地否定了外层:后文本溢出的最后一行。内部包装与其内容(图像)具有相同的高度。内包装的宽度硬编码与容器相同,外包装由于其负右边距而宽 0.5 em,在右侧的行之间留出空间。
  • @GregoryPakosz 我看到的唯一错误是body 元素的边距不是零或行高的倍数,并且背景应用于html元素,因此它相对于文本行向上移动。垂直节奏看起来仍然正确(无论如何在我的浏览器中)。左列和右列中的文本行似乎在图像前后完美对齐,并且背景图像中的行穿过每个文本行上的相同位置。您看到了什么,您使用的是什么浏览器?
  • @SteveJorgensen 为什么将 imginner 向左浮动很重要?否则生成的行会在下方而不是右侧?
【解决方案2】:

如果你想纯粹用 CSS 来做这件事,那么你必须提前知道每张图片的大小。比如在this demo:

我有一个 20px 的网格,图像的高度为 150px,所以我将图像包裹在一个高度为 160px 的容器中。这需要额外的标记:

<div class=figure>
  <div class=image-wrap style="height:160px">
    <img width=150 height=150>
  </div>
  <p class=caption>Figure 1
</div>

也许这样的标记可以由 WordPress 插件生成,该插件接收图像标记和最小高度并输出网格对齐的 div 包装器。 (我不熟悉 WordPress。)

替代方法是使用 JavaScript,这已在 this similar question 中得到解决。

【讨论】:

  • 具有示例中的标题的图像是自动生成的,因此在这些 div 上工作应该不难。我从未使用过插件,但我想应该可以修改高度以适应基线的倍数。没有标题的图像没有包装器 div,但正如您所建议的,它应该可以通过插件实现。也感谢您的链接!
  • 这种方法的一个问题是,使用编辑器可以修改大小,事先知道图像的高度并不容易。 Wordpress 有一些默认大小(缩略图、中等和完整),所以这是我能想到的最接近“提前了解图像”的东西。在这种情况下,我失去了一些灵活性,但仍然是个好主意。
【解决方案3】:

在我看来,纯 CSS 解决方案是不可能的。以一张桌子为例。默认情况下,表格单元格有一点填充,因此它的内容是可读的。您可以尝试使每个表格单元格的高度完全正确,但这很难。此外,添加例如底部边框也会增加元素的高度,这意味着您必须考虑到它。我喜欢 Compass 的垂直节奏工具帮助保持垂直节奏的方式,但对于内联图像和例如表格,我发现缺少纯 CSS。出于这个原因,我编写了一个简单的 jquery 插件来帮助解决这个问题,在这里找到它:https://github.com/dagomar/rhythm.js

唯一的缺点是要使内联元素起作用,它需要一个偏移量,我还没有弄清楚这是否可以自动化。您只能通过测试才能找到偏移量,我发现偏移量 6(默认)最适合 21-24 像素的基线,但可能是字体大小有影响。目前,作为概念验证,我发现它运行得非常好。它也适用于响应式图像(window.resize)。希望这会有所帮助。

【讨论】:

  • 是的,你是对的......我已经看到了一些新的 js 库,它们是轻量级的(比如baseline.js 似乎也是一个好主意)。感谢您的见解。
【解决方案4】:

我建议使用像 Foundation 或 Bootstrap 和 Compass+SCSS 这样的 CSS 框架来帮助解决这个问题。实际上,我已经做了一些工作来设置 Foundation,它具有一套不错的默认垂直节奏规则,您可以直接使用这些规则。我有一篇博文对此进行了解释,并有一个指向 Github 上的拉取请求的链接。

http://lucisferre.net/2012/10/08/getting-into-vertical-rhythm/

这样您就可以为您的排版和其他页面元素生成一些不错的基础 CSS。或者您可以将该技术应用于现有的 CSS。这有点乏味,但并不难。

【讨论】:

  • 抱歉,我不明白那篇文章与问题 D: 有何关系:
  • 呸!我修好了它。大声笑这就是当你使用复制/过去太多时会发生的事情。我以为我抓住了链接,但是,唉......
  • 抱歉,链接一定是复制错了。不知道乔恩的评论是关于什么的。
  • 我刚刚发现你更正了链接,很奇怪。嗯,谢谢,我会尽快看看。
【解决方案5】:

@PaBLoX,我相信完全可以只使用 CSS 来实现垂直节奏。真正的问题是,“你能否仅使用 CSS 创建可重用的垂直节奏样板?”。每个项目都是不同的,使用不同的字体系列等。虽然垂直节奏应该基于输入驱动的数学,但变量会随着每个项目而变化。您可能不需要购物网站上的“博客式”垂直节奏......

无论如何,这个问题被问到已经有一段时间了,但是如果你或其他人想看到一个为垂直节奏创建样板的示例(尝试),这里是 github 上的 repo:https://github.com/jonschlinkert/vertical-rhythm

这是一个起点。我怀疑该项目最终将包含几个不同的样板以满足不同的需求。

【讨论】:

  • 是的,已经有一段时间了。虽然我可能需要在接下来的几周内再次这样做。我会检查一下,谢谢=)。
【解决方案6】:

我不能保证这一切都会奏效,但可能值得一试:

如果您可以保证所有图像的高度都在em 中指定,则可以将img 元素的字体大小设置为与line-height 相同,以确保所有正确插入的图像的大小都相同正确:

html
{
  font-size: 15px;
  line-height: 18px;
}

img
{
  font-size: 18px;
  line-height: 18px;
}

或者,您可以尝试在段落中浮动图像,以便以正确的节奏包裹图像。

<p><img ... /> Lorem ipsum dolor sit amet...</p>

最后,你必须疯狂地实现这个方法的纯 CSS:

  1. 计算您使用的行距
  2. 确保它是一个完整的像素(否则这将永远无法工作)。
  3. 确保统一指定所有高度:&lt;img height="100" vs &lt;img height="100px"
  4. 写一大堆 CSS 规则:
img[height$="1"]
{
  margin-bottom: 9px;
}
img[height$="2"]
{
  margin-bottom: 8px;
}
...etc...

请注意,这对于 10 以及 10 和 5 的其他倍数都适用,但对于其他几乎所有内容来说,这将是一种巨大的痛苦。

【讨论】:

  • 谢谢,它部分适用于浮动图像,但并非每次都适用。如果你改变图像的高度,节奏就会立即中断。我可以提出两种可能的解决方案:a)由于 wordpress 允许定义主要“尺寸”的高度,我可以将它们全部保留为基线的倍数,或者 b)由于 css 无法进行动态计算,我应该使用 javascript 添加一些底部边距,等于下一个基线倍数的差异。 (顺便说一句,可能类似于this
  • @PaBLoX,PHP 可以根据需要/需要输出动态 CSS。
  • 您需要完美的节奏有什么特别的原因吗?如果您将内容放在水平条纹背景上或类似的东西上,我绝对可以理解,但如果只是因为您听说节奏很好,那并不重要。绝大多数有吸引力的网站都很少考虑节奏。用户不会注意到不匹配,他们已经习惯了。
  • 其实没有,只是巧合的是,我看的多的网站都是有垂直节奏的。当然,我正在尝试找到一种舒适的方法,如果我发现自己在做奇怪的事情,我可能会放弃它。我试图找出是否有一种我没有看到的更简单的方法;)。顺便说一句......我怎么能用 PHP 输出动态 css?你能告诉我在哪里可以找到它吗?
  • 取一个.css文件,重命名为.php,在第一行添加&lt;?php header('Content-type: text/css'); ?&gt;。您现在可以编写将作为 CSS 输出的 php。如果你做了一些花哨的 mod-rewrite 东西,你甚至可以将你的 .css 文件评估为 php 文件,或者你想要的任何东西。如果您确定您阅读的网站具有完美的垂直节奏,请查看他们的来源,看看他们正在做些什么来使其完美。
猜你喜欢
  • 2019-08-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-08-04
  • 2012-07-25
相关资源
最近更新 更多