One place for hosting & domains

      An Essential Guide on How to Add JavaScript to HTML


      JavaScript is a scripting language that is widely used to add dynamic functionality to a web page, alongside HTML and CSS. User triggered events, animations, and content updates are among some of the features on a web page that are powered by JavaScript. In order to use JavaScript on an HTML web page, you must use the <script> tag to either write your JavaScript code directly in your HTML markup or to link to an external JavaScript file. This guide shows you how to use the <script> tag to link JavaScript to an HTML page. You also learn about <script> tag attributes that help you optimize your web page’s loading time.

      The <script> tag is used to add JavaScript to an HTML web page. The following sections further explain how the <script> tag behaves when added to HTML markup and the different ways you can use it to add JavaScript to a web page.

      What is a <script> Tag?

      The <script> tag can be used to embed JavaScript into a web page in the following two ways:

      • Writing JavaScript code directly within an opening and closing <script> tags.
      • Referencing the path to a JavaScript file using the <script> tag’s src attribute.

      In both cases, when the HTML page loads, the web browser executes any JavaScript that it finds, in sequential order. There are two useful principles to keep in mind when using the <script> tag:

      • The JavaScript contained within or referenced by <script> tags is executed immediately when its portion of the page loads. So, a <script> tag placed within a page’s <head> tag executes before the HTML body. A <script> tag placed just before the end of the closing </body> tag, on the other hand, executes after everything else on the page has loaded and rendered.

      • The JavaScript used in your HTML markup defines functions and variables in the global scope. This means that if your web page has two <script> tags — say, one at the beginning and one at the end — they can reference the same functions and variables.

        Keep in mind that the code still follows the ordering described in the point above. For that reason, a script at the beginning of a web page cannot reference a variable assigned in a script at the end of the web page.

      How to Add JavaScript to HTML

      You can add JavaScript to your HTML markup by embedding JavaScript code between opening and closing <script> tags. For example, to add an alert box to an HTML page with a message that reads The script is working, add the following code to your HTML markup:

      <script>
          alert("The script is working!");
      </script>
      

      This example adds the JavaScript code directly to the HTML markup.

      The next example demonstrates the <script> tag contained within the body of an HTML page. As the browser sequentially executes the HTML, when it encounters the <script> tag, it executes the JavaScript within the tag. The JavaScript adds an event listener to the button with id="exampleButton". If a user clicks on the button, an alert box presents the message passed as an argument to the alert() method.

      File: example.html
       1
       2
       3
       4
       5
       6
       7
       8
       9
      10
      11
      12
      13
      14
      15
      
      <!doctype html>
      <html lang="en">
        <head>
          <title>Example Web Page with JavaScript</title>
        </head>
        <body>
          <button id="exampleButton">Click Me!</button>
          <script>
              exampleButtonElement = document.getElementById("exampleButton");
              exampleButtonElement.addEventListener("onclick", () => {
                  alert("The button has been clicked!");
              }
          </script>
        </body>
      </html>

      In the example, the <script> tag is placed after the <button> tag. This is necessary because the JavaScript references the button element. If the JavaScript had been inserted any earlier, the button element would not yet have been created by the time the JavaScript executes.

      Adding External JavaScript Files

      As your JavaScript code gets more complicated, you are likely to prefer keeping it in an external JS file, rather than including the script directly in your HTML markup.

      To include an external JavaScript file in HTML, you still use the <script> tag. However, instead of adding JavaScript directly between the <script> tags, you use the tag’s src attribute to point to an external JS file. The steps below give you a simple example that references an external JavaScript file HTML markup.

      The steps below assume that you are developing a simple website on your local computer. Your site files are stored in a directory named example-site.

      1. In your example-site directory, add a new subdirectory named js_files. This directory stores any JavaScript files that are referenced by HTML files.

        mkdir js_files
        
      2. Using your preferred text editor, add a new file named example.js to the js_files directory with the JavaScript displayed below.

        File: ~/username/js_files/example.js
         1
         2
         3
         4
         5
         6
         7
         8
         9
        10
        11
        12
        13
        
        // Create a button element.
        const buttonElement = document.createElement("button");
        const buttonElementText = document.createTextNode("Click Me!");
        buttonElement.appendChild(buttonElementText);
        
        // Add a 'click' event to that button element.
        buttonElement.addEventListener("click", () => {
            alert("The button has been clicked!");
        });
        
        // Insert the button element into the body of the web page.
        document.body.appendChild(buttonElement);
            
        
      3. Create an HTML file with the example markup. The markup uses the <script> tag to reference the JavaScript file created in the previous step.

        File: ~/username/example.html
         1
         2
         3
         4
         5
         6
         7
         8
         9
        10
        
        <!doctype html>
        <html lang="en">
          <head>
            <title>Example Web Page with JavaScript</title>
          </head>
          <body>
            <script src="js_files/example.js"></script>
          </body>
        </html>
            

        The src attribute uses the relative path to the example.js file that contains the JavaScript code you want to execute.

      4. Visit the HTML page in a browser by entering the following address: file:///home/username/example-site/example.html. Click on the button and observe that it produces an alert dialog.

        You can also see the result by
        viewing our included example.html file
        .

      Defining <script> Tag Attributes

      Like all other HTML tags, the <script> tag supports a series of attributes that you can use to further control the behavior of the JavaScript that is executed on a web page. The list below contains some of the most useful attributes.

      • The async attribute tells the browser to download the referenced JavaScript file as the web page is parsed. Once the file has downloaded, its contents are immediately executed.

      • The defer attribute tells the browser to download a JavaScript file as the web page is parsed. The file is only executed once the entire web page has loaded.

      • The type attribute is used to identify the kind of script that is referenced by the src attribute. However, since JavaScript has become the unambiguous standard, this attribute is rarely necessary anymore.

      • The charset attribute lets you define a different character set for an external JavaScript file. This attribute, though common to see, is
        considered deprecated
        since documents now must use UTF-8.

      The sections below dive deeper into the two most useful <script> tag attributes, async and defer. These sections discuss how these attributes can be used to improve a web page’s performance.

      Async

      Normally, when a browser encounters the <script> tag with a linked JavaScript file, it stops loading the HTML in order to start downloading the referenced JavaScript file. Using the async attribute, it is possible to improve your web page’s performance by having the browser download the JavaScript file in the background while the page continues to load.

      The example file’s script tag makes use of the async attribute.

      File: index.html
      1
      2
      3
      4
      5
      6
      7
      8
      9
      
      <!doctype html>
      <html lang="en">
        <head>
          <title>Example Web Page with JavaScript</title>
        </head>
        <body>
          <script src="js_files/main.js" async></script>
        </body>
      </html>

      It’s not always advisable to use the async attribute. For instance, if your script depends on certain elements not yet being rendered, or if the elements themselves depend on the script creating certain elements, async would likely be a problematic choice. When such cases are not a concern, async can help with your page’s load speed and user experience.

      Defer

      Like async, using defer tells the browser to download a linked JavaScript file in the background while the page continues to load. Unlike async, however, defer prevents the loaded script from being executed until the page has been fully rendered. This makes defer especially useful when your JavaScript code relies on one or more elements being rendered and available. Because defer ensures that the script only runs once the page has been loaded completely, you can be assured that the script does not run until all required elements are present on the page.

      File: index.html
      1
      2
      3
      4
      5
      6
      7
      8
      9
      
      <!doctype html>
      <html lang="en">
        <head>
          <title>Example Web Page with JavaScript</title>
        </head>
        <body>
          <script src="js_files/main.js" defer></script>
        </body>
      </html>

      Conclusion

      This guide covered the foundational information you need to start using JavaScript on your HTML pages. Whether you plan to embed a script or link a JavaScript file in your HTML, this guide outlined the steps needed to do so.

      As a next step, you may be interested in looking at some of our other JavaScript tutorials. For instance, take a look at our
      Traversing the Document Object Model with JavaScript
      tutorial, our
      How to Modify the DOM with JavaScript
      tutorial, and our
      JavaScript Objects
      tutorial.



      Source link

      How To Style Figure and Image HTML Elements with CSS


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

      Introduction

      When styling images on a web page with CSS, there are many important ideas to keep in mind. By default, web browsers display images in a raw format at their default size. This can lead to images being larger than the rest of the content, or can introduce unexpected spacing problems for your page layout. This tutorial will lead you through examples of image styling for web pages, allowing you to make informed decisions about how images are displayed and altered to fit the context.

      In this tutorial, you will create a web page consisting of content and three images. The first image will be loaded as an <img /> element on its own, the second will be wrapped in the <figure> element with an appropriate <figcaption>, and the third will use the <picture> element to load different images at different screen sizes and use the object-fit and object-position properties to resize the image. You will also explore some of the fundamentals of responsive web design and ensure the accessibility of your images.

      Prerequisites

      Setting Up the Base HTML and CSS

      In this section, you will set up the base HTML for all the visual styles you will write throughout the tutorial. You will also create your styles.css file and add styles that set the layout of the content.

      Start by opening index.html 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>City Night</title>
          <link rel="preconnect" href="https://fonts.googleapis.com"> 
          <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> 
          <link href="https://fonts.googleapis.com/css2?family=Inconsolata:wght@300;400&display=swap" rel="stylesheet">
          <link rel="stylesheet" href="styles.css" />
        </head>
        <body>
        </body>
      </html>
      

      There are several page aspects defined inside the <head> element. The first <meta> element specifies the character set to use for the text. This way, special characters like accent marks will render without special HTML codes. The second <meta> element tells browsers (mobile browsers in particular) how to treat the width of the content; otherwise, the browser would simulate a 960px desktop width. Next, the <title> element provides the browser with the title of the page. The <link> elements load in the page styles. The first three load in the font, Inconsolata, from Google Fonts, and the last loads the styles you will write in this tutorial.

      Next, the page will need content to style. You will use sample content from Cupcake Ipsum as filler text to use with the styles. Throughout the tutorial, additions to code from previous steps 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>
          <main>
            <h2>City Night</h2>
            <p> Candy bonbon carrot cake jelly beans shortbread fruitcake. Donut lollipop shortbread soufflé cotton candy cupcake cake. Pastry bear claw powder shortbread gingerbread.</p>
            <p>Caramels jelly-o marshmallow muffin macaroon bear claw candy canes gummies. Muffin shortbread sweet roll pastry marzipan pudding.</p>
            <p>Danish gummies oat cake marzipan shortbread pudding chocolate cake. Donut biscuit danish chocolate cake marzipan. Bonbon cheesecake gingerbread sesame snaps brownie ice cream caramels halvah.</p>
          </main>
        </body>
      </html>
      

      The <main> element contains the primary content of the page, with an <h2> text heading of City Night followed by three <p> elements of content. As you work through the tutorial, you will add images to the page between the content.

      Save your changes to index.html, then create a file in the same directory called styles.css. Open this file in your text editor. In your styles.css file, add the CSS from the following code block:

      styles.css

      body {
        margin: 0;
        font: 100% / 1.5 Inconsolata, monospace;
        color: hsl(230, 100%, 95%);
        background-color: hsl(230, 40%, 10%);
      }
      
      h2 {
        font-size: 3.5rem;
        font-weight: 300;
        text-shadow: 0 0 1em hsla(320, 100%, 50%, 0.5),
          0 0 0.125em hsla(320, 100%, 60%, 0.5),
          -0.25em -0.125em 0.125em hsla(40, 100%, 60%, 0.125),
          0.25em 0.125em 0.125em hsla(200, 100%, 60%, 0.25);
      }
      
      main {
        margin: 2rem auto 4rem;
        width: 90%;
        max-width: 70rem;
      }
      
      p {
        font-size: 1.25rem;
        max-width: 75ch;
      }
      

      These styles add the visual aesthetic and layout to the page. The body rule set adjusts the defaults to load the Inconsolata font, then changes the color to be light blue and the background color to a dark blue-purple. Next, the h2 header gets resized, uses a thinner font weight, and gains a unique effect with the use of the text-shadow property. The main element is set up to remain in the center of the page and stop growing in width once it reaches a size of 70rem, which is approximately 1120px. Lastly,the p selector sets the font-size a bit larger to 1.25rem and sets a separate max-width to 75ch, which is 75 characters at the current font-size.

      Save your changes to styles.css and then open your web browser. Select the File menu item, then select the Open option and load your index.html file in the browser. The following image demonstrates how this HTML will render in the browser:

      White monospace text on a dark blue purple background.

      In this section, you created the initial HTML and CSS for this tutorial. You loaded a custom font on the page and created a distinctive headline by using the text-shadow property. In the next section, you will add your first image to the page using the <img /> element, learn about its default browser styles, and set up the images on the page to be responsive.

      Setting Fluid Widths with the <img /> Element

      There are several things to be aware of when working with images on the web. First, images are by default shown on a page pixel for pixel. This means that if an image is 2048 pixels tall and wide it will occupy that much space on the browser, often causing horizontal and vertical scrolling. Next, images are considered inline flow content, which means images are treated like text in a browser and can be placed inline. This can be beneficial when wrapping text around an image with a float property, but otherwise it is best to separate images from text content to improve the final layout.

      To start working with images in your web page, create a new directory called images by running the following in your command prompt:

      Next, you will download a photo of a building with brightly colored doors by Luke Stackpoole. This image comes from the stock photography website Unsplash. Run the following curl command to download the photo into the new images directory:

      • curl -sL https://assets.digitalocean.com/articles/68128/night-doors.jpg -o images/night-doors.jpg

      Now that you have the image available on your computer to use, open index.html in your text editor. After the first paragraph in the content, add an <img /> self-closing element with a src attribute, as highlighted in the following code block:

      index.html

      ...
      <main>
        <h2>City Nights</h2>
        <p>Candy bonbon carrot cake jelly beans shortbread fruitcake. Donut lollipop shortbread soufflé cotton candy cupcake cake. Pastry bear claw powder shortbread gingerbread.</p>
        <img src="https://www.digitalocean.com/community/tutorials/images/night-doors.jpg" />
        ...
      </main>
      ...
      

      The src attribute directs the browser to the image you downloaded from Unsplash.

      A very important aspect of working with an image is to provide an alt attribute with a description of the image. This will help various users of your website know the image content, especially those using a screen reader. It is helpful to provide details around the context of the image, especially as it pertains to the rest of the text content. If an image is purely for decorative purposes, an alt attribute set to an empty string is acceptable, as otherwise a screen reader would read the file name.

      The highlighted HTML in the following code block provides a alt text description of this image:

      index.html

      ...
      <img src="https://www.digitalocean.com/community/tutorials/images/night-doors.jpg" alt="Three floors of several brightly-colored doors with a person walking on the second floor" />
      ...
      

      Save the addition of an image to index.html, then open the file in your web browser. The image will load between the first and second paragraph. Resizing the browser will have no effect on the image, as shown in the following animation:

      Animation of a page with an image causing a horizontal scrollbar to appear as the window width shrinks.

      As mentioned at the beginning of the section, images are shown at their native size, regardless of screen size. In order to make this image fit more screen sizes, you will next give the image fluid dimensions. Fluid image media is a key tenet of responsive web design, a method of web development that emphasizes code that adjusts to the constraints of the screen or browser size.

      In order to define fluid images, open styles.css in your text editor. Create an img element selector, then add a max-width property with a value of 100%, as highlighted in the following code block:

      styles.css

      ..
      p {
        font-size: 1.25rem;
        max-width: 75ch;
      }
      
      img {
        max-width: 100%;
      }
      

      The max-width property tells images they can scale down to fit a space. It also allows the image to grow until it hits the native pixel size. This different from using the width property set to 100%, which would allow the image to grow beyond the native size if the container were larger than the image. Additionally, the default behavior of a browser is to scale an image proportionally, so no height property is necessary.

      Save your changes to styles.css and then return to the browser and refresh index.html. Resize the browser so that the images scales down and back up until it reaches its full pixel size. The following animation depicts how this resizing interaction is rendered in a browser:

      Animation of a web page with an image, which shrinks as the window size shrinks.

      In this section you worked with the <img /> tag and successfully loaded an image on the page. You used the alt attribute on an image and applied a sufficient description of the image. Lastly, you tried out a way to resize all image to fit the space available. In the next section, you will use the <figure> and <figcaption> elements and change their default styling values.

      Providing Captions with <figure> and <figcaption>

      Often an image needs accompanying descriptive text to give the reader more context about the image, such as who is in the image or where the image is from. For this kind of situation, it is useful to place the <img /> inside a <figure> element with a <figcaption> element to hold the descriptive text. In this section, you will use these elements and adjust their default styles to overlay the text on a photo of a street in Tokyo by Jezael Melgoza.

      First, run this curl command in the following code block to download the image into the images directory:

      • curl -sL https://assets.digitalocean.com/articles/68128/tokyo-street.jpg -o images/tokyo-street.jpg

      Next, open index.html in your text editor. In between the second and third paragraphs, add a <figure> element. Within the <figure>, add a <img /> element with a src attribute pointing to the image you just downloaded. Then, add alt text that describes the contents of the photo. These updates are highlighted in the following code block:

      index.html

      ...
      <p>Caramels jelly-o marshmallow muffin macaroon bear claw candy canes gummies. Muffin shortbread sweet roll pastry marzipan pudding.</p>
      
      <figure>
        <img src="https://www.digitalocean.com/community/tutorials/images/tokyo-street.jpg" alt="A motion blurred street with an in-focus taxi." />
      </figure>
      
      <p>Danish gummies oat cake marzipan shortbread pudding chocolate cake. Donut biscuit danish chocolate cake marzipan. Bonbon cheesecake gingerbread sesame snaps brownie ice cream caramels halvah.</p>
      ...
      

      Save these updates, then return to your browser to load index.html. The image is displayed between the second and third paragraphs, but due to default styling has some inset spacing applied, as shown in the following image:

      White monospace text above and below an inset image of a taxi in Tokyo at night.

      The extra spacing of the <figure> is applied with the margin property on the left and right sides of the element. This is the default styling found on most browsers, which puts a 40px margin on the left and right and a 1em margin on the top and bottom.

      To adjust this default style, return to styles.css in your text editor. Create a new figure element selector and inside add a margin property set to 2rem 0, as highlighted in the following code block:

      styles.css

      ...
      img {
        max-with: 100%;
      }
      
      figure {
        margin: 2rem 0;
      }
      

      Setting the margin to 2rem 0 will apply 2rem spacing to the top and bottom of the figure and remove the spacing on the sides. This gives the image more space between the text, but allows it to occupy more space.

      Save your changes to styles.css and return to your browser to refresh the page. The following image shows how the figure spacing is now rendered:

      White monospace text above and below an image aligned to the text depicting a taxi in Tokyo at night.

      Next, to add a caption for the image, return to index.html in your text editor. Inside the <figure> element and beneath the <img /> element, add a <figcaption> tag. The highlighted HTML in the following code block demonstrates this setup with caption text:

      index.html

      ...
      <figure>
        <img src="https://www.digitalocean.com/community/tutorials/images/tokyo-street.jpg" alt="A motion blurred street with an in focus taxi." />
        <figcaption>Taxi in Tokyo, Japan</figcaption>
      </figure>
      ...
      

      The contents of a caption are useful to provide further information about the image that is not clearly evident. This is unlike the alt text, which describes in words the contents of the image. In this case, a useful caption is the location where the photo was taken.

      Due to the HTML order, the <figcaption> content will display below the image, but next you will style it so that it overlays the image with a dark gradient to help make the text legible.

      Return to styles.css in your text editor. In order to create an overlay, a position: relative property value will need to be added to the figure selector. Then, create a figcaption element selector and add the following highlighted CSS:

      styles.css

      ...
      figure {
        margin: 2rem 0;
        position: relative;
      }
      
      figcaption {
        position: absolute;
        bottom: 0;
        left: 0;
        right: 0;
        padding: 5rem 1rem 1rem;
        background: linear-gradient(to top, hsla(230, 40%, 5%, 0.95), hsla(230, 40%, 5%, 0));
      }
      

      The figcaption styles set the container to overlay the bottom of the image with the position, bottom, right, and left properties. Next, the padding property is large on the top side with 5rem to give ample space for the gradient to spread above the text content, and the left, right, and bottom sides have a smaller 1rem spacing. Lastly, you create the gradient with the background property’s linear-gradient() value that transition’s a dark blue at 95% opacity up to the same color with 0% opacity. Together, this creates a shadowed edge at the bottom to contain the caption.

      Save your changes to styles.css and return to your browser to refresh the page. The gradient background of the <figcaption> shows up at the bottom of the image, but it overshoots the image on the bottom and right sides. The following image shows a close-up view of the difference between the image and the gradient:

      A misaligned dark blue gradient covering a photo on a dark blue-purple background.

      There are two different issues that cause this misalignment, which require two methods to adjust the styles and correct the issue.

      The first deals with how <img /> elements are treated as inline text by default. This extra space at the bottom is the line-height spacing that makes space between lines of text. There are two ways to adjust this, by either changing the line-height of the <figure> element or setting the <img> to have a display property set to block.

      The second issue is the difference in size between the image’s pixel-to-pixel dimensions and the max-width of the <main> element. Since the <figure> is a block element and the <figcaption> is set to span from the left edge to the right edge, it grows to fill a space larger than the image. The first way to fix this issue is to change the <img /> to have a width set to 100%. By setting this width the image will ignore the max-width: 100% default and instead fill the whole space. Note that this approach can cause image distortion depending on the difference in size. The second strategy to fix this is to change the <figure> to have a display property set to inline-block. This approach will cause the <figure> element’s size to shrink to fit its contents.

      Return to styles.css in the text editor and add the display approach for each issue. In the figure selector, add a display property set to a value of inline-block. Then, create a figure img descendant combinator selector with a display: block, as highlighted in the following code block:

      styles.css

      ...
      figure {
        margin: 2rem 0;
        position: relatve;
        display: inline-block;
      }
      
      figure img {
        display: block;
      }
      
      figcaption {
        ...
      }
      

      Save your changes to styles.css and then refresh index.html in the web browser. The <figure> shrinks down to the natural size of the image and the image is no longer treated as text. The following image shows how this adjustment to the display properties is rendered:

      White monospace text above and below an inset image of a taxi in Tokyo at night with a gradient and descriptive text overlaying the image.

      In this section, you used the <figure> and <figcaption> elements. You learned about the default styles of the <figure> and <img /> elements and how to change them for a more controlled outcome. Lastly, you created a caption that overlays the image with contextual information about the photo. In the last section, you will work with styling the <picture> element using the object-fit and object-position properties.

      Using Responsive Image Swapping with <picture>

      When working with images across various screen sizes, there are times when the image isn’t the right size and needs to adapt to the layout. The <picture> element exists to meet this need by defining different images to display at different screen sizes. The images can then be more tightly controlled with the object-fit and object-position properties, which set how an image scales between the specific sizes.

      To begin working with the <picture> element, you will need a series of different-sized images of the same source image. Use the following curl command to download a zip archive of three images of the same aerial photo of Tokyo by Pawel Nolbert:

      • curl -sL https://assets.digitalocean.com/articles/68128/picture.zip -o images/picture.zip

      Once the zip file finishes downloading, extract the content to your image folder. Run the following command in your prompt to place the files in the images directory:

      • unzip images/picture.zip -d ./images

      Now, open index.html in your text editor. First, you will create a <div> with a class attribute of hero between the opening <body> and <main> elements. Then add the remaining highlighted <picture> elements from the following code block:

      index.html

      ...
      <body>
        <div class="hero">
          <picture>
            <source  media="(min-width:70rem)" />
            <source  media="(min-width:40rem)" />
            <img class="hero-image" src="https://www.digitalocean.com/community/tutorials/images/tokyo-small.jpg" alt="Time-lapse exposure of a city at night." />
          </picture>
        </div>
        <main>
      ...
      

      The <picture> element requires a specific structure consisting of as many <source /> elements as needed and one <img /> element as the last item inside. All the accessibility and styling of the <picture> element comes from the <img /> element, which is why the <img /> has a class and the <picture> does not.

      The <img /> is the default image that is used to start when there are no media query requirements. The <source /> elements define two things: the location of the image file with the srcset attribute, and the screen size scenario with the media attribute. The browser will then access and load the appropriate image for the stated screen size, swapping out the image if the size changes.

      Save your changes to index.html, then open the file in your web browser. The following animation depicts the browser swapping the images as the window grows in size:

      Animation depicting an image changing to new cropped versions of the image as the window size increases.

      As the screen size changes, the image size changes as well, causing the text below to be pushed further down the page. In order to create a consistent spacing between this hero image area and the content, height properties can be set to maintain a consistent size.

      Return to styles.css in your text editor. At the bottom of the page, create a class selector for .hero. In the selector block, add the highlighted CSS from the following code block:

      styles.css

      ...
      .hero {
        height: 80vh;
        max-height: 40rem;
      }
      

      The height value set to 80vh means that the .hero container will at the least take up 80% of the browser’s screen height. Then the max-height property ensures that the .hero will not grow larger than 40rem, which is equivalent to 640 pixels tall.

      Save your changes to styles.css and refresh index.html in the browser. As the following animation illustrates, the text now maintains a consistent position. Meanwhile the visual distance between the image and content adjusts to the point that the image slides behind the text:

      Animation depicting shifting spacing between an image and the page content as the window size increases with the image and text, eventually overlapping.

      This overlap of the text and the image is a result of the browser erring on the side of content remaining visible, even if it goes beyond its ancestor’s container. A quick fix for this would be to apply an overflow: hidden on the .hero element, but that does not address the extra space when the image is scaled down smaller. To create a solution for both issues, the object-fit property can help by giving an image similar controls as a background image has with the background-size property.

      To begin working with object-fit, return to styles.css in your text editor. Since the <img /> element is the element that controls styling for a <picture> element, create a class selector for .hero-image and add the highlighted CSS from the following code block:

      styles.css

      ...
      .hero {
        height: 80vh;
        max-height: 40rem;
      }
      
      .hero-image {
        height: 100%;
        width: 100%;
        object-fit: cover;
      }
      

      In order to work with the object-fit property, the image needs to be able to grow both vertically and horizontally. By setting the height and width properties to 100%, you give the object-fit property full control of resizing the image. Without the object-fit property, the image would be squashed to fit the parent container. The cover value allows the image to be edge to edge either vertically or horizontally, depending on the orientation of the container. The object-fit property can accept the same values as the background-size property, including contain and dimension values.

      Save this new addition to styles.css and refresh index.html in your web browser. The following animation illustrates how the object-fit property allows the image to grow to fill the whole space of the .hero container and be hidden when it crosses the edge of the container, just like a background image:

      Animation depicting a defined spacing between image and text, where as the window size increases the image grows, and portions of the image are hidden as they grow beyond the bounds.

      Lastly, there is the object-position property. This works similarly to the background-position property to allow an image to be anchored to a specific area.

      Return to styles.css in your text editor and add an object-position property to the .hero-image selector. Set the value of the property to bottom right, which will anchor the image to the bottom right area as it resizes. The highlighted CSS in the following code block demonstrate how this is written:

      styles.css

      ...
      .hero-image {
        height: 100%;
        width: 100%;
        object-fit: cover;
        object-position: bottom right;
      }
      

      Save this change to styles.css, then return to your browser and refresh index.html.

      This time as the browser width changes and the image scales, the scaling stems from the center of the container, as shown in the following animation:

      Animation depicting a defined spacing between image and text, where as the window size increases the image grows, and portions of the image are hidden as they grow beyond the bounds, anchored at the bottom right of the image.

      This section introduced you to the <picture> media elements, the object-fit property, and the object-position property. You used this combination of elements and properties to create a resizing and adjusting large image at the top of the page.

      Conclusion

      With the techniques you practiced throughout this tutorial, you are now prepared to write styles that will format images to fit your design and layout. You created responsive images by setting a global max-width: 100% to all <img /> elements on the page. Next, you formatted an image caption to overlay the image and grow and shrink with the image. Then, you used the <picture> element along with the object-fit and object-position properties to swap and scale images to best fit the screen size. Using these strategies will help you solve more complex situations involving images and page layout.

      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 Style HTML Elements with Borders, Shadows, and Outlines in CSS


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

      Introduction

      Working with shadows, borders, and outlines is a key component of web development, and can provide visual definition around HTML elements and text items. The appearance of borders and shadows can be manipulated via five main CSS properties: border, border-radius, box-shadow, text-shadow, and outline. Shadows provide depth and help elements stand out, while the border properties can perform many different visual functions, from creating a linear divider between content to defining the space of a grid. The border-radius property creates rounded corners on boxes, and can even make a circular shape. Lastly, outline is an often overlooked property that provides much of the same functionality of the border property without disrupting the flow of content.

      In this tutorial, you will work with these properties to create a legality notice for a fictional space tourism company. Throughout the demo you will create visually rich containers by using edge-based properties. Additionally, you will take into account the nuances about more complex values, such a multiple shadows and how different browsers can implement certain properties differently.

      Prerequisites

      Setting Up the Base HTML and CSS

      In this section, you will set up the HTML base for all the visual styles you will write throughout the tutorial. You will also create your styles.css file and add styles that set the layout of the content.

      Start by opening index.html 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>Travel Disclosure - Destination: Moon</title>
          <link href="https://www.digitalocean.com/community/tutorials/styles.css" rel="stylesheet" />
        </head>
        <body>
        </body>
      </html>
      

      There are a lot of page settings defined inside the <head> element. The first <meta> element defines the character set to use for the text. This way most special characters, such as accent marks, will render without special HTML codes. The second <meta> element tells browsers, and mobile browsers in particular, how to treat the width of the content; otherwise, the browser will simulate a 960px desktop width. The <title> element provides the browser with the title of the page. The <link> element loads the CSS file in which you will write your styles throughout this tutorial.

      The page will also need content to style. For the legal text, you will use sample content from Legal Ipsum as filler copy, intended for styling purposes only.

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

      index.html

      <!doctype html>
      <html>
        ...
        <body>
          <section class="disclosure-alert">
            <header class="disclosure-header">
              <h2  class="disclosure-title"><em>Destination: Moon</em> Travel Disclosure</h2>
            </header>
            <div class="disclosure-content">
              <p>Although space travel is routine practice, there are many unknown possibilities that any traveller must be aware of before traveling with <em>Destination: Moon</em>. Agreeing to this disclosure of knowns is required prior to purchase of tickets with <em>Destination: Moon</em>. PLEASE, READ AND AGREE TO THE FOLLOWING DISCLOSURE OF TRAVEL UNKNOWNS BEFORE PROCEEDING TO PURCHASE.</p>
              <div class="legal-contents">
                <p>Effect of Termination. Upon termination, You agree not to use it under the terms of Sections 4(a) through 4(e) for that Covered Code, or any third party. Description of Modifications.<p>
                <p>You must make sure that you know you can do these things. To make sure the requirements of this Agreement. REQUIREMENTS A Contributor may participate in any way. Notwithstanding the foregoing, if applicable law or agreed to in writing, the Copyright Holder, but only to the terms applicable to Covered Code. Inability to Comply Due to Statute or Regulation.</p>
                <p>If it is impossible for You to the Recipient retains any such Additional Terms. Versions of This License. If you are re-using, b) a hyperlink (where possible) or URL to the terms of Sections 4(a) through 4(e) for that Work shall terminate if it fails to comply with the exception of content that is granting the License. License Terms 1.</p>
                <p>Grant of Patent Infringement. If you have knowledge of patent infringement litigation, then the only applicable Base Interpreter is a "commercial item" as defined in 48 C.F.R. Consistent with 48 C.F.R.</p>
                <p>U.S. Government End Users acquire Covered Code (Original Code and/or as part of a Larger Work; and b) allow the Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor's responsibility alone. Under this section, the Commercial Distributor in writing of such Contributor, if any, to grant more extensive warranty protection to some or all of these conditions: (a) You must make it clear that any Modifications made by such Respondent, or (ii) withdraw Your litigation claim is resolved (such as Wikimedia-internal copying), it is Recipient's responsibility to secure any other exploitation. Program, and in any of the provisions set forth in Section 4(b), you shall terminate if it fails to comply with.</p>
                <p>Please note that these licenses do allow commercial uses of your company or organization, to others outside of this License Agreement), provided that You meet the following terms which differ from this License) and (b) You must duplicate the notice in Exhibit A in each changed file stating how and when you changed the files and the definitions are repeated for your past or future use of the Original Code; or 3) for infringements caused by: i) third party against the drafter will not be used as a handle): 1895.22/1011. This Agreement shall be held by the terms of this agreement. If any provision of this license which gives you legal permission to modify NetHack, or otherwise using this software in source and binary forms, with or without modification in printed materials or in related documentation, stating that you provide a service, including but not limited to the terms under which you distribute, wherever you describe the origin or ownership of such termination, the Recipient a non-exclusive, royalty-free, world-wide license to reproduce, analyze, test, perform and/or display publicly, prepare derivative works, distribute, and otherwise use Python 1.6b1 or any part of Derivative Works. If You initiate litigation by asserting a patent infringement against You in that instance.</p>
                <p>Effect of New York and the like. While this license document the following disclaimer in the Work contain all the conditions listed in Clause 6 above, concerning changes from the Work. If you created a Modification, you may at your option offer warranty protection to some or all of the Licensed Program as a product of your Modifications available to others outside of this License.</p>
                <p>Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted to Licensor for inclusion in the documentation and/or other rights consistent with this program; if not, write to the modified files to carry prominent notices stating that You distribute, all copyright, patent, trademark, and attribution notices from the Public Domain or from the Original Code; 2) separate from the Public Domain or from the Work, you may distribute a Compiled Work on their system exactly as it is being maintained, then ask the Current Maintainer to update their communication data within one month. If the program is free software; you can change the License will not have to defend and indemnify every other Contributor to control, and cooperate with the Source Code version of the Licensed Program, or any Contributor.</p>
              </div>
              <div class="button-group">
                <a href="#" class="button button-primary">
                  Agree
                </a>
                <a href="#" class="button button-secondary">
                  Disagree
                </a>
              </div>
            </div>
          </section>
        </body>
      </html>
      

      Save your changes to index.html and then open your web browser. Select the File menu item and then select the Open option and load your index.html file in the browser. The following image demonstrates how this HTML will render in the browser:

      Several paragraphs of content in black serif text on a white background, with a larger bold headline above and two blue text links below.

      Make a new file called styles.css in the same directory as index.html, then 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 from. Apply the CSS from the following code block to your styles.css file:

      styles.css

      html, body {
        height: 100%;
      }
      
      body {
        display: flex;
        margin: 0;
        font: 100% / 1.5 sans-serif;
        background: url("images/moon-bg.jpg") no-repeat fixed center / cover black;
      }
      .disclosure-alert {
        background-color: hsl(0, 0%, 95%);
        width: 85%;
        max-width: 48rem;
        margin: auto;
        color: hsl(0, 0%, 20%);
      }
      .disclosure-header {
        background: linear-gradient(hsl(300, 50%, 20%), hsl(300, 50%, 10%));
        padding: 2rem 0.5rem;
        text-align: center;
        color: hsl(300, 50%, 95%);
      }
      .disclosure-title {
        margin: 0;
        font-size: 2rem;
        line-height: 1.25;
      }
      .disclosure-content {
        margin: 1.5rem;
      }
      .legal-contents {
        margin-top: 1.5rem;
        background-color: white;
        padding: 0.75rem;
        font-family: "Times New Roman", serif;
      }
      .button-group {
        margin-top: 1.5rem;
        display: flex;
        justify-content: center;
      }
      .button {
        display: inline-block;
        text-align: center;
        padding: 0.5rem 1rem;
        background: black;
        text-decoration: none;
        color: white;
        width: 50%;
        max-width: 8rem;
      }
      .button + .button {
        margin-left: 1.5rem;
      }
      .button-primary {
        background: linear-gradient(to bottom, hsl(200, 100%, 30%), hsl(200, 100%, 20%));
      }
      .button-primary:hover {
        background: linear-gradient(to bottom, hsl(200, 100%, 25%), hsl(200, 100%, 15%));
      }
      .button-secondary {
        background: linear-gradient(to bottom, hsl(200, 10%, 30%), hsl(200, 10%, 20%));
      }
      .button-secondary:hover {
        background: linear-gradient(to bottom, hsl(200, 10%, 25%), hsl(200, 10%, 15%));
      }
      

      The styling in this file sets the initial layout of the page, with a centered legal disclosure, buttons with spacing and rendered with a linear gradient, and an image of the moon used as the background. Before continuing, be sure to save the styles.css file.

      In order to display the image linked in the background property of the body ruleset, you will need the Moon background image. First, make an images directory in the same folder as your index.html file:

      Use your browser to download this file to your newly created images directory, or use the following curl command to download it via the command line:

      • curl -sL https://assets.digitalocean.com/articles/68102/moon-bg.jpg -o images/moon-bg.jpg

      Next, return to and refresh your browser. The browser will now render and apply the styles to the content of the page. The following image shows how the full page is rendered:

      Large webpage showing multiple paragraphs inside a container with a purple bar at the top with light pink text with a blue and gray button at the bottom, in front of a close up photo of the moon.

      The length of the content makes for a very long page. Since this is intended as legal copy, the content of .legal-contents can become a scrollable space. This is done through a combination of the properties height, max-height, and overflow.

      To create a scrollable area, open styles.css in your text editor. Next, adjust the height of the legal content with the following code:

      styles.css

      ...
      .legal-contents {
        height: 50vh;
        max-height: 20rem;
        overflow: auto;
        margin-top: 1.5rem;
        background-color: white;
        padding: 0.75rem;
        font-family: "Times New Roman", serif;
      }
      ...
      

      In this code, you created a height property in the .legal-contents selector block, then set its value to 50vh, meaning 50% of the viewport window’s height. You also created a max-height property with its value set to 20rem. Lastly, you added an overflow property with a value of auto, which creates the scroll bar if the content overflows the container.

      Save these additions to your styles.css file, then return to your browser and refresh index.html. The full height of the page and main container has condensed. Now, the Legal Ipsum copy can be scrolled inside of its designated container, as illustrated in the following animation:

      Animation of paragraphs of text scrolling with in a smaller content area.

      Throughout this section, you set up the primary HTML that you will use for the remainder of the tutorial. You also set up a scrollable space with the overflow property. In the next section, you will work with the border property to apply a border to these containers.

      Using the border Property

      The border property is one of the original ways to apply styles on the edges of elements. It applies a line in any color to the outer perimeter of a container. The property’s value consists of three components: the thickness, the style, and the color. The border property applies these values to all four sides of an element. You can specify individual sides with the direction variations of border, such as the border-top property, which will apply only to the top of an element.

      To begin working with the border property, open styles.css in your text editor and go to the .disclosure-alert class selector. Within the selector block, add a border property with a value set to 1px solid hsl(0, 0%, 0%), as highlighted in the following code block:

      styles.css

      ...
      .disclosure-alert {
        background-color: hsl(0, 0%, 95%);
        width: 85%;
        max-width: 48rem;
        margin: auto;
        color: hsl(0, 0%, 20%);
        border: 1px solid hsl(0, 0%, 0%);
      }
      ...
      

      This border property is a shorthand property, meaning its value is a combination of other values. In this case, the thickness of 1px represents the border-width property value. This value can be any numerical value with a unit along with a few named values: thin, medium, and thick. Next, solid is the border-style value, which defines how the line around the element will appear, in this case as a solid, continuous line. Other values for border-style include dotted, dashed, double, and none. The final value defines the border-color property, which can be any valid color value.

      Save your changes to styles.css, then open index.html in a web browser. The primary content container will now have a thin black border around it, which is most evident as it overlays the moon background image. The following image depicts how the border appears on the main content area:

      Box of content with purple heading wrapped by a thin black border over a photo of the moon.

      Next, you can use the border property to create a sense of depth by applying highlights and shadows to an element. You can accomplish this by using a directional border on one side that is lighter than the background color, then a darker color on the adjacent side.

      Return to styles.css in your text editor, then go to the .disclosure-header class selector block. The linear-gradient() on the background property defines a dark purple gradient transitioning to a slightly darker shade. To create more depth than the gradient alone, adjust the border with the following code:

      styles.css

      ...
      .disclosure-header {
        background: linear-gradient(hsl(300, 50%, 20%), hsl(300, 50%, 10%));
        padding: 2rem 0.5rem;
        text-align: center;
        color: hsl(300, 50%, 95%);
        border-top: 1px solid hsl(300, 50%, 35%);
        border-bottom: 1px solid hsl(300, 50%, 5%);
      }
      ...
      

      You added a border-top property with a value of 1px solid hsl(300, 50%, 35%), which is a bit lighter than the starting gradient value. Next, you created a border-bottom property set to a value of 1px solid hsl(300, 50%, 5%), which is slightly darker than the end of the gradient.

      Save your changes to styles.css, then return to the browser and refresh index.html. The purple header background now has a slight highlight of purple running across the top of the header, and a slight shadow along the bottom. The following image shows how this will appear in the browser:

      A purple background header with a light purple thin border on the top and a dark purple thin border on the bottom.

      Since border is a shorthand property, you can add additional longhand properties. A border can be applied that defines the width and the style of the two button classes, while a border-color can be applied on the individual classes.

      To start working with border-color, open styles.css in your text editor. In the selector block for .button, add a border property with a value of 1px solid, then add a border-color property for .button-primary and .button-secondary:

      styles.css

      ...
      .button {
        ...
        border: 1px solid;
      }
      ...
      .button-primary {
        background: linear-gradient(to bottom, hsl(200, 100%, 30%), hsl(200, 100%, 20%));
        border-color: hsl(200, 100%, 15%);
      }
      .button-primary:hover {
        background: linear-gradient(to bottom, hsl(200, 100%, 25%), hsl(200, 100%, 15%));
        border-color: hsl(200, 100%, 10%);
      }
      .button-secondary {
        background: linear-gradient(to bottom, hsl(200, 10%, 30%), hsl(200, 10%, 20%));
        border-color: hsl(200, 10%, 15%);
      }
      .button-secondary:hover {
        background: linear-gradient(to bottom, hsl(200, 10%, 25%), hsl(200, 10%, 15%));
        border-color: hsl(200, 10%, 10%);
      }
      

      This defines a 1px width solid style border to both buttons. Then, you added a border-color property to customize the colors for the .button-primary, .button-secondary, and their associated :hover state selectors.

      Save these changes to styles.css, then refresh the page in your web browser. As shown in the following image, the buttons now have a bit more definition provided by a matching darker color border:

      Two buttons, one blue and the other gray, with a darker blue and darker gray border surrounding the buttons, respectively.

      Lastly, each border direction is a shorthand as well. This means that -width, -style, and -color can each be applied to a direction property. For example, the longhand property border-right-color will only apply a color to the right side border.

      To work with these directional longhand border properties, return to styles.css in your text editor. Go to the .legal-contents selector block and set the width and style for all four border sides, then customize the colors of each side:

      styles.css

      ...
      .legal-contents {
        height: 50vh;
        max-height: 20rem;
        margin-top: 1.5rem;
        overflow: auto;
        background-color: white;
        border: 1px solid;
        border-top-color: hsl(0, 0%, 65%);
        border-bottom-color: hsl(0, 0%, 100%);
        border-right-color: hsl(0, 0%, 80%);
        border-left-color: hsl(0, 0%, 80%);
        padding: 0.75rem;
        font-family: "Times New Roman", serif;
      }
      ...
      

      In this code, you added border: 1px solid to the end of the file. After that, you additionally created the border-top-color, border-bottom-color, border-right-color, and border-left-color properties. For the values, you used the different hsl() values for grays.

      Save your changes to styles.css, then reload the page in the browser. The scrollable content container now has a dark gray border along the top, a slightly lighter gray on the sides, and a white border on the bottom. This is to give the perception that the content is inset behind the light gray background, causing an effect where the highlight is on the bottom edge, as shown in the following image:

      A box of scrollable content with a dark border on top, a mid-gray border on the sides, and a white border on the bottom.

      In this section, you used the border property and its various longhand variations. You created several borders, which were applied to different sides as needed. In the next section, you will work with the border-radius property, which allows for the corners of containers to be rounded.

      Applying a border-radius

      Rounded corners have been a design aesthetic on the web long before the border-radius property was around to accomplish the task. This property can accept any numerical unit or percentage value, and is a shorthand property like the margin or padding properties. This means each corner can be individually adjusted as needed.

      To begin working with the border-radius property, open styles.css in your text editor. Go to the .disclosure-alert selector block and the border-radius property. Then, set the value to 1.5rem, which will apply that value to all four corners of the property. The highlighted CSS in the following code block shows how this is written:

      styles.css

      ...
      .disclosure-alert {
        ...
        border: 1px solid hsl(0, 0%, 0%);
        border-radius: 1.5rem;
      }
      ...
      

      Save this addition to styles.css then open or refresh index.html in a web browser. Only the bottom two corners will appear to be rounded, while the top two will remain pointed edges. The following image illustrates how this is rendered in the browser:

      Container of content with a large rounded corner on the bottom and straight edges on the top.

      The reason only two rounded corners are visible is due to how descendent elements interact with each other on the web. The browser errs on the side of keeping content visible. The .disclosure-alert does have four rounded corners, but because .disclosure-header is inside the element and does not have rounded corners, it overlaps the rounded corners. A quick fix is to add overflow: hidden to .disclosure-alert, causing the container to clip any descendent containers and content. However, this approach can lead to necessary content becoming illegible or invisible. A better practice is to apply a border-radius to the .disclosure-header class to match the curve of its ancestor’s corner.

      To adjust the overlapping corners, return to styles.css in your text editor. Go to the .disclosure-header selector block and add the border-radius property. Since only the top two corners need adjustment, the value will be 1.5rem 1.5rem 0 0:

      styles.css

      ...
      .disclosure-header {
        ...
        border-top: 1px solid hsl(300, 50%, 35%);
        border-bottom: 1px solid hsl(300, 50%, 5%);
        border-radius: 1.5rem 1.5rem 0 0;
      }
      ...
      

      The extended format of this value will apply a 1.5rem curve to the top-left and top-right corners.

      Save your changes to styles.css and refresh index.html in the browser. The purple header now has a rounded corner and is not covering the main container. A new problem has shown up though, as a white sliver from the parent container is peaking from behind the purple header, as shown in the following zoomed-in image:

      Close-up of a purple rounded corner with a sliver of light gray rounded corner showing.

      The corners for both the .disclosure-alert and .disclosure-header are the same size of 1.5rem, but their widths have a size difference. This size difference is caused by the border on the left and right of the .disclosure-alert element. Since the width of the border is 1px on both sides, the size difference is 2px or 0.125rem. To make the curves match, the border-radius for .disclosure-header needs to be 0.125rem smaller than it is currently. Change the border-radius values of 1.5rem to 1.375rem, as highlighted in the following code block:

      styles.css

      ...
      .disclosure-header {
        background: linear-gradient(hsl(300, 50%, 20%), hsl(300, 50%, 10%));
        padding: 2rem 0.5rem;
        text-align: center;
        color: hsl(300, 50%, 95%);
        border-top: 1px solid hsl(300, 50%, 35%);
        border-bottom: 1px solid hsl(300, 50%, 5%);
        border-radius: 1.375rem 1.375rem 0 0;
      }
      ...
      

      Save this change to styles.css and then refresh the page in the web browser. The sliver of white is now gone and the curves of the two elements meet at the appropriate place. The following zoomed-in screenshot shows how these curves line up:

      Close-up of a purple rounded corner with light purple highlight.

      Lastly, you will apply a rounded corner to the buttons at the bottom of the main container. These buttons will have a pill-shape, with a long, flat top and bottom and full rounded sides. To accomplish, this the border-radius value needs to be a unit-based value larger than the element’s height.

      To make a pill-shaped button, open styles.css in your text editor. In the .button selector block, add the border-radius property and then set the value to 2rem. This can be an arbitrary number as long as it is larger than the computed height, the combination of the font-size, line-height, padding, and border-width that can affect the overall height of an element. The highlighted CSS in following code block shows where to add this property:

      styles.css

      ...
      .button {
        ...
        border: 1px solid;
        border-radius: 2rem;
      }
      ...
      

      There are two things to note about this approach. The first is that a height value is not set on this element. Setting a height value should be avoided as content can and will be in a position of flowing outside the container. By avoiding a set height, the button can grow to match the total content. Second is that this will not work correctly with a percent-based value. Percent-based values on a border-radius property curve a percent of the height and the width, causing an oval shape instead of a rounded corner.

      Save your changes to styles.css, then return to the browser and refresh index.html. The page will now render two oblong, pill-shaped buttons, as show in the following image:

      A blue and gray button with rounded edges on the left and right of each button.

      Throughout this section, you used the border-radius property to apply rounded corners to multiple elements, discovering that a border-radius does not prevent descendent elements from leaving the curved space. You also adjusted the value of a border-radius to match the width of an element when multiple rounded elements are layered on top of one another. In the next section, you will use the text-shadow property to apply drop shadows to text content.

      Using the text-shadow Property

      Applying shadows to text has many uses in everyday web development. Shadows can create depth, a glow effect, or help text standout in places where it might be overlooked. Throughout this section, you will apply text-shadow to multiple elements to create various visual effects.

      The text-shadow property consists of up to four values: x-axis offset, y-axis offset, blur radius, and color. As an example, the values could look like this: 2px 4px 10px red. Of these four values, only the offset values are required. The shadow color by default is the color of the text.

      To begin working with text-shadow, you will start by creating a glow effect on the header. Open styles.css in your text editor and go to the .disclosure-header class selector. Within the selector block, add the following text-shadow property:

      styles.css

      ...
      .disclosure-header {
        ...
        border-radius: 1.375rem 1.375rem 0 0;
        text-shadow: 0 0 0.375rem hsl(300, 50%, 50%);
      }
      ...
      

      A glow effect means the color will emanate from every edge of the text, so the x- and y-axis offset values here are set to 0. You set the blur for the glow to 0.375rem (equivalent to 6px) to give a subtle halo of color to the text. Lastly, the color value was set to a bit darker than the color property: hsl(300, 50%, 50%).

      Save this addition to your styles.css file. Next, open index.html in a web browser. The bold heading text on the purple gradient background now has a glow of a middle purple around it. The follow image illustrates how this effect is rendered in the browser:

      Light pink sans-serif font on a purple background with a light purple glow around the text.

      Next, multiple shadows can be placed on text elements, allowing for the creation of an embossed effect on text. This effect is accomplished by placing a lighter-colored shadow below the object and a darker-colored shadow above.

      To create an embossed effect, return to styles.css in your text editor. The effect will be added to the buttons at the bottom of the container. For the .button-primary, .button-primary:hover, .button-secondary, and .button-secondary:hover selectors, add a text-shadow property. Review the highlighted CSS in the following code block for the values:

      styles.css

      ...
      .button-primary {
        border: 1px solid hsl(200, 100%, 5%);
        background: linear-gradient(to bottom, hsl(200, 100%, 30%), hsl(200, 100%, 20%));
        text-shadow: 0 1px hsl(200, 100%, 50%),
                     0 -1px hsl(200, 100%, 5%);
      }
      .button-primary:hover {
        border: 1px solid hsl(200, 100%, 0%);
        background: linear-gradient(to bottom, hsl(200, 100%, 25%), hsl(200, 100%, 15%));
        text-shadow: 0 1px hsl(200, 100%, 45%),
                     0 -1px hsl(200, 100%, 0%);
      }
      .button-secondary {
        border: 1px solid hsl(200, 10%, 5%);
        background: linear-gradient(to bottom, hsl(200, 10%, 30%), hsl(200, 10%, 20%));
        text-shadow: 0 1px hsl(200, 10%, 50%),
                     0 -1px hsl(200, 10%, 5%);
      }
      .button-secondary:hover {
        border: 1px solid hsl(200, 10%, 0%);
        background: linear-gradient(to bottom, hsl(200, 10%, 25%), hsl(200, 10%, 15%));
        text-shadow: 0 1px hsl(200, 10%, 45%),
                     0 -1px hsl(200, 10%, 0%);
      }
      

      The first shadow is a lighter bottom inset highlight. This is done with the 0 1px offset, then the lighter version of the background gradient hues. Next, you made the shadow above the text with a 0 -1px offset, which pulls the shadow up 1px and uses a darker variation of the background colors.

      Save these changes to styles.css, then refresh the page in your web browser. The text inside the buttons now has a slight highlight below the text and a slight shadow above the text. The combination of these text-shadow values creates the embossed effect as rendered in the following image:

      A blue and gray button with text that appear etched into the buttons.

      In this section, you applied the text-shadow property to a few elements. You created a glow effect on the header and an embossed effect with multiple shadows on the buttons. In the next section, you will apply shadows to HTML elements with the box-shadow property.

      Adding box-shadow to Elements

      Just as the text-shadow property allows for text content to have shadows, the box-shadow property allows for elements and containers to have shadows as well. The box-shadow has two additional features that you will explore throughout this section, including the ability to control the blur’s spread and set the shadow inside the element.

      To begin working with the box-shadow property, open styles.css in your text editor. In the .disclosure-alert selector block, add the box-shadow property. Just like the text-shadow, the x- and y-axis offset values are required, and if a color is not provided, the color property value is used. For this first box-shadow, set the offsets to 0, the blur to 0.5rem, and the color to a dark hsl(300, 40%, 5%), as highlighted in the following code block:

      styles.css

      ...
      .disclosure-alert {
        ...
        border-radius: 1.5rem;
        text-shadow: 0 0 0.375rem hsl(300, 50%, 50%);
        box-shadow: 0 0 0.5rem hsl(300, 40%, 5%);
      }
      ...
      

      Save the changes to styles.css and refresh the page in your web browser. There is now a near black shadow spreading out from the container. Note, too, that the shadow respects and follow the curves you created with the border-radius property. The following image shows how this is rendered in the browser:

      Box of content with a short shadow in black coming from the box.

      Next, return to styles.css and begin creating a more complex effect by adding two additional large glow effects to the box-shadow. Add a comma between each new shadow, setting each to have a y-axis offset of 0.5rem. Then set large blurs and use lighter variations of the blue and purple from the color palette, as highlighted in the following code block:

      styles.css

      ...
      .disclosure-alert {
        ...
        box-shadow: 0 0 0.5rem hsl(300, 40%, 5%),
                    0 0.5rem 6rem hsl(200, 40%, 30%),
                    0 0.5rem 10rem hsl(300, 40%, 30%);
      }
      ...
      

      The order of these shadows matter. The first shadow with the near black color will be presented above the new shadows, and each subsequent shadow is added behind the next.

      Save your changes to styles.css and refresh the page in your browser. As illustrated in the following image, the combination of multiple shadows renders a unique effect:

      Box of content with several compound shadows of varying colors creating a bluish purple dark glow.

      The box-shadow property’s blur spread feature can be used to create a feeling of depth. The spread value accepts both positive and negative values. A negative value spread combined with a strong offset and blur creates a shadow that feels distant and far from the source container.

      To begin, return to styles.css in your text editor. In between the dark small shadow and the larger blue shadow on the .disclosure-alert selector, add the following highlighted CSS from the code block:

      styles.css

      ...
      .disclosure-alert {
        ...
        box-shadow: 0 0 0.5rem hsl(300, 40%, 5%),
                    0 6rem 4rem -2rem hsl(300, 40%, 5%),
                    0 0.5rem 6rem hsl(200, 40%, 30%),
                    0 0.5rem 10rem hsl(300, 40%, 30%);
      }
      ...
      

      This addition to the shadow set keeps the x-axis offset at 0, but moves the y-axis considerably to 6rem. Next, the blur is not as large as the glow, but is at a decent size of 4rem. Then comes to the blur spread value, which in this case is set to -2rem. The default value for the spread is 0, which is equal to the container. At -2rem the spread will condense inward from the container to create a visual effect of depth.

      Save your changes to styles.css, then refresh index.html in the browser. The shadow is a deep purple color that creates a sense that the main content box is floating well above the surface of the moon, as rendered in the following image:

      Box of content with several compound shadows of varying colors creating a bluish purple dark glow and a deep shadow covering a photo of the moon.

      Another use of a box-shadow is to create a slight highlight and shadow bevel effect, like you did earlier with the border property on the header. The advantage of using a box-shadow instead of a border is that it does not affect the box model, which causes shifts in the content flow. It can also be used in conjunction with a border. When using this effect with a border, the inset value must be added to the box-shadow so that the shadow is inside the container.

      To begin using an inset value on the box-shadow, open styles.css in your text editor. This effect will be added to the buttons, so you will be applying these styles to .button-primary, .button-primary:hover, .button-secondary, and .button-secondary:hover. Like the text-shadow, this will consist of a 0 1px and 0 -1px offset combination. The difference is that the word inset can be added to the beginning or the end of the value, as highlighted in the following code block:

      styles.css

      ...
      .button-primary {
        ...
        text-shadow: 0 1px hsl(200, 100%, 50%),
                     0 -1px hsl(200, 100%, 5%);
        box-shadow: inset 0 1px hsl(200, 100%, 50%),
                    inset 0 -1px hsl(200, 100%, 15%);
      }
      .button-primary:hover {
        ...
        text-shadow: 0 1px hsl(200, 100%, 45%),
                     0 -1px hsl(200, 100%, 0%);
        box-shadow: inset 0 1px hsl(200, 100%, 45%),
                    inset 0 -1px hsl(200, 100%, 10%);
      }
      .button-secondary {
        ...
        text-shadow: 0 1px hsl(200, 10%, 50%),
                     0 -1px hsl(200, 10%, 5%);
        box-shadow: inset 0 1px hsl(200, 10%, 50%),
                    inset 0 -1px hsl(200, 10%, 15%);
      }
      .button-secondary:hover {
        ...
        text-shadow: 0 1px hsl(200, 10%, 45%),
                     0 -1px hsl(200, 10%, 0%);
        box-shadow: inset 0 1px hsl(200, 10%, 45%),
                    inset 0 -1px hsl(200, 10%, 10%);
      }
      

      Save these changes to styles.css and then refresh index.html in your browser. The buttons now have a highlight and a shadow, similar to the text. This combined with the gradient background creates a simple, yet distinguished effect for buttons. The following image shows how this is rendered in the browser:

      A blue and gray button with a thin highlight and shadow on the top and bottom of the buttons.

      Lastly, you can also apply a blur spread value to an inset shadow. The spread moves the starting point of the blur outward from the edge, but when using inset the spread moves the starting point inward. This means that when a negative value is applied to the spread on an inset, the shadow expands out of the viewing area of the element. The outward expansion of the spread can create a shadow that looks like a short gradient. This can create the illusion of an element having rounding at the edges as the shadow is applied below the content of the element.

      To begin creating this effect, open styles.css in your text editor. Navigate to the .legal-contents class selector and add a box-shadow property. This shadow will consist of three shadows. The first will set a short shadow around the inside of the whole container, and the next two will provide an elongated light shadow on the top and bottom of the element. The highlighted CSS in the following code block demonstrates how this is set up:

      styles.css

      ...
      .legal-contents {
        ...
        font-family: "Times New Roman", serif;
        box-shadow: 0 0 0.25rem hsl(0, 0%, 80%) inset,
                    0 4rem 2rem -4rem hsl(0, 0%, 85%) inset,
                    0 -4rem 2rem -4rem hsl(0, 0%, 85%) inset;
      }
      ...
      

      Save your changes to styles.css, then refresh the page in the browser. The shadows are now creating an effect that makes the legal text appear set like a window into the container. The shadows also help enhance the border colors that were applied to this element. The following image illustrates how this is rendered in the browser:

      A box of scrollable content with inset shadows to give the illusion of depth.

      In this section, you put the box-shadow property into practice. You also used the blur spread and inset features of box-shadow to allow for more styling options. In the last section, you will implement the outline property, then use box-shadow to make a more versatile outline.

      Using the outline Property

      The last property that affects the edges of elements is the outline property. Across all browsers, the :focus state of elements is made using the outline property. However, each browser’s implementation of the default :focus style varies significantly. The outline property is similar to the border property, except for two key differences: It does not have directional property variations, and it does not affect the box model. The last of those two differences makes it ideal for :focus styles, as it provides a visual indicator of the active element without disrupting the content flow.

      To observe the browser default of a :focus state, open index.html in your browser. Use the TAB key to navigate the page until one of the bottom buttons has focus. Depending on which browser you are using, you may or may not be able to see the default :focus styles. For example, Firefox shows a white dotted outline, but it isn’t perceivable against the light gray background. The following image shows from left to right how the default focus style appears in Firefox, Safari, and Chrome:

      Default focus styles of Firefox, Safari, and Chrome.

      To begin customizing your own :focus state with the outline property, open styles.css in your text editor. Go to the .button class selector and add in the outline property:

      styles.css

      ...
      .button {
        ...
      }
      .button:focus {
        outline: 0.25rem solid hsl(200, 100%, 50%);
      }
      ...
      

      As with the border property, the value for the outline includes a width, style, and color value. Since the goal of a focus state is to bring attention to an element, the width increases to 0.25rem, which is equivalent to 4px. Next, you set the style to solid, so that the focus state is more similar to that of Safari and Chrome. Lastly, you set the color to a deep blue with hsl(200, 100%, 50%).

      Save your changes to styles.css, then return to your browser and refresh the page. Once again, the browser determines how the outline renders. The following image shows what these styles look like in Firefox, Safari, and Chrome, from left to right:

      Custom focus stlyes of Firefox, Safari, and Chrome.

      Across all three browsers, the outline property is displayed quite differently. Firefox holds tight around the whole rounded shape of the button. Safari creates a right-angle box, but touches the edges of the button. Chrome is similar to Safari, but adds some extra space between the button and the outline.

      To create a style that looks like Firefox’s across all browsers requires using box-shadow instead of outline.

      To begin creating a more custom :focus state, return to your styles.css file in your text editor. The first thing to do is disable the browser’s default outline style by changing the value on .button:focus selector’s outline to none, as highlighted in the following code block:

      styles.css

      ...
      .button {
        ...
      }
      .button:focus {
        outline: none;
      }
      ...
      

      Next, go down to the button-primary:hover and button-secondary:hover selectors and add a comma followed by a :focus state variation, as highlighted in the following code block:

      styles.css

      ...
      
      .button-primary {
        ...
      }
      .button-primary:hover,
      .button-primary:focus {
        ...
      }
      .button-secondary {
        ...
      }
      .button-secondary:hover,
      .button-secondary:focus {
        ...
      }
      

      Finally, create two new selectors for each button’s :focus, .button-primary: focus, and .button-secondary:focus. Inside the new selector blocks, add a new box-shadow property with the same inset shadows from their :hover, :focus counterpart. Then, add another shadow to the series with the offsets and blur all set to 0. After that, add a spread of 0.25rem, which will create a solid, non-blurred line around the element. Finally, add the same color to both instances. The highlighted CSS in the following code block show how this is written:

      styles.css

      ...
      
      .button-primary {
        ...
      }
      .button-primary:hover,
      .button-primary:focus {
        ...
      }
      .button-primary:focus {
        box-shadow: inset 0 1px hsl(200, 100%, 45%),
                    inset 0 -1px hsl(200, 100%, 10%),
                    0 0 0 0.25rem hsl(200, 100%, 50%);
      }
      .button-secondary {
        ...
      }
      .button-secondary:hover,
      .button-secondary:focus<^> {
        ...
      }
      .button-secondary:focus {
        box-shadow: inset 0 1px hsl(200, 10%, 45%),
                    inset 0 -1px hsl(200, 10%, 10%),
                    0 0 0 0.25rem hsl(200, 100%, 50%);
      }
      

      Save these changes to styles.css and return to your browser to refresh index.html. Now, as you use the TAB key to navigate through the page. Regardless of the browser, the :focus style on the buttons will now look the same. The following image is how the box-shadow version of an outline appears in the browser along with the whole page:

      The final styling of the content with a blue outline focus state on a blue button at the bottom of the content.

      This last section introduced you to the outline property and how each browser uses it in different ways. At minimum, a :focus indicator is needed for accessibility, and the outline property gets the job done. Expanding on this, you also made a more advanced and visually consistent :focus style by creating a box-shadow with a large spread value.

      Conclusion

      Styling the edges of elements allows the design of a website to gain variance and attention. The border property can help provide definition and separation between content. The border-radius property softens the aesthetic and helps define the attitude of the design. Shadows on text and boxes bring depth and help bring attention to content. Lastly, the outline property provides accessible ways to bring attention to elements with keyboard focus. In this tutorial, you used all these properties to create a visually interesting and useable web page. Understanding each of these properties and how and when to use them will help solve all kinds of front-end interface problems and create new experiences.

      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