How to span an image over multiple columns in a CSS3 site layout?

前端 未结 4 865
情话喂你
情话喂你 2020-12-24 06:05

Given a basic four-column layout with a simple continuous paragraph of text, along with just one image spanning three columns, top-right aligned, how can we span our image o

相关标签:
4条回答
  • 2020-12-24 06:14

    To keep the original suggested solution using column-span instead of an absolute positioned image.


    Here's my suggested solution for this. The only thing you need to know is the height of the image, this might not be ideal but I think this solution is as close to perfect as it gets.

    No javascript is used to calculate the columns, no added elements or classes are needed to make it work. I split up the block of text into multiple paraphrase since I think that's a more correct way of doing it. However this solution does not depend on the multiple paragraphs, you could remove them and it would still work the same. I just randomly added paragraphs to get a more natural text.

    The following are the important parts.

    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); }
    }
    

    The full, working, example

    /* 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>

    Please run the demo in full screen mode to see the responsive columns.

    On a side not, you can actually span images without added wrappers as seen in my example.

    To make it a little bit nicer I also added two media queries. The layout will go from 4 to 2 to 1 column based on the width of the screen. The nice part of keeping the image as the first element is that on smaller screens it will show up first.

    I've also added a codepen example of what it would look like written in scss with the image height as a variable and using autoprefixer to keep the css a bit more clean. Since we're using column we of course limit the browser support but that seemed to be an ok solution.

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

    Please not that this solution only works in Chrome and Safari but not Firefox. Since firefox does not yet support column-span https://developer.mozilla.org/en-US/docs/Web/CSS/column-span. According to that article Internet Explorer should work but I've not tested it.

    0 讨论(0)
  • 2020-12-24 06:16

    I think that splitting the text in two blocks is currently the only solution. Bascially, you float the image right, place a first single column diff with the first text next to it and than place a second four column diff with the remaining text under it.

    This solution works in 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;
    }
    

    Here is a fiddle with an example:http://jsfiddle.net/1ye9tyhq/

    0 讨论(0)
  • 2020-12-24 06:24

    Hello: Please find an example of my answer HERE

    HTML CODE

    <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 CODE

    #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%;
    }
    

    THANKS T04435

    0 讨论(0)
  • 2020-12-24 06:32

    This is a cleaned up solution that should work in all major browsers. It relays on an absolute positioned image instead of using column-span since Firefox not yet supports that.

    /* 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>

    For a scss version of this look at the this codepen

    This answer originally contained a solution using column-span (sadly not yet supported by Firefox). For reference I've added this solution as a separate answer to this question.

    0 讨论(0)
提交回复
热议问题