Difference between inline and inline-block

As I was working on a side project, the same one where I was using buttons I saw examples using display: inline-block used in the button styles.

Why should I use inline-block instead of inline styles? What difference does it make?

Difference between inline-block and inline

display: inline-block respect top and bottom margins & paddings. display: inline, doesn’t.

In the example below, we use both inline and inline-block elements in the same paragraph to illustrate the process.

<p>Cheese and wine ricotta danish fontina.
Brie cheesy grin paneer squirty cheese taleggio
cheesecake <span class="inline-block-box">goat
taleggio</span> <span class="inline-box">goat
taleggio</span>. Bavarian
bergkase emmental fromage cheesecake
cheese slices cheesy grin queso caerphilly.</p>

The styles for the span elements are identical except for the display attribute.

Again, the difference is that inline-block will honor dimensions and padding but inline will not.

span.inline-block-box {
  display: inline-block;
  width: 100px;
  height: 100px;
  padding: 1em;
  background-color: rebeccapurple;
  color: white;
}

span.inline-box {
  display: inline;
  width: 100px;
  height: 100px;
  padding: 1em;
  background-color: rebeccapurple;
  color: white;
}

You can see multiple examples using the styles described above in Codepen: https://codepen.io/caraya/pen/wvvpEQo

The first example uses inline-block for two span elements.

The second example uses inline for both span elements

The last example combines the two. It uses inline-block for the first span and inline for the second.

Why would we use inline-block?

There may be times when we want to style inline elements with attributes that will only work with inline-block elements.

Styling buttons

I was working on a side project where I have a series of buttons but when I tried to style them the CSS did nothing.

In doing research, I discovered several things you can do and that I wasn’t doing and things that I was doing wrong.

I’m working with SCSS/SASS because it’s easier for me to nest rules and figure out associations between elements. It will be converted to CSS at build time.

Quick Reset

The example I’ll use in the rest of the post uses a reset. This could be used in addition to normalize.css or Eric Meyer’s CSS Reset or as a standalone quick reset for all button elements.

button {
  background-color: transparent;
  border: none;
  cursor: pointer;
  color: inherit;
  font: inherit;
  padding: 0;
}

Styling buttons

I start with setting the buttons to be inline-block rather than inline or block to keep being able to style and align them together if I so choose. (1)

display: inline-block brought a new way to create side by side boxes that collapse and wrap properly depending on the available space in the containing element.

From: Inline vs Inline-Block Display in CSS

We align the text and remove any existing underline.

In the next block, we define margins, border-radius. It appears that this is the only way to size buttons. (2)

Next, we define the color for the text and background. In this case, we use a linear-gradient as an experiment. (3)

.btn {
  display: inline-block; /* 1 */
  text-align: center; /* 1 */
  text-decoration: none; /* 1 */

  margin: 2px 0; /* 2 */
  border-radius: 4px; /* 2 */
  padding: 1em 3em; /* 2 */

  color: #ffffff; /* 3 */
  background:
    linear-gradient(#9198e5, #e66465);/* 3 */

The two pseudo-classes, :active and :hover define two possible states for the button.

:active indicates the styles active when the user clicks the button. For this state, we move the element to the right and saturate the color (make it darker) and add an outline. (4)

  &:active { /* 4 */
    transform: translateX(10px);
    filter: saturate(300%);
    outline: 3px solid blue;
  }

:hover provides the styles for when the user hovers over the button. In this state, we reverse the colors for the background and text.

  &:hover { /* 5 */
    color: white;
    border-color: currentColor;
    background: transparent;
    background-color: lightblue;
    outline: 3px solid blue;
  }
}

Accessibility

One additional thing to consider is accessibility.

Wes Bos asked on Twitter this question about button accessibility.

In particular pay attention to Andy Bell’s answer in the Gist he provided

Conclusion

This button is a test. All colors and actions are done as a test and will most likely change for production. You can see a working example in this codepen

Shapes in CSS: Freeing the layout

Shapes allow you to wrap text around parts of an image or a predefined shape. Using these shapes we can change the way text looks on the screen

Shape without image

In its most simple way, we can wrap text around an invisible shape defined as we would a clip-path.

The HTML defines an empty div element that will hold the shape we define in CSS.

<div class="coffee"></div>
<p>Dark, lungo, café au lait in latte fair
trade blue mountain strong, redeye sugar
seasonal café au lait Turkish. Black mug
variety, cappuccino, single-shot body sit
grounds coffee whipped Turkish et, skinny,
doppio so filter Turkish spoon affogato rich.

The CSS for the .cofee div we defined in markup holds the shape that the text will flow around.

The element must have explicit dimensions (width and height) and must be floated.

The shape-outside attribute describes the shape that the text will wrap around.

.coffee {
  shape-outside: circle(40%);
  float: left;
  height: 300px;
  width: 300px;
}

The examples, so far have only used a single shape, but you can use other values for shape-outside as shown in the list below, taken from (MDN).

none
The float area is unaffected. Inline content wraps around the element’s margin box, like usual.
<shape-box>
The float area is computed according to the shape of a float element’s edges (as defined by the CSS box model). This can be margin-box, border-box, padding-box, or content-box. The shape includes any curvature created by the border-radius property.
margin-box
Defines the shape enclosed by the outside margin edge. The corner radii of this shape are determined by the corresponding border-radius and margin values.
border-box
Defines the shape enclosed by the outside border edge. The shape follows the normal border radius shaping rules for the outside of the border.
padding-box
Defines the shape enclosed by the outside padding edge. The shape follows the normal border radius shaping rules for the inside of the border.
content-box
Defines the shape enclosed by the outside content edge. Each corner radius of this box is the larger of 0 or border-radius - border-width - padding.
<basic-shape>
The float area is computed based on the shape created by of one of inset(), circle(), ellipse(), or polygon().
<image>
The float area is extracted and computed based on the alpha channel of the specified <image> as defined by shape-image-threshold.

Shape with an image

We can combine shapes with images to get a graphical effect of the text wrapping around an image rather than around a space.

In this example, we add an image of a coffee cup and give it a class to reference it from CSS.

<h1>I'm nice, once I've
had my coffee</h1>

<img class="coffee"
src='path/to/coffee2.png' alt='coffee cup'>
<p>Dark, lungo, café au lait in latte
fair trade blue mountain strong, redeye
sugar seasonal café au lait turkish.
Black mug variety, cappuccino, single shot
 body sit grounds coffee whipped
 Turkish et, skinny …</p>

The CSS for the image (.coffee) uses shape-outside and shape-image-threshold.

When you use an image as the value for shape-outside the shape is defined by the pixels whose alpha value is greater than the threshold.

.coffee {
  shape-outside: circle(50%);
  shape-image-threshold: 0.5;
  float: left;
}

We can play with shape-outside to place text on top of the image and use images of arbitrary complexity to make our text “speak” in the voice we want.

Shapes and multiple images

Another way we can use shapes to make text flow between shapes creating custom layouts that move us outside boxes, at least visually.

The example adds two empty divs (coffee and coffee2).

<div class="coffee"></div>
<div class="coffee2"></div>
<p>Dark, lungo, café au lait in latte fair
 trade blue mountain strong, redeye sugar
 seasonal café au lait Turkish. Black mug
 variety, cappuccino, single-shot body sit
 grounds coffee whipped Turkish et, skinny,
 doppio so filter Turkish spoon affogato
 rich. Steamed roast, froth fair trade
 chicory a dripper, Turkish, extra milk,
 wings, milk dark Viennese, and est, filter,
 caffeine café au lait ut aromatic aged.</p>

The CSS defines two identical properties that create the same space on the left and right sides.

We could abstract the common elements to a third class that we can reuse but for this example, I’m ok with the duplication.

.coffee {
  shape-outside: circle(50%);
  float: left;
  height: 300px;
  width: 300px;
}

.coffee2 {
  shape-outside: circle(50%);
  float: right;
  height: 300px;
  width: 300px;
}

You can see the final product in this Codepen

A more complex example

When shapes were first released there was a companion specification for regions. This demo from the Adobe Web Platform team uses both.

Sadly, Regions are not supported in any browser other than old Edge so instead, I chose to present a video from Adobe, showing the project.

CSS clipping and masking

Both Clipping and masking hide some parts of the elements and show other parts. But there are, of course, differences between the two. Differences in what they can do, differences in syntaxes, different technologies involved, the new and the deprecated, and browser support differences.

clip-path and CSS

The clip-path CSS property allows you to specify a specific region of an element to display, instead of the complete area. There used to be a clip property, but it has been deprecated.

The common HTML for clipping with CSS

This is the markup we’ll use for the examples below.

<div class="box">
  <h1>Box 1</h1>
</div>

Clip Path

The first exercise will create a purple circle with the string “box1” centered vertically and horizontally.

.box {
  display: flex;
  flex direction: column;
  align-items: center;
  justify-content: center;

  color: #fff;
  height: 300px;
  width: 300px;
  background-color: rebeccapurple;
  clip-path: circle(50% at center center);
}

Animating clip-path

Once we have the shape defined, we can animate it using CSS transitions and animations.

To accomplish this we need to do two things:

  1. add a transition attribute to the .box element
  2. add a :hover pseudo-class for the .box element where we change the clip-path to whatever we want to use, in this case, a smaller circle.
.box {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;

  color: #fff;
  height: 300px;
  width: 300px;
  background-color: rebeccapurple;
  clip-path: circle(75%);
  transition: clip-path 1s; /* 1 */
}

.box:hover { /* 2 */
  clip-path: circle(20%);
}

Clipping with SVG

Developers have been able to do clipping and masking with SVG. We’ll SVG to clip parts of an element from CSS.

The common HTML for clipping with SVG

This is the markup we’ll use for the examples clipping using an SVG element. The HTML may look a little weird but it’s OK to put the SVG inside the HTML document as this particular SVG fragment will not render anything, it just defines the shape we will use in CSS.

<svg class="svg-defs">
  <defs>
    <clipPath id="clipping">
      <polygon id="Star-1"
      points="98.4999978 153.75 38.2520165
       185.424245 49.7583542 118.337123
       1.01670635 70.8257603 68.3760155
       61.037872 98.5000012 1.1379786e-14
       128.624005 61.0378871 195.98331
       70.8258091 147.241642 118.337136
       158.747982 185.424247"/>
    </clipPath>
  </defs>
</svg>

<div class="box">
  <h1>Box 1</h1>
</div>

The CSS changes only slightly, instead of specifying a shape and a position, we use a relative URL to the SVG definition (clip-path: url('#clippiing'))

.box {
  height: 300px;
  width: 300px;
  background-color: rebeccapurple;
  clip-path: url(#clipping);
}

Links

Layering and compositing content with CSS

One of the things you can do with CSS is to layer content and have the layers perform different tasks.

Some of these techniques are inherited from and used together with, SVG and others are specific to CSS.

CSS Background Images

The first way I learned to layer content was using an image as the lowest item on the stack and then position text or other images on top of our ‘base layer’.

<div class="back">
  <h1>Santiago, Chile</h1>
</div>

The background image has to have a size, in this case, I chose to use viewport units to make sure that it’ll work the same in all devices.

We absolutely position the H1 element so we can play with top and left to control the position on the screen.

.back {
  background:
    url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/32795/chile-01.jpg)
    no-repeat center center fixed;
  width: 100vw;
  height: 100vh;
  background-size: cover;
}

h1 {
  position: absolute;
  color: #fff;
  font-size: 6em;
  top: 50vh;
  left: 50vw;
}

With this technique, you can also use CSS gradients as the background. The text remains the same.

<div class="back">
  <h1>Santiago, Chile</h1>
</div>

We modify the .back selector to use a linear gradient as the background.

.back {
  background: red;
  background:
    linear-gradient(
      to bottom right,
      white, rebeccapurple);
  height: 100vh;
  width: 100vw;
  background-size: cover;
}

h1 {
  color: #fff;
  position: absolute;
  left: 50%;
  top: 45vh;
}

CSS Tricks explains techniques and best practices in CSS Gradients so I’ll defer to them in terms of what you can do with gradients.

Z-Index

The next way to layer content is to use z-index. The idea is that elements with the higher z-index value are laid “closer to the user” (over other elements) while those with lower or negative are laid “away from the user” (below elements with higher z-index).

The example below uses an image element for the background instead of relying on CSS background images.

<img class="layer1"
  src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/32795/santiago002.jpg">
<h1>Santiago, Chile</h1>

Because we’re using an element that is in the DOM we need to position the base layer image relative to the other content for this technique to work.

The h1 element is positioned absolutely and placed using a combination of top, left and z-index to place it on screen relative to the background image.

.layer1 {
  position: relative;
  width: 100%;
  height: auto;
}

h1 {
  color: #fff;
  font-size: 6rem;
  position: absolute;
  z-index: 1;
  top: 1.5em;
  left: 40%;
}

blending and composition

There are times when we want more than we can do with just layering. It wasn’t until the Compositing and Blending Level 1 specification there was no equivalent way to do blending with CSS other than opacity.

The spec defines two modes to blend content: background-blend-mode and mix-blend-mode

background-blend-mode

This mode allows you to blend elements (images or colors) with their background. It also allows for multiple background images and blend modes so different portions of the image will blend with their background differently.

An example of using background-blend-mode with one background image and a single color looks like this:

.back {
  background: 
    url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/32795/chile-02.jpg) 
    center center;
  background-color: orange;
  background-blend-mode: hard-light;
  height: 100vh;
  width: 100vw;
}

We can add more background images and background blend modes to create more complex effects.

mix-blend-mode

Mix-blend-mode lets us use things other than images in the blending. I love to use this for blending text with a color and a background image.

The example uses a single image, a background color defined in CSS and a string.

<div>
  <img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/32795/chile-01.jpg" alt="" />
  <h1>Santiago, Chile</h1>
</div>

We give the div element a relative position so we can layer content above it and have elements “higher” in the stacking order blend with it.

We use an rgba color to the background color so we can control its opacity.

We position it absolutely so we can move it around by controlling the top and left attributes.

We make the full string uppercase with text-transform and use an overlay blend mode.

div {
  position: relative;
}

img {
  width: 100%;
}

h1 {
  background-color: rgba(201,201,201,.01);
  padding: .5em 1em;
  position: absolute;
  top: 0;
  left: 20vw;
  width: 75%;
  font-size: 10vw;
  font-weight: 900;
  text-transform: uppercase;
  mix-blend-mode: overlay;
}

In the example you can see how only the text inherits the color of the background image at the same position. The rest of the image looks a little hazy but, to me, that enhances the effect.

Another example, taken from Exploring Blend Modes in CSS blends two images.

The HTML code has the two images inside a div.

<div class="blend1">
  <img  src="/images/monkey.jpg" 
        width="400" height="600">
  <img  src="/images/sky.jpg" 
        width="400" height="600">
</div>

The CSS changes the position of the first image and uses a soft-light mix-blend-mode.

.blend1 img:first-child {
  position: absolute;
  mix-blend-mode: soft-light;
}

Isolate

Setting isolation to isolate will turn the element into a stacking context, and control if the element’s contents can blend with their backdrop outside this context.

By default, the isolation property is set to auto – which implies that they are not isolated.

This feature gives us tighter control over blending as we can choose which elements of our stack we blend and which one to leave out of the blending process.

The blend modes

There are 16 blend modes available in CSS and they will each change the way the blended images look.

  • normal The default blend mode and indicates that no blending is applied
  • multiply
  • screen
  • overlay
  • darken
  • lighten
  • color-dodge
  • color-burn
  • hard-light
  • soft-light
  • difference
  • exclusion
  • hue
  • saturation
  • color
  • luminosity

Sara Soedain’s Compositing And Blending In CSS has explanations of what these modes do.

Links and Resources