草庐IT

如何不移除<p>标签而将段落连接起来?

我的技术园地 2023-03-28 原文

这是一个很经典的CSS布局问题,新人彻底理解了这个问题,HTML网页布局思想便已掌握了七七八八了。

问题

先看一段HTML代码:

<!DOCTYPE html>
<html>
<body>
<h1>这是一个标题</h1>
  <div class="wrapper">
    <p>这是一个段落</p>
    <p>这是一个段落</p>
    <p>这是一个段落</p>
  </div>
</body>
</html>

因为p标签默认是块级元素,宽度默认会占满父容器的100%,所以这个代码默认展现出来的样式是这样的:

问题与这个示例有关,是这样的:如何将三行文本“这是一个段落”合并到一行,从左向右排行显示,且不用移除<p>标签?

最简单的解决方案只需要加一行CSS样式代码:

.wrapper p {
  display: inline;
}

运行效果如下所示:

为什么简单加一个inline样式就可以解决问题?

早期网页为了从向至下流式展示内容,根据需要将标签元素默认分为了两类:

  • 块级元素
  • 行内元素

块级元素默认占据父容器的100%宽度,同时可以有高度,在不指定高度的时候,高度由子元素堆积决定。例如div、p、h1~h6等标签,凡是默认在网页中占据全部页面宽度的元素,都是块级元素。

而行内元素用于在一行内从左向右展示小内容,行内元素默认只有宽度,没有高度,并且它们的宽度也是由它们本身的内容所决定的。例如a、br、b、em、img、sub、sup、strong等标签,凡是默认不占据100%父容器宽度的元素,都可以视为行内元素。如果想给行内元素指定高度,可以在父容器上给行元素设置line-height样式。

这两类元素的作用,就是合起来展示一个从上至下依次展示、每行从左至右依次排列的流布局,如下所示。

回头看我们的示例,p标签默认是块级标签,它在渲染时要占满页面容器的100%宽度,所以默认效果三行文本“这是一个段落”是从上向下依次排列的。

当我们通过类选择器+标签选择器(.wrapper p),修改了所有p标签的display样式后,即将display样式设置为inline,这时候这个页面内的所有p标签已经不是块级元素了,都变成了行内元素。

HTML元素是什么块级元素,还是行内元素,本质上是由它们携带的默认的CSS样式决定的,也就是由display等于block或inline决定的,等于block就是块级元素,等于inline就是行内元素。因为CSS可以控制一切HTML元素的样式,事实上我们甚至可以将任何一个HTML元素修改为其他元素————当然如果真修改的话,这里还涉及元素属性的问题,在这里我们只谈样式。HTML元素默认携带的样式是由其名称决定的,所有元素的默认样式都是可以通过CSS代码修改的。

当给p标签设置了display样式为inline以后,这时候p标签的行为与span标签类似了,于是三行文本“这是一个段落”便是从左向右,在一行内展示了,如果一行展示不了,内容还会自动换行,就像其他行内元素所表示出来的行为那样。

由inline-block决定的行内块级元素

随着网页布局复杂度的提升,后来又出现了inline-block样式值,我们可以修改示例,看一看将display修改为inline-block之后的效果,如下所示。

效果与修改为inline是相似的,在这个示例中看不出什么差别。事实上inline-blcok代表行内的块级元素,这样的元素既可以在一行之内从左向右自动依次排列,可以拥有自己的高度,又可以作为一个局部的小容器,再容纳其他子元素。

inline-blcok样式的出现,代表CSS在网页布局方面已经没有什么能力短板了,只有网页设计师想不到的,没有CSS实现的布局。

flex布局

但CSS的网页布局能力发展到这里并没有停止,后来为了更好了处理父容器与子元素的组合样式,flex布局被发明出来了。flex布局能够实现的效果,用以往的CSS也可以实现,但用flex布局的方法实现,代码会更简洁、逻辑会更加清晰、页面的扩展性也更好。

下面作者仍然拿上面的示例改造,如果不设置display为inline或inline-block,使用flex布局怎么达到同样的效果呢?也是只添加一行CSS代码就足够了,如下所示。

<!DOCTYPE html>
<html>
<body>
  <style>
  .wrapper {
    display: flex;
  }
</style>
  <h1>这是一个标题</h1>
  <div class="wrapper">
    <p>这是一个段落</p>
    <p>这是一个段落</p>
    <p>这是一个段落</p>
  </div>
</body>
</html>

运行效果如下所示:

效果是一样的。

将display设置为flex就代表了启用flex布局。因为默认情况下flex-direction等于row,子元素会像行内元素那样从左向右排行,所以只写一行display等于flex样式代码就可以了。

flex布局能力很强大,它不仅可以处理从左向右的横向布局,还可以处理从上向下的纵向布局,两个方向的布局使用的是同一套样式语义。

很多人都觉得这套语义记了又忘,实在很难记住,即使是富有经验的网页设计师在许久不手写CSS代码之后,也需要借助工具才可以将样式代码写对。针对开发者的这个痛点,新版本的Chrome浏览器现在提供了这样的一个flex布局辅助设计功能,如下所示,当我们给元素添加了display等于flex的样式代码后,后面会出现一个功能按钮,点击它,会展开一个flex布局互动小面板。点击这个面板上具体的排列项,相应的样式代码即会自动生成。

以后不用再记那些难记的样式名称了,有需要的时候调出这个flex布局互动小面板,动手你发财的小手点一点,所有布局代码都能搞定了。

小结

HTML开发主要有两种布局思想:传统div流式布局和flex布局。

还有一种全页面都使用绝对值定位的布局思想,这种布局思想只适用于Web管理后台或工具Web项目等开发场景,对于面向C端用户的场景是不适用的。HTML网页的根本设计哲学是流式布局————整体上从上向下、行内从左向右的流式布局,这种布局可以让HTML内容可以一边加载一边渲染与展示,这是一种很好的设计哲学,不要轻易舍弃这种哲学。

flex布局本质上继承了流式布局的思想,它与流式布局并不冲突,只是丰富了CSS在父容器子元素组合关系布局上的能力。在网页设计中,现在普遍优先使用flex布局,用最简单的CSS代码达到设计的需求。在具体设计时,配合使用Chrome开发者工具中的flex布局小面板,写起flex布局代码也很容易。


著作权归LIYI所有
基于CC BY-SA 4.0协议
原文链接:https://yishulun.com/posts/2022/34.html

有关如何不移除<p>标签而将段落连接起来?的更多相关文章

  1. ruby-on-rails - 如何从 format.xml 中删除 <hash></hash> - 2

    我有一个对象has_many应呈现为xml的子对象。这不是问题。我的问题是我创建了一个Hash包含此数据,就像解析器需要它一样。但是rails自动将整个文件包含在.........我需要摆脱type="array"和我该如何处理?我没有在文档中找到任何内容。 最佳答案 我遇到了同样的问题;这是我的XML:我在用这个:entries.to_xml将散列数据转换为XML,但这会将条目的数据包装到中所以我修改了:entries.to_xml(root:"Contacts")但这仍然将转换后的XML包装在“联系人”中,将我的XML代码修改为

  2. ruby - 在院子里用@param 标签警告 - 2

    我试图使用yard记录一些Ruby代码,尽管我所做的正是所描述的here或here#@param[Integer]thenumberoftrials(>=0)#@param[Float]successprobabilityineachtrialdefinitialize(n,p)#initialize...end虽然我仍然得到这个奇怪的错误@paramtaghasunknownparametername:the@paramtaghasunknownparametername:success然后生成的html看起来很奇怪。我称yard为:$yarddoc-mmarkdown我做错了什么?

  3. ruby - 续集在添加关联时访问many_to_many连接表 - 2

    我正在使用Sequel构建一个愿望list系统。我有一个wishlists和itemstable和一个items_wishlists连接表(该名称是续集选择的名称)。items_wishlists表还有一个用于facebookid的额外列(因此我可以存储opengraph操作),这是一个NOTNULL列。我还有Wishlist和Item具有续集many_to_many关联的模型已建立。Wishlist类也有:selectmany_to_many关联的选项设置为select:[:items.*,:items_wishlists__facebook_action_id].有没有一种方法可以

  4. ruby-on-rails - rspec should have_select ('cars' , :options => ['volvo' , 'saab' ] 不工作 - 2

    关闭。这个问题需要detailsorclarity.它目前不接受答案。想改进这个问题吗?通过editingthispost添加细节并澄清问题.关闭8年前。Improvethisquestion在首页我有:汽车:VolvoSaabMercedesAudistatic_pages_spec.rb中的测试代码:it"shouldhavetherightselect"dovisithome_pathit{shouldhave_select('cars',:options=>['volvo','saab','mercedes','audi'])}end响应是rspec./spec/request

  5. ruby - 无法在 60 秒内获得稳定的 Firefox 连接 (127.0.0.1 :7055) - 2

    我使用的是Firefox版本36.0.1和Selenium-Webdrivergem版本2.45.0。我能够创建Firefox实例,但无法使用脚本继续进行进一步的操作无法在60秒内获得稳定的Firefox连接(127.0.0.1:7055)错误。有人能帮帮我吗? 最佳答案 我遇到了同样的问题。降级到firefoxv33后一切正常。您可以找到旧版本here 关于ruby-无法在60秒内获得稳定的Firefox连接(127.0.0.1:7055),我们在StackOverflow上找到一个类

  6. ruby-on-rails - Nokogiri:使用 XPath 搜索 <div> - 2

    我使用Nokogiri(Rubygem)css搜索寻找某些在我的html里面。看起来Nokogiri的css搜索不喜欢正则表达式。我想切换到Nokogiri的xpath搜索,因为这似乎支持搜索字符串中的正则表达式。如何在xpath搜索中实现下面提到的(伪)css搜索?require'rubygems'require'nokogiri'value=Nokogiri::HTML.parse(ABBlaCD3"HTML_END#my_blockisgivenmy_bl="1"#my_eqcorrespondstothisregexmy_eq="\/[0-9]+\/"#FIXMEThefoll

  7. css - 用 watir 检查标签类? - 2

    我有一个div,它根据表单是否正确提交而改变。我想知道是否可以检查类的特定元素?开始元素看起来像这样。如果输入不正确,添加错误类。 最佳答案 试试这个:browser.div(:id=>"myerrortest").class_name更多信息:http://watir.github.com/watir-webdriver/doc/Watir/HTMLElement.html#class_name-instance_method另一种选择是只查看具有您期望的类的div是否存在browser.div((:id=>"myerrortes

  8. ruby-on-rails - 没有参数的 `<<`(小于两倍)是什么意思? - 2

    我在一个我想在formtasticGem中覆盖的方法中找到了这个。该方法如下所示:defto_htmlinput_wrappingdohidden_field_html是什么意思?在第三行做什么?我知道它对数组有什么作用,但在这里我不知道。 最佳答案 你可以这样读:hidden_field_htmllabel_with_nested_checkbox是连接到hidden_​​field_html末尾的参数-为了“清晰”,他们将其分成两行 关于ruby-on-rails-没有参数的`

  9. ruby-on-rails - 找不到 gem railties (>= 0.a) (Gem::GemNotFoundException) - 2

    我已经看到了一些其他的问题,尝试了他们的建议,但没有一个对我有用。我已经使用Rails大约一年了,刚刚开始一个新的Rails项目,突然遇到了问题。我卸载并尝试重新安装所有Ruby和Rails。Ruby很好,但Rails不行。当我输入railss时,我得到了can'tfindgemrailties。我当前的Ruby版本是ruby2.2.2p95(2015-04-13修订版50295)[x86_64-darwin15],尽管我一直在尝试通过rbenv设置ruby​​2.3.0。如果我尝试rails-v查看我正在运行的版本,我会得到同样的错误。我使用的是MacOSXElCapitan版本10

  10. ruby - 我的 Ruby IRC 机器人没有连接到 IRC 服务器。我究竟做错了什么? - 2

    require"socket"server="irc.rizon.net"port="6667"nick="RubyIRCBot"channel="#0x40"s=TCPSocket.open(server,port)s.print("USERTesting",0)s.print("NICK#{nick}",0)s.print("JOIN#{channel}",0)这个IRC机器人没有连接到IRC服务器,我做错了什么? 最佳答案 失败并显示此消息::irc.shakeababy.net461*USER:Notenoughparame

随机推荐