Complete, Concrete, Concise https://complete-concrete-concise.com/ Practical Information Without The Bloat Sat, 18 Mar 2023 19:55:18 +0000 en-US hourly 1 https://wordpress.org/?v=6.4.3 Attribute Selectors – Advanced CSS Selectors – Part 4 https://complete-concrete-concise.com/tutorials/webdev/front-end-basics/attribute-selectors-advanced-css-selectors-part-4/ Tue, 07 May 2019 18:16:02 +0000 https://complete-concrete-concise.com/?p=3844 Learn the 7 different ways to write [attribute] selectors.

The post Attribute Selectors – Advanced CSS Selectors – Part 4 appeared first on Complete, Concrete, Concise.

]]>

Attribute selectors offer more options than selectors for HTML tags, IDs, and classes.

As with all selectors, you can combine them to create powerful and specific selectors.

Contents

  1. Review of Attributes Seen So Far
  2. Attribute
  3. Exact Value
  4. Exact Match a Single Value
  5. Partial Match at Start of Value #1
  6. Partial Match at Start of Value #2
  7. Partial Match at End of Value
  8. Partial Match Anywhere in Value
  9. Case Sensitivity
  10. Closing Thoughts
  11. References

Review of Attributes Seen So Far

Attributes are additional information included inside HTML tags. So far, we have seen 9 of them (each item links to their first use in this tutorial series):

  1. id
  2. class
  3. href
  4. target
  5. download
  6. src
  7. alt
  8. reversed
  9. start

Example use is shown below:

<div id="main">
  <p class="important todo scale">
    Some paragraph text.
  </p>
</div>  

<a href="http://example.com"
   target="_blank"
   download="file.txt">
   This is a link.
</a>

<img src="/img/picture.jpg"
     alt="Description of the image">

<ol reversed
    start="101">
  <li>Item 1</li>
  <li>Item 2</li>
</ol>

Attribute

You can select elements by the attributes they contain by writing the attribute between square braces:

/*
  select all HTML elements containing the
  'reversed' attribute
*/
[reversed] {
  /* specificity = 0:1:0 */
}

/*
  select all HTML elements containing the
  'id' attribute
*/
[id] {
  /* specificity = 0:1:0 */
}

Exact Value

You can select by specifying the exact attribute and its value. The value must be in quotes:

[id="footer"] {
  /* specificity = 0:1:0 */
}

[class="red box"]{
  /* specificity = 0:1:0 */
}

[start="101"] {
  /* specificity = 0:1:0 */
}

Exact Match a Single Value

If you have attributes with multiple values (classes are a good example), you can select based on one of the values by placing a tilde (~) before the equals sign:

[class~="box"] {
  /* specificity = 0:1:0 */
}

The selector above will select the following HTML elements because they all contain box:

<p class="red box">This is a selected paragraph.</p>
<p class="box blue">This one too.</p>
<p class="red green box blue">This too!</p>

The attribute values must be separated by spaces:

<!--
  Validly separated attribute values
-->
<p class="red box a b c"></p>

<!--
  incorrectly separated attribute values
-->
<p class="red,box,a,b,c"></p>
<p class="a, b, c"></p>

You can only match one attribute value:

/*
  THIS NEVER MATCHES ANYTHING

  Even if you have an element like this:

  <p class="a red box blue">

*/
[class~="red box"] {

}

Partial Match at Start of Value #1

You can match the beginning of a value string by using the vertical-bar before the equals sign (|=). The match must be followed by a hyphen:

[class|="cf"] {
  /* specificity = 0:1:0 */
}

The selector above will match the following:

<div class="cf-abc"></div>

<div class="cf-"></div>

<div class="cf-d blue box"></div>

The selector above will not match any of the following:

<!--
  cf is not followed by a hyphen
-->
<div class="cf"></div>

<!--
  cf is not at the start of the value string
-->
<div class="red cf- box"></div>

This is an extremely specific behaviour that was originally introduced for dealing with language codes.1

Partial Match at Start of Value #2

This is the more common way to match the start of an attribute value string.

You can match the beginning of a value string by using the caret before the equals sign (^=):

[class^="cf"] {
  /* specificity = 0:1:0 */
}

The selector above will match the following:

<div class="cfabc"></div>

<div class="cf"></div>

<div class="cf-"></div>

<div class="cf-d blue box"></div>

The selector above will not match any of the following:

<!--
  cf is not at the start of the value string
-->
<div class="red cf box"></div>

It should be obvious that you can make the ^= equivalent to the |= by simply appending a hyphen to your string:


/*
  These two selectors are identical.
*/
[class^="cf-"] {

}

[class|="cf"] {

}

Partial Match at End of Value

You can match the end of a value string by using the dollar symbol before the equals sign ($=):

[class$="nt"] {
  /* specificity = 0:1:0 */
}

The selector above will match the following:

<div class="nt"></div>

<div class="plant"></div>

<div class="cf-d blue box plant"></div>

The selector above will not match any of the following:

<!--
  nt is not at the end of the value string
-->
<div class="red nt box"></div>

<div class="plants"</div>

Partial Match Anywhere in Value

You can match the value anywhere in a string by using the asterisk symbol before the equals sign (*=):

[class*="nt"] {
  /* specificity = 0:1:0 */
}

The selector above will match the following:

<div class="nt"></div>

<div class="planter"></div>

<div class="cf-d blue plant box"></div>

The selector above will not match any of the following:

<!--
  nt is not is not found in any value string
-->
<div class="red flat box"></div>

<div class="explains"</div>

Case Sensitivity

If you want to match values without regard to upper and lower case, you append i to the end of the attribute selector:

[class="red" i] {
  /* specificity = 0:1:0 */
}

The selector above will match any of the following:2

<div class="red"></div>

<div class="RED"></div>

<div class="Red"></div>

<div class="rED"></div>

<div class="rEd"></div>

<div class="ReD"></div>

<div class="REd"></div>

<div class="reD"></div>

It is a good idea to be consistent in your use of case to avoid situations where you might need to use case insensitive matching.

Closing Thoughts

  1. Attribute selectors provide 7 different ways to match attributes and their values.
    1. [attribute] – select only by attribute name
    2. [attribute=“value”] – select by attribute name and exact value
    3. [attribute~=“value”] – select by attribute name and exact match one value in the value string
    4. [attribute|=“val”] – select by attribute name and exact match at the beginning of the value string which must then be followed by a hyphen
    5. [attribute^=“val”] – select by attribute name and exact match match at the beginning of the value string
    6. [attribute$=“lue”] – select by attribute name and exact match at the end of the value string
    7. [attribute*=“value”] – select by attribute name and exact match anywhere in the value string
  2. You can combine attribute selectors with other selectors and combinators:
    /*
      only selects ordered lists that contain the
      attribute reversed and the attribute list
    */
    ol[reversed][start] {
      /* specificity 0:2:1 */
    
    }
    
    /*
      selects elements contained within objects
      having an ID of #main if those elements
      contain an attribute of target
    */
    #main [target="_blank"] {
      /* specificity = 1:1:0 */
    }
  3. You could colour code links to visually show if they refer this site or an external site:
      /*
        as long as the link contains
        complet-concrete-concise.com
        we assume is points to this website
      */
      a[href*="complete-concrete-concise.com"] {
        color: green;
      }
  4. You could colour code links to visually show if a link uses a secure or unsecured connection:
      /*
        secure links begin with https
      */
      a[href^="https:"] {
        color: green;
      }
    
      /*
        unsecured links begin with http
      */
      a[href^="http:"] {
        color: red;
      }
  5. Given the following HTML code:
    <p class="box">Some paragraph.</p>

    There is no functional difference between these pairs of selectors:

    
    [class="box"] {
    
    }
    
    .box {
    
    }
    
    
    p[class="box"] {
    
    }
    
    p.box {
    
    }
  6. Given the following HTML code:
    <p class="box blue">Some paragraph.</p>

    These pairs of selectors behave differently:

    /*
      selects only if the class is exactly "box"
    */
    [class="box"] {
    
    }
    
    /*
      selects if the class contains "box"
    */
    .box {
    
    }
    
    
    p[class="box"] {
    
    }
    
    p.box {
    
    }

    You might be tempted to rewrite the attribute selector as:

    [class*="box"] {
    
    }

    But that selector will match not only box, but also: matchbox, bitbox, and any other class with box in it.

    The correct substitution would be:

    [class~="box"] {
    
    }
  7. Analyzing 4632 CSS rules3 from the home pages of 5 different websites4 revealed the following attribute selector distribution:5
    • 2.5% of the rules use attribute selectors
    • 85.2% of the attribute selectors use an exact match ([attribute=“value”])
    • 11.3% of the attribute selectors match the attribute ([attribute])
    • 3.5% of the attribute selectors do a partial on the start of the value ([attribute^=“val”])
    • No other attribute selector types were used
  8. To see some real world selector examples using attribute selectors, consider the following from the WordPress 2016 Theme:6
    /*
      Style a link (<a>) only if:
      (1) the value of href begins with "mailto:"
      (2) it is somewhere inside a block with a
          class of .social-navigation
    
      :before is a pseudo-element which will be
      covered in a later tutorial. Pseudo-elements
      add 0:1:0 to specificity
    
      specificity = 0:3:1
    */
    .social-navigation a[href^="mailto:"]:before {
        content: "\f410";
    }
    
    /*
    Style a link (<a>) only if:
    (1) the value of href ends with "/feed/:"
    (2) it is somewhere inside a block with a
        class of .social-navigation
    
    :before is a pseudo-element which will be
    covered in a later tutorial. Pseudo-elements
    add 0:1:0 to specificity
    
    specificity = 0:3:1
    */
    .social-navigation a[href$="/feed/"]:before {
        content: "\f413";
    }
    
    /*
      Style <img> tags only if:
      (1) they have a class name containing
          "wp-image-"
      (2) they are somewhere inside a block with
          a class of .wp-caption
    
      specificity = 0:2:1
    */
    .wp-caption img[class*="wp-image-"] {
        display: block;
        margin: 0;
    }

References

  1. CSS Attribute Selectors

  1. This will be covered in a future tutorial. Essentially, language tags allow on to specify the primary language and a subset of that language. For example: en specifies the English language, en-ca specifies Canadian English, en-nz specifies New Zealand English, etc.
  2. This does not work with all browsers. It does not work with Internet Explorer, Microsoft Edge version 18 or lower, Android Browser (Android version 4.4 or earlier). A good site to check if a particular HTML or CSS feature is supported is Can I Use.
  3. Yes, it is a lot of rules.
  4. I pulled the CSS from the main landing pages of the following:
    • BBC,
    • Engadget,
    • The Verge,
    • Wikipedia,
    • WordPress

  5. Take these numbers as a rough guide to their relative use.
  6. There is plenty in the CSS Styling that you haven’t seen – but they will be covered in future tutorials.

The post Attribute Selectors – Advanced CSS Selectors – Part 4 appeared first on Complete, Concrete, Concise.

]]>
CSS Combinators – Advanced CSS Selectors – Part 3 https://complete-concrete-concise.com/tutorials/webdev/front-end-basics/css-combinators-advanced-css-selectors-part-3/ Thu, 02 May 2019 14:58:31 +0000 https://complete-concrete-concise.com/?p=3830 Learn how to use CSS combinators to combine CSS selectors for more flexible and precise selection of HTML elements for styling.

The post CSS Combinators – Advanced CSS Selectors – Part 3 appeared first on Complete, Concrete, Concise.

]]>

In the previous tutorial, you have seen how to combine CSS selectors to precisely specify an HTML element for styling and the rules by which the specificity of a CSS selector is calculated.

You will learn about combinators for combining CSS selectors to more precisely select HTML elements for styling.

Contents

  1. Child Combinator
  2. Descendant Combinator
  3. Next Sibling Combinator
  4. Subsequent Sibling Combinator
  5. Closing Thoughts
  6. References

Child Combinator

You were introduced to the Child Combinator in the first part of this series on Advanced CSS Selectors:

.column-left > .card > .headline {
  background-color: lightgreen;
}

The combinator > (greater-than symbol1) specifies a direct parent-child relationship.

In the example above, it selects an element with the class of .headline only if it is an immediate child of an element with the class of .card AND the element with the class of .card is an immediate child of an element with the class of .column-left.

It has a specificity of 0:3:0.

Consider the following HTML code and the selector declared above:

<!--
  The <p> tag will be selected because the
  parent-child relationships match the selector.

  You could also use the selector:

  div > div > p

  That selector has a specificity of 0:0:3
-->
<div class="column-left">
  <div class="card">
    <p class="headline">A Headline</p>
  </div>
</div>

<!--
  The <p> tag will NOT be selected because the
  parent-child relationships do not match the
  selector

  To select the <p> tag, the selector could be:

  .column-left  > div > .headline

  That selector has a specificity of 0:2:1
-->
<div class="column-left">
  <div>
    <p class="headline">A Headline</p>
  </div>
</div>

<!--
  The <p> tag will NOT be selected because the
  parent-child relationships do not match the
  selector.

  To select the <p> tag, the selector could be:

  .card > .column-left  > .headline

  That selector has a specificity of 0:3:0
-->
<div class="card">
  <div class="column-left">
    <p class="headline">A Headline</p>
  </div>
</div>

<!--
  The <p> tag WILL be selected because the
  parent-child relationships match the selector.

  Both <p> tags are children of the parent with
  the class .card. The position of the child
  within the parent doesn't affect its selection.
  All that matters is that it is a direct child.
-->
<div class="column-left">
  <div class="card">
    <p>Some random text.</p>
    <p class="headline">A Headline</p>
  </div>
</div>

<!--
  The <p> tag will NOT be selected because the
  parent-child relationships do not match the
  selector.

  To select the <p> tag, the selector could be:

  .column-left > .card > div > .headline

  That selector has a specificity of 0:3:1

  It could also be:

  div > div > div > p

  That selector has a specificity of 0:0:4
-->
<div class="column-left">
  <div class="card">
    <div>
      <p class="headline">A Headline</p>
    </div>
  </div>
</div>

While I wrote the selector with a space around the combinator, there is no need for that. The following child selectors are also valid:

.column-left>.card.>.headline {

}

div>div>p {

}

While the direct selection method discussed in the previous tutorial can never have an #ID specificity greater than 1 (because an HTML element can never have more than 1 ID associated with it), with combinators, it is possible to have an #ID specificity greater than 1. Consider the following (based on the More Advanced float Example):

#wrapper > #title {
  /* specificity = 2:0:0 */
}

#wrapper > #navbar {
  /* specificity = 2:0:0 */
}

#wrapper > #content > .column-left > .card > .headline {
  /* specificity = 2:3:0 */
}

Descendant Combinator

This is the most commonly used combinator.

The descendant combinator is more general than the child combinator and is useful for styling different sections of your document without having to specify the exact parent-child relationships.

As you recall, when you create your HTML page, you divide the page into various sections. Common sections include:

  • Header
  • Navigation Bar
  • Main Body
  • Side Bar
  • Footer

You might like to have common styles within a section, but not have to specify the exact relationship for every element in a section, but give a more general “all p tags in the Main Body, regardless of how the main body is subdivided, have the following styling”.

Consider the clone page created in an earlier lesson, it had a #content section that contained three columns:

You can style ALL p elements in the document using:

/*
  applies to all <p> tags, unless
  overridden by a more specific selector
*/
p {
  /* specificity = 0:0:1 */
}

You can also style all p elements that are immediate children of the #content section using the child combinator:

/*
  Only applies to <p> elements that are
  immediate children of a #content element,
*/
#content > p {
  /* specificity = 1:0:1 */  
}

But the child combinator will not select p elements if they are nested deeper:


<div id="content">
  <p>This will be selected.</p>
  <div class="aside">
    <p>This will NOT be selected</p>
  </div>
</div>

The descendant combinator allows you to create a selector for ALL p elements located inside a #content container – you can select immediate children, grandchildren and more deeply nested elements. The descendant combinator is a space character:2

/*
  The descendant combinator is the space character.
*/
#content p {
  /* specificity = 1:0:1 */  
}

/*
  The space character acts as a descendant combinator
  when it is alone. If you write a child combinator
  with spaces it is a child combinator, not a
  child + descendant combinator.
*/
#content > p {
  /* specificity = 1:0:1 */
}

This top selector will select all the p elements in the HTML example above, but if they are located anywhere inside a block with an ID of #content.

The bottom selector will only select those the p elements which are immediate children of a block with an ID of #content.

This is useful for defining styles that are localized to particular sections of your webpage without having to rigidly follow the structure of your page:

#header p {
  /*
    applies to all <p> tags inside #header
    specificity = 1:0:1
  */
}

#navbar a{
  /*
    applies to all links inside #navbar
    specificity = 1:0:1
  */
}

#content .sidebar img {
  /*
    applies to all images located anywhere
    inside .sidebar, when .sidebar is
    located anywhere inside #content
    specificity = 1:1:1
  */
}

#content .aside > img {
  /*
    applies to images inside #content that
    are direct children of .aside
    specificity = 1:1:1
  */
}

#footer img {
  /*
    applies to all images inside #footer
    specificity = 1:0:1
  */
}

Remember to pay attention to the specificity of your selector:

#content p {
  /* specificity 1:0:1 */
}

.aside > p {
  /* specificity 0:1:1 */
}

/*
  Even though the bottom selector looks more "specific"
  than the top selector, because the top selector says
  "select any <p> found anywhere inside #content" and
  the bottom selector says "only select <p> if it is
  an immediate child of .aside".

  However, the calculated specificity of the top selector
  is greater than the specificity of the bottom selector.
*/

Next Sibling Combinator

This is also known as the first sibling combinator and adjacent sibling combinator.

The first two combinators allow you to select HTML elements based on how they are contained within other HTML elements – either as children, grandchildren, great-grandchildren, etc.

The next sibling combinator allows you to select HTML elements in relation to other elements at the same nesting level. Consider the following:

<!-- This is a parent element -->
<div>
  <!--
    The <h1>, <p>, <p>, <ol>, <img>, and <p>
    are siblings and children of <div>
  -->
  <h1>A Header</h1>
  <p>A paragraph.</p>
  <p>Another paragraph</p>
  <!--
    While <ol> is a child of <div> and a sibling
    to <h1>, <p>, <p>, <img>, and <p>, it is also
    the parent of the <li> elements.
  -->
  <ol>
    <!-- All the <li> elements are siblings -->
    <li>Item 1</li>
    <li>Item 2</li>
    <li>Item 3</li>
  </ol>
  <img src="/valid/image.jpg">
  <p>Maybe a caption?</p>
</div>

Consider the following rules using the next sibling combinator (which is the plus ‘+’ symbol):

/*
  Select a <p> element if it immediately follows
  an <h1> element.

  You might want the first paragraph following
  <h1> to be special in some way - perhaps a
  slightly larger font or italicized. This could
  also be done by applying a class to the first
  <p> element.
*/
h1 + p {
  /* specificity = 0:0:2 */
}

/*
  Select a <p> element if it immediately follows
  an <img> element.

  You might use the convention that each image
  in your documents must be followed by a caption.
  You could also apply a class (like .caption) to
  the <p> element instead.
*/
img p {
  /* specificity = 0:0:2 */
}

/*
  Select an <li> element if it immediately follows
  an <li> element.

  Applied to the HTML code above, it will
  select the <li>s containing 'Item 2' and
  'Item 3' - this is because:
  - <li>Item 1</li> is the first li in the
    rule and <li>Item 2</li> is the second
    li in the rule - the one that is
    selected.
  - then <li>Item 2</li> is the first li in
    the rule and <li>Item 3</li> is the second
    li in the rule - the one that is
    selected.
  - when <li>Item 3</li> is evaluated as the
    first li in the rule, because there is
    no subsequent li, this selector isn't
    applied to anything.
*/

li + li {
  /* specificity = 0:0:2 */
}

Let’s apply these selectors to the HTML code above:

h1 + p {
  font-size: 20px;
  font-style: italic;
}

img + p {
  font-weight: bold;
  text-align: center;
}

/*
  Remove the yellow background from all list
  items, except the first one.
*/
li + li {
background-color: transparent;
}

/*
  Select all list items and set the
  background to yellow.

  I'm putting this rule here to demonstrate
  selector specificity.
*/
li {
  background-color: yellow;
}

Results in the following output:

A Header

A paragraph.

Another paragraph

  1. Item 1
  2. Item 2
  3. Item 3

Maybe a caption?

Subsequent Sibling Combinator

This is also known as the general sibling combinator and following sibling combinator4.

It is similar to the next sibling combinator in specifying the relationship between child elements, except that:

  1. the selected element does not need to be adjacent to the first element
  2. it selects ALL subsequent elements that match

The combinator is the tilde (~) symbol.

Consider:

/*
  Select all <p> elements following an <h1>
  element as long as the <p> elements are
  all siblings with the <h1> element.
*/
h1.important ~ p {
  /* specificity = 0:1:2 */
  background-color: yellow;
}

When applied to the following code:

<p>This is a paragraph.</p>
<p>So is this.</p>
<h1 class="important">This is important!</h1>
<p>This paragraph is selected.</p>
<p>So is this one.</p>
<div>
  <p>These paragraphs are not selected.</p>
  <p>Because they are not siblings.</p>
  <p>They are nested inside a div.</p>
</div>
<p>But this paragraph is selected.</p>

Results in the following:

This is a paragraph.

So is this.

This is important!

This paragraph is selected.

So is this one.

These paragraphs are not selected.

Because they are not siblings.

They are nested inside a div.

But this paragraph is selected.

Closing Thoughts

  1. The four types of combinators allow you to combine various selectors to create selectors based on their relationships. This allows for more powerful selection.
  2. The child combinator allows you to precisely specify the parent-child relationship of the elements:
parent > child > grandchild {

}
  1. The descendant combinator allows you to target elements based on whether they are nested inside other elements without caring about the specific details of the nesting:
outer-element inner-element {

}
  1. The next sibling combinator allows you to select an element if it immediately follows another element:
first-element + adjacent-element {

}
  1. The subsequent sibling combinator allows you to select all elements that follow the first element – as long as they are siblings:
key-element ~ following-elements {

}
  1. The combinators can be combined and you can more use more specific combinations of html elements, IDs, classes, and attributes:
div#main > p.important + [reversed] {

}
  1. There is no combinator that allows you to select preceding elements:
/*
  There is no select parent combinator.

  For example, you cannot style the parent
  based on the child tag.
*/
div < p {
  /* This does NOT exist */
}

/*
  There is NO preceding adjacent sibling
  combinator.

  For example, you could not select an <h1>
  element that is followed by a <p> element
*/
h1 <+ p {
  /* This does NOT exist */
}

/*
  There is no preceding sibling combinator.

  For example, you cannot select the <p>
  elements that occur before an <h1> element.
*/
h1 <~ p {
  /* This does NOT exist */
}

/*
  There is no select antedent combinator.

  For example, you cannot style an enclosing
  element based on an enclosed element.
*/
#main << .some-deeply-embedded-element {
  /* This does NOT exist */
}
  1. While it may seem unfair to not allow selecting preceding elements or parents by their children or enclosing elements from interior elements, recall that the page is rendered from top to bottom. Rendering preceding elements would require rendering the page from bottom to top or from innermost elements to outermost elements and would make application of CSS rules far more complex regarding whether top-down, bottom-up, or inner-outer rules take precedence. As well, processing from the inner elements to the outer elements is computationally more expensive – making page renders slower.
  2. You don’t need to use all combinators all the time. In fact, the descendant combinator is the most commonly used one. An analysis of 4632 CSS rules5 from 5 different websites6 revealed the following combinator distribution:7
    • 78.5% use the descendant combinator
    • 2.9% use the child combinator
    • 0.2% use the next sibling combinator
    • 0% use the subsequent sibling combinator
    • 18.4% are single item selector rules8
  3. To see some real world selector examples using combinators, consider the following from the WordPress 2019 Theme:9
/*
  Styles an element with the class .comments-title
  that immediately follows a sibling element with
  an ID of #respond that is located at any level
  inside a block with a class of .comment-form-flex.

  specificity = 1:2:0
*/
.comment-form-flex #respond + .comments-title {
  display: block;
}

/*
  Styles all elements that are direct children of
  a block with the class .comments-area.

  You've seen calc() in the lesson
  "CSS – How and When to Use Float".

  'rem' will be covered in a future tutorial,
  but it is a measurement unit like px or %.

  specificity = 0:1:0
*/
.comments-area > * {
  margin-top: calc(2 * 1rem);
  margin-bottom: calc(2 * 1rem);
}

/*
  Styles any <img> nested within the three classes
  laid out below.

  specificity = 0:3:1
*/
.entry .post-thumbnail .post-thumbnail-inner img {
  position: relative;
  display: block;
  width: 100%;
}

References

  1. Descendant Combinator
  2. Child Combinator
  3. Next Sibling Combinator
  4. Subsequent Sibling Combinator

  1. It is sometimes called closing angle bracket or right pointing angle bracket – although these are distinct symbols contrast ‘>’ with ‘〉’
  2. The space character only acts as a descendant combinator when it is alone. If you write a child combinator with spaces (.parent > .child), it is a child combinator, not a child + descendant combinator.
  3. In earlier versions of the CSS specification, it was called following sibling combinator, but the internal anchor was (and still is) general-sibling combinators (look at the end of the URL).
  4. Yes, it is a lot of rules.
  5. I pulled the CSS from the main landing pages of the following:
    • BBC,
    • Engadget,
    • The Verge,
    • Wikipedia,
    • WordPress

  6. Take these numbers as a rough guide to their relative use – if you find yourself using a lot of subsequent sibling combinators, then you are, probably, doing something wrong.
  7. This is not entirely accurate. There are other selector types you can use (which will be covered over the next few tutorials) but, for now, it is accurate enough. One such selector is the ::after pseudo-element you saw in one of the float tutorials.
  8. There is plenty in the CSS Styling that you haven’t seen – but they will be covered in future tutorials.

The post CSS Combinators – Advanced CSS Selectors – Part 3 appeared first on Complete, Concrete, Concise.

]]>
CSS Specificity – Advanced CSS Selectors – Part 2 https://complete-concrete-concise.com/tutorials/webdev/front-end-basics/css-specificity-advanced-css-selectors-part-2/ Fri, 19 Apr 2019 14:57:44 +0000 https://complete-concrete-concise.com/?p=3822 Learn to be more specific in selecting elements for styling and how to calculate the specificity of CSS selectors.

The post CSS Specificity – Advanced CSS Selectors – Part 2 appeared first on Complete, Concrete, Concise.

]]>

Understanding CSS specificity will help you understand how rules are applied to the elements on your page and allow you greater control over how your page is styled.

Contents

  1. Getting Specific
  2. Calculating Specificity
  3. Rules for Creating Specific Selectors
  4. Final Words
  5. References

Getting Specific

You’ve seen that you can apply multiple styles to an HTML element like this:

And you can create individual styles for various elements on the page:

A number of rules style the same CSS properties – background-color and color – and final result depends on:

  1. the priority (or significance) of the selectors
  2. for selectors with the same priority, the last defined property takes priority.

Which means that the final style rule looks like this

This can seem haphazard and you might like to have better control over your CSS style rules – especially if later declarations can override earlier declarations.

We can overcome this by being more specific with our styling rules:

We can get even more specific with the following:

However, if you created the following rule:

And you applied it to the following code:

You would find that the styles of #first would take priority over the styles in p.important despite p.important appearing to be more specific – after all, it specifies two selectors (<element> and .class) over the single ID selector.

This is because the significance of a rule depends on the specificity of the selector. CSS specificity is calculated using a few straightforward rules.

Calculating Specificity

Specificity is calculated as a string of three values1. Many resources and tutorials show it as a single number like 000 or 130. Some tutorials show it in the form 0-0-0 or 1-3-0 – which is a better representation. I will use the following representation: 0:0:0 or 1:3:0.

The specificity number indicates the total counts of various basic selectors. The universal selector always has a specificity of 0:0:0 – so any selector with a higher specificity will trump it. As with normal numbers, the leftmost digits are more significant than the rightmost digits. Consider the ranking of the following specificities:

  • 0:0:1 > 0:0:0
  • 0:2:0 > 0:1:0
  • 0:2:1 > 0:1:6
  • 0:2:5 > 0:2:4
  • 1:2:3 > 0:12:7

The specificity number is calculated as the total number of CSS specifiers used for that style rule. The totals are arranged in the following manner:

IDs .classes and [attributes] <elements>

Consider the specificity of the following selectors:

In each case, you simply add up the total number of basic selectors, put them in the correct location and compare.

Rules for Creating Specific Selectors

  1. If you specify an HTML element, then it must be at the beginning of the selector. i.e.: p[attribute] not [attribute]p.
  2. There can be a maximum of 1 HTML element in a specific selector. i.e.: p.class or ul[reversed], but not pspan.class.
  3. There can be a maximum of 1 #ID in a selector. This is because an element can have at most 1 #ID.
  4. The order of .class, [attribute], or #ID doesn’t matter. i.e.: #ID.class is equivalent to .class#ID.
  5. .class, [attribute], and #ID selectors may be repeated to increase their specificity. i.e.: .class has a specificity of 0:1:0, but .class.class has a specificity of 0:2:0.
  6. You cannot repeat HTML elements. i.e.: pppp or ulul have no meaning and will be ignored by the browser.
  7. All selectors are written together without spaces between them. i.e.: p.class is not the same as p .class and #id[attribute] is not the same as #id [attribute].2

Final Words

  1. You can be very specific about which HTML element to style on a page by stringing together various selectors associated with that element:

  2. Specificity is calculated by summing and arranging the total number of basic specifiers in each of the following groups:
    IDs .classes and [attributes] <elements>
  3. In deciding which styling rule to apply, the rule with the higher specificity is applied.
  4. If two rules have the same specificity then the last rule defined is applied.
  5. The universal selector always has a specificity of 0:0:0.
  6. There are no spaces between the selectors – it is written as one long expression.

References

  1. CSS Selectors

  1. For now it is three values, in reality there two more values that have higher specificity and can be considered as the fourth and fifth specificity values – they will be covered in a future tutorial.

  2. The next tutorial will show how spaces between selectors changes the meaning of the selection expression.

The post CSS Specificity – Advanced CSS Selectors – Part 2 appeared first on Complete, Concrete, Concise.

]]>
Advanced CSS Selectors – Part 1 https://complete-concrete-concise.com/tutorials/webdev/front-end-basics/advanced-css-selectors-part-1/ Wed, 17 Apr 2019 12:42:14 +0000 https://complete-concrete-concise.com/?p=3813 Expand your skill set from 5 basic CSS selectors to over 50 advanced CSS selectors.

The post Advanced CSS Selectors – Part 1 appeared first on Complete, Concrete, Concise.

]]>

We’ve seen 5 different ways to select page elements for styling. Over the next few tutorials we will add more than 50 advanced CSS selectors for targeting HTML elements for styling.

Contents

  1. A Quick Recap and Introduction
  2. Updated Clone Page Code
  3. Final Words
  4. References

A Quick Recap and Introduction

You have seen how to style HTML elements using the following selectors:


/*
  This styling will be applied to all elements on
  the page unless another style overrides it.
*/
* {
  box-sizing: border-box;
}

/*
  This styling will be applied to all <p> elements
  on the page unless overridden by a style applied
  via a .class, [attribute], or #ID
*/
p {
  color: black;
  background-color: white;
}

/*
  This styling will be applied to all elements
  with this class.

  It can be overridden by other classes or [attributes]
  that are applied to the element, but only if they are
  defined after this one.

  An #ID style will always override this style.
*/
.myStyle {
  color: blue;
  background: yellow;
}

/*
This styling will be applied to all elements
matching this attribute.

It can be overridden by other classes or [attributes]
that are applied to the element, but only if they are
defined after this one.

An #ID style will always override this style.
*/
[reversed] {
  color: white;
  background-color: black;
}

/*
  This styling will be applied to the element
  with this ID. Remember: each ID must be
  unique on the page and an element can have a
  maximum of 1 ID.

  This styling overrides any other styling
  applied to the element.
*/

#myID {
  font-size: 24px;
  color: black;
  background-color: orange;
}

This sort of styling is very direct: you explicitly specify the element you want styled and rely on inheritance to pass styles from parent to child elements.

This direct form of styling does have shortcomings – if we want to style part of the page differently, we have to explicitly create new styles for that (likely using classes) and apply them to the elements we want styled. This creates a multiplicity of style rules than can quickly become unwieldy.1 As well, if you apply multiple styles (via classes) then the order in which the styles were defined matters.

Let’s consider the clone page created earlier: one of the things used was a card pattern for the articles on the page:

<div class="card">
  <div class="image">
    <img src="">
  </div>
  <div class="headline">

  </div>
  <div class="timestamp">🕔 2 Hours</div>
</div>

This worked fine, except that instead of using a generic class of .headline, specific headline classes were used depending on which column the card was located: .headline-small, .headline-large, and .headline-medium.

This makes moving cards from one column to another complicated because styling information (rather than content information) is embedded in the class. Moving a card requires the class be updated because its location changed.

CSS allows you to apply styles based on the context your content appears in. Consider:

/*
apply the following style to elements
with the class .headline that are
immediate children of elements with the
class .card that are immediate children
of elements with the class .left-column
*/
.column-left > .card > .headline {

}

/*
apply the following style to elements
with the class .headline if their parent
element has class .card and their
grandparent has class .middle-column
*/
.column-middle > .card > .headline {
  font-size: 32px;
}

/*
apply the following style to elements
with the class .headline only if it is
nested exactly as follows:
  class=“right-column”
      class=“card”
          class=“headline”
*/
.column-right > .card > .headline {
  font-size: 24px;
}

If you replace the .headline-small, .headline-large, and .headline-medium. style definitions in the clone page with the above code and replace their use in the HTML with .headline, you will notice everything still works correctly.

Updated Clone Page Code

You can see how the updated clone page looks here and you can see how the original clone page looks here. You can also inspect the page source code using the view source tool you learned about here or inspect the updated source code below:

<!DOCTYPE HTML>
<html>
  <head>
    <title>Clone Page</title>
    <meta charset="utf-8"  />

    <style>

      * {
        box-sizing: border-box;
        font-family: sans-serif;
        font-size: 16px;
      }

      img {
        width: 100%;
      }

      #wrapper {
        width: 960px;
        margin: auto;
      }

      #title {
        background-color: white;
        color: black;
        padding: 8px;
      }

      #site-name {
        font-size: 32px;
        font-weight: bold;
      }

      #login {
        color: grey;
        padding-top: 8px;
        float: right;
      }

      #search {
        color: grey;
        float: right;
        padding-top: 18px;
        padding-right: 16px;
        font-size: 24px;
      }

      #navbar {
        background-color: #333333;
        color: white;
        border-bottom: 2px solid grey;
      }

      #darkbox {
        background-color: #333333;
        height: 100px;
      }

      #content {
        margin-top: -90px;
      }

      #popular {
        color: white;
        padding-left: 16px;
        font-weight: bold;
      }

      #footer {
        text-align: center;
        padding: 24px;
        background: #333333;
        color: white;
        font-size: 20px;
      }

      .nav-item {
        display: inline-block;
        padding: 24px 16px;
      }

      .column-left {
        width: 20%;
        float: left;
      }

      .column-middle {
        width: 55%;
        float: left;
        border-left: 2px solid grey;
        border-right: 2px solid grey;
      }

      .column-right {
        width: 25%;
        float: left;
      }

      .clearfix::after {
        clear: both;
        display: block;
        content: "";
      }

      .card {
        padding: 0 16px 16px 16px;
      }

      .image {

      }

      /*
      Use the more specific styling selectors
      that select HTML elements based on their
      class AND placement in the page.
      */
      .column-left > .card > .headline {

      }

      .column-middle > .card > .headline {
        font-size: 32px;
      }

      .column-right > .card > .headline {
        font-size: 24px;
      }

      .timestamp {
        padding-top: 8px;
        color: gray;
        font-size: 12px;
      }

    </style>
  </head>
  <body>
    <div id="wrapper">
      <div id="title">
        <span id="site-name">clonage</span>
        <span id="login" class="clearfix">Login</span>
      </div>
      <div id="navbar">
        <span class=nav-item>Gear</span>
        <span class=nav-item>Gaming</span>
        <span class=nav-item>Entertainment</span>
        <span class=nav-item>Tomorrow</span>
        <span class=nav-item>Video</span>
        <span class=nav-item>Reviews</span>
        <span class=nav-item>Events</span>
        <span class=nav-item>Local Edition</span>
        <span id="search" class="clearfix"></span>
      </div>
      <div id="darkbox"></div>
      <div id="content" class="clearfix">
        <!--
        Update all the .headline-small,
        .headline-large, and .headline-medium
        class tags to the .headline class.
        -->
        <div class="column-left">
          <p id="popular">Popular Now</p>
          <div class="card">
            <div class="image">
              <img src="32-small-1.jpg">
            </div>
            <div class="headline">
              Foods that boost your learning
            </div>
            <div class="timestamp">🕔 2 Hours</div>
          </div>
          <div class="card">
            <div class="image">
              <img src="32-small-2.jpg">
            </div>
            <div class="headline">
              Robot arms may be the next
              technological frontier
            </div>
            <div class="timestamp">🕔 2 Hours</div>
          </div>
          <div class="card">
            <div class="image">
              <img src="32-small-3.jpg">
            </div>
            <div class="headline">
              Is virtual reality going to far?
            </div>
            <div class="timestamp">🕔 2 Hours</div>
          </div>
          <div class="card">
            <div class="image">
              <img src="32-small-4.jpg">
            </div>
            <div class="headline">
              The latest trends in cosplay
            </div>
            <div class="timestamp">🕔 2 Hours</div>
          </div>

        </div>
        <div class="column-middle">
          <div class="card">
            <div class="image">
              <img src="32-big-1.jpg">
            </div>
            <div class="headline">
              Before you buy, check our review of the
              hottest cars on the market
            </div>
            <div class="timestamp">🕔 2 Hours</div>
          </div>
          <div class="card">
            <div class="image">
              <img src="32-big-2.jpg">
            </div>
            <div class="headline">
              Health benefits of fresh fruits
            </div>
            <div class="timestamp">🕔 2 Hours</div>
          </div>
        </div>
        <div class="column-right">
          <div class="card">
            <div class="image">
              <img src="32-medium-1.jpg">
            </div>
            <div class="headline">
              The best places to visit on Jupiter
            </div>
            <div class="timestamp">🕔 2 Hours</div>
          </div>
          <div class="card">
            <div class="image">
              <img src="32-medium-2.jpg">
            </div>
            <div class="headline">
              The latest smart watches monitor your
              body's vitals while looking stylish
            </div>
            <div class="timestamp">🕔 2 Hours</div>
          </div>
          <div class="card">
            <div class="image">
              <img src="32-medium-3.jpg">
            </div>
            <div class="headline">
              Keeping yourself safe while shopping online
            </div>
            <div class="timestamp">🕔 2 Hours</div>
          </div>
        </div>
      </div>
      <div id="footer">Copyright 2018</div>
    </div>

  </body>
</html>

Final Words

You’ve received a brief introduction to one advanced CSS selector known as a combinator. This combinator (denoted with the symbol ‘>’) specifies an explicit parent-child relationship for the selection.

The next few tutorials will cover in more detail the various combinators, pseudo-classes, and pseudo-elements that can be used for advanced CSS selection of HTML elements (there are more than 50 of them).

References

  1. CSS Selectors

  1. Ok, styling rules can become very messy, very quickly if you are not clear in what you are doing. Always ensure you constructing your rules in a well ordered rather than ad-hoc manner.

The post Advanced CSS Selectors – Part 1 appeared first on Complete, Concrete, Concise.

]]>
CSS – Understanding Inheritance and Default Values https://complete-concrete-concise.com/tutorials/webdev/front-end-basics/css-understanding-inheritance-and-default-values/ Fri, 22 Mar 2019 19:59:11 +0000 https://complete-concrete-concise.com/?p=3801 Learn which CSS properties child elements inherit from their parents and what their default values are.

The post CSS – Understanding Inheritance and Default Values appeared first on Complete, Concrete, Concise.

]]>

You’ve implicitly encountered inheritance and default values while working with CSS.

Contents

  1. Inheritance
  2. Default Values
  3. Table of Inheritance and Default Values
  4. The ‘inherit’ Value
  5. The ‘default’ Value
  6. Final Words
  7. References

Inheritance

When working with CSS, you probably noticed that styling like this:

.important {
  font-size: 32px;
}

When applied to HTML like this:

<div class="important">
  <p>This is important!</p>
</div>

Results in output that looks like this:

This is important!

This is because the p element inherits the font-size property applied to its parent div.

Not all properties are inherited by child elements.

Consider the following CSS:

.important {
  border: 1px red solid;
}

When applied to the following HTML:

<div class="important">
  <p>This is important!</p>
</div>

Results in the border only applied to the div element and not the p element:

This is important!

If the p tag inherited the border property from the parent div tag, it would have looked like this:

This is important!

Which is, probably, not what you want.

Default Values

When you write some HTML like:

<!DOCTYPE HTML>
<html>
  <head>
    <title>Hello World</title>
    <meta charset="utf-8"  />
  </head>
  <body>
    <p>Hello World!</p>
  </body>
</html>

You see Hello World! displayed in the browser.

It is very likely that the font will be serif or sans serif, it will be 16px in size, the text will be black on a white background, and there is no border – and you didn’t have to style anything.

This is because every CSS property has a default value. The default value may be changed through inheritance or when you explicitly set the value.

Table of Inheritance and Default Values

The following table shows which CSS properties (that we’ve seen) are inherited by child elements from their parents.

It also shows the default values for those CSS properties.

Browser implementations sometimes set values other than what is defined in the CSS specification. Footnotes are given for many of the values and any alternate values given should be regarded as informative rather than absolute.

CSS Property Inherited Default Value
color Yes Depends on the browser (usually black)1
background-color No transparent2
padding No See the individual properties
padding-left No 03
padding-right No 04
padding-top No 05
padding-bottom No 06
margin No See the individual properties
margin-left No 07
margin-right No 08
margin-top No 09
margin-bottom No 010
border No The border is transparent and has a style of none
display No Depends on the HTML element, but the most common are inline and block11.
width No auto
height No auto
box-sizing No content-box
font-size Yes medium (usually 16px)12
font-family Yes Depends on the browser
font-weight Yes normal13
font-style Yes normal14
line-height No normal
text-align No A nameless value that acts as ‘left’ if the text direction is left-to-right and ‘right’ if ‘direction’ is right-to-left.
float No none
clear No none
content No normal

The ‘inherit’ Value

You can force a child element to inherit its parent’s property by using the CSS value inherit:

.important {
  border: 1px red solid;
}

.what-will-this-do {
  border: inherit;
}

When applied to the following HTML:

<div class="important">
  <p class="what-will-this-do">This is important!</p>
</div>

Will cause the child element to inherit the parent’s border property:

This is important!

The ‘default’ Value

If you want to reset an element’s property to its default value, you can use the CSS value initial15.

Consider the following styling:

p {
  color: red;  
}
.default {
  color: initial;
}

When applied to the following code:

<p >This is some styled text!</p>
<p class="default">This is some default styled text</p>

Results in the following:16

This is some styled text!

This is some default styled text

Final Words

Child elements may inherit CSS values from their parents – it depends on the specific CSS property.

All HTML elements have default styles applied to them. Some of these styles are determined by browser settings, others from the CSS specification.

References

  1. CSS Default Properties
  2. CSS Inheritance
  3. Firefox’s Default Style Settings
  4. Chrome’s Default Style Settings

  1. The <mark> tag has a default color of black. The <a> tag default color is defined by the browser – it is usually #0000EE for an unvisited link, #551A8B for a visited link, and #EE0000 for a link you are hovering over.
  2. The <mark> tag has a default background-color of yellow.
  3. This is true for all the HTML elements we have seen so far. Some HTML elements we haven’t seen may have a non-zero default value.
  4. This is true for all the HTML elements we have seen so far. Some HTML elements we haven’t seen may have a non-zero default value.
  5. This is true for all the HTML elements we have seen so far. Some HTML elements we haven’t seen may have a non-zero default value.
  6. This is true for all the HTML elements we have seen so far. Some HTML elements we haven’t seen may have a non-zero default value.
  7. This is true for all the HTML elements we have seen so far. Some HTML elements we haven’t seen may have a non-zero default value.
  8. This is true for all the HTML elements we have seen so far. Some HTML elements we haven’t seen may have a non-zero default value.
  9. This is true for most HTML elements we have seen so far. For <p> tags it is equal to the font-size. The <h1> <through <h6> also have default values for top and bottom margin that are non-zero – the specific value depends on the tag.
  10. This is true for most HTML elements we have seen so far. For <p> tags it is equal to the font-size. The <h1> <through <h6> also have default values for top and bottom margin that are non-zero – the specific value depends on the tag.
  11. The following tags have a default display of none: <head>, <title>, and <meta>. The following tags have a a default display of block: <html>, <body>, <h1> through <h6>, <img>, <ol>, <ul>, <li>, and <p>. The following tags have a a default display of inline: <strong>, <em>, <i>, <mark>, and <a>.
  12. The <h1> through <h6> tags have varying default font sizes. Assuming 16px as the default font size: H1 = 32px, H2 = 24px, H3 = 19px, H4 = 16px, H5 = 13px, and H6 = 11px.
  13. The <h1> through <h6> and the <b> and <strong> tags have a default font-weight of bold.
  14. The <i> and <em> tags have a default font-style of italic.
  15. Yes, it would make more sense if it was called default, but the CSS specification calls it initial.
  16. If your default color (set in the browser) is red, then both outputs will be red.

The post CSS – Understanding Inheritance and Default Values appeared first on Complete, Concrete, Concise.

]]>
Comments in HTML and CSS https://complete-concrete-concise.com/tutorials/webdev/front-end-basics/comments-in-html-and-css/ Mon, 11 Feb 2019 15:36:32 +0000 https://complete-concrete-concise.com/?p=3789 Comments help to document and explain your code to others and your future self.

The post Comments in HTML and CSS appeared first on Complete, Concrete, Concise.

]]>

An important part of coding is documenting your code with comments

Contents

  1. Introduction to Comments
  2. HTML Comments
  3. CSS Comments
  4. Guidelines for Writing Good Comments
  5. Final Words
  6. References

Introduction to Comments

In a perfect world, code would be self documenting and as you read it from top to bottom you would perfectly understand its structure and behaviour.

In the real world – except for trivial code examples (the kind you fit in a dozen lines or less and can keep in your head) – understanding any significant piece of code takes considerable effort.

Comments are textual information that are added to the code to help document the code. Comments do not affect the behaviour of the code in any way and are ignored when the code is processed. Comments are there to help humans understand the code easier – but only if they are useful and accurate.

HTML Comments

HTML comments begin with <!-- and end with -->. In between those characters, you can have almost any type of text string you like and it can span multiple lines.

The specification has a few rules regarding HTML comments:

  1. the text must not start with the string >,
  2. nor start with the string ->,
  3. nor contain the strings <!--, -->, or --!>, +
  4. nor end with the string <!-

Basically, as long as you don’t try to nest HTML comments inside HTML comments, you will be fine.

CSS Comments

CSS comments begin with /* and end with */. In between those characters you can have almost any types of text string you like and it can span multiple lines.

As with HTML comments, you cannot nest CSS comments, so the first */ will always end the comment:

Guidelines for Writing Good Comments

Comments are written for two types of audience:

  1. Your future self
  2. Others

Your future self (technically speaking) is somebody else because, 6 months or a year or 10 years in the future, you are unlikely to still be in the same frame of mind as when you wrote the code. So everything that was “obvious” when you were writing your code is no longer obvious.

Comments are written for two different purposes:

  1. Documenting (what you are doing)
  2. Clarifying (why you are doing it)

Comments should answer the questions: what and why. The how is answered by the code itself because that is the implementation.

Let’s comment the first HTML program we encountered in this tutorial series:

In general, you shouldn’t comment as extensively as I did in the example above – but for a tutorial it is fine.

When you are learning, it is a good idea to comment freely – explain what you are doing and why you are doing it. As your knowledge develops, you will find yourself documenting less and less.

Your comments should document why you are doing something. For example, you might have a requirement for a particular type of webpage, you could embed the webpage description as a comment:

Of course, this information could be in an external design document instead of the webpage.

The big problem is maintaining the code comments up to date. You have to be diligent to ensure that you update the comments when making changes to the code that don’t do what the comments say.

I recommend you comment freely as you learn to develop. Comment what you have learned:

Eventually, you will stop writing mundane comments.

You should avoid commenting what is obvious from reading the code because it adds nothing to the information:

But you can document specific requirements:1

One use of comments is to structure your code:

Unfortunately, your code won’t always cooperate to break down into such nice clear categories.

Final Words

  1. Comment your code freely.
  2. Don’t comment anything that is obvious.
  3. You can explain what you are doing.
  4. You can explain why you are doing something.
  5. Don’t explain how how you are doing something because that is the code itself.
  6. Keep your comments up to date (in general, you should avoid comments that could be rendered obsolete)

References

  1. HTML comments
  2. CSS comments

  1. Read more about Twitter’s brand requirements. Many organizations and companies have very specific rules regarding the use of colours or fonts or any other aspects that are associated with their brand.

The post Comments in HTML and CSS appeared first on Complete, Concrete, Concise.

]]>
A Quick Introduction to Two Development Tools Built into your Browser https://complete-concrete-concise.com/tutorials/webdev/front-end-basics/a-quick-introduction-to-two-development-tools-built-into-your-browser/ Tue, 05 Feb 2019 18:33:44 +0000 https://complete-concrete-concise.com/?p=3778 Every modern browser has a number of web inspection and development tools built in.

The post A Quick Introduction to Two Development Tools Built into your Browser appeared first on Complete, Concrete, Concise.

]]>

Using a text editor for writing code and a browser for viewing the results works well. However, you can increase your productivity by using two of the tools built into modern browsers:

  1. View Page Source and
  2. Inspect Element

Every modern browser has a number of web inspection and development tools built in. While it is beyond the scope of this article to cover everything in detail, I can still point you in the right direction and you can learn as you go along. You won’t use all the features and – depending on what you are doing – will focus on a small subset of the available features.

Contents

  1. Overview
  2. FireFox
  3. Chrome
  4. Edge
  5. View Page Source
  6. Inspect Element
    1. HTML Elements
    2. CSS Styles
    3. Experimenting
  7. Final Comments

Overview

The tools vary a little from browser to browser, but the basic functionality is the same.

Right clicking on a webpage will bring up a menu with options. Depending on where you right-click, some options may not be available.1

Below are 3 examples of the right-click menu from various browsers in January 2019:

FireFox

Firefox right-click menu

Chrome

Chrome right-click menu

Edge

Edge right-click menu

View Page Source

Depending on the browser being used, the name might vary a bit, but it will probably have the word source in it.

When you select this menu item, it will open a new2 tab and display the HTML code of the page. This is a good way for you to inspect the actual HTML code making up the page or to print it out.

Selecting View Page Source on the previous example page in Firefox 64 looks something like this:3

Sample of View Page Source screenshot

Inspect Element

Inspect Element offers a wealth of features to you – well beyond the scope of this article to explore – but feel free to explore on your own.

You don’t have to worry about damaging the web page or accidentally overwriting your code because browsers cannot modify the source files – only what is being displayed. A fresh reload overwrites any changes you have made.

Depending on the browser being used, the name might vary a bit, but it will probably have the word Inspect in it.

Your browser will split its display window and show the webpage in one section and the HTML and other information in another section. It will go to the location in the HTML source that chose to inspect.

Selecting Inspect Element on the previous example page in Firefox 64 looks something like this:4

Sample Inspect Element screenshot

HTML Elements

One of the inspector panes should display the HTML source code – shaded in red in the image above.

  1. As you move your mouse over the HTML elements, you will notice that parts of the webpage get shaded. This shows you which part of the webpage this element affects.
  2. You can left-click on the little triangles found on the left-hand side to expand elements and inspect their sub elements.
  3. Right-clicking on an element will bring up a menu with various options. These often include: edit as HTML and delete element. (don’t worry about damaging your source code, any changes you make in the Element Inspector are not permanent – you can always reload the page to get back to the original).

CSS Styles

Another inspector pane should display the CSS styles being applied to the selected element – shaded in green in the image above.

  1. You can disable a particular style by unticking the checkbox.
  2. You can edit the value of a CSS attribute by right-clicking it.
  3. You can add more CSS attributes by right-clicking just after the last CSS style element.

Experimenting

There are many options available and it is impossible to cover all of them here. However, feel free to experiment and use a search engine to research the various features.

In general, it should be fairly self-obvious what things are doing. At the moment, you should restrict yourself to just the HTML source and CSS styles. You are free to explore further.

Final Comments

The more you play, work, and practice with these tools, the more familiar they will become and the easier they will be to use.

You are likely to only use a small subset of the features available in Inspect Element.

If you use this to inspect live websites, you will – very likely – find they are much more complicated than what you have learned so far. Don’t worry about it.

Many websites are built around something called a CMS (Content Management System) – like WordPress. Content Management Systems automate a lot of things for you and often do many extra things. While the output of a CMS is HTML + CSS, the backend relies on other languages to generate the HTML + CSS displayed in the browser. You still have to be able to create the HTML and CSS and then (programmatically) instruct the CMS when and how to send it to the browser. As a someone learning about web development and starting out with fundamentals of HTML and CSS, you don’t need to worry about all that.

Another thing many websites include is JavaScript code – which you haven’t seen either.

Focus on getting the fundamentals down and writing clean, well structured HTML and CSS first before worrying about how to integrate it with a CMS or using JavaScript on your pages.

 


  1. This usually happens when you click on an image or video. Just right-click somewhere else on the webpage.
  2. Depending on your browser (or browser settings) it might open in your current tab instead.
  3. Different browsers and browser versions may display things slightly differently.
  4. Different browsers and browser versions may display things slightly differently.

The post A Quick Introduction to Two Development Tools Built into your Browser appeared first on Complete, Concrete, Concise.

]]>
CSS – A More Advanced Float Example: Part 3 https://complete-concrete-concise.com/tutorials/webdev/front-end-basics/css-a-more-advanced-float-example-part-3/ Tue, 08 Jan 2019 18:51:51 +0000 https://complete-concrete-concise.com/?p=3765 A detailed walk through the completed code.

The post CSS – A More Advanced Float Example: Part 3 appeared first on Complete, Concrete, Concise.

]]>

A detailed walk through the code.

Contents

  1. The Final Page
  2. Source Code
  3. Detailed Code Walkthrough
    1. Setting Some Page Level Defaults
    2. The Highest Level Structure
    3. The Wrapper
    4. The Title
    5. The Navigation Bar
    6. The Dark Box
    7. The Content
    8. The column-left
    9. The column-middle
    10. The column-right
    11. The card
    12. The footer
  4. Final Thoughts
  5. Image Credits

The Final Page

You can see the finished page here.

It is best viewed in a browser window that is 960px wide or larger.

Source Code

<!DOCTYPE HTML>
<html>
  <head>
    <title>Clone Page</title>
    <meta charset="utf-8"  />

    <style>

      * {
        box-sizing: border-box;
        font-family: sans-serif;
        font-size: 16px;
      }

      img {
        width: 100%;
      }

      #wrapper {
        width: 960px;
        margin: auto;
      }

      #title {
        background-color: white;
        color: black;
        padding: 8px;
      }

      #site-name {
        font-size: 32px;
        font-weight: bold;
      }

      #login {
        color: grey;
        padding-top: 8px;
        float: right;
      }

      #search {
        color: grey;
        float: right;
        padding-top: 18px;
        padding-right: 16px;
        font-size: 24px;
      }

      #navbar {
        background-color: #333333;
        color: white;
        border-bottom: 2px solid grey;
      }

      #darkbox {
        background-color: #333333;
        height: 100px;
      }

      #content {
        margin-top: -90px;
      }

      #popular {
        color: white;
        padding-left: 16px;
        font-weight: bold;
      }

      #footer {
        text-align: center;
        padding: 24px;
        background: #333333;
        color: white;
        font-size: 20px;
      }

      .nav-item {
        display: inline-block;
        padding: 24px 16px;
      }

      .column-left {
        width: 20%;
        float: left;
      }

      .column-middle {
        width: 55%;
        float: left;
        border-left: 2px solid grey;
        border-right: 2px solid grey;
      }

      .column-right {
        width: 25%;
        float: left;
      }

      .clearfix::after {
        clear: both;
        display: block;
        content: "";
      }

      .card {
        padding: 0 16px 16px 16px;
      }

      .image {

      }

      .headline-small {

      }

      .headline-medium {
        font-size: 24px;
      }

      .headline-large {
        font-size: 32px;
      }

      .timestamp {
        padding-top: 8px;
        color: gray;
        font-size: 12px;
      }

    </style>
  </head>
  <body>
    <div id="wrapper">
      <div id="title">
        <span id="site-name">clonage</span>
        <span id="login" class="clearfix">Login</span>
      </div>
      <div id="navbar">
        <span class=nav-item>Gear</span>
        <span class=nav-item>Gaming</span>
        <span class=nav-item>Entertainment</span>
        <span class=nav-item>Tomorrow</span>
        <span class=nav-item>Video</span>
        <span class=nav-item>Reviews</span>
        <span class=nav-item>Events</span>
        <span class=nav-item>Local Edition</span>
        <span id="search" class="clearfix"></span>
      </div>
      <div id="darkbox"></div>
      <div id="content" class="clearfix">
        <div class="column-left">
          <p id="popular">Popular Now</p>
          <div class="card">
            <div class="image">
              <img src="32-small-1.jpg">
            </div>
            <div class="headline-small">
              Foods that boost your learning
            </div>
            <div class="timestamp">🕔 2 Hours</div>
          </div>
          <div class="card">
            <div class="image">
              <img src="32-small-2.jpg">
            </div>
            <div class="headline-small">
              Robot arms may be the next
              technological frontier
            </div>
            <div class="timestamp">🕔 2 Hours</div>
          </div>
          <div class="card">
            <div class="image">
              <img src="32-small-3.jpg">
            </div>
            <div class="headline-small">
              Is virtual reality going to far?
            </div>
            <div class="timestamp">🕔 2 Hours</div>
          </div>
          <div class="card">
            <div class="image">
              <img src="32-small-4.jpg">
            </div>
            <div class="headline-small">
              The latest trends in cosplay
            </div>
            <div class="timestamp">🕔 2 Hours</div>
          </div>

        </div>
        <div class="column-middle">
          <div class="card">
            <div class="image">
              <img src="32-big-1.jpg">
            </div>
            <div class="headline-large">
              Before you buy, check our review of the
              hottest cars on the market
            </div>
            <div class="timestamp">🕔 2 Hours</div>
          </div>
          <div class="card">
            <div class="image">
              <img src="32-big-2.jpg">
            </div>
            <div class="headline-large">
              Health benefits of fresh fruits
            </div>
            <div class="timestamp">🕔 2 Hours</div>
          </div>
        </div>
        <div class="column-right">
          <div class="card">
            <div class="image">
              <img src="32-medium-1.jpg">
            </div>
            <div class="headline-medium">
              The best places to visit on Jupiter
            </div>
            <div class="timestamp">🕔 2 Hours</div>
          </div>
          <div class="card">
            <div class="image">
              <img src="32-medium-2.jpg">
            </div>
            <div class="headline-medium">
              The latest smart watches monitor your
              body's vitals while looking stylish
            </div>
            <div class="timestamp">🕔 2 Hours</div>
          </div>
          <div class="card">
            <div class="image">
              <img src="32-medium-3.jpg">
            </div>
            <div class="headline-medium">
              Keeping yourself safe while shopping online
            </div>
            <div class="timestamp">🕔 2 Hours</div>
          </div>
        </div>
      </div>
      <div id="footer">Copyright 2018</div>
    </div>

  </body>
</html>

Detailed Code Walkthrough

Setting Some Page Level Defaults

* {
  box-sizing: border-box;
  font-family: sans-serif;
  font-size: 16px;
}

The box-sizing property1 is set to border-box – instead of the default content-box – for all elements. You almost always want to do this because it makes layout much easier.

The font-family is set to sans-serif, but you are free to choose serif or monospace.2

The font-size is set to 16px. This is the default value for almost all web browsers.

These settings will be applied to all the HTML elements unless overridden by more specific styling.3

The Highest Level Structure

When writing the code, it became obvious that another element – which I call darkbox – was needed below the navbar.

It didn’t have to be added to the high level structure, it could have been nested inside the navbar – but it seemed simpler this way.

At the highest level, the (new) HTML structure looks like this:

<body>
  <div id="wrapper">
    <div id="title"></div>
    <div id="navbar"></div>
    <div id="darkbox"></div>
    <div id="content" class="clearfix">
      <div class="column-left"></div>
      <div class="column-middle"></div>
      <div class="column-right"></div>
    </div>
    <div id="footer"></div>
  </div>
</body>

As we walk through the code, it should become clear why it was added.

The Wrapper

The standard way of laying out a webpage is to add a content wrapper between the body tags rather than directly adding content to the body section of the document.

<body>
  <div id="wrapper">

  </div>
</body>

There is no change from the design decision to make the content 960px wide and to center it inside the body section by setting the margins to auto:

#wrapper {
  width: 960px;
  margin: auto;
}

The Title

<div id="title">
  <span id="site-name">clonage</span>
  <span id="login" class="clearfix">Login</span>
</div>

The Title section consists of a single line with two parts:

  1. the site title
  2. the login

The span tag is used to style elements in a line.4

We want one element to be to the left and one to the right. This can be accomplished by floating the login to the right.5

A .clearfix is applied to the final element to remove the effect of the float.6

#title {
  background-color: white;
  color: black;
  padding: 8px;
}

Some basic properties are set for the title area:

  • background colour,
  • text colour,
  • and a little bit of padding to make it look nice.
#site-name {
  font-size: 32px;
  font-weight: bold;
}

To make the site name stand out, the font size is set to 32px and made bold. You could also make the site name an image – this would allow you to use a logo as well.

The title could be floated to the left, but it left justifies automatically, so it is unnecessary. You can add float:left to the class – if you want.

#login {
  color: grey;
  padding-top: 8px;
  float: right;
}

The login is subdued compared to the surrounding text, so it was set to grey instead of black. A custom hexadecimal RGB value could be used as well.

8px of padding was added to the top to vertically align the login text with the site name.7 If you wanted to adjust the margin instead of the padding, then the display mode of the span must be changed to inline-block.8

The HTML element was also floated to the right of the page.

The Navigation Bar

<div id="navbar">
  <span class=nav-item>Gear</span>
  <span class=nav-item>Gaming</span>
  <span class=nav-item>Entertainment</span>
  <span class=nav-item>Tomorrow</span>
  <span class=nav-item>Video</span>
  <span class=nav-item>Reviews</span>
  <span class=nav-item>Events</span>
  <span class=nav-item>Local Edition</span>
  <span id="search" class="clearfix"></span>
</div>

Each menu or navigation item is enclosed inside a span element. This allows each item to be individually styled.9 Recall that HTML eliminates all excess whitespace characters.10

The element containing the “search” icon is given the id search since there should be only one search item on the page. It is floated to the right. A suitably sized image of a magnifying glass could have been used, instead similar looking text character is used instead – it is a “telephone recorder” (⌕). This simplifies everything by keeping everything text instead of mixing text and images (not that there is anything wrong with doing that). Finally, the .clearfix is applied to clear the float.

#navbar {
  background-color: #333333;
  color: white;
  border-bottom: 2px solid grey;
}

The background is dark, but not black. A thin border is set on the bottom.

.nav-item {
  display: inline-block;
  padding: 24px 16px;
}

Each .nav-item has display set to inline-block. This allows us full control of the margins (including the top and bottom).

The padding is set to something I considered pleasing looking.

#search {
  color: grey;
  float: right;
  padding-top: 18px;
  padding-right: 16px;
  font-size: 24px;
}

The search element is floated to the right. The colour is a more muted and set to grey. Because the “telephone recorder” is a bit small, the font-size was increased to 24 px. This required adjusting the top padding to make it look centred.

The Dark Box

This is the trickiest element and requires a bit of lateral thinking.

If you look at the original page layout, you see the columns overlap a dark region above them. You also notice that there is a vertical line dividing the columns and a horizontal line dividing the navigation bar from the columns:11
A screenshot of a website home page.
The horizontal dividing line is made by setting the border-bottom of the navbar container to something visible.

Placing an identically coloured element below the navigation bar, it looks like there is a horizontal line dividing the dark region into a top and bottom.

<div id="darkbox"></div>

The darkbox is an empty div with some height applied.

Perhaps a better name would be navbar-extension instead of darkbox.

#darkbox {
  background-color: #333333;
  height: 100px;
}

The background-color is set the same as for the navbar.

A height of 100px looks about the right size.

The Content

<div id="content" class="clearfix">
  <div class="column-left"></div>
  <div class="column-middle"></div>
  <div class="column-right"></div>
</div>

The content is a container holding three left floating columns. It is styled with .clearfix to restore normal flow. The .clearfix could be applied only to .column-right, but it seems better to clear at the parent container level.

#content {
  margin-top: -90px;
}

The margin-top is set to -90px. This causes the content area to be shifted upwards 90px. This causes it to overlap the darkbox. It is possible to use negative values for positioning elements.

The column-left

The .column-left contains the title Popular and 4 cards.

<div class="column-left">
  <p id="popular">Popular Now</p>
  <div class="card">  </div>
  <div class="card">  </div>
  <div class="card">  </div>
  <div class="card">  </div>
</div>

The .column-left is styled to have a width of 20% and to float left.

.column-left {
  width: 20%;
  float: left;
}

The Popular title is styled using the #popular class which sets the text color to white, adds 16px of padding-left to nicely align the title and set the font-weight to bold so it stands out.

#popular {
  color: white;
  padding-left: 16px;
  font-weight: bold;
}

We will examine the details of the .card class a little later.

The column-middle

The .column-middle consists of two cards.

<div class="column-middle">
  <div class="card">  </div>
  <div class="card">  </div>
</div>

If you wanted to be more like the Verge website, which has a single large card and then two columns of cards beneath it, the code would look something like this this:

<div class="column-middle">
  <div class="card">  </div>
  <div class="dual-columns">  
    <div class="dual-left">
      <div class="card">  </div>
      <div class="card">  </div>
      <div class="card">  </div>
    </div>
    <div class="dual-right">
      <div class="card">  </div>
      <div class="card">  </div>
      <div class="card">  </div>
    </div>      
  </div>
</div>

There might be better class names or you might want to use IDs instead of classes.

The .column-middle is styled to have a width of 55% and to float left. It also has a thin border on the left and right side – this gives a nice visual esthetic. How could you make these vertical borders touch the horizontal border applied to the #navbar?12

.column-middle {
  width: 55%;
  float: left;
  border-left: 2px solid grey;
  border-right: 2px solid grey;
}

The column-right

The .column-right consists of three cards.

<div class="column-right">
  <div class="card">  </div>
  <div class="card">  </div>
  <div class="card">  </div>
</div>

The .column-right is styled to have a width of 25% and to float left.

.column-right {
  width: 25%;
  float: left;
}

The card

A .card encapsulates an:

  1. image,
  2. headline,
  3. and timestamp .
<div class="card">
  <div class="image">
    <img src="image.jpg">
  </div>
  <div class="headline">
    A Headline
  </div>
  <div class="timestamp">🕔 A Timestamp</div>
</div>

The img is wrapped inside a div. This is common practice.13 It allows the image and everything associated with the image to be encapsulated in its own container.

The headline contains some text. It could be wrapped inside a p tag, but it is not necessary.

The timestamp also contains some – which also could be wrapped inside a p tag. The clock (🕔) could be an image, but there are some Unicode clock characters14 – which what is used. It is easier to work with text instead of mixing text and images. However, whatever gets the job done is (usually) good.

The .card is styled to have 16px of padding on the left, right, and bottom. This padding allows the card to have some esthetic spacing on the sides and between cards. If 16px of padding were also applied to the top, then there would be 32px of spacing between the bottom of one card and the top of the next card.

.card {
  padding: 0 16px 16px 16px;
}

The img tag is styled with a width of 100%. This causes the image scale correctly to fit whatever container it is in – the same .card is used in all the columns (20%, 55%, and 25%).15

img {
  width: 100%;
}

The wrapper for the [img]{html-tag} has the class .image applied to it. At the moment, it doesn’t apply any styling, but it is available for modification in the future.16

.image {

}

The footer has its own ID and is styled to match the rest of the content on the page.

<div id="footer">Copyright 2018</div>
#footer {
  text-align: center;
  padding: 24px;
  background: #333333;
  color: white;
  font-size: 20px;
}

Final Thoughts

Using only what we’ve covered so far, it is possible to create quite sophisticated looking webpages.

You can go a step further and make the page “functional” by adding links to all the articles17 and creating the corresponding pages.

While it is a lot of work to create a webpage, it is not difficult work.

I encourage you to try and “clone” webpages from other sites. Remember, the goal is to practice and hone your skills, not to wear yourself out.

There is still a lot more to developing webpages and websites. Responsiveness[^responsive] is an important one: your webpage should look good on a 320px X 480px phone display as on a 1920px X 1080px desktop display. But this is something you don’t worry about in the beginning. First get the skills down to make pages that look good on the screen you are working on. In future lessons, we will look at how to make the page look good on varying display sizes.

Image Credits

The images used in the example page are courtesy of:

  1. Apple and Books by jarmoluk
  2. Robotic Arm by PIRO4D
  3. Virtual Reality Cyclist by VR Pexels
  4. Cosplay Girl by ptksgc
  5. Toy Cars by kamal1118
  6. Fruit Salad by silviarita
  7. Astronaut and Jupiter by DasWortgewand
  8. Watch by the5th
  9. Keyboard by atthree23

  1. This was covered in None More CSS Properties to Play With
  2. A future tutorial will show how to use specific fonts like: Arial, Courier, Times New Roman, etc.
  3. A future tutorial will explore how CSS properties are applied when the same property is styled differently in multiple rules. This can happen when two or more classes are applied to the same element (or and ID and a class).
  4. This was covered in Sectioning Using HTML and Auto Centering Content. I could have floated the title to the left and the login to the right, but it wasn’t necessary. This is a design decision. You are free to float the title to the left.
  5. See CSS – Understanding How Float Works – Part 2
  6. See CSS – Understanding How Float Works – Part 1 for a discussion of clearfix.
  7. The site is set to 32px, and the default text size is set to 16px. This means the default text is 16px smaller than the site name. This is divided between the top and bottom of the login (or 8px on the top and 8px on the bottom). We know that floats move up as far as they can, so it is only necessary to add 8px of padding to the top. You can also use trial and error until it looks the way you want.
  8. This was discussed in HTML Flow and the CSS Box Model – the ‘Display’ Property
  9. It is more common to use an unordered list (ul) and make each element a list item (li). The list items are styled with display:inline instead of the default display:list-item. This requires using a property I haven’t discussed yet: list-style-type which controls what is displayed next to each list item. Some of the values are: disc, circle, square, none. If you want to use a list instead, then apply list-style-type:none to the unordered list.
  10. See HTML Basics – Conclusion
  11. OK, the lines are not so visible in the tiny little image I provide, but they are visible if you go to the engadget website.
  12. You move the content area up 100px – the full height of the #darkbox – instead of 90px. You then add a bit of padding (maybe 10px) to the top of the content area so there is some spacing between the content and the horizontal line.
  13. Common practices, are often called design patterns. A design pattern is a generic solution for problems that repeatedly come up in software engineering. There are many different types of design patterns.
  14. Some of the available Unicode time characters are:

    ⏰ – Alarm Clock

    🕰 – Mantelpiece Clock

    ⌚ – Watch

    ⏱ – Stopwatch

    ⏲ – Timer

    ⌛ – Hourglass

    ⏳- Hourglass with flowing sand

    ⧗ – Black Hourglass

    ⧖ – White Hourglass

    🕛 – 12:00

    🕧 – 12:30

    🕐 – 1:00

    🕜 – 1:30

    🕑 – 2:00

    🕝 – 2:30

    🕒 – 3:00

    🕞 – 3:30

    🕓 – 4:00

    🕟 – 4:30

    🕔 – 5:00

    🕠 – 5:30

    🕕 – 6:00

    🕡 – 6:30

    🕖 – 7:00

    🕢 – 7:30

    🕗 – 8:00

    🕣 – 8:30

    🕘 – 9:00

    🕤 – 9:30

    🕙 – 10:00

    🕥 – 10:30

    🕚 – 11:00

    🕦 – 11:30

  15. This was covered in Nine More CSS Properties to Play With
  16. You could argue that if there is no styling being applied, the class .image shouldn’t exist. It is difficult to always know what is needed or what sort of changed might be made in the future. Having the class allows you to add a border or background colour. It is common to see unique empty classes applied to certain elements on a page for future styling. For example, you could add a unique paragraph class to each p:
    <p class="par-1234">Some text</p>
    <p class="par-1235">Some other text</p>

    This allows you to change the appearance of individual paragraphs at a future date without having to change the HTML code – just the CSS. This can be applied to images, or other blocks of text.

  17. There is complexity in adding links to the articles. By default, anchored text, has a different default colour from surrounding text, hovering a mouse over the link unlerlines the link, a previously visited link has a different colour. You can style the a tag, but the options are more restricted (for security reasons).When .clearfix was discussed, you saw the ::after pseudo element selector. CSS has other selectors as well. The most commonly used with anchor tags are: :hover for styling when the mouse is over the content and :visited which allows styling visited links. You are free to experiment with them now, but they will be covered in a future tutorial.

    To disable underlining when hovering over a link, you would apply the following style:

    a:hover {
      text-decoration: none;
    }

The post CSS – A More Advanced Float Example: Part 3 appeared first on Complete, Concrete, Concise.

]]>
CSS – A More Advanced Float Example: Part 2 https://complete-concrete-concise.com/tutorials/webdev/front-end-basics/css-a-more-advanced-float-example-part-2/ Tue, 08 Jan 2019 14:36:01 +0000 https://complete-concrete-concise.com/?p=3759 Having our project in mind, we break it down into the components that we need to think about as we code the page.

The post CSS – A More Advanced Float Example: Part 2 appeared first on Complete, Concrete, Concise.

]]>

Every complicated task needs to be broken down into smaller, simpler tasks.

Here we define the general structure before filling in the details in the next tutorial.

Contents

  1. Deciding on the Overall Structure
  2. A Skeleton to Work With
    1. ID Styles in More Detail
      1. #wrapper
      2. #title
      3. #navbar
      4. #content
      5. #footer
    2. Class Styles in More Detail
      1. .column
      2. .clearfix
    3. The HTML in More Detail
  3. Cards

Deciding on the Overall Structure

When we examine the engadget website:

A screenshot of a website home page.

we see that its general structure looks something like this:

High level overview of the page layout

It consists of 6 rectangles:

  • 2 stacked one atop the other at the top
  • 3 stacked side-by-side in the middle
  • 1 at the bottom of the page

It should be obvious that the 3 side-by-side columns are positioned using float.

Estimating the columns widths, it looks like:

  • the narrowest column occupies about 20% of the display
  • the widest column occupies about 50% of the display
  • this leaves 30% for the medium width column

This is a rough guess, but it is a starting point. As we refine the page, we may adjust the relative widths of the columns to make the layout appear more pleasing.

I will make the content section 960px wide.1 I previously mentioned that 960px is a good rule of thumb for the content width of a webpage2

A Skeleton to Work With

A rough page skeleton might look something like this:

<!DOCTYPE HTML>
<html>
  <head>
    <title>Rough Layout</title>
    <meta charset="utf-8"  />

    <style>

      #wrapper {
        width: 960px;
        margin: auto;
      }

      #title {
        background-color: white;
        color: black;
        width: 100%;
      }

      #navbar {
        background-color: black;
        color: white;
        width: 100%;
      }

      #content {
        width: 100%;
      }

      #footer {
        width: 100%;
      }

      .column-left {
        width: 20%;
        float: left;
      }

      .column-middle {
        width: 50%;
        float: left;
      }

      .column-right {
        width: 30%;
        float: left;
      }

      .clearfix::after {
        clear: both;
        display: block;
        content: "";
      }

    </style>
  </head>
  <body>
    <div id="wrapper">
      <div id="title">Title and Login</div>
      <div id="navbar">Navigation Bar and Search</div>
      <div id="content" class="clearfix">
        <div class="column-left">Narrowest Column</div>
        <div class="column-middle">Widest Column</div>
        <div class="column-right">Medium Width Column</div>
      </div>
      <div id="footer">The Footer</div>
    </div>

  </body>
</html>

The rough layout consists of 5 ID styles and 4 class styles.

ID Styles in More Detail

If you remember, each ID must be unique3 on the page and each HTML element can have only one ID.4

IDs are used to refer to elements that the should only ever be one of on the page.

#wrapper

#wrapper {
  width: 960px;
  margin: auto;
}

Because we are restricting the content width to 960px, we need to wrap all the content in a container that is 960px wide. We also set the margin to auto so the browser will automatically horizontally center the container in the browser window.5

All other elements are styled to occupy the full width of the #wrapper by setting their width to 100%.6 By using percentages for all other element dimensions, we can change the content width by altering a single value in #wrapper instead of having to change it everywhere we use px.

#title

#title {
  background-color: white;
  color: black;
  width: 100%;
}

There should only be one title section on a page. We set the background to white (but you can make it any colour you like, you can be creative in your reimagining of the page).

#navbar {
  background-color: black;
  color: white;
  width: 100%;
}

There should be only one navbar on a page. The background is set to black (but you can make it a different colour if you like). The text colour is set to white so it contrasts against the black background.

#content

#content {
  width: 100%;
}

There should be only one content section (even if though it contains 3 columns).

#footer {
  width: 100%;
}

There should be only one footer on a page.

Class Styles in More Detail

.column

.column-left {
  width: 20%;
  float: left;
}

.column-middle {
  width: 50%;
  float: left;
}

.column-right {
  width: 30%;
  float: left;
}

Because we have 3 unique columns, they could have been made IDs. I decided to make them classes because if I decide to go with a 4 column or 5 column layout, I might be able to reuse existing classes (I could have named the columns better).

They are all floated left and have their widths set as a percentage totaling 100%.

.clearfix

.clearfix::after {
  clear: both;
  display: block;
  content: "";
}

The clearfix for the #content could have been written as:

#content::after {
  clear: both;
  display: block;
  content: "";
}

But, we may find ourselves using float in more places as we refine the page, so it is better to have it as a generic clearfix that can be applied as needed.

The HTML in More Detail

<body>
  <div id="wrapper">
    <div id="title">Title and Login</div>
    <div id="navbar">Navigation Bar and Search</div>
    <div id="content" class="clearfix">
      <div class="column-left">Narrowest Column</div>
      <div class="column-middle">Widest Column</div>
      <div class="column-right">Medium Width Column</div>
    </div>
    <div id="footer">The Footer</div>
  </div>

</body>

It should be straightforward:

  • the #wrapper encloses all the other html
  • the #title, #navbar, #content, and #footer stack one atop the other in normal flow
  • the columns are left floated inside the #content

Cards

Having completed the basic structure, we can now focus on some of the internal details.

Each column contains a number of stacked cards containing information about the article. Each card contains:

  1. An image
  2. A title
  3. A timestamp

The HTML should look something like this:

<div class="card">
  <div class="image">
    <img>
  </div>
  <div class="headline"></div>
  <div class="timestamp"></div>
</div>

It should be straightforward:

  • a card consists of a wrapper which I call card
  • inside the card wrapper we have the image, the article headline, and the timestamp
  • the actual image is placed inside an image container because the image only has a single tag and it is easier to manipulate if we place it inside a div element.7

And with some styling it could look something like this:

An apple sitting on top of books resting atop a desk.
Foods that boost your learning
🕔 2 Hours

  1. If you are curious, the engadget content is 1275px wide. The narrowest column is 255px, the widest column is 680px, and the medium width column is 340px. Corresponding to column widths of 20%, 53.3%, and 26.7% respectively.
  2. See note 4 in the tutorial CSS – Understanding How Float Works – Part 2. It’s a good rule of thumb for desktop webpages because it will render correctly on most desktop browsers.
  3. This was covered in the article CSS – Selecting Specific Elements for Styling.
  4. This was mentioned in a footnote in the article CSS – Selecting Specific Elements for Styling.
  5. Of course, if the browser window is narrower than 960px the page will overflow the browser window – the likely result being a horizontal scroll bar. In future tutorials, we will see how to dynamically adjust the page width and layout to fit different browser window widths. This is known as Responsive Web Design
  6. Using percentage as a width value was discussed in
  7. This is a common design style: start with the largest structures and nest things inside until we get to the individual elements. It may seem unnecessary, but it makes for easier maintainability. Remember, div has no semantic meaning, it only provides structure. See Sectioning Using HTML and Auto Centering Content

The post CSS – A More Advanced Float Example: Part 2 appeared first on Complete, Concrete, Concise.

]]>
CSS – A More Advanced Float Example: Part 1 https://complete-concrete-concise.com/tutorials/webdev/front-end-basics/css-a-more-advanced-float-example-part-1/ Tue, 08 Jan 2019 14:23:29 +0000 https://complete-concrete-concise.com/?p=3748 Taking everything we've learned so far and using it to make a more sophisticated page layout using floats.

The post CSS – A More Advanced Float Example: Part 1 appeared first on Complete, Concrete, Concise.

]]>

Taking what we know about float and creating a more sophisticated webpage layout.

Instead of creating our own layout, we will copy – more or less – an existing design.

It doesn’t have to be an exact copy.

Contents

  1. The Objective
  2. Simplifications
  3. A Tease of What It Could Look Like

The Objective

  1. Copy – more or less – the layout of the homepage of the website Engadget which can be done using float.
  2. Don’t clone the whole page, just the part that you see in your web browser without scrolling. In my browser window, Engadget looks something like this (I eliminated the ads from the page for simplicity):A screenshot of a website home page.It might look different in your browser.
  3. Don’t make the webpage functional – just go for the look. Creating clickable article links, a working navigation menu, search and login functions are beyond the scope of this exercise. This exercise is just about layout.
  4. Include a footer at the bottom.

Simplifications

To make things easier:

  1. Assume the articles in the central column are the same size instead being a large item on top and two smaller items beneath.
  2. Since the only fonts you know1 are serif, sans-serif, and monospace don’t worry about trying to match the fonts.2

A Tease of What It Could Look Like

Over the next two tutorials, I will develop code to create a page that looks like this:

A screenshot of a website home page.

This page is similar, but not identical, to the Engadget homepage.

Depending on your browser display width, the Engadget homepage may appear differently. For displays 960 pixels or wider, it should look similar.


  1. Fonts were covered in Nine More CSS Properties to Play With
  2. Future tutorials will cover how to specify other types of fonts, like: Times New Roman, Helvetica, Comic Sans, etc.

The post CSS – A More Advanced Float Example: Part 1 appeared first on Complete, Concrete, Concise.

]]>
CSS – How and When to Use Float https://complete-concrete-concise.com/tutorials/webdev/front-end-basics/css-how-and-when-to-use-float/ Mon, 25 Jun 2018 12:54:41 +0000 https://complete-concrete-concise.com/?p=3743 Floats are easier to use when you know when and how you should be using them.

The post CSS – How and When to Use Float appeared first on Complete, Concrete, Concise.

]]>
While float is not ideal for every column organizing idea, it is a tried and true method and works well with older web browsers.
In this tutorial we are going to look at some best practices for the use of floating HTML elements.

Contents

  1. Divide the Page so Floats are in their own Block
  2. Float Everything in the Same Direction
    1. Everything Floating Left
    2. Everything Floating Right
    3. Mixed Left and Right Floats
  3. When You Want Floats to Overlap other Blocks
  4. float and box-sizing
  5. calc()
  6. Summary
  7. Playing Around
  8. References

Divide the Page so Floats are in their own Block

When you divide up a page, you want to ensure that floating elements are contained inside their own stacking block and .clearfix is applied to that block.
Notice how the 3 small floating images are in their own block, with other elements stacking above and below:

Header section
Large image goes here.
Smaller image
Smaller image
Smaller image
Footer section

In general, you want to use floats to make elements flow horizontally inside a vertically stacking block.
As much as possible, avoid having floating elements actually floating on top of other elements – but there are exceptions.

Float Everything in the Same Direction

As a general rule, you should float all your elements in the same direction. For English language websites (or any other language that is written from left-to-right), you want to use float: left.

Everything Floating Left

Consider the following left floating elements which overflow and wrap:

float:left
float:left
float:left

While there is too much white space on the right side, the overall flow and alignment look fine.

Everything Floating Right

Consider the following right floating elements which overflow and wrap:

float:right
float:right
float:right

There is too much white space on the left side and the right alignment looks somewhat “unnatural” or out of place.
Floating to the right is a good choice for webpages written in languages written from right to left.1

Mixed Left and Right Floats

Consider the following floating elements which overflow and wrap. The left-most elements are floated left and the right-most element is floated to the right:

float:left
float:left
float:right

The way the content overflows doesn’t look quite right.

When You Want Floats to Overlap other Blocks

There are times when you want a floating element to overlap other blocks. The most common is getting text to flow around an image:

Having text flow around an embedded image looks natural and is what most people would expect because this is a common layout style we find in books and magazines.
So this is one case where it makes sense to allow a floating image block to overlap with paragraph blocks.

Another common case is when you want to insert a side note or comment as a visible part of your content.
Consider the following (although you might want to justify the text to make it less ragged):

Another common use for a float that overlaps HTML blocks in your content is when you want to insert some sort of side note for the reader.

According to legend, Galileo Galilei dropped two canon balls of different mass from the top of the tower to show they fell at the same speed.

For example, you might be writing a document on the Tower of Pisa – which is more commonly known as the “Leaning Tower of Pisa”.
In the course of the article you will likely mention a number of facts about the tower. You might also want to mention something that doesn’t really belong in the main text, but is still a fun fact.
One way to do this would be to use a footnote or endnote. Another way, would be to insert it into the main text, but set it apart.

When you choose to deliberately overlap HTML blocks, you need to be careful about ensuring the floating element does not overlap blocks it shouldn’t.

float and box-sizing

Earlier, we saw the box-sizing property which instructs the User Agent (browser) to size HTML elements by either content area (default) or border. Recall the CSS box model:

Sizing using the content-box does not include the padding, border, or margin when setting the size of the HTML element.
Sizing using the border-box includes the padding and border when setting the size of an HTML element. It does not include the margin in the size of the element.
For normal flow objects, this doesn’t make much difference to the layout since objects just flow downwards.
When we apply float to objects, they flow horizontally and will overflow and wrap around when they reach the edge of the browser – so we have to be more careful when specifying dimensions for floating objects. It is usually best to use box-sizing: border-box for floating HTML elements. Consider the following styling and code:

.parent {
  margin: auto;
  width: 300px;
  background-color: yellow;
}

.clearfix::after {
  clear: both;
  display: block;
  content: "";
}

.block {
  width: 100px;
  height: 50px;
  background-color: red;
  float:left;
}
<div class="parent clearfix">
  <div class="block"></div>
  <div class="block"></div>
  <div class="block"></div>
</div>

Which results in:

There is no obvious separation between one child block and another, since they all run together. The obvious solution is to insert a bit of space between them. We can do this by giving each child block a small margin (let’s say 10px all around):

Unfortunately, this causes the child blocks to overflow and wrap around. Remember:

  1. the parent container is 300px wide,
  2. each child is 100px wide,
  3. each child has a 10px margin,
  4. this makes each child block 100px + 10px + 10 px = 120px wide (there are 10px for the left margin and 10px for the right margin) and
  5. 50px + 10px + 10px = 70px high (there are 10px for the top margin and 10px for the bottom margin)

The height of the child blocks is not the problem for us, it is the width, so we can adjust our CSS to account for the 10px margin on the left and right of the child block:

.block {
  margin: 10px;
  width: 80px;
  height: 50px;
  background-color: red;
  float:left;
}

Which gives us the result we would expect:

If we decide to add a border (even just a 1px border) or padding (even just 1px of padding), it will cause the elements to wrap (again).
We can compensate by subtracting the added widths of our border and padding, or we can set the box-sizing property to border-box:

* {
  box-sizing: border-box;
}

Using the universal selector will cause all HTML elements to be sized according to their borders and not their content area. Personally, I think it is easier and more intuitive to work this way. When you layout the content on a page you imagine each block of content as being completely self contained – i.e., it includes the content, the padding around the content, and the border around the content. However, you do have to compensate for any margins you might use.

calc()

We’ve seen that % is a more convenient way of dimensioning floating elements than using pixels. If you want 3 equally sized columns you can make them each 33.33% of the width of the parent container. You could also make 2 of them 25% and one 50%. Unfortunately, this makes compensating for margins a bit trickier.
CSS has a function called calc() that makes this a lot easier. You simply enter the dimensions – even if they are different units – and calc() will perform the necessary calculation for you.
Taking the example above, we can write the CSS code for the blocks as follows:

.block {
  margin: 10px;
  width: calc(33.33% - 10px - 10px);
  height: 50px;
  background-color: red;
  float:left;
}

The width is set to 33.33% less 10px for the left margin and 10px for the right margin. It could have also been written as calc(33.33% – 20px), but I chose to explicitly subtract each margin independently for clarity.

Summary

  1. Divide the vertically stacking blocks
  2. Try to contain horizontally stacking blocks (floating elements) in their own vertically stacking block.
  3. As a general rules, you want all your floats to go in the same direction. In most cases this will be float: left. If you are developing webpages for a language that is written right-to-left, you will prefer [float: right]{css-property}
  4. Mixing float: left and float: right in the same containing block is, usually, a bad idea.
  5. Sometimes, you do want floating elements to overlap other blocks (like images, or side notes). In this case, you need to ensure appropriate overlapping.
  6. Setting your HTML elements to have box-sizing: border-box makes it easier to layout horizontally flowing elements, since it takes into account any border and padding values you set.
  7. Regardless of which box-sizing model you choose, you must always compensate for any margin values you apply.
  8. The CSS function calc() makes it easier to compute box sizes. It even allows mixing units (like pixels and % together).

Playing Around

Dividing Up a Page

Learning how to divide up a page layout into HTML block elements is crucial to being able to code that page.

  1. Explore a number of websites (news websites tend to be very good for this2) and pay attention to how the pages are laid out.
  2. How would you arrange the various HTML elements to create a similar layout?
    1. Which are the vertically flowing blocks?
    2. How are vertical elements nested inside of blocks?
  3. Can you code a page with a similar layout?

Many of these sites have very long pages. It is not necessary to replicate the entire page from top to bottom – just focus on the portion of the page you see in your browser window.
Don’t try to mimic all the functionality or behaviour. You haven’t learned to embed videos yet (just substitute a picture). There are effects (like shadows, animations, or dropdowns) that you haven’t learned either. Just focus on getting the general layout and look, more or less, right.

box-sizing and calc()

  1. Experiment with using box-sizing: border-box. You can do this by setting all HTML elements to have this property.
  2. Experiment using the calc() function.

You can use these with the page layouts you try out above.

References

  1. float property
  2. clear property
  3. box-sizing property
  4. calc() function

  1. The most commonly used RTL languages are Arabic, Hebrew, Persian, and Urdu.
  2. Some sites that I find interesting for their layout include: CBC, BBC, Engadget. Of course, you are free to try and copy the look and layout of other sites as well.

The post CSS – How and When to Use Float appeared first on Complete, Concrete, Concise.

]]>
CSS – A Simple Page Using Float https://complete-concrete-concise.com/tutorials/webdev/front-end-basics/css-a-simple-page-using-float/ Wed, 30 May 2018 06:58:32 +0000 https://complete-concrete-concise.com/?p=3729 A simple example putting theoretical knowledge of floats into practice.

The post CSS – A Simple Page Using Float appeared first on Complete, Concrete, Concise.

]]>
The previous exercise asked to create a page with the following layout:

Header section
Large image goes here.
Smaller image
Smaller image
Smaller image
Footer section

The purpose being to try and use floating elements in a design.

Contents

  1. An Example Using float
  2. Source Code
  3. Notes
  4. Image Credits

An Example Using float

You can see how the page I styled and structured using float looks here.

Source Code

<!DOCTYPE HTML>
<html>
  <head>
    <title>Floating on Dreams</title>
    <meta charset="utf-8"  />

    <style>

      #title {
        font-size: 48px;
        text-align: center;
      }

      #subtitle {
        font-size: 24px;
        text-align: center;
      }

      .main {
        font-family: sans-serif;
        box-sizing: border-box;
        width: 960px;
        margin: auto;
      }

      .header {

      }

      .images {
      }

      .large-image {
          margin: auto;
      }

      .small-image-container {

      }

      .small-image {
          float: left;
          margin: 50px 10px 0 10px;
      }

      .footer {
          text-align: center;
      }

      .clearfix::after {
        clear: both;
        display: block;
        content: "";
      }

    </style>

  </head>
  <body>

    <div class="main">
      <div class="header">
        <p id="title">Floating on Dreams</p>
        <p id="subtitle">A simple page using floats</p>
      </div>

      <div class="images">
        <div class="large-image">
          <img src="28-big-image.jpg">
        </div>

        <div class="small-image-container clearfix">
          <div class="small-image">
            <img src="28-small-1.jpg">
          </div>
          <div class="small-image">
            <img src="28-small-2.jpg">
          </div>
          <div class="small-image">
            <img src="28-small-3.jpg">
          </div>
        </div>
      </div>

      <div class="footer">
        <p>Copyright 2018</p>
      </div>

    </div>

  </body>
</html>

Notes

  1. The first thing that needs to be done is to divide the document into nesting and stacking HTML blocks.
  2. This is one possible way to section the document: 
  3. There is always a Main container which contains all the content. It was set to have a width of 960 pixels.
  4. The Header and Footer blocks are nested inside the main container.
  5. Between the header and footer there is some content. The content (in this case) is images and is contained within an Images container.
  6. Nested inside the images container is a stacking of large and small images.
  7. The large image has its own container
  8. The small floating images are wrapped in their own container so they act like a single block. The small images block has .clearfix applied to it.
  9. Not all the sectioning divs have styling applied since their sole purpose is to provide structure.
  10. While styling could have been applied directly to the img tags, I chose to wrap them in a div because it allows for greater flexibility in the future.
    • Imagine turning those small floating images into a “card”:

      A Pensive Cat

Image Credits

The images I used are courtesy of:

  1. charloisporto : Tranquil nature scene
  2. silviarita : Fruit salad
  3. Ataner007 : Woman meditating
  4. susannp4 : Cat

The post CSS – A Simple Page Using Float appeared first on Complete, Concrete, Concise.

]]>