如何在 CSS3 站点布局中将图像跨越多个列?

Posted

技术标签:

【中文标题】如何在 CSS3 站点布局中将图像跨越多个列?【英文标题】:How to span an image over multiple columns in a CSS3 site layout? 【发布时间】:2016-01-28 06:50:22 【问题描述】:

给定一个基本的四列布局和一个简单的连续文本段落,以及一个跨越三列的图像,右上对齐,我们如何将图像跨越最后三列,以便我们的文本自动流动图片?

.quatroColumns             /* css multi column 4 columns */
.imageSpanning2Columns     /* align to top-right */
.imageSpanning3Columns     /* align to top-right */
.imageDescription          /* description box over image */

http://jsfiddle.net/Vbr9d/205/(很难找到图像应该放在哪里:不简单且不优雅的开始!)http://jsfiddle.net/Vbr9d/206/(看起来很难看,但 html 开始优雅地分离图片和文字段落!


*忘记旧的浏览器版本,除了当前的主要版本:Firefox、Internet Explorer、Chrome、Safari。欢迎任何想法、方向或实验。也欢迎使用其他 javascript 实现来自动将段落文本分成不同的 div。

【问题讨论】:

问题,列宽是固定的还是可变的? 在尝试解决这个问题之前,我想澄清一些事情。查看您的 jsfiddles,您只有一个

标记,其中包含一个巨大的文本块。这真的不是一个理想的写作方式。

标签应该只是一段文本。一个更理想的标记会,恕我直言。

...

@KimvdLinde 我真的不认为您的解决方案可以解决问题,因为您实际上拆分了文本以使其看起来一切正常。这是我解释为重要的一个限制,而不是拆分段落。 @stenehall 我个人认为将数据拆分到两个 div 上以便它在所有浏览器上都可以正常工作,这是一个在某些浏览器中根本不起作用的解决方案。但这就是我。提出尚未起作用且取决于功能实现的解决方案真的很容易。据我所知,OP 明确要求:“提供的解决方案只需要在当前的主流浏览器 FireFox InternetExplorer Chrome Safari 上运行。” @stenehall 大写的部分是句子的第二部分,以“也欢迎自动将段落文本拆分为不同 div 的替代 javascript 试用,但是......”那是为了 javascript 解决方案,而不是 css 解决方案。无论如何,您添加的第二个解决方案似乎适用于所有浏览器。 【参考方案1】:

我认为将文本分成两个块是目前唯一的解决方案。基本上,您将图像向右浮动,将第一个单列差异与第一个文本放在它旁边,然后将第二个四列差异与其余文本放在它下面。

此解决方案在 Firefox 中有效!

HTML:

<div>
    <img src="http://www.robfraser-photographer.co.uk/wp-content/uploads/2012/07/SHOT-9.jpg" class="imageSpanning3Columns"/>
</div>
<div>
    <p class="singleColumns border">Het was 17 graden onder nul toen het ijs onder onze benen begon te kraken. Consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam. Paragraph Duis autem vel eum iriure dolor in hendrerit in </p>
</div>
<div>
    <p class="quatroColumns border">vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi. Nam liber tempor cum soluta nobis eleifend option congue nihil imperdiet doming id quod mazim placerat facer possim assum. Dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam. Paragraph Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi. Nam liber tempor cum soluta nobis eleifend option congue nihil imperdiet doming id quod mazim placerat facer possim assum. Consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam. Paragraph Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi. Nam liber tempor cum soluta nobis eleifend option congue nihil imperdiet doming id quod mazim placerat facer possim ass.

CSS:

.quatroColumns             /* css multi column 4 columns */
    -webkit-column-count: 4; -webkit-column-gap: 20px; /* Chrome, Safari, Opera */   
    -moz-column-count: 4; -moz-column-gap: 20px; /* Firefox */
    column-count: 4; column-gap: 20px;
    width: 860px;
    font-size: 15px;
    text-align: justify;


.singleColumns             /* css multi column 4 columns */
    -webkit-column-count: 1; -webkit-column-gap: 20px; /* Chrome, Safari, Opera */   
    -moz-column-count: 1; -moz-column-gap: 20px; /* Firefox */
    column-count: 1; column-gap: 20px;
    width: 198px;
    font-size: 15px;
    text-align: justify;


.singleColumns:first-child:first-letter 
    float: left; font-size: 67px; margin:  7px 5px -10px 20px;


.imageSpanning3Columns     /* align to top-right */
    width:640px;
    top: 0 px;
    float:right;


.border
    border: solid 0px;
    margin: 0px;

这里有一个例子:http://jsfiddle.net/1ye9tyhq/

【讨论】:

+1 尽管您的方法仍然需要人工来分隔列之间的文本,而不是让 css 多列为我们发挥作用。尽管如此,我还是赞成您对您的想法+试用的回答!每一点都有助于并激发人们寻求永恒的解决方案。【参考方案2】:

这是一个干净的解决方案,应该适用于所有主要浏览器。它基于绝对定位的图像而不是使用列跨度,因为 Firefox 尚不支持。

/* Just to make it look a little nicer */
body 
  font-size: 16px;
  line-height: 1.4;
  color: #333;
  padding: 1em;



article 
  /* We're giving our article a max-width. This isn't needed if a parent already does this.*/
  max-width: 860px;
  
  /* Create a 4 column layout */
  -webkit-column-count: 4;
     -moz-column-count: 4;
     column-count: 4;

  /* Give each column a little added spacing */
  -webkit-column-gap: 20px;
     -moz-column-gap: 20px;
     column-gap: 20px;
     
  /* To be able to absolute position the image we need to give the parent a position */
  position: relative;
  
  /* This pulls up the first column of text to align with the image */
  padding-top: 225px;


article img 
  /* Absolute position our image */
  position: absolute;

  /* Place it in the top right cornet */
  top: 0;
  right: 0;

  /* Give it a height of 200px, this can of course be change if needed. If you update the height here make sure you also change the padding-top of the article and the negative margin later down. */
  height: 200px;
  
  /* We only want the image to spread 3 columns in width, that's 75% of the entire width. We also use 10px (half of the column-gap). */
  width: calc(75% - 10px);



/* Give the first paragraph a negative margin to pull it back up. (right now we're only using one parapgrah but if you'd want more in the future lets be specific here) */
article p:first-of-type 
  margin-top: -225px;


/* Some media queries to make it look nice on all resolutions */
@media screen and (max-width: 800px) 
  article 
    padding-top: 0;
    -webkit-column-count: 2;
       -moz-column-count: 2;
       column-count: 2;
  
  article p:first-of-type 
    margin-top: 0;
  
  article img 
    position: static;
    margin: 0 0 30px;
    width: 100%;
    height: auto;
  

@media screen and (max-width: 600px) 
  article 
    -webkit-column-count: 1;
       -moz-column-count: 1;
       column-count: 1;
  
<article>
  <img src="http://www.robfraser-photographer.co.uk/wp-content/uploads/2012/07/SHOT-9.jpg" />
<p>Het was 17 graden onder nul toen het ijs onder onze benen begon te kraken. Consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam. Paragraph Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi.Nam liber tempor cum soluta. nobis eleifend option congue nihil imperdiet doming id quod mazim placerat facer possim assum. Dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam.Paragraph Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi.Nam liber tempor cum soluta nobis eleifend option congue nihil imperdiet doming id quod mazim placerat facer possim assum. Consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam.Paragraph Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi.Nam liber tempor cum soluta nobis eleifend option congue nihil imperdiet doming id quod mazim placerat facer possim ass.</p>
</article>

对于这个的 scss 版本看这个codepen

这个答案最初包含一个使用 column-span 的解决方案(遗憾的是 Firefox 还不支持)。作为参考,我已将此解决方案添加为对此问题的单独答案。

【讨论】:

+1 stenehall 为您的想法和出色的阐述!不幸的是,在我的 最常用 浏览器 FireFox(最新版本)中,结果还远未完成。你自己看到结果了吗? SooO 奇怪为什么 FireFox 选择留在别人后面!也许有人对此有解决方案,在这种情况下,您的建议是 the 答案! (这就是我等待好消息/FireFox 修复的原因) 如果您查看我的最后一个 codepen,该解决方案在 Firefox 中确实有效,即使它不如第一个干净。据我所知,没有解决方案可以让列跨度在 Firefox 中工作。 抓住你的马! @stenehall Bravo 为您提供额外的步骤!让我们重新审视您的新提案! (请删除不适用于 FireFox 的部分并将其作为不同的答案!)让我们测试您的最终链接,该链接也适用于 FireFox 和我们当前版本的不同浏览器中的其他主要浏览器(FF, IE、Chrome、Safari)和平台,并在脚注中报告回来检查是否在您的机器/浏览器组合上看起来还不错。我将在以下评论中打破僵局: 哦不!我自己尝试了您的 html 和 css,但它在 Firefox 41 或 Internet Explorer 11 中不起作用!在 codepen.io 演示中,它“看起来像”在他们自己的演示中工作,但是当我使用 css(在你的 css 中添加 -moz)在真实世界的 html 文件中构建它时,它在两个浏览器中都崩溃了!这是为什么???您能否清理一下您的答案,并提供一个在没有代码笔的情况下在 FireFox 中工作的示例?如果单独测试,您当前的最终代码笔无法在 FIrefox 和 IE 11 中运行,请自行尝试! 你复制的是scss还是css版本?如果您直接从 codepen 复制代码,您很可能已经复制了 scss 版本。这需要运行抛出一个 scss 插值器 + 一个 autoprefixer 才能工作。我已经清理了上面的回复,它使用了 的 css 版本【参考方案3】:

您好:请看我的回答示例HERE

HTML 代码

<div id="news_paper">

    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
    tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
    quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
    consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse
    cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non
    proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
    Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
    tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
    quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
    consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse
    cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non
    proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
    Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
    tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
    quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
    consequat.
    </p>
    <img id="news_paper_image" src="http://lorempixel.com/600/275/">
    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
    tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
    quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
    consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse
    cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non
    proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
    </p>
    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
    tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
    quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
    consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse
    cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non
    proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
    </p>
    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
    tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
    quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
    consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse
    cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non
    proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
    </p>   
</div>

CSS 代码

#news_paper
  margin: 7rem auto;
  width: 70%;


#news_paper > p
  width: 22%;
  float: left;
  padding: 1%;
  text-align: justify;


#news_paper > p:first-child
  margin-top: -1rem;


p
  font-family:sans-serif;

#news_paper > p:first-child::first-letter
  font-size: 2.5rem;
  color: whitesmoke;
  float: left;
  margin-top: -0.25rem;
  padding: 0 0.25rem 0.25rem;
  background-color: tomato;


#news_paper_image
  width: 70%;
  float: left;
  margin-left: 1%;

谢谢T04435

【讨论】:

感谢您的回答和您的示例 +1。我看到您的答案受到 KimvdLinde 的启发(它的功能基本相同)。您是否像 KimvdLinde 一样支持在段落中包含图片?如果是,您能否在回答中解释为什么您认为这是最好的解决方案?因为这需要更多的体力劳动,而且更改文字需要更改放置图像的位置。【参考方案4】:

使用 column-span 而不是绝对定位的图像来保留原始建议的解决方案。


这是我建议的解决方案。您唯一需要知道的是图像的高度,这可能并不理想,但我认为此解决方案已接近完美。

没有使用 javascript 来计算列,也不需要添加元素或类来使其工作。我将文本块分成多个释义,因为我认为这是一种更正确的做法。但是,此解决方案不依赖于多个段落,您可以删除它们,它仍然可以正常工作。我只是随机添加段落以获得更自然的文本。

以下是重要部分。

article
  column-count: 4; /* Create 4 columns */

  img 
    /* For an image to work with column-span it needs to be a 
       block element */   
    display: block;

    /* Now we can let the image expand to all columns */
    column-span: all;

    /* We'll need to give the image a fixed height.
       A problem here is if we want a responsive layout. This wont 
       respect the aspect ratio of the image. That could be solve
       by only allowing an adoptive layout and set hard heights
       on the image. */
    height: 200px;

    /* Give it some margin to the columns under it */
    margin-bottom: 25px;

    /* Now comes the trick, first we want to push the image one 
       column to the right, that will be 25%, we're also adding
       some extra spacing to make it look nicer */
    margin-left: calc(25% + 10px); 

    /* Since we've pushed it one column to the right we only
       want it to take up 75% (3/4) of the total width. */
    width: calc(75% - 10px);
  

  /* Lastly we want to give the first paragraph a negative margin
     equal to the image height. This will move the first column
     up to align with the top of the image. */
  p:first-of-type  margin-top: -($imageHeight+25); 

完整的、有效的示例

/* Just to make it look a little nicer */
body 
  font-size: 16px;
  line-height: 1.4;
  color: #333;
  padding: 1em;


article 
  max-width: 860px;
  -webkit-column-count: 4;
     -moz-column-count: 4;
          column-count: 4;
  -webkit-column-gap: 20px;
     -moz-column-gap: 20px;
          column-gap: 20px;

article img 
  display: block;
  -webkit-column-span: all;
     -moz-column-span: all;
          column-span: all;
  height: 200px;
  width: calc(75% - 10px);
  margin-bottom: 25px;
  margin-left: calc(25% + 10px);

article p 
  margin-bottom: 1.3em;

article p:first-of-type 
  margin-top: -225px;


@media screen and (max-width: 800px) 
  article 
    -webkit-column-count: 2;
       -moz-column-count: 2;
            column-count: 2;
  
  article p:first-of-type 
    margin-top: 0;
  
  article img 
    margin: 0 0 30px;
    width: 100%;
    height: auto;
  

@media screen and (max-width: 600px) 
  article 
    -webkit-column-count: 1;
       -moz-column-count: 1;
            column-count: 1;
  
<article>
  <img src="http://www.robfraser-photographer.co.uk/wp-content/uploads/2012/07/SHOT-9.jpg" />
  <p>Het was 17 graden onder nul toen het ijs onder onze benen begon te kraken. Consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam. Paragraph Duis autem vel eum
    iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi.</p>
  <p>Nam liber tempor cum soluta. nobis eleifend option congue nihil imperdiet doming id quod mazim placerat facer possim assum. Dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat.
    Ut wisi enim ad minim veniam.</p>
  <p>Paragraph Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore
    te feugait nulla facilisi.</p>
  <p>Nam liber tempor cum soluta nobis eleifend option congue nihil imperdiet doming id quod mazim placerat facer possim assum. Consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim
    ad minim veniam.</p>
  <p>Paragraph Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore
    te feugait nulla facilisi.</p>
  <p>Nam liber tempor cum soluta nobis eleifend option congue nihil imperdiet doming id quod mazim placerat facer possim ass.</p>
</article>

请以全屏模式运行演示以查看响应列。

另一方面,您实际上可以在不添加包装器的情况下跨越图像,如我的示例所示。

为了让它更好一点,我还添加了两个媒体查询。布局将根据屏幕宽度从 4 到 2 到 1 列。将图像保留为第一个元素的好处是在较小的屏幕上它将首先显示。

我还添加了一个 codepen 示例,说明用 scss 编写的代码笔示例,其中图像高度作为变量,并使用 autoprefixer 来保持 css 更加干净。由于我们使用的是列,我们当然会限制浏览器支持,但这似乎是一个不错的解决方案。

http://codepen.io/stenehall/pen/yYEEva?editors=110

请注意,此解决方案仅适用于 Chrome 和 Safari,不适用于 Firefox。由于 Firefox 还不支持列跨度https://developer.mozilla.org/en-US/docs/Web/CSS/column-span。 根据那篇文章,Internet Explorer 应该可以工作,但我还没有测试过。

【讨论】:

实际上,它不适用于 Chrome。添加了一个新帖子:***.com/questions/46848645/... 和一个小提琴 jsfiddle.net/20drzb3k/5 - Chrome 隐藏了受负上边距影响的文本。

以上是关于如何在 CSS3 站点布局中将图像跨越多个列?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 GridPane JavaFX 使按钮跨越多个列/行?

CSS3 多列布局:如何设置特定列的样式

如何在kivy的gridlayout中使小部件跨越多个列/行

如何让 Bootstrap 列跨越多行?

如何在数据表中将 group_concat() 列显示为一列?

在Bootstrap3中将一列分成两行时如何获得等高的列[重复]