One place for hosting & domains

      Content

      How To Use Float and Columns to Lay Out Content with CSS


      The author selected the Diversity in Tech Fund to receive a donation as part of the Write for DOnations program.

      Introduction

      There are many ways to work with layout on the web. The modern approaches tend to rely on CSS Grid and Flexbox properties to create many web layouts. However, before Grid and Flexbox existed, web developers relied heavily on the float and columns properties. The float property is used to allow inline elements to wrap around a floating element, and column sets parameters for arranging text in columns. Because these properties also have properties that neither Grid and Flexbox can replicate, learning this method of layout can add options and flexibility to a designer’s set of skills.

      In this tutorial you will work with the float and columns properties to create various layout styles and effects. You will use the float property to float a pull quote and an image and cause the content to wrap around those elements. Then you will use the columns property to adjust vertically long content to spread across the horizontal axis. Additionally, the concepts and methods of responsive web design will be covered as you work to apply the various styles.

      Prerequisites

      Setting Up the Initial HTML and CSS

      In this section you will set up the base HTML and CSS that will be used throughout the tutorial. You will use demo text content from Cupcake Ipsum and the font Comfortaa from Google Fonts.

      To begin, open the index.html file in your text editor. Then, add the following HTML to the file:

      index.html

      <!doctype html>
      <html>
        <head>
          <meta charset="utf-8">
          <meta name="viewport" content="width=device-width, initial-scale=1">
          <title>Cupcake Layouts</title>
          <link rel="preconnect" href="https://fonts.gstatic.com"> 
          <link href="https://fonts.googleapis.com/css2?family=Comfortaa:wght@400;700&display=swap" rel="stylesheet">
          <link rel="stylesheet" href="styles.css" />
        </head>
        <body>
      
        </body>
      </html>
      

      There are a lot of page settings being defined inside the <head> element. The first <meta> element defines the characters set to use for the text. This way most special characters, such as an accent mark, will render without special HTML codes. The second <meta> element tells browsers (mobile browsers in particular) to treat the width of the device as the width of the content; otherwise the browser will simulate a 960 pixel desktop width. The <title> element provides the browser with the title of the page. The <link> elements load in the page styles: The first two load in the font, Comfortaa, from Google Fonts and the last loads the styles you will write for this tutorial.

      Next, the page will need content to style. You will use sample content from Cupcake Ipsum as filler copy to work with the styles. Throughout the tutorial, new code will be highlighted.

      Return to index.html in your text editor and add the highlighted HTML from the following code block:

      index.html

      <!doctype html>
      <html>
        <head>
          ...
        </head>
        <body>
          <article>
            <h1>Carrot Cake Pie Toffee Cheesecake</h1>
      
            <p>Gummi bears powder tootsie roll biscuit. Icing jelly-o tootsie roll powder pie dessert biscuit tiramisu. Jelly beans pudding lemon drops sesame snaps jujubes sesame snaps gummi bears tiramisu. Apple pie danish soufflé soufflé cupcake cookie donut. Cookie gummies powder dragée powder chocolate bar muffin jelly marshmallow. Cheesecake dessert chocolate bar chocolate cake gingerbread chocolate bar gingerbread wafer brownie. Bear claw cake sugar plum muffin candy canes tart cheesecake croissant candy canes. Gummi bears carrot cake sweet chocolate. Carrot cake cake sweet bear claw. Gummi bears chocolate pie croissant chocolate cake bear claw dragée.</p>
      
            <p>Tootsie roll cotton candy cake tiramisu pastry. Croissant oat cake ice cream dragée sweet roll soufflé marshmallow powder marzipan. Lemon drops cake bear claw cake sweet lollipop. Lollipop toffee liquorice apple pie gingerbread pastry tiramisu.</p>
      
            <h2>Jelly Beans Wafer Apple Pie Icing</h2>
      
            <p>Jelly cotton candy cake pastry carrot cake. Topping icing danish. Lollipop sesame snaps muffin bonbon icing. Lollipop chocolate bar jelly-o sweet roll. Topping bear claw sweet. Apple pie bonbon sweet lemon drops caramels topping pastry. Biscuit jelly tootsie roll cookie tiramisu cotton candy. Icing chocolate cake liquorice ice cream sesame snaps cupcake chocolate bar pudding gingerbread. Donut toffee ice cream chocolate biscuit.</p>
      
            <p>Carrot cake pie halvah toffee cheesecake chocolate cake gingerbread liquorice. Marshmallow danish candy fruitcake chocolate dessert. Bear claw chocolate bar sugar plum pudding cake cheesecake sweet. Marzipan lemon drops croissant gummies. Dessert carrot cake carrot cake cookie candy canes toffee. Biscuit bear claw candy canes muffin. Lollipop gummies tart danish tart sugar plum biscuit. Lemon drops muffin sugar plum sweet. Cotton candy pastry topping caramels gummies carrot cake marzipan tiramisu sesame snaps.</p>
      
            <p>Ice cream donut cookie. Donut icing cookie sweet roll topping cookie. Jelly beans marzipan jujubes jelly beans ice cream marzipan apple pie cake. Sweet croissant sweet roll carrot cake oat cake tiramisu ice cream wafer wafer. Candy canes jelly beans toffee danish. Liquorice donut macaroon caramels. Donut pie cupcake gummies. Icing jujubes pudding apple pie pastry muffin sweet roll ice cream chocolate bar. Liquorice icing sugar plum marshmallow icing.</p>
      
            <h2>Jelly Sugar Plum Chocolate Danish</h2>
      
            <p>Topping marzipan sesame snaps soufflé chupa chups cookie wafer cupcake. Jelly beans lollipop jelly beans. Chocolate cake lemon drops chupa chups candy icing tootsie roll danish liquorice. Gummies danish dragée apple pie jelly pie topping icing tootsie roll. </p>
      
            <p>Apple pie bear claw muffin tiramisu gummi bears cake muffin. Candy canes oat cake croissant cake liquorice topping halvah dessert cheesecake. Candy fruitcake muffin. Cookie oat cake gummies brownie dessert candy canes icing. Soufflé chocolate cake pastry toffee cheesecake macaroon liquorice gummi bears. Halvah tiramisu jujubes. Bear claw candy danish. Macaroon chocolate wafer soufflé biscuit. Bear claw biscuit sesame snaps biscuit liquorice sweet roll lollipop. Marshmallow bear claw dragée icing liquorice candy donut chupa chups. Halvah dessert bonbon cupcake cupcake sugar plum cotton candy toffee muffin. Bonbon gummi bears jujubes chupa chups oat cake candy canes.</p>
      
            <p>Gummies bonbon marzipan icing pudding. Jujubes croissant carrot cake. Pastry halvah pudding toffee. Lemon drops gingerbread chocolate apple pie jelly cheesecake.</p>
      
            <p>Fruitcake dessert chocolate cupcake carrot cake dessert candy canes chocolate soufflé. Cookie cupcake marzipan sesame snaps biscuit tart pie jelly-o. Halvah tiramisu gummies biscuit powder donut. Chocolate cake bear claw macaroon.</p>
      
            <h2>Gingerbread Macaroon Fruitcake</h2>
      
            <p>Jelly chocolate gummies cupcake liquorice chocolate. Sugar plum donut tiramisu muffin chupa chups. Cake caramels fruitcake jelly beans pudding I love pie lollipop jelly beans. Gummi bears cheesecake dragée I love fruitcake sesame snaps I love. Apple pie muffin donut. Fruitcake donut chocolate bar cotton candy topping candy macaroon I love. Fruitcake sesame snaps jelly-o. Tart wafer sugar plum I love apple pie biscuit. Pastry sesame snaps tart. Apple pie gingerbread chocolate candy canes.</p>
      
            <p>I love cake sweet roll toffee lemon drops bonbon sweet. Oat cake lemon drops candy canes topping macaroon.</p>
      
            <p>Sweet cotton candy danish. Lollipop bear claw pudding carrot cake. Gummi bears candy canes chocolate cake chupa chups. Sugar plum jelly cake cookie cheesecake croissant muffin carrot cake. Pudding I love liquorice jelly-o caramels I love sweet roll bonbon oat cake. Caramels gummi bears gingerbread.</p>
          </article>
        <body>
      </html>
      

      Save these additions to your index.html file then open it in your web browser. The content will use the browser default styles, as shown in the following image:

      Several paragraphs and headings of black serif text on a white background

      Create a file called styles.css in the same folder as index.html and open it in your text editor. This file will contain all the styles used throughout the tutorial. The first set of styles will apply a general aesthetic that you will build on later. Apply the CSS from the following code block to your styles.css file:

      styles.css

      body {
        font: 100%/1.5 Comfortaa, sans-serif;
        color: hsl(300, 100%, 10%);
        background-color: hsl(300, 100%, 98%);
      }
      
      article {
        width: 90%;
        max-width: 75ch;
        margin: 2rem auto;
      }
      
      h1 {
        font-size: 1.75rem;
        color: hsl(204, 100%, 29%);
        margin: 1em 0  0.5em;
      }
      
      h2 {
        font-size: 1.5rem;
        color: hsl(204, 100%, 29%);
        margin: 1em 0 0.5em;
      }
      

      These styles add a minimal set of styles, using a shorthand font property on the body selector to set a new default font family and line height between lines of the text. The styles set to the article selector make the container have a width slightly smaller than the full screen width, but keep that content centered with the margin property set to auto for the left and right values. The article also has a maximum with of 75ch, which means it only gets as wide as 75 zero characters of the set font-size value. Lastly, the h1 and h2 selectors set a new font-size, color, and margin for each.

      Save your changes to styles.css, then refresh index.html in your web browser. The following image shows how these new base styles will appear in the browser:

      Several paragraphs in a dark purple sans-serif font with larger headings in blue sans-serif font, all on a light purple background.

      In this section you set up the the base HTML and CSS needed to begin adding float and columns content. In the next section, you will create a block quote that floats, allowing content to wrap around it. You will also create a horizontal rule line that stops content from wrapping around the floating element.

      Floating Content

      Next you will add a <blockquote> element and apply a float property to cause the content to wrap around the floating content.

      To create the quote content, open index.html in your text editor. After the first <p> content block, add a <blockquote> opening and closing tag. Inside the <blockquote> tags, add a new <p> content block with a couple of sentences from Cupcake Ipsum. After the next <p> content block, but before the <h2> heading, add a horizontal rule using a self-closing <hr /> element. The highlighted HTML in the following code block indicates where and what to add to your file:

      index.html

      <!doctype html>
      <html>
        ...
        <body>
          <article>
            <h1>Carrot Cake Pie Toffee Cheesecake</h1>
      
            <p>Gummi bears powder tootsie roll biscuit. Icing jelly-o tootsie roll powder pie dessert biscuit tiramisu. Jelly beans pudding lemon drops sesame snaps jujubes sesame snaps gummi bears tiramisu. Apple pie danish soufflé soufflé cupcake cookie donut. Cookie gummies powder dragée powder chocolate bar muffin jelly marshmallow. Cheesecake dessert chocolate bar chocolate cake gingerbread chocolate bar gingerbread wafer brownie. Bear claw cake sugar plum muffin candy canes tart cheesecake croissant candy canes. Gummi bears carrot cake sweet chocolate. Carrot cake cake sweet bear claw. Gummi bears chocolate pie croissant chocolate cake bear claw dragée.</p>
      
            <blockquote>
              <p>Apple pie danish soufflé soufflé cupcake cookie donut. Cookie gummies powder dragée powder chocolate bar muffin jelly marshmallow.</p>
            </blockquote>
      
            <p>Tootsie roll cotton candy cake tiramisu pastry. Croissant oat cake ice cream dragée sweet roll soufflé marshmallow powder marzipan. Lemon drops cake bear claw cake sweet lollipop. Lollipop toffee liquorice apple pie gingerbread pastry tiramisu.</p>
      
            <hr />
      
            <h2>Jelly Beans Wafer Apple Pie Icing</h2>
            ...
          </article>
        </body>
      </html>
      

      Save these changes to your index.html file, then return to the web browser and refresh the page. The quote will inherit some styles from the initial set of CSS you wrote, but still have some browser default styles applied. The following image shows how the quote and horizontal rule will appear in the browser:

      Default indentation of a block quote in the browser with a rule line before the next heading text

      To start adding styles to the quote content, open styles.css in your text editor. First create a blockquote element selector and then add a padding of 1rem, a background-color property set to a dark purple with hsl(204, 100%, 15%), and lastly a color property set to a light yellow with hsl(24, 100%, 85%). Next, add a blockquote p combinator selector to increase the font-size of the content to 1.25rem and remove the default spacing by adding a margin property with a value of 0. The highlighted CSS in the following code block shows how this will be formatted in your text editor:

      styles.css

      ...
      h2 {
        font-size: 1.5rem;
        color: hsl(204, 100%, 29%);
        margin: 1em 0 0.5em;
      }
      
      blockquote {
        padding: 1rem;
        background-color: hsl(204, 100%, 15%);
        color: hsl(24, 100%, 85%);
      }
      
      blockquote p {
        font-size: 1.25rem;
        margin: 0;
      }
      

      Save your changes to styles.css, then reload index.html in the web browser. The blockquote styling will now have larger text with a darker background and light yellow text, as shown in the following image:

      Block quote in a dark blue background container with light yellow text

      Next, you will apply the float property to the blockquote. There are three value options for the float property: left, right, and none. This means the floating content will either go the left side of the wrapping content or the right side. If the content is already floating, you can use none to remove the floating feature. For the blockquote, you will set it to float to the left, so the paragraph below it wraps to the right.

      Return to styles.css in your text editor. In the blockquote element selector, add the float property with the value set to left, as highlighted in the following code block:

      styles.css

      ...
      blockquote {
        padding: 1rem;
        background-color: hsl(204, 100%, 15%);
        color: hsl(24, 100%, 85%);
        float: left;
      }
      ...
      

      At this point the blockquote is floating, but it will not cause any content to wrap because of an aspect of how floating is handled with the contents inside. A floating element still expands to the natural width of the content. This means that since the content inside the blockquote is so long, it will still take up the same amount of space as though it were not floating. To force a visual change, add a width property set to a value of 40% to the blockquote selector, as highlighted in the following code block:

      styles.css

      ...
      blockquote {
        padding: 1rem;
        background-color: hsl(204, 100%, 15%);
        color: hsl(24, 100%, 85%);
        float: left;
        width: 40%;
      }
      ...
      

      Save these changes to styles.css and then refresh index.html in your web browser. The width of the <blockquote> element is now constrained to 40% of the parent container width, which allows the paragraph below to pull up and wrap on the right. The following image shows how this will appear in your browser:

      Blockquote content on the left side with the following text content wrapping on the right side

      The last formatting adjustment that needs to be made to the blockquote is the spacing around the element.

      Return to styles.css in your text editor. Then go to blockquote element selector block and add a margin property with a value of 0 1rem 1rem 0. The highlighted line of CSS in the following code block shows how this is formatted:

      styles.css

      ...
      blockquote {
        padding: 1rem;
        background-color: hsl(204, 100%, 15%);
        color: hsl(24, 100%, 85%);
        float: left;
        width: 40%;
        margin: 0 1rem 1rem 0;
      }
      ...
      

      This margin value will set the right and bottom margin values to 1rem and the top and left values to 0, which provides space along the sides where the text wraps around the quote.

      Save your changes to styles.css, then return to index.html in your web browser and refresh. The following image shows how this will appear in the browser:

      Blockquote content on the left side with the following text content wrapping on the right side with less space around the block quote

      As it is now, the floating pull quote is large enough that it is causing the heading of the next section to wrap as well. This where the clear property is helpful to prevent this situation. The clear property, like float, has three property values to counteract the float property and stop content from wrapping. The values for clear are left, right, and a combination of the two with both. The element on which this property is placed will stop the wrapping from that point forward.

      To use the clear property, open styles.css in your text editor. You will use the <hr /> element to apply the clear property, so begin by creating an hr element selector. Then, to add an aesthetic style, add a border property with a value of 0.125 rem solid hsl(300, 50%, 90%) to create a thick border. Next, add a margin property set to 3rem 0 so there is extra space above and below the border. Finally, add the clear property and use the both value to stop the content from wrapping around the quote element. The highlighted CSS in the following code block shows how to format these styles:

      styles.css

      ...
      
      blockquote p {
        font-size: 1.25rem;
        margin: 0;
      }
      
      hr { 
        border: 0.125rem solid hsl(300, 50%, 90%);
        margin: 3rem 0;
        clear: both;
      }
      

      Save your changes to styles.css and return to the browser and refresh index.html. As shown in the following image, the <hr> element is no longer wrapping to the right of the quote. Instead, the rule line is below, extending the full width of the content. However, the distance between the quote and the <hr> uses the margin on the float and not the larger margin value of the <hr> element:

      Blockquote content on the left side with the following text content wrapping on the right side with a light purple rule line below

      In this section, you applied a float to a <blockquote>, which caused the other elements to wrap around it. You also added the margin to give white space around the quote, making the wrapping content more legible. In the next section, you will float an image when the screen size reaches a certain width using a media query.

      Floating Image at a Given Screen Width

      There are three requirements for effective responsive web design: flexible width, resizable images, and media queries. In this step, you will use all three of these to cause an image to float to the right at a specific screen width, and then at a larger screen size pull the image into the right side margin.

      To begin, load an image on to the page. Open index.html in your text editor, and add an <img /> element between the first two paragraphs following <h2>Jelly Beans Wafer Apple Pie Icing</h2>. Like the <hr /> element from the previous section, <img /> is a self-closing element; however, the <img /> requires a src attribute to where the image file is located that will be placed on the page. The highlighted HTML in the following code block shows how to set up the <img /> in your code:

      index.html

      <!doctype html>
      <html>
        ...
        <body>
          <article>
            ...
            <hr />
      
            <h2>Jelly Beans Wafer Apple Pie Icing</h2>
      
            <p>Jelly cotton candy cake pastry carrot cake. Topping icing danish. Lollipop sesame snaps muffin bonbon icing. Lollipop chocolate bar jelly-o sweet roll. Topping bear claw sweet. Apple pie bonbon sweet lemon drops caramels topping pastry. Biscuit jelly tootsie roll cookie tiramisu cotton candy. Icing chocolate cake liquorice ice cream sesame snaps cupcake chocolate bar pudding gingerbread. Donut toffee ice cream chocolate biscuit.</p>
      
            <img src="https://source.unsplash.com/-hM0-PSO3FY/450x300" alt="Icing lemon drops danish tiramisu soufflé" />
      
            <p>Carrot cake pie halvah toffee cheesecake chocolate cake gingerbread liquorice. Marshmallow danish candy fruitcake chocolate dessert. Bear claw chocolate bar sugar plum pudding cake cheesecake sweet. Marzipan lemon drops croissant gummies. Dessert carrot cake carrot cake cookie candy canes toffee. Biscuit bear claw candy canes muffin. Lollipop gummies tart danish tart sugar plum biscuit. Lemon drops muffin sugar plum sweet. Cotton candy pastry topping caramels gummies carrot cake marzipan tiramisu sesame snaps.</p>
            ...
          </article>
        </body>
      </html>
      

      For your image you are using a picture from the Unsplash image service to provide the src value. <img /> elements also need to have an alt attribute to provide description text. This description text can be used in many ways, but it is most important to provide contextual information for screen reader users.

      Save your changes to index.html and refresh the page in your browser. You will now have an image loading on the page between two of the paragraphs, as shown in the following image:

      Image between two paragraphs of text

      Images on web pages, by default, are displayed at their given pixel size. In the case of the image added to the HTML earlier, it has a size of 450 pixels wide and 300 pixels tall. When loaded on a mobile phone that has a screen size smaller than 450 pixels wide, then the image will go off screen and cause a horizontal scroll bar. To set images to resize to fit the space contained, you can use width: 100% on the img. However, this approach allows the image to get larger than its actual size, distorting the image as it grows, known as pixelization. Instead it is better to use max-width: 100%, which allows the image to shrink into more restrictive spaces, but not grow past its actual size.

      To create these resizing images, return to styles.css in your text editor. After the body element selector at the top of the document, add an img element selector. Inside the selector block add the max-width property with a value of 100%. The highlighted CSS in the following code block demonstrates how to set up the img selector:

      styles.css

      body {
        font: 100%/1.5 Comfortaa, sans-serif;
        color: hsl(300, 100%, 10%);
        background-color: hsl(300, 100%, 98%);
      }
      
      img {
        max-width: 100%;
      }
      
      article {
        width: 90%;
        max-width: 75ch;
        margin: 2rem auto;
      }
      ...
      

      Save these changes to styles.css and refresh index.html in your web browser. Take the browser window and decrease the width to something closer to a phone size. The image will shrink once the window width becomes smaller than the width of the image. The following image shows how this will look in the browser on a narrow width window:

      Image between two paragraphs of text on a small screen width device. The image is as wide as the text contnt.

      Now that you have a responsively scaling image, you will next move the image to float right when there is sufficient space. Changing styles at a certain window or screen width is accomplished with special at-rule conditions called media queries. A media query is defined by using the @media rule followed by a media condition in which to apply the styles it contains. In this case, you want the window size to be at least 640px. Since the end user can affect the meaning of a pixel, divide 640 by 16 to get a rem unit value of 40. After the query is defined it will have its own set of curly braces, inside which are the selectors that need to change at the specified screen width.

      Open the styles.css file in your text editor. Then create a media query set to a min-width of 40rem. Inside the query block, add an img element selector with a float property set to right. So the image doesn’t take up too much space in this view, set the max-width value to 50%. Lastly, use the margin property to add a margin to the left and bottom position of the image. The highlighted CSS in the following code block demonstrates how to add the media query and the associated styles:

      styles.css

      ...
      blockquote p {
        font-size: 1.25rem;
        margin: 0;
      }
      
      @media (min-width: 40rem) {
        img {
          float: right;
          max-width: 50%;
          margin: 0 0 1rem 1rem;
        }
      }
      ...
      

      Save your changes to styles.css, then return to the browser and refresh the page. Be sure to resize your browser from a small screen size out to a more common desktop browser window size. The image will now float to the right with the text content wrapping around to the left, as shown in the following image:

      Image floating on the right side, below the first paragraph, with the second paragraph wrapping to the left and beneath the image.

      The text now defines the layout and leaves lots of extra space on the right and left when on a larger desktop screen size. In this case, it can be both aesthetically and functionally helpful to pull the image into that extra space. This can be done with a negative margin value on the floating element.

      To create this effect, open styles.css in your text editor then add another media query for a min-width of 80rem, which is equivalent to 1280 pixels. Inside the query block, add an img element selector and return the max-width property to a value of 100%. Then add a margin property with the top and bottom positions set to 1rem and the left position set to 2rem. Set the right position to -40%. This value will pull the image into the white space on the right side of the content by 40% of the parent element’s width, not the img width. The highlighted CSS in the following code block demonstrates how to set this up:

      styles.css

      ...
      @media (min-width: 40rem) {
        img {
          float: right;
          max-width: 50%;
          margin: 0 0 1rem 1rem;
        }
      }
      
      @media (min-width: 80rem) {
        img {
          max-width: 100%;
          margin: 1rem -40% 1rem 2rem;
        }
      }
      ...
      

      Save these changes to styles.css then refresh index.html in the browser. You may need to expand the width of your window, but once it reaches a width of approximately 1280 pixels the image will pull to the right and the content will continue to wrap on the left. The following image shows how this will appear in the browser:

      Image floating on the right side and into the margins. The image is below the first paragraph, with the second and third paragraphs wrapping to the left and beneath the image.

      In this section you used a media query, a percentage width, and negative margin values to float an image and pull it into the white space of the layout. In the next section, you will begin to use the columns property to change some content from a single column to two columns at a given media query screen width.

      Column content

      When working with text content it can be helpful at times to adjust the layout so that the content is side by side, or even wrap from one column to the next. There are many ways to create columns with CSS, but only the columns property will divide the content of one element between different columns. In this section, you will use the columns property to create a two-column layout for the content to wrap. Then, you will use additional columns properties to create a dividing line between the columns and tell an element how to interact with the columns to force a column break.

      To begin, open index.html and wrap the two paragraphs after <h2>Jelly Sugar Plum Chocolate Danish</h2> in a <div> element with a class property of column. The highlighted HTML in the following code block shows how this will look in your file:

      index.html

      <!doctype html>
      <html>
        ...
        <body>
          <article>
            ...
            <h2>Jelly Sugar Plum Chocolate Danish</h2>
      
            <div class="column">
            <p>Topping marzipan sesame snaps soufflé chupa chups cookie wafer cupcake. Jelly beans lollipop jelly beans. Chocolate cake lemon drops chupa chups candy icing tootsie roll danish liquorice. Gummies danish dragée apple pie jelly pie topping icing tootsie roll. </p>
      
            <p>Apple pie bear claw muffin tiramisu gummi bears cake muffin. Candy canes oat cake croissant cake liquorice topping halvah dessert cheesecake. Candy fruitcake muffin. Cookie oat cake gummies brownie dessert candy canes icing. Soufflé chocolate cake pastry toffee cheesecake macaroon liquorice gummi bears. Halvah tiramisu jujubes. Bear claw candy danish. Macaroon chocolate wafer soufflé biscuit. Bear claw biscuit sesame snaps biscuit liquorice sweet roll lollipop. Marshmallow bear claw dragée icing liquorice candy donut chupa chups. Halvah dessert bonbon cupcake cupcake sugar plum cotton candy toffee muffin. Bonbon gummi bears jujubes chupa chups oat cake candy canes.</p>
      
            <p>Gummies bonbon marzipan icing pudding. Jujubes croissant carrot cake. Pastry halvah pudding toffee. Lemon drops gingerbread chocolate apple pie jelly cheesecake.</p>
      
            <p>Fruitcake dessert chocolate cupcake carrot cake dessert candy canes chocolate soufflé. Cookie cupcake marzipan sesame snaps biscuit tart pie jelly-o. Halvah tiramisu gummies biscuit powder donut. Chocolate cake bear claw macaroon.</p>
            </div>
      
            <h2>Gingerbread Macaroon Fruitcake</h2>
            ...
          </article>
        </body>
      </html>
      

      Save your changes to index.html, then return to styles.css in your text editor. When the content width is narrow, it is too small to be divided into columns. Instead, add a .column class selector within the min-width: 40rem media query. Then give the .column selector a columns property with a value of 2, as highlighted in the following code block:

      styles.css

      ...
      @media (min-width: 40rem) {
        img {
          float: right;
          max-width: 50%;
          margin: 0 0 1rem 1rem;
        }
      
        .column {
          columns: 2;
        }
      }
      
      @media (min-width: 80rem) {
        ...
      }
      

      Save the changes to styles.css and then refresh index.html in your web browser. The content of these two paragraphs will be separated into two columns with the first line of the second sentence at the bottom of the first column wrapping into the second column, as shown in the following image:

      Two columns of paragraph text flowing from one column on the left into the second column on the right.

      There are a handful of columns properties. The columns property itself is a shorthand combination of column-count and column-width. Should you need to define a specified width of the columns, it is important to know columns are always equal in size. There are also two companion properties to help with the visual presentation of the columns. The first is column-gap, which allows for specifying spacing between each column. The second property is called column-rule, which functions similarly to a border, but only draws a vertical line between the columns.

      To add a custom gap and rule, open styles.css in your text editor. In the .columns selector block, add the column-gap property with a value of 2rem. Next, add the column-rule property with a value of 2px solid hsl(300, 50%, 90%), which will create a vertical rule line between the columns using the same color as the <hr /> element earlier. The highlighted HTML in the following code block shows how this will look in your file:

      styles.css

      ...
      @media (min-width: 40rem) {
        img {
          float: right;
          max-width: 50%;
          margin: 0 0 1rem 1rem;
        }
      
        .column {
          columns: 2;
          column-gap: 2rem;
          column-rule: 2px solid hsl(300, 50%, 90%);
        }
      }
      
      @media (min-width: 80rem) {
        ...
      }
      

      Save the changes to styles.css and refresh index.html in your web browser. The space between the columns has increased and in the middle of the gap is now a solid vertical rule line, as shown in the following image:

      Two columns of text with a thin light purple line between the columns.

      Lastly, it is possible to apply properties to the elements inside the column to influence how they interact with the layout. The paragraph in the first column has more space on it than the text in the second column. This is because of how the column interacts with the margin property and the default margin value on <p> elements. The :first-child pseudo-class can be used to change the margin-top of the first <p> element inside the column. Next, there are a few properties to control how column elements interact with the column flow: break-inside, break-after, and break-before. You will use the break-inside property with the value avoid, which tells the browser to prevent breaking apart the contents of the <p> elements.

      Return to styles.css in your text editor to begin applying these new styles to the column content. Inside the media query, add a combinator selector consisting of .column p:first-child to scope the styles to the first <p> element inside the <div class="columns"> element. Then add the margin-top property set to a value of 0. Create a new combinator selector of .column p to apply these styles to all the <p> elements inside the <div class="columns"> element. Finally, add the break-inside property with a value of avoid to keep the columns from breaking apart the content. The highlighted CSS in the following code block demonstrates how to set this up:

      styles.css

      ...
      @media (min-width: 40rem) {
        ...
      
        .column {
          columns: 2;
          column-gap: 2rem;
          column-rule: 2px solid hsl(300, 50%, 90%);
        }
      
        .column p:first-child {
          margin-top: 0;
        }
      
        .column p {
          break-inside: avoid;
        }
      }
      ...
      

      Note: There are a some things to be aware of when it comes to using the break-inside, break-after, and break-before properties. While there is good browser support for these properties, the avoid value is the most well-supported, and the other values have mixed support. Additionally, the browsers that do support the avoid value will interpret when to break the column differently, causing varying layouts between browsers. Be cautious when using the property when visual parity is needed between browsers.

      Save your changes to styles.css and refresh the page in your web browser. The second paragraph has now been forced fully into the first column. This may make the first column larger than the second, but the vertical rule accommodates the change. The first paragraph also now aligns at the top with the second column. The following image shows how this will look in most browser:

      Two paragraphs of text, each in a different column, with a light purple vertical line between.

      In this section, you used the columns property to create two columns of flowing content. You used the column-gap property to provide more space and column-rule to create a dividing line between the columns. Finally, you used the break-inside property to force how the elements interacted with the column flow. In the last section you will apply the columns property to an ordered list and adjust its presentation with media queries.

      Column List

      In this last section, you apply what you have learned with columns, media queries, and negative margin values to style an ordered list. One of the advantages of the columns property comes in making long lists a much shorter height by dividing them into two or three columns.

      To begin, you will need to add an ordered list to your HTML. Open index.html in your text editor and add the highlighted HTML in the following code block just before the last paragraph in your file:

      index.html

      <!doctype html>
      <html>
        ...
        <body>
          <article>
            ...
            <h2>Gingerbread Macaroon Fruitcake</h2>
            <p>Jelly chocolate gummies cupcake liquorice chocolate. Sugar plum donut tiramisu muffin chupa chups. Cake caramels fruitcake jelly beans pudding I love pie lollipop jelly beans. Gummi bears cheesecake dragée I love fruitcake sesame snaps I love. Apple pie muffin donut. Fruitcake donut chocolate bar cotton candy topping candy macaroon I love. Fruitcake sesame snaps jelly-o. Tart wafer sugar plum I love apple pie biscuit. Pastry sesame snaps tart. Apple pie gingerbread chocolate candy canes.</p>
      
            <p>I love cake sweet roll toffee lemon drops bonbon sweet. Oat cake lemon drops candy canes topping macaroon.</p>
      
            <ol class="column-list">
              <li>Cookie I love gingerbread topping</li>
              <li>Carrot cake toffee I love croissant pudding</li>
              <li>Sesame snaps pastry jelly-o</li>
              <li>Fruitcake pastry dessert</li>
              <li>Lollipop gingerbread I love caramels</li>
              <li>Toffee</li>
              <li>Croissant pudding I love muffin</li>
              <li>Dessert jelly beans</li>
              <li>jelly beans</li>
              <li>Liquorice</li>
              <li>I love cotton candy</li>
              <li>Apple pie</li>
              <li>Lemon raspberry cheesecake</li>
              <li>muffin donut</li>
            </ol>
      
            <p>Sweet cotton candy danish. Lollipop bear claw pudding carrot cake. Gummi bears candy canes chocolate cake chupa chups. Sugar plum jelly cake cookie cheesecake croissant muffin carrot cake. Pudding I love liquorice jelly-o caramels I love sweet roll bonbon oat cake. Caramels gummi bears gingerbread.</p>
            ...
          </article>
        </body>
      </html>
      

      Save your changes to index.html and reload the page in the web browser. As shown in the following image, the ordered list is numbered 1–14 in a single column of content:

      An ordered list of content with sequential numbers preceding each list item

      Next, open up styles.css in your text editor and just before the first media query create an ol element selector. You will then add styles to help the list stand out visually with padding, a background-color, and finally a border. The highlighted CSS in the following code block demonstrates how to set this up and the values to use for the properties:

      styles.css

      ...
      blockquote p {
        font-size: 1.25rem;
        margin: 0;
      }
      
      ol {
        padding: 2rem;
        background-color: hsl(300, 60%, 95%);
        border: 0.25rem solid hsl(300, 50%, 90%);
      }
      
      @media (min-width: 40rem) {
        ...
      }
      ...
      

      Save the changes to styles.css then return to the web browser and refresh the page. The list will have a darker border and background color, as seen in the following image:

      Numerical ordered list of content within a container with a light purple border and an even lighter purple background.

      Next, return to styles.css in your text editor to add the column styles. Like the paragraphs in the previous section, these columns are most effective for larger screen sizes and better as a single column on smaller screens. Add an ol element selector in the min-width: 40rem media query. In the selector block add a columns property with a value of 2. Then, because the numbers of the ordered list are outside the container, the columns need extra space between them. To accomodate for this extra content, add a column-gap property set to 3rem. Lastly, at larger screen sizes it can be helpful to give more vertical space between elements. Add a margin property with the top and bottom positions set to 2rem and the left and right to 0. The highlighted CSS in the following code block demonstrates how to set this up:

      styles.css

      ...
      ol {
        padding: 2rem;
        background-color: hsl(300, 60%, 95%);
        border: 0.25rem solid hsl(300, 50%, 90%);
      }
      
      @media (min-width: 40rem) {
        ...
        ol {
          columns: 2;
          column-gap: 3rem;
          margin: 2rem 0;
        }
      }
      ...
      

      Save your changes to styles.css and return to the browser to refresh index.html. Be sure your browser window is at least 640 pixels wide. The list is now separated into two columns of similar length, as shown in the following image:

      Numerical ordered list of content within a boxed container split between two columns

      Next, the items in the ordered list could use more space between each. Return to styles.css in your text editor. After the ol selector in the (min-width: 40rem) media query, add a ol li combinator selector. In the selector block, add a margin-bottom property set to 1em, which sets it to be equal to the li element’s font-size. The highlighted CSS in the following code block shows where and how to add these styles:

      styles.css

      ...
      @media (min-width: 40rem) {
        ...
        ol {
          columns: 2;
          column-gap: 3rem;
          margin: 2rem 0;
        }
      
        ol li {
          margin-bottom: 1em;
        }
      }
      ...
      

      Save the changes to your index.html file, then return to the web browser and refresh the page. The spacing between each list item is now much larger, making the list more easily scanned by the reader. The following image shows how the list spacing looks in the browser:

      Numerical ordered list of content within a boxed container split between two columns with vertical space between each list item

      Lastly, return to styles.css in your text editor to apply a third column when there is enough screen space. Start by adding a ol element selector in the (min-width: 80rem) media query, then add a columns property set to 3. The gap between the columns will be inherited from the previous media query because you are using min-width queries, so that does not need to be redefined. However, three columns need extra space so the columns are not too narrow. In order to give the list extra space, add a margin property that keeps the top and bottom positions set to 2rem, but changes the left and right positions to a negative value of -5rem. The highlighted CSS in the following code block demonstrates how to set this up:

      styles.css

      ...
      @media (min-width: 40rem) {
        ...
      }
      
      ...
      
      @media (min-width: 80rem) {
        img {
          float: right;
          width: 80%;
          margin: 1rem -40% 1rem 2rem;
        }
      
        ol {
          columns: 3;
          margin: 2rem -5rem;
        }
      }
      ...
      

      Save your changes to styles.css, then reload index.html in the web browser. Like the floating image earlier, this negative value will pull the sides of the list into the extra side space of the page. This creates a visual prominence that brings attention to the list. The following image shows how this looks in the browser:

      Numerical ordered list of content within a boxed container split between three columns and extending outside the layout into the space on the right and left.

      In this last section you combined everything you learned from the previous sections. You used media queries, columns, and negative margins to create a striking ordered list style that can be used to help lists have a more interesting presentation.

      Conclusion

      There are many ways to lay out content with CSS, and each property has its own special strength. In this tutorial, you used the float property to create elements that cause the other content to wrap around it. You also used the columns property to create content that flows from one column to the next. Additionally, you put into practice some of the principles of effective responsive design using media queries and flexible widths. As you approach layout solutions in your web projects, it is important to be aware of the various ways to accomplish the task. Both the float and columns properties provide a way to create something unique and help provide good visual design.

      If you would like to read more CSS tutorials, try out the other tutorials in the How To Style HTML with CSS series.



      Source link

      How To Use WordPress Content with a Gatsby.js Application


      The author selected the Internet Archive to receive a donation as part of the Write for DOnations program.

      Introduction

      WordPress is a popular CMS (Content Management System). It allows you to edit posts within a visual editor, as opposed to hand-coding pages of your website with raw HTML, and offers additional features, such as collaborative editing and revision history.

      Traditionally, WordPress has functioned as both the backend and frontend of a website. The posts are edited within the Admin editor, and the backend dynamically generates each public page of your site when a visitor hits it by passing it through a PHP theme.

      A new paradigm in WordPress is using it only for the content part of your site (also known as running headless), and using Gatsby to statically generate the frontend. By leveraging both and decoupling content from the user interface (UI), you can keep the content editor and collaborative features of WordPress, but also enjoy the faster load times and React-based UI ecosystem of Gatsby.

      In this tutorial, you will provision WordPress to talk to Gatsby, set up a new Gatsby project based on a starter template, define the connection to WordPress in your Gatsby configuration, and put it all together to statically generate some pages based on posts that live inside your WordPress installation.

      Prerequisites

      Before you start on this guide, here are a few things you will need:

      • An environment with sufficient resources to support building and serving your site. If you are using the same server to both host WordPress and build your Gatsby site, the recommended minimum amount of RAM is 2GB. If you would like to use a DigitalOcean Droplet, check out our How to Create a Droplet from the DigitalOcean Control Panel article.
      • A working WordPress installation that is reachable from where Gatsby is running. If you are brand new to WordPress, you might want to start with a guide on What is WordPress first, but for general setup, there are also guides for multiple environments, such as Docker. This tutorial was tested on a LAMP stack set up by following How To Install WordPress on Ubuntu 20.04 with a LAMP Stack.
      • Node.js, installed locally, for running Gatsby and building your site. The installation procedure varies by operating system, but there are guides for installing Node.js on Ubuntu and installing Node.js on Mac, and you can always find the latest release on the official NodeJS download page.
      • The Gatsby CLI tool, installed locally. For how to install this and to learn some of the Gatsby basics, you can follow Step 1 of the How to Set Up Your First Gatsby Website tutorial.
      • Some familiarity with JavaScript, for working in Gatsby. There is a lot of depth to JavaScript, but a good starting spot is our How to Code in JavaScript series. Additionally, it will help to have some knowledge of HTML, such as understanding HTML elements, and if you want to customize the UI of your posts beyond what is covered in this tutorial, it will also help to know some React and JSX.

      This tutorial was tested on WordPress v5.7.1, Gatsby v3.3.0, and Node.js v14.17.0. Additionally, the WordPress setup was tested on both Windows 10 and Ubuntu 20.04 with Apache v2.4.41 and PHP v7.4.3.

      Step 1 — Installing and Configuring the Required WordPress Plugins

      In this first step, you will give WordPress the ability to talk to Gatsby by installing some plugins and adjusting settings. You will also verify that your local or hosted WordPress instance supports these changes, and record some details about your specific setup that will be needed later.

      Start by logging into the admin dashboard of your WordPress instance by navigating to https://your_domain_name/wp-admin in your browser and inputting your credentials. Then go to the plugins page by clicking Plugins in the left sidebar. Next, navigate to the plugin installation page by clicking Add New at the top of the page, or in the same sidebar. If your WordPress installation uses standard paths, you will also be able to find this page at https://your_domain/wp-admin/plugin-install.php. This will bring you to the plugins page, as shown in the following image:

      Screenshot showing the Add New link selected in the Plugins sidebar in WordPress Admin

      The two required plugins are as follows, and will be installed in this order:

      Screenshot of the WordPress plugin listing for WPGraphQL

      Screenshot of the WordPress plugin listing for WPGatsby

      Install and activate both of these plugins by searching for them and then pressing their associated Install Now buttons. Once they are installed, select the Activate button. After both plugins have been installed and activated, you will see some new settings panels within your WordPress admin dashboard. The following image shows these new settings panels.

      Screenshot showing that both required plugins, WPGraphQL and WPGatsby, are installed, activated, and have added settings panels around the admin dashboard

      To verify that the GraphQL connection will be available for connecting to Gatsby, open the Settings panel, under the GraphQL sub-section in the Admin sidebar.

      Screenshot of the WPGraphQL settings page, with the GraphQL endpoint URL highlighted. In this example, it is

      Take special note of the GraphQL endpoint. You can find this in the section labeled GraphQL Endpoint, below the text entry box. It is also highlighted in yellow in the screenshot. You will need this later, so to save some time you can copy it into your clipboard and/or paste it into a temporary text document.

      For the best results with WPGraphQL, it is recommended to use a WordPress permalink setting other than plain, especially if this is a new WordPress installation where changing the URL structure will not affect a live website. To navigate to your permalink settings, click on Settings in the left sidebar of your WordPress admin dashboard, then click on Permalinks in that expanded section. From the permalink settings page, change your setting to any option other than plain, and then press Save Changes to update your site.

      Setting your permalinks to something other than plain comes with some specific technical requirements; with the Apache web server, you need to enable the mod_rewrite module and set the AllowOverride directive to all. These will enable WordPress to dynamically route new paths. Step 3 of the WordPress on Ubuntu 20.04 tutorial covers this, with step-by-step instructions. If you ran Let’s Encrypt to provide an SSL certificate for your site, as is instructed in the How To Secure Apache with Let’s Encrypt on Ubuntu 20.04 tutorial, you will have to complete these steps for the new virtual host at /etc/apache2/sites-available/your_domain-le-ssl.conf.

      Now that you have a GraphQL endpoint configured, you will test this connection. You can do so immediately; no Gatsby is installation required yet. You can use the GraphiQL IDE for a visual query builder tool (accessible through the sidebar), or you can even query the endpoint directly with your favorite network request tool of choice.

      If you prefer the command line and have cURL installed, you could use the following command to retrieve all post titles:

      • curl --location --request POST 'https://your_domain/graphql'
      • --header 'Content-Type: application/json'
      • --data-raw '{
      • "query": "query { posts { nodes { title } } }"
      • }'

      This command makes a request to your GraphQL endpoint for a JSON response containing your WordPress posts, but only with their titles. With GraphQL, this is also called a query; the tutorial Understanding Queries in GraphQL explains them more in-depth.

      The response JSON to your query will be something like this:

      Output

      {"data":{"posts":{"nodes":[{"title":"Hello world!"}]}},"extensions":{"debug":[{"type":"DEBUG_LOGS_INACTIVE","message":"GraphQL Debug logging is not active. To see debug logs, GRAPHQL_DEBUG must be enabled."}]}}

      Now that you have successfully installed and configured the required WordPress plugins to communicate with Gatsby, you can move on to setting up your new Gatsby project.

      Step 2 — Setting Up a New Gatsby Project

      In this step, you will set up a new Gatsby project based on a starter template specifically designed for sourcing data from WordPress. It will require using the Gatsby CLI to download and install the starter and its dependencies.

      To speed up your development process and reduce the amount of setup that is required, you will start by using the Gatsby CLI and the Gatsby WordPress Blog Starter template.

      Navigate to the local parent directory that will hold your Gatsby project, then run the following command to have the Gatsby CLI download and pre-install most of what you will need to get started building your site:

      • gatsby new my-wordpress-gatsby-site https://github.com/gatsbyjs/gatsby-starter-wordpress-blog

      You can replace my-wordpress-gatsby-site with whatever you would like the directory name to be for your local Gatsby files.

      It will take a while for Gatsby to download and install all the necessary dependencies and assets. Once it has finished, you will receive a message similar to this one:

      Output

      ... Your new Gatsby site has been successfully bootstrapped. Start developing it by running: cd my-wordpress-gatsby-site gatsby develop

      Normally with a Gatsby site, this is the point at which you would hand-edit the gatsby-config.js file with details about your site known as metadata. However, in addition to pulling posts from WordPress, this starter also pulls the metadata in for you automatically; no need to hand-code the site title or description.

      Having scaffolded a new Gatsby project, you are now ready to modify its configuration to tell it to pull data from WordPress.

      Step 3 — Configuring Gatsby to Use WordPress Data

      Now that you have a working Gatsby project, the next step is for you to configure it to pull in the data from WordPress. You will do this by editing the main Gatsby configuration file and working with the gatsby-source-wordpress plugin.

      Thanks to the starter template you used, the gatsby-source-wordpress plugin will already be installed as a dependency and have a settings entry in the Gatsby config file; you just need to tweak it slightly.

      Move into your local Gatsby directory that was created in the previous step:

      • cd my-wordpress-gatsby-site

      Then, open the file named ./gatsby-config.js in your text editor of choice. This is the main configuration file for all Gatsby projects.

      Within the config file, you will find an existing settings entry for gatsby-source-wordpress within the plugins array. You can now take your specific GraphQL endpoint you copied from the previous step and replace the default demo endpoint, https://wpgatsbydemo.wpengine.com/graphql, with your value, as highlighted in the following code:

      gatsby-config.js

      module.exports = {
          plugins: [
              {
                  resolve: `gatsby-source-wordpress`,
                  options: {
                      url:
                          process.env.WPGRAPHQL_URL ||
                          `https://your_domain/graphql`,
                  },
              },
              ...
          ],
          ...
      }
      

      Save and close this file so that future builds of the site will use the updated value.

      Note: url is the only required setting option, but there are a lot that are available; take a look at the Gatsby GitHub repostory for more. For example, there are options for enabling debug output, connecting to an HTACCESS, password-protected site, and performance related options, such as schema.requestConcurrency, which is especially important if your WordPress site is running on a server with limited resources.

      Before moving on to customizing how Gatsby uses your WordPress data to build pages, build and preview your site as-is to make sure everything is working correctly. You can do this by running the following command:

      Or, if you are using the yarn package manager:

      Warning: If you get an error at this step, especially if it is an error about a missing dependency or can't resolve '...' in '....cache, it might be that part of the dependency install process has failed. This is a known issue in Gatsby projects. Try running npm i again (or yarn install if using yarn) to check for and install any missing dependencies. If that fails to fix the issue, completely rebuild your dependencies by deleting the node_modules folder, deleting package-lock.json or yarn.lock, and then running npm i or yarn install.

      This command will run the gatsby develop process, which will pull in data from WordPress, combine it with the starter template’s pre-built UI files, and start a local development server so you can view a preview of the actual generated website in a browser. This command also runs Gatsby in a mode that supports hot-reloading, so that if you make edits to your local files, you will see those changes reflected instantly in your web browser.

      Navigate to localhost:8000 in your browser and you will find your Gatsby site with WordPress content:

      Gatsby site entitled

      With your Gatsby project now pulling data from WordPress, the next step will be to customize the actual template files so that you can make your Gatsby site look and act just how you want it to.

      Step 4 — Customizing the Starter Template Files

      The Gatsby WordPress starter template provides a lot of default functionality, but in this step you will explore how you can customize the template files to make the project your own, in both form and function. By editing some Gatsby source files, you will bring a new piece of WordPress content—the post excerpt—into your Gatsby site and style it with CSS.

      For most Gatsby sites, your starter template included, there are a few key files and folders to be aware of when it comes to customization:

      • ./gatsby-node.js: This could be considered the center of the Static Site Generation process. It has the code for querying WordPress for all your content, then passing it through template files to generate the static output. If you want to modify what content ends up on your site, this is the main entry-point. In terms of WordPress development, this is similar to working with The Loop and similar concepts.
      • ./src/templates: This contains individual template files, each of which should contain and export a React component responsible for rendering the content passed in. If you want to change how content looks, integrate third-party UI libraries, or build skeletons around content, this is the usual place to do it. In terms of WordPress development, these are similar to Template Files.
      • ./src/components: Typically, each file in this folder is a singular React component that is dedicated to a specific UI task, and is meant to be pulled into template files. Think of these as UI building blocks, but not as templates. If you have a UI element that you want to share across multiple template files, this is a good place to put it and avoid copying and pasting the same code over and over. Some examples of this would be menus, author bio displays, header and footer elements, etc. In terms of WordPress development, these are similar to Template Partials.
      • ./src/css: This contains CSS files that are shared across the site, as opposed to inline-styling, or a popular css-in-js solution, such as styled-components. In this tutorial, and with your specific starter template, this folder provides the majority of styling for your new site. In terms of WordPress development, this is equivalent to style.css, or any number of stylesheets that a theme can inject into a page through WordPress’s enqueue system.

      For an example of how you can edit the existing template files, open ./src/templates/blog-post.js in your text editor.

      In WordPress, there is a special text value for each post called the excerpt, which is a short descriptive summary of the post. By default, this Gatsby template file pulls in the WordPress excerpt, but only uses it for SEO purposes, putting it in the <meta name="description" /> tag. You can modify the blog post template file to include the post excerpt visually, like so, adding the highlighted code to your file:

      /src/templates/blog-post.js

      const BlogPostTemplate = ({ data: { previous, next, post } }) => {
          ...
          return (
              <Layout>
                  ...
                  <h1 itemProp="headline">{parse(post.title)}</h1>
      
                  <p>{post.date}</p>
      
                  {/* Checking for and adding the post excerpt if the current post has one*/}
                  {post.excerpt && (
                      <div className="post-excerpt">{parse(post.excerpt)}</div>
                  )}
      
            {/* if we have a featured image for this post let's display it */}
              {featuredImage?.fluid && (
                <Image
                  fluid={featuredImage.fluid}
                    alt={featuredImage.alt}
                    style={{ marginBottom: 50 }}
                />
              )}
            ...
              </Layout>
          )
      }
      

      In this code, you are checking if the post has an excerpt (important since it is not mandatory in WordPress), and if it does, displaying the text content of the excerpt inside a <div> element. The parse() function comes from html-react-parser, and is being used here to make sure that the <p> tag that will hold your excerpt is parsed into HTML rather than plain text, so you can echo out the content directly. An alternative approach would be to use dangerouslySetInnerHTML, with <div className="post-excerpt" dangerouslySetInnerHTML={{__html: post.excerpt}} ></div>.

      Save and close the blog-post.js file.

      Since the excerpt is a summary of the post, it might help the visitors to your site if you visually separate it from the body of the post, highlighting it at the top of the page and making it easy to find. You can do this by editing the main shared CSS file at ./src/css/style.css:

      /src/css/style.css

      .post-list-item header {
        margin-bottom: var(--spacing-4);
      }
      
      /* CSS targeting your new post excerpt element */
      .post-excerpt {
        box-shadow: 0px 1px 9px 1px rgb(0 0 0 / 50%);
        padding: 6px;
        border-radius: 8px;
        margin-bottom: 14px;
      }
      
      .post-excerpt p {
        margin-bottom: 0px;
      }
      

      In your CSS, you have now used box-shadow to add a shadow effect around the excerpt container, contrasting it with the actual body of the post, as well as added padding, rounded edges, and spacing between itself and adjacent elements. Furthermore, you removed the default bottom margin from the text of the excerpt, since spacing is now provided by the container .post-excerpt element.

      Save the style.css file. To test this out, add an excerpt in WordPress to take advantage of this new visual feature. In the sidebar of the WordPress admin view, navigate to the Posts tab, then select the sample Hello world! post. This will take you to the WordPress post editor view. In the newer block-based editor, the excerpt field appears under the Post tab in the right sidebar, near the bottom. In the legacy editor, the location of the excerpt field is customizable, so it might appear in different locations depending on your theme and custom settings.

      Add in an excerpt, then select the Update button at the top of the screen. Then, go to your Gatsby site at localhost:8000, and select the Hello world! blog post. You will find the excerpt you wrote rendered on the page:

      The sample

      Note: If you are looking for pre-built themes that don’t require any additional coding or configuration, similar to how WordPress themes work, there is a growing number of both official and community themes for using WordPress with Gatsby.

      You have just embedded and styled a post excerpt from WordPress into a custom Gatsby static site. This used data that was already configured for use by your starter template. The next step will explore how to bring new pieces of data via GraphQL and integrate them into your Gatsby site.

      Step 5 — Using WordPress Data in Gatsby with Custom Templates

      In the previous steps, you edited an existing template and used some standard WordPress data (post title and post content) to render your blog posts with Gatsby’s static output. For many sites, this alone might be all that is needed. However, to showcase how decoupling the UI from WordPress gives you greater flexibility, in this step you will explore how you would add support for a special video post type in Gatsby, going beyond that existing blog post template.

      In this scenario, you are adding support for posts that each showcase a single video, sourced from YouTube. You will make it so that you or your content collaborators can copy and paste a YouTube URL into the WordPress post editor and the Gatsby site itself will show the video inside a customized YouTube embed widget.

      For the post template, create a new file under /src/templates, and name it video-post.js. Before building the UI of the page that will be generated, you can write a GraphQL query to retrieve data for it. In Gatsby, this is called a Page Query, and uses the graphql tag.

      Add the following code to the video-post.js file:

      /src/templates/video-post.js

      import React from "react"
      import { graphql } from "gatsby"
      
      export const pageQuery = graphql`
        query VideoPostById(
          # these variables are passed in via createPage.pageContext in gatsby-node.js
          $id: String!
        ) {
          # selecting the current post by id
          post: wpPost(id: { eq: $id }) {
            id
            content
            title
            date(formatString: "MMMM DD, YYYY")
          }
        }
      `
      

      In this snippet, you are using the post ID to query for specific values belonging to that exact post—such as the actual post content, title, and date.

      Next, you can add the actual React component that returns JSX, which will be rendered as the webpage. A good place to start is by copying most of the structure from the existing blog-post.js template file and adding the following highlighted lines:

      /src/templates/video-post.js

      import React from "react"
      import { graphql } from "gatsby"
      import parse from "html-react-parser"
      
      import Bio from "../components/bio"
      import Layout from "../components/layout"
      import Seo from "../components/seo"
      
      const VideoPostTemplate = ({ data: { post } }) => {
        return (
          <Layout>
            <Seo title={post.title} description={post.excerpt} />
      
            <article
              className="blog-post"
              itemScope
              itemType="http://schema.org/Article"
            >
              <header>
                <h1 itemProp="headline">{parse(post.title)}</h1>
                <p>{post.date}</p>
              </header>
      
              <footer>
                <Bio />
              </footer>
            </article>
          </Layout>
        )
      }
      
      export default VideoPostTemplate;
      
      export const pageQuery = graphql`
        query VideoPostById(
          # these variables are passed in via createPage.pageContext in gatsby-node.js
          $id: String!
        ) {
          # selecting the current post by id
          post: wpPost(id: { eq: $id }) {
            id
            content
            title
            date(formatString: "MMMM DD, YYYY")
          }
        }
      `
      

      In addition to creating the React component, you also used export default to make sure that the component is the default item exported from the file. This is important because of how the file is imported later on by Gatsby when it compiles the template against data from WordPress.

      Now, you can add some logic to your React component to check if there is a raw YouTube URL embedded in the body of the post:

      /src/templates/video-post.js

      ...
      
      const VideoPostTemplate = ({ data: { post } }) => {
        // RegEx to find YouTube IDs
        const youtubeIdPattern = /watch?v=([a-z_0-9-]+)|youtu.be/([a-z_0-9-]+)|youtube.com/embed/([a-z_0-9-]+)/i;
      
        const matches = youtubeIdPattern.exec(post.content);
        let videoId;
      
        if (matches) {
          // Use first available match
          videoId = matches[1] || matches[2] || matches[3];
        }
      
        return (
          <Layout>
            <Seo title={post.title} description={post.excerpt} />
      
            <article
              className="blog-post"
              itemScope
              itemType="http://schema.org/Article"
            >
              <header>
                <h1 itemProp="headline">{parse(post.title)}</h1>
                <p>{post.date}</p>
              </header>
      
              <footer>
                <Bio />
              </footer>
            </article>
          </Layout>
        )
      }
      ...
      

      In this code, youtubeIdPattern is a Regular Expression (or RegEx), which is a search pattern you are executing against the body of the post with youtubeIdPattern.exec(post.content) to try and find any YouTube IDs which were included. If matches are found, the variable videoId is set to the first match.

      Finally, you can add the JSX that renders the video based on the videoId you’ve extracted:

      /src/templates/video-post.js

      ...
      
        return (
          <Layout>
            <Seo title={post.title} description={post.excerpt} />
      
            <article
              className="blog-post"
              itemScope
              itemType="http://schema.org/Article"
            >
              <header>
                <h1 itemProp="headline">{parse(post.title)}</h1>
                <p>{post.date}</p>
              </header>
      
              {videoId ? (
                <div className="video-embed">
                  <iframe width="512" height="288" src={`https://www.youtube-nocookie.com/embed/${videoId}?controls=0&autoplay=1`} title={post.title} frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
                </div>
              ) : (
                <div className="no-video-found">
                  <p>Sorry, could not find a video in this post!</p>
                </div>
              )}
      
              <hr />
      
              <footer>
                <Bio />
              </footer>
            </article>
          </Layout>
        )
      }
      ...
      

      If a videoId is found, your code returns a customized, privacy-enhanced YouTube embed, served through an iframe, set to autoplay. Otherwise, it returns a message that no video was found. It also adds a horizontal break between the video embed and the footer of the post.

      Now that your component template file is built, you will tell Gatsby to use the new template for posts that are set to the Video type within WordPress, and not use the regular blog post template for them.

      Make sure to save your changes in video-post.js, then open gatsby-node.js in your text editor.

      First, modify the getPosts() function, which the starter uses as the main GraphQL query to the WordPress backend for posts. You’ll modify the query to pull in the postFormats that the given post belongs to:

      gatsby-node.js

      ...
      async function getPosts({ graphql, reporter }) {
        const graphqlResult = await graphql(/* GraphQL */ `
          query WpPosts {
            # Query all WordPress blog posts sorted by date
            allWpPost(sort: { fields: [date], order: DESC }) {
              edges {
                previous {
                  id
                }
      
                ...
      
                post: node {
                  id
                  uri
                  postFormats {
                    formats: nodes {
                      name
                    }
                  }
                }
      
                next {
                  id
                }
              }
            }
          }
        `)
      
        ...
      
        return graphqlResult.data.allWpPost.edges
      }
      

      Next, you need to implement the logic that separates the video posts and sends them to their unique template file for rendering. For this, you can hook into the existing createIndividualBlogPostPages() function in the starter.

      You can pull the data from the GraphQL query you modified and use that to determine if the current post is a video post or not:

      gatsby-node.js

      const createIndividualBlogPostPages = async ({ posts, gatsbyUtilities }) =>
        Promise.all(
          posts.map(({ previous, post, next }) => {
            const postFormats = post.postFormats.formats;
            const isVideo = postFormats.length && postFormats[0].name === 'Video';
      ...
                // We also use the next and previous id's to query them and add links!
                previousPostId: previous ? previous.id : null,
                nextPostId: next ? next.id : null,
              },
            })}
          )
        )
      

      Then, change the component property in createPage to use the corresponding template file:

      gatsby-node.js

      const createIndividualBlogPostPages = async ({ posts, gatsbyUtilities }) =>
        Promise.all(
          posts.map(({ previous, post, next }) => {
            const postFormats = post.postFormats.formats;
            const isVideo = postFormats.length && postFormats[0].name === 'Video';
      
            return gatsbyUtilities.actions.createPage({
              // Use the WordPress uri as the Gatsby page path
              // This is a good idea so that internal links and menus work 👍
              path: post.uri,
      
              // Use special video template if post format === Video, else use blog post template
              component: isVideo ? path.resolve(`./src/templates/video-post.js`) : path.resolve(`./src/templates/blog-post.js`),
      
              ...
            });
          })
        )
      

      To keep things concise, this code statement uses a ternary operator, which is a way to return one value if another is truthy (truth-like) and a different value if it is falsy, all without an if/else statement. The code uses isVideo from your previous post format check, and if true, returns the path of the new video template. If false, it tells Gatsby to use the regular blog post template. The Node.js path.resolve() function is used to turn the relative path (./src/...) into an absolute path (the full filepath), which Gatsby requires to load a component file.

      Save and exit the file.

      Next, style your video embed by editing ./src/css/style.css again:

      /src/css/style.css

      .video-embed {
        /* Shadow effect around box to give it contrast */
        box-shadow: 0px 2px 12px 4px rgb(0 0 0 / 50%);
        /* All four declarations below help center our video and give it space */
        display: block;
        line-height: 0px;
        margin: 20px auto;
        max-width: 512px;
      }
      

      In adding the this CSS, you’ve given the video embed a shadow effect around it, which also gives it contrast with the page, as well as centered it and given it space away from other elements.

      To test the functionality of this new code, you can create a new post in WordPress that matches the criteria required by the template. From your WordPress Admin Dashboard, click on Posts in the left sidebar, then Add New to start building a new post. Give your post a title, and then make sure it meets these two criteria:

      • The Post Format will be set to Video. You can find the format dropdown in the right sidebar
      • The post body will contain a YouTube URL (and not as an embed). To test this, you can use this short link to a DigitalOcean promotional video: youtu.be/iom_nhYQIYk.

      Screenshot showing the WordPress post editor with a YouTube URL in the body of the post, and the post format type set to Video

      After filling out the post, select Publish (or Update if this is an existing post) and click to confirm the prompt that appears, so that your post goes live and Gatsby can fetch it over the GraphQL connection.

      Navigate to localhost:8000 in your browser and select your test video post. The YouTube video will be rendered in the browser, as shown in the following image:

      Video blog post with rendered DigitalOcean promotional video on page

      Conclusion

      By working through the steps in this tutorial, you now have a statically generated Gatsby site that sources its content from a WordPress backend. In decoupling content from UI, you have opened up new possibilities for speeding up your site, reduced the barriers to cross-discipline content collaboration, and taken advantage of the rich ecosystem that Gatsby and React provide for UI development.

      If you would like to read more Gatsby tutorials, try out the other tutorials in the How To Create Static Web Sites with Gatsby.js series.



      Source link

      What is a Content Security Policy?


      A Content Security Policy (CSP) is a mechanism for web developers to increase the security of their websites. By setting a Content Security Policy, web developers can instruct web browsers to only load resources from certain trusted domains, enforce secure HTTPS connections, and even report policy violations as they occur. This can prevent many content injection and cross-site scripting (XSS) vulnerabilities, which often lead to data leaks, website vandalism, and malware distribution.

      Policies are transmitted to the web browser by either setting the Content-Security-Policy HTTP header, or including a <meta http-equiv="Content-Security-Policy" ... > tag in the HTML source of the site. The actual policy data is a text string, made up of one or more directives that specify the desired restrictions and configurations.

      To find out more about Content Security Policies, and their implementation in production applications, please refer to the following resources:



      Source link