logical properties – CSS-Tricks https://css-tricks.com Tips, Tricks, and Techniques on using Cascading Style Sheets. Wed, 07 Dec 2022 13:49:34 +0000 en-US hourly 1 https://wordpress.org/?v=6.1.1 https://i0.wp.com/css-tricks.com/wp-content/uploads/2021/07/star.png?fit=32%2C32&ssl=1 logical properties – CSS-Tricks https://css-tricks.com 32 32 45537868 Manuel Matuzovic: max() Trickery https://css-tricks.com/manuel-matuzovic-max-trickery/ https://css-tricks.com/manuel-matuzovic-max-trickery/#comments Tue, 18 Oct 2022 13:54:38 +0000 https://css-tricks.com/?p=374466 By way of a post by Manuel Matuzović which is by way of a demo by Temani Afif.

.wrapper {
  margin-inline: max(0px, ((100% - 64rem) / 2)); 
}

You’d be doing yourself a favor to read Manuel’s breakdown of …


Manuel Matuzovic: max() Trickery originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>
By way of a post by Manuel Matuzović which is by way of a demo by Temani Afif.

.wrapper {
  margin-inline: max(0px, ((100% - 64rem) / 2)); 
}

You’d be doing yourself a favor to read Manuel’s breakdown of all what’s happening here, but it basically works out to the equivalent of this longer syntax:

.wrapper {
  max-width: 64rem;
  margin: 0 auto;
  width: 100%;
}

…where:

  • max() acecepts a comma-separated list of CSS numeric values, where the applied value is the largest (or as MDN puts it, the “most positive”) one in the set.
  • 0px is the first value in the set, ensuring that the smallest value is always going to be greater than zero pixels.
  • (100% - 64rem) is the second “value” in the set, but is expressed as a calculation (note that calc() is unnecessary) that subracts the the max-width of the element (64rem) from its full available width (100%). What’s left is the space not taken up by the element.
  • ((100% - 64rem) / 2)) divides that remaining space equally since we’re divying it between the inline boundaries of the element.
  • max(0px, ((100% - 64rem) / 2)) compares 0px and (100% - 64rem) / 2). The largest value is used. That’ll be the result of the equation in most cases, but if 64rem is ever greater than the computed value of the element’s full 100% width, it’ll lock that value at zero to ensure it never results in a negative value.
  • margin-inline is the property that the winning value sets, which applies margin to the inline sides of the element — that’s the logical shorthand equivalent to setting the same value to the margin-left and margin-right physical properties.

It’s the same sort of idea Chris shared a while back that uses the CSS max()function to solve the “Inside Problem” — a container that supports a full-bleed background color while constraining the content inside it with padding.

max(), calc(), margin-inline… that’s a lot of newfangled CSS! And Manuel is right smack dab in the middle of writing about these and other modern CSS features over 100 days.

To Shared LinkPermalink on CSS-Tricks


Manuel Matuzovic: max() Trickery originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>
https://css-tricks.com/manuel-matuzovic-max-trickery/feed/ 4 374466
Logical Properties for Useful Shorthands https://css-tricks.com/logical-properties-for-useful-shorthands/ https://css-tricks.com/logical-properties-for-useful-shorthands/#respond Wed, 20 Jul 2022 16:16:34 +0000 https://css-tricks.com/?p=367064 Michelle Barker with my favorite sorta blog post: short, practical, and leaves you with a valuable nugget for your time. Here, she gets into logical property shorthands in CSS, particularly those that set lengths just on a single axis, …


Logical Properties for Useful Shorthands originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>
Michelle Barker with my favorite sorta blog post: short, practical, and leaves you with a valuable nugget for your time. Here, she gets into logical property shorthands in CSS, particularly those that set lengths just on a single axis, say only the block (vertical) axis or just the inline (horizontal) axis.

I say “block” and ”inline” because, as far as logical properties are concerned, the x-axis could just as well behave like a vertical axis depending on the current writing-mode.

So, where we’ve always had padding, margin, and border shorthands that can support a multi-value syntax, none of them allow us to declare lengths on a specific axis without also setting a length on the other axis.

For example:

/* This gives us margin on the inline axis */
margin: 0 3rem;

…but we had to set the other axis in order to get there. With logical properties, however, we have additional shorthands for each axis meaning we can cue up the margin-inline shorthand to work specifically on the inline axis:

margin-inline: 3rem;

Michelle mentions my favorite logical property shorthand in passing. How many times do you position something to this sort of tune:

.position-me {
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
}

We can get those four lines into in with inset: 0. Or we could target the block and inline axis directly with inset-block and inset-inline, respectively.

While we’re talking shorthands, I always like to put a word of caution about ”accidental” CSS resets. Just one of the common CSS mistakes I make.

To Shared LinkPermalink on CSS-Tricks


Logical Properties for Useful Shorthands originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>
https://css-tricks.com/logical-properties-for-useful-shorthands/feed/ 0 367064
Faulty logic https://css-tricks.com/faulty-logic/ https://css-tricks.com/faulty-logic/#respond Tue, 14 Dec 2021 22:28:29 +0000 https://css-tricks.com/?p=359180 Ain’t this the truth:

It’s like when you’re learning a new language. At some point your brain goes from translating from your mother tongue into the other language, and instead starts thinking in that other language.

I don’t speak …


Faulty logic originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>
Ain’t this the truth:

It’s like when you’re learning a new language. At some point your brain goes from translating from your mother tongue into the other language, and instead starts thinking in that other language.

I don’t speak any other language besides English, but I’ve heard that’s true. With perhaps a last step being when you start dreaming in the new language.

But here Jeremy is using it as a metaphor for learning new CSS syntax. First you hear about it, then you try it, then you grok it, then a switch flips in your brain and you start reaching for it intuitively. Indeed thinking in that new syntax.

I deeply love that moment. It feels like you’ve gone up a level.

The sad part of Jeremy’s article is that there is a disconnect happening. Like logical properties have arrived, we can use them, many of our brains are starting to make the switch. But… they aren’t used consistently.

For example, if you’re thinking in logical properties and setting margin and padding, you might do:

.button {
  padding-inline: 1rem;
  margin-inline: 1rem;
}

In fact, you can even set what would have been width in a top-to-bottom language as inline-size. But, once @container queries drop, which is happening, you can’t express that width breakpoint as inline-size, it’s back to traditional min-width and max-width stuff.

That would be a bummer as it muddies the water of how clearly we are able to think. This stuff is moving very fast though, as I just took a peek at the Draft Spec (soon to be Working Draft?) and Example 2 is:

main, aside {
  container: inline-size;
}

.media-object {
  display: grid;
  grid-template: 'img' auto 'content' auto / 100%;
}

@container (inline-size > 45em) {
  .media-object {
    grid-template: 'img content' auto / auto 1fr;
  }
}

So, it looks like this inconsistency has been mopped up. Example 3 has @container (width > 40em) in it, so maybe it’ll ship being able to use them either way. I’d probably vote they roll with only logical properties, but I imagine that ship is close to sailing.

Jeremy also points out that overflow-* properties aren’t converted to logical yet, as something like overflow-x should be overflow-inline. Only Firefox has support for that so far.

I hope that’ll get cleaned up soon. But all in all, there is a ton of logical properties that are ready to think in: size, position, margin, padding, border, alignment, and more. Heck, even something like border-top-left-radius can now be thought of and used as border-start-start-radius, and you can float: inline-end instead of float: right.


Faulty logic originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>
https://css-tricks.com/faulty-logic/feed/ 0 359180
Control Layout in a Multi-Directional Website https://css-tricks.com/control-layout-in-a-multi-directional-website/ https://css-tricks.com/control-layout-in-a-multi-directional-website/#comments Tue, 23 Nov 2021 16:06:44 +0000 https://css-tricks.com/?p=356977 Many business websites need a multilingual setup. As with anything development-related, implementing one in an easy, efficient, and maintainable way is desirable. Designing and developing to be ready for multiple languages, whether it happens right at launch or is expected …


Control Layout in a Multi-Directional Website originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>
Many business websites need a multilingual setup. As with anything development-related, implementing one in an easy, efficient, and maintainable way is desirable. Designing and developing to be ready for multiple languages, whether it happens right at launch or is expected to happen at any point in the future, is smart.

Changing the language and content is the easy part. But when you do that, sometimes the language you are changing to has a different direction. For example, text (and thus layout) in English flows left-to-right while text (and thus layout) in Arabic goes right-to-left.

In this article, I want to build a multilingual landing page and share some CSS techniques that make this process easier. Hopefully the next time you’ll need to do the same thing, you’ll have some implementation techniques to draw from.

We’ll cover six major points. I believe that the first five are straightforward. The sixth includes multiple options that you need to think about first.

1. Start with the HTML markup

The lang and dir attributes will define the page’s language and direction.

<!-- English, left-to-right -->
<html lang="en" dir="ltr">

<!-- Arabic, right-to-left -->
<html lang="ar" dir="rtl">

Then we can use these attributes in selectors to do the the styling. lang and dir attributes are on the HTML tag or a specific element in which the language varies from the rest of the page. Those attributes help improve the website’s SEO by showing the website in the right language for users who search for it in case that each language has a separate HTML document.

Also, we need to ensure that the charset meta tag is included and its value is UTF-8 since it’s the only valid encoding for HTML documents which also supports all languages.

<meta charset="utf-8">

I’ve prepared a landing page in three different languages for demonstration purposes. It includes the HTML, CSS, and JavaScript we need.

2. CSS Custom Properties are your friend

Changing the direction may lead to inverting some properties. So, if you used the CSS property left in a left-to-right layout, you probably need right in the right-to-left layout, and so on. And changing the language may lead to changing font families, font sizes, etc.

These multiple changes may cause unclean and difficult to maintain code. Instead, we can assign the value to a custom property, then change the value when needed. This is also great for responsiveness and other things that might need a toggle, like dark mode. We can change the font-size, margin, padding, colors, etc., in the blink of an eye, where the values then cascade to wherever needed.

Here are some of the CSS custom properties that we are using in this example:

html {
  /* colors */
  --dark-color: #161616;
  --light-color: #eee;
  --primary-text-color: var(--dark-color);
  --primary-bg-color: #fff;
  --shadow-color: var(--light-color);
  --hero-bg-gradient: linear-gradient(90deg, #30333f, #161616, #161616);

  /* font sizes */
  --logo-font-size: 2rem;
  --lang-switcher-font-size: 1.02em;
  --offers-item-after-font-size: 1.5rem;

  /* margin and padding */
  --btn-padding: 7px;
  --sec-padding-block: 120px;

  /* height and width */
  --hero-height: 500px;
  --cta-img-width: 45.75%;
}

While styling our page, we may add/change some of these custom properties, and that is entirely natural. Although this article is about multi-directional websites, here’s a quick example that shows how we can re-assign custom property values by having one set of values on the <body>, then another set when the <body> contains a .dark class:

body {
  background-color: var(--primary-bg-color);
  color: var(--primary-text-color);
}
body.dark {
  --primary-bg-color: #0f0f0f;
  --primary-text-color: var(--light-color);

  /* other changes */
  --shadow-color: #13151a;
  --hero-bg-gradient: linear-gradient(90deg, #191b20, #131313, #131313);
}

That’s the general idea. We’re going to use custom properties in the same sort of way, though for changing language directions.

3) CSS pseudo-classes and selectors

CSS has a few features that help with writing directions. The following two pseudo-classes and attribute are good examples that we can put to use in this example.

The :lang() pseudo-class

We can use :lang() pseudo-class to target specific languages and apply CSS property values to them individually, or together. For example, in this example, we can change the font size when the :lang pseudo-class switches to either Arabic or Japanese:

html:lang(ar),
html:lang(jp){
  --offers-item-after-font-size: 1.2rem; 
}

Once we do that, we also need to change the writing-mode property from its horizontal left-to-right default direction to vertical right-to-left direction account:

html:lang(jp) .about__text {
  writing-mode: vertical-rl;
}

The :attr() pseudo-class

The :attr() pseudo-class helps makes the “content” of the pseudo-elements like ::before or ::after “dynamic” in a sense, where we can drop the dir HTML attribute into the CSS content property using the attr() function. That way, the value of dir determines what we’re selecting and styling.

<div dir="ltr"></div>
<div dir="rtl"></div>
div::after {
  content: attr(dir);
}

The power is the ability to use any custom data attribute. Here, we’re using a custom data-name attribute whose value is used in the CSS:

<div data-name="English content" dir="ltr"></div>
<div data-name="محتوى عربي" dir="rtl"></div>
div::after {
  content: attr(data-name);
}

This makes it relatively easy to change the content after switching that language without changing the style. But, back to our design. The three-up grid of cards has a yellow “special” or “best” off mark beside an image.

This is the HTML for each card:

<div class="offers__item relative" data-attr="data-offer" data-i18n_attr="special_offer">
  <figure class="offers__item_img">
    <img src="./assets/images/offer1.png" data-attr="alt" data-i18n_attr="image_alt" alt="" class="w-100">
  </figure>
  <div class="offer-content_item-text">
    <p class="para" data-i18n="offer_item_text"></p>
    <span class="price bolder" data-i18n="offer_item_price"></span>
  </div>
</div>

JavaScript’s role is to:

  1. Set an attribute called data-offer on each card.
  2. Assign a “special offer” or “best offer” value to it.

Finally, we can use the data-offer attribute in our style:

.offers__item::after {
  content: attr(data-offer);
  /* etc. */
}

Select by the dir attribute

Many languages are left-to-right, but some are not. We can specify what should be different in the [dir='rtl']. This attribute must be on the element itself or we can use nesting to reach the wanted element. Since we’ve already added the dir attribute to our HTML tag, then we can use it in nesting. We will use it later on our sample page.

4. Prepare the web fonts

In a multilingual website, we may also want to change the font family between languages because perhaps a particular font is more legible for a particular language.

Fallback fonts

We can benefit from the fallback by writing the right-to-left font after the default one.

font-family: 'Roboto', 'Tajawal', sans-serif;

This helps in cases where the default font doesn’t support right-to-left. That snippet above is using the Roboto font, which doesn’t support Arabic letters. If the default font supports right-to-left (like the Cairo font), and the design needs it to be changed, then this is not a perfect solution.

font-family: 'Cairo', 'Tajawal', sans-serif; /* won't work as expected */

Let’s look at another way.

Using CSS variables and the :lang() pseudo-class

We can mix the previous two technique where we change the font-family property value using custom properties that are re-assigned by the :lang pseudo class.

html {
  --font-family: 'Roboto', sans-serif;
}

html:lang(ar){
  --font-family: 'Tajawal', sans-serif;
}

html:lang(jp){
  --font-family: 'Noto Sans JP', sans-serif;
}

5. CSS Logical Properties

In CSS days past, we used to use left and right to define offsets along the x-axis, and the top and bottom properties to define offsets along the y-axis. That makes direction switching a headache. Fortunately, CSS supports logical properties that define direction‐relative equivalents of the older physical properties. They support things like positioning, alignment, margin, padding, border, etc.

If the writing mode is horizontal (like English), then the logical inline direction is along the x-axis and the block direction refers to the y-axis. Those directions are flipped in a vertical writing mode, where inline travels the y-axis and and block flows along the x-axis.

Writing Modex-axisy-axis
horizontalinlineblock
vertical blockinline

In other words, the block dimension is the direction perpendicular to the writing mode and the inline dimension is the direction parallel to the writing mode. Both inline and block levels have start and end values to define a specific direction. For example, we can use margin-inline-start instead of margin-left. This mean the margin direction automatically inverts when the page direction is rtl. It’s like our CSS is direction-aware and adapts when changing contexts.

There is another article on CSS-Tricks, Building Multi-Directional Layouts from Ahmad El-Alfy, that goes into the usefulness of building websites in multiple languages using logical properties.

This is exactly how we can handle margins, padding and borders. We’ll use them in the footer section to change which border gets the rounded edge.

The top-tight edge of the border is rounded in a default ltr writing mode.

As long as we’re using the logical equivalent of border-top-right-radius, CSS will handle that change for us.

.footer {
  border-start-end-radius: 120px;
}

Now, after switching to the rtl direction, it’ll work fine.

The “call to action” section is another great place to apply this:

.cta__text {
  border-start-start-radius: 50%;
  border-end-start-radius: 50px;
}
.cta__img {
  border: 1px dashed var(--secondary-color);
  border-inline-start-color: var(--light-color);
}

Now, in Arabic, we get the correct layout:

You might be wondering exactly how the block and inline dimensions reverse when the writing mode changes. Back to the Japanese version, the text is from vertical, going from top-to-bottom. I added this line to the code:

/* The "About" section when langauge is Japanese */
html:lang(jp) .about__text {
  margin-block-end: auto;
  width: max-content;
}

Although I added margin to the “block” level, it is applied it to the left margin. That’s because the text rotated 90 degrees when the language switched and flows in a vertical direction.

6. Other layout considerations

Even after all this prep, sometimes where elements move to when the direction and language change is way off. There are multiple factors at play, so let’s take a look.

Position

Using an absolute or fixed position to move elements may affect how elements shift when changing directions. Some designs need it. But I’d still recommend asking yourself: do I really need this?

Fro example, the newsletter subscription form in the footer section of our example can be implemented using position. The form itself takes the relative position, while the button takes the absolute position.

<form id="newsletter-form" class="relative">
  <input type="email" data-attr="placeholder" data-i18n_attr="footer_input_placeholder" class="w-100">
  <button class="btn btn--tertiary footer__newsletter_btn bolder absolute" data-i18n="footer_newsLetter_btn"></button>
</form>
html[dir="ltr"] .footer__newsletter_btn {
  right: 0;
}
html[dir="rtl"] .footer__newsletter_btn {
  left: 0;
}
This works fine in a rtl writing mode.

In the “hero” section, I made the background using a ::before pseudo-class with an absolute position:

<header class="hero relative">
  <!-- etc. -->
</header>
.hero {
  background-image: linear-gradient(90deg, #30333f, #161616, #161616);
}
.hero::before  {
  content: '';
  display: block;
  height: 100%;
  width: 33.33%;
  background-color: var(--primary-color);
  clip-path: polygon(20% 0%, 100% 0, 100% 100%, 0% 100%);
  position: absolute;
  top: 0;
  right: 0;
}

Here’s the HTML for our hero element:

<header class="hero relative">
  <!-- etc. -->
  <div class="hero__social absolute">
    <div class="d-flex flex-col">
      <!-- etc. -->
    </div>
  </div>
</header>

Note that an .absolute class is in there that applies position: absolute to the hero section’s social widget. Meanwhile, the hero itself is relatively positioned.

How we move the social widget halfway down the y-axis:

.hero__social {
  left: 0;
  top: 50%;
  transform: translateY(-50%);
}

In the Arabic, we can fix the ::before pseudo-class position that is used in the background using the same technique we use in the footer form. That said, there are multiple issues we need to fix here:

  1. The clip-path direction
  2. The background linear-gradient
  3. The coffee-cup image direction
  4. The social media box’s position

Let’s use a simple flip trick instead. First, we wrap the hero content, and social content in two distinct wrapper elements instead of one:

<header class="hero relative">
  <div class="hero__content">
      <!-- etc. -->
  </div>
  <div class="hero__social absolute">
    <div class="d-flex flex-col">
      <!-- etc. -->
    </div>
  </div>
</header>

Then we rotate both of the hero wrappers—the social box inner wrapper and the image—180 degrees:

html[dir="rtl"] .hero,
html[dir="rtl"] .hero__content,
html[dir="rtl"] .hero__img img,
html[dir="rtl"] .hero__social > div {
  transform: rotateY(180deg);
}

Yeah, that’s all. This simple trick is also helpful if the hero’s background is an image.

transform: translate()

This CSS property and value function helps move the element on one or more axes. The difference between ltr and rtl is that the x-axis is the inverse/negative value of the current value. So, we can store the value in a variable and change it according to the language.

html {
  --about-img-background-move: -20%;
}

html[dir='rtl']{
  --about-img-background-move: 20%;
}

We can do the same thing for the background image in the another section:

<figure class="about__img relative">
  <img src="image.jpg" data-attr="alt" data-i18n_attr="image_alt" class="w-100">
</figure>
.about__img::after {
  content: '';
  position: absolute;
  z-index: -1;
  transform: translateY(-75%) translateX(var(--about-img-background-move));
  /* etc. */
}

Margins

Margins are used to extend or reduce spaces between elements. It accepts negative values, too. For example, a positive margin-top value (20%) pushes the content down, while a negative value (e.g. -20%) pulls the content up.

If margins values are negative, then the top and left margins move the item up or to the left. However, the right and bottom margins do not. Instead, they pull content that is located in the right of the item towards the left, and the content underneath the item up. For example, if we apply a negative top margin and negative bottom margin together on the same item, the item is moved up and pull the content below it up into the item.

Here’s an example:

<section>
  <div id="d1"></div>
  <div id="d2"></div>
  <div id="d3"></div>
</section>
div {
  width: 100px;
  height: 100px;
  border: 2px solid;
}
#d1 {
  background-color: yellow;
  border-color: red;
}
#d2 {
  background-color: lightblue;
  border-color: blue;
}
#d3 {
  background-color: green;
  border-color: red;
}

The result of the above code should be something like this:

Let’s add these negative margins to the #d2 element:

#d2 {
  margin-top: -40px;
  margin-bottom: -70px;
}

Notice how the second box in the diagram moves up, thanks to a negative margin-top value, and the green box also moves up an overlaps the second box, thanks to a negative margin-bottom value.

The next thing you might be asking: But what is the difference between transform: translate and the margins?

When moving an element with a negative margin, the initial space that is taken by the element is no longer there. But in the case of translating the element using a transform, the opposite is true. In other words, a negative margin leads pulls the element up, but the transform merely changes its position, without losing the space reserved for it.

Let’s stick to using margin in one direction:

#d2 {
  margin-top: -40px;
  /* margin-bottom: -70px; */
}

Now let’s replace the margin with the transform:

#d2 {
  /* margin-top: -40px;*/
  transform: translateY(-40px);
}

You can see that, although the element is pulled up, its initial space is still there according to the natural document flow.

Flexbox

The display: flex provides a quick way to control the how the elements are aligned in their container. We can use align-items and justify-content to align child elements at the parent level.

In our example, we can use flexbox in almost every section to make the column layout. Plus, we can use it in the “offers” section to center the set of those yellow “special” and “best” marks:

.offers__item::after {
  content: attr(data-offer);
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
}

The same can be applied to the hero section to center text vertically.

<div class="d-lg-flex align-items-center">
  <div class="hero__text d-xl-flex align-items-center">
    <div>
      <!-- text -->
    </div>
  </div>
  <figure class="hero__img relative">
    <img src="/image.jpg" data-attr="alt" data-i18n_attr="image_alt" class="w-100">
  </figure>
</div>

If the flex-direction value is row, then we can benefit from controlling the width for each element. In the “hero” section, we need to set the image on the angled slope of the background where the color transitions from dark gray to yellow.

.hero__text {
  width: 56.5%;
}
.hero__img {
  width: 33.33%;
}

Both elements take up a a total of 89.83% of the parent container’s width. Since we didn’t specify justify-content on the parent, it defaults to start, leaving the remaining width at the end.

We can combine the flexbox with any of the previous techniques we’ve seen, like transforms and margins. This can help us to reduce how many position instances are in our code. Let’s use it with a negative margin in the “call to action” section to locate the image.

<section class="cta d-xl-flex align-items-center">
  <div class="cta__text w-100">
    <!-- etc. -->
  </div>
  <figure class="cta__img">
    <img src="image.jpg" data-attr="alt" data-i18n_attr="image_alt" class="w-100">
  </figure>
</section>

Because we didn’t specify the flex-wrap and flex-basis properties, the image and the text both fit in the parent. However, since we used a negative margin, the image is pulled to the left, along with its width. This saves extra space for the text. We also want to use a logical property, inline-start, instead of left to handle switching to the rtl direction.

Grid

Finally, we can use a grid container to positing the elements. CSS Grid is powerful (and different than flexbox) in that it lays things along both the x-axis and the y-axis as opposed to only one of them.

Suppose that in the “offers” section, the role of the “see all” button is to get extra data that to display on the page. Here’s JavaScript code to repeat the current content:

// offers section ==> "see all" btn functionality
(function(){
  document.querySelector('.offers .btn').addEventListener('click', function(){
    const offersContent = document.querySelector('.offers__content');
    offersContent.innerHTML += offersContent.innerHTML;
    offersContent.classList.remove('offers__content--has-margin');
    this.remove();
  })
})();

Then, let’s use display: grid in the CSS for this section. First, here’s our HTML, with our grid container highlighted.

<div class="offers__content offers__content--has-margin d-grid">
  <div class="offers__item relative" data-attr="data-offer" data-i18n_attr="special_offer">
    <!-- etc. -->
  </div>
  <div class="offers__item relative" data-attr="data-offer" data-i18n_attr="best_offer">
    <!-- etc. -->
  </div>
  <div class="offers__item relative" data-attr="data-offer" data-i18n_attr="best_offer">
    <!-- etc. -->
  </div>
</div>

We implement CSS Grid on the .offers__content element:

html {
  /* custom properties */
  --offers-content-column: repeat(3, 1fr);
  --offers-content-gap: 5vw;
}

.offers__content {
  display: grid;
  grid-template-columns: var(--offers-content-column);
  gap: var(--offers-content-gap);
}
.offers__content--has-margin {
  margin-block-end: 60px;
}

This is the result after clicking the button:

Our page is far from being the best example of how CSS Grid works. While I was browsing the designs online, I found a design that uses the following structure:

Notice how CSS Grid makes the responsive layout without media queries. And as you might expect, it works well for changing writing modes where we adjust where elements go on the grid based on the current writing mode.

Wrapping up

Here is the final version of the page. I ensured to implement the responsiveness with a mobile-first approach to show you the power of the CSS variables. Be sure to open the demo in full page mode as well.

I hope these techniques help make creating multilingual designs easier for you. We looked at a bunch of CSS properties we can use to apply styles to specific languages. And we looked at different approaches to do that, like selecting the :lang pseudo-class and data attributes using the attr() function. As part of this, we covered what logical properties are in CSS and how they adapt to a document’s writing mode—which is so much nicer than having to write additional CSS rulesets to swap out physical property units that otherwise are unaffected by the writing mode.

We also checked out a number of different positioning and layout techniques, looking specifically at how different techniques are more responsive and maintainable than others. For example, CSS Grid and Flexbox are equipped with features that can re-align elements inside of a container based on changing conditions.

Clearly, there are lots of moving pieces when working with a multilingual site. There are probably other requirements you need to consider when optimizing a site for specific languages, but the stuff we covered here together should give you all of the layout-bending superpowers you need to create robust layouts that accommodate any number of languages and writing modes.


Control Layout in a Multi-Directional Website originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>
https://css-tricks.com/control-layout-in-a-multi-directional-website/feed/ 8 356977
CSS Logical Properties and Values https://css-tricks.com/css-logical-properties-and-values/ https://css-tricks.com/css-logical-properties-and-values/#comments Tue, 27 Jul 2021 15:02:43 +0000 https://css-tricks.com/?p=344815 Now that cross-browser support is at a tipping point, it’s a good time to take a look at logical properties and values. If you’re creating a website in multiple languages, logical properties and values are incredibly useful. Even if you’re …


CSS Logical Properties and Values originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>
Now that cross-browser support is at a tipping point, it’s a good time to take a look at logical properties and values. If you’re creating a website in multiple languages, logical properties and values are incredibly useful. Even if you’re not, there are still some convenient new shorthands it’s worth knowing about.

For example, I’ve lost count of the amount of times I’ve written this to center something:

.thing {
  margin-left: auto;
  margin-right: auto;
}

We could make it a one-liner with something like margin: 0 auto; but then the top and bottom margins get thrown into the mix. Instead, we can select just the left and right margin with the margin-inline logical property.

Start thinking of things as “inline” or “block”

That last demo is pretty neat, right? The margin-inline property sets both margin-left and margin-right. Similarly, the margin-block property sets both margin-top and margin-bottom. And we’re not only talking margins. Logical properties has similar shorthands to set border and padding. So if you have a visual design that calls for borders only on the sides, you can just use border-inline instead of fussing with each physical direction on its own.

Showing border-left and border-right with matching values combined together as border-inline as a single declaration, and another example showing padding-top and padding-bottoms et to 32 pixels combined to padding-block set to 32 pixels.
Rather than thinking in physical terms, like left and right, we can think of an “inline” direction and a “block” direction.

So, as we move ahead, we now know that we’re dealing with inline and block directions instead of physical directions. Inline handles the left and right directions, while block manages top and bottom.

That is, until things get swapped around when the writing-mode changes.

Pay attention to direction and writing mode

What we’ve seen so far are examples of CSS logical properties. These are versions of CSS properties were used to like margin and padding, but written in a new way that forgoes physical directions (i.e. left, right, top, and bottom).

CSS was developed with the English language in mind and English is written and read from left-to-right. That’s not the case for all languages though. Arabic, for example, is read from right-to-left. That’s why HTML has a dir attribute.

<html dir="rtl">

CSS has an equivalent property (although it’s recommended to use the HTML attribute just in case the CSS fails to load):

.foreign-language { direction: rtl; }
Two cards, one in english and one in arabic, Both cards have a subtitle in gray above a main heading in a larger black font. The english goes from left to right and indicates the direction with an arrow below the card. The arabic direction is reverse of the english.
Credit: Ahmad Shadeed

Chinese, Japanese, Korean and Mongolian can be written either horizontally from left-to-right, or vertically from top to bottom. The majority of websites in these languages are written horizontally, the same as with English.

Comparatively, vertical writing is more common on Japanese websites. Some sites use a mixture of both vertical and horizontal text.

baroku.co.jp

When written vertically, Chinese, Japanese and Korean are written with the top-right as a starting point, whereas Mongolian reads from left to right. This is exactly why we have the writing-mode property in CSS, which includes the following values:

  • horizontal-tb: This is the default value, setting the the direction left-to-right for languages like English or French, and right-to-left languages like Arabic. The tb stands for “top-to-bottom.”
  • vertical-rl: This changes the direction to right-to-left in a vertical orientation for languages like Chinese, Japanese and Korean.
  • vertical-lr: This is used for vertical left-to-right languages, like Mongolian.

CSS logical properties offer a way to write CSS that is contextual. When using logical properties, spacing and layout are dependent on both the writing-mode and direction (whether set by either CSS or HTML). It therefore becomes possible to reuse CSS styles across different languages. BBC News, for example, rebuild their website in over a dozen languages. That’s a better experience than leaving users to rely on autotranslate. It also means they can better cater specific content to different parts of the world. The visual styling though, remains much the same across regions.

Screenshot of the BBC website. The header is red with the BBC logo aligned to the right of the screen. The navigation is also in red and aligned to the right. There is a featured article with right-aligned text and a large image to the right of it. Below that are four more article cards in a single row, each with an image above a title and date and aligned right.
bbc.com/arabic

Let’s look at the example below to see the shortcomings of physical properties. Using the physical margin-left property (shown in red), everything looks good in English. If you were to reuse the CSS but change the writing mode to rtl (shown at the bottom) there’s no space between the text and the icon and there’s excess white space on the left of the text. We can avoid this by using a logical property instead.

Two buttons, both with an envelope icon and a label. The left-to-right version of the button on top shows the spacing between the icon and the label. The right-to-left version shows the spacing to the left of both the label and icon.

What makes logical properties and values so useful is that they will automatically cater to the context of the language. In a left-to-right language like English, margin-inline-start will set the left-side margin. For a right-to-left language like Arabic, Urdu, or Hebrew, it will set the right-hand margin — which solves the layout problem in the above example. That’s right-to-left taken care of. If you have vertical text, margin-inline-start will cater to that context to, adding the margin at the top, which is where you would start reading from in any vertical language (that’s why it’s called margin-inline-start — just think about which direction you start reading from). The direction of inline changes based on the element’s writing-mode. When a vertical writing-mode is set, it handles the vertical direction top and bottom. See how things can get switched around?

An example of the writing direction in Mongolian. (Credit: W3C)

A complete list of logical properties and values

There are dozens of CSS properties that have a logical alternative syntax. Adrian Roselli has a handy visualization where you can toggle between the physical CSS properties that we’re all used to and their logical property equivalents. It’s a nice way to visualize logical properties and the physical properties they map to when the direction is ltr and the writing-mode is horizontal-tb.

Let’s break all of those down even further and map each and every physical CSS property to its logical companion, side-by-side. The tables shown throughout this article show traditional physical CSS in the left column and their logical equivalents (using a left-to-right horizontal mapping) in the right column. Remember though, the whole point of logical properties is that they change based on context!

Sizing

In a horizontal writing mode, inline-size sets the width of an element, while block-size sets the height. In a vertical writing mode, the opposite is true: inline-size sets the height and block-size sets the width.

Physical propertyLogical property
widthinline-size
max-widthmax-inline-size
min-widthmin-inline-size
heightblock-size
max-heightmax-block-size
min-heightmin-block-size

Logical properties for sizing have good cross-browser support.

Borders

Everything here has solid cross-browser support among modern browsers.

Physical propertyLogical property
border-topborder-block-start
border-bottomborder-block-end
border-leftborder-inline-start
border-rightborder-inline-end

Here’s an example of using border-inline-start shown with English, Arabic, and Chinese.

Here’s an example that sets border-block-start dotted and border-block-end dashed:

There are also logical properties for setting the border color, width, and style individually:

Physical propertyLogical property
border-top-colorborder-block-start-color
border-top-widthborder-block-start-width
border-top-styleborder-block-start-style

So, again, it’s about thinking in terms of “inline” and “block” instead of physical directions, like left and top. We also have shorthand logical properties for borders:

Physical propertyLogical property
border-top and border-bottomborder-block
border-left and border-rightborder-inline

Margin

Here are all the individual logical margin properties:

Physical propertyLogical property
margin-topmargin-block-start
margin-bottommargin-block-end
margin-leftmargin-inline-start
margin-rightmargin-inline-end

These logical properties has comprehensive modern cross-browser support, including Samsung Internet, and has been supported in Safari since 12.2.

And, remember, we have the shorthands as well:

Physical propertyLogical property
margin-top and margin-bottommargin-block
margin-left and margin-rightmargin-inline

Padding

Padding is super similar to margin. Replace margin with padding and we’ve got the same list of properties.

Physical propertyLogical property
padding-toppadding-block-start
padding-bottompadding-block-end
padding-leftpadding-inline-start
padding-rightpadding-inline-end
padding-top and padding-bottompadding-block
padding-left and padding-rightpadding-inline

Just like margins, logical properties for padding have good cross-browser support.

Positioning

Need to offset an element’s position in a certain direction? We can declare those logically, too.

Physical propertyLogical property
topinset-block-start
bottominset-block-end
leftinset-inline-start
rightinset-inline-end
top and bottominset-block
left and rightinset-inline

In a horizontal writing mode (either left-to-right, or right-to-left) inset-block-start is equivalent to setting top, and inset-block-end is equivalent to setting bottom. In a horizontal writing mode, with a left-to-right direction, inset-inline-start is equivalent to left, while inset-inline-end is equivalent to right, and vice-versa for right-to-left languages.

Conversely, for a vertical writing mode, inset-inline-start is equivalent to top while inset-inline-end is equivalent to bottom. If writing-mode is set to vertical-rl, inset-block-start is equivalent to right and inset-block-end is equivalent to left. If the writing-mode is set to vertical-lr, the opposite is the case and so inset-block-start is equivalent to left.

Logical propertyWriting modeEquivalent to:
inset-block-startHorizontal LTRtop
inset-block-startHorizontal RTLtop
inset-block-startVertical LTRleft
inset-block-startVertical RTLright

Here’s an example of how the same CSS code for absolute positioning looks in each of the four different writing directions:

Logical properties for positioning are supported in all modern browsers, but only recently landed in Safari.

There’s also a new shorthand for setting all four offsets in one line of code. Here’s an example using inset as a shorthand for setting top, bottom, left, and right in one fell swoop to create a full-page overlay:

I’ve heard inset incorrectly referred to as a logical property. But, a quick look in DevTools shows that it is actually a shorthand for physical values, not logical properties:

What it’s actually doing is defining physical offsets (i.e. left, right, top and bottom) rather than logical ones (i.e. inline, block, start and end). Obviously if you want to set the same value for all four sides, as in the example above, it doesn’t matter.

inset: 10px 20px 5px 8px; /* shorthand for physical properties not logical properties  */

Text alignment

Logical values for text alignment enjoy great browser support and have for many years. When working in English, text-align: start is the same as text-align: left, while text-align: end is the same as text-align: right. If you set the dir attribute to rtl, they switch and text-align: start aligns text to the right.

Physical valueWriting modeEquivalent to:
startLTRleft
startRTLright
endLTRright
endRTLleft

Border radius

So far everything we’ve looked at has decent browser support. However, there are some other logical properties where support is still a work in progress, and border radius is one of them. In other words, we can set a different border-radius value for different corners of an element using logical properties, but browser support isn’t great.

Physical propertyLogical property
border-top-left-radiusborder-start-start-radius
border-top-right-radiusborder-start-end-radius
border-bottom-left-radiusborder-end-start-radius
border-bottom-right-radiusborder-end-end-radius

It’s worth noting that the spec doesn’t include shorthand properties, like border-start-radius and border-end-radius. But, like I said, we’re still in early days here, so that might be a space to watch.

Floats

Flow-relative values for logical floats have terrible browser support at the time I’m writing this. Only Firefox supports inline-start and inline-end as float values.

Physical valueLogical value
float: leftfloat: inline-start
float: rightfloat: inline-end
clear: leftclear: inline-start
clear: rightclear: inline-end

Other logical properties

There are proposed logical properties for overflow and resize, but they currently have horrendous browser support.

PhysicalLogical
resize: verticalresize: block
resize: horizontalresize: inline
overflow-yoverflow-block
overflow-xoverflow-inline

Digging deeper

We explored what it means for a property to be considered “logical” and then mapped out all of the new logical properties and values to their physical counterparts. That’s great! But if you want to go even deeper into CSS Logical Properties and Values, there are a number of resources worth checking out.

  • “RTL Styling 101” (Ahmad Shadeed): A great resource if you’re dealing with Arabic or other right-to-left languages. Ahmad covers everything, from logical properties to considerations when working with specific layout techniques, like flexbox and grid.
  • text-combine-upright (CSS-Tricks): If you’re dealing with vertical text, did you know that this property can rotate text and squeeze multiple characters into the space of a single character? It’s a nice touch of refinement in specific situations where some characters need to go together but still flow with a vertical writing mode.

If you want to view some nice real-world examples of vertical typography from across the web, take a look at the Web Awards for Horizontal and Vertical Writings. There’s a lot of great stuff in there.

Wrapping up

Do you need to rush and swap all of the physical properties out of your codebase? Nope. But it also doesn’t hurt to start using logical properties and values in your work. As we’ve seen, browser support is pretty much there. And even if you’re working on a site that’s just in English, there’s no reason to not use them.


CSS Logical Properties and Values originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>
https://css-tricks.com/css-logical-properties-and-values/feed/ 7 344815
You want margin-inline-start https://css-tricks.com/you-want-margin-inline-start/ https://css-tricks.com/you-want-margin-inline-start/#comments Tue, 30 Mar 2021 14:24:19 +0000 https://css-tricks.com/?p=337010 David Bushell in ”Changing CSS for Good“:

I’m dropping “left“ and “right“ from my lexicon. The new CSS normal is all about Logical Properties and Values […] It can be as easy as replacing left/right


You want margin-inline-start originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>
David Bushell in ”Changing CSS for Good“:

I’m dropping “left“ and “right“ from my lexicon. The new CSS normal is all about Logical Properties and Values […] It can be as easy as replacing left/right with inline start/end. Top/bottom with block start/end. Normal inline flow, Flexbox, and Grid layouts reverse themselves automatically.

I figured it made sense as a “You want…” style post. Geoff has been documenting these properties nicely in the Almanac.


You want margin-inline-start originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>
https://css-tricks.com/you-want-margin-inline-start/feed/ 2 337010
Platform News: Defaulting to Logical CSS, Fugu APIs, Custom Media Queries, and WordPress vs. Italics https://css-tricks.com/platform-news-defaulting-to-logical-css-fugu-apis-custom-media-queries-and-wordpress-vs-italics/ https://css-tricks.com/platform-news-defaulting-to-logical-css-fugu-apis-custom-media-queries-and-wordpress-vs-italics/#comments Fri, 12 Mar 2021 15:51:32 +0000 https://css-tricks.com/?p=336380 Looks like 2021 is the time to start using CSS Logical Properties! Plus, Chrome recently shipped a few APIs that have raised eyebrows, SVG allows us to disable its aspect ratio, WordPress focuses on the accessibility of its typography, and …


Platform News: Defaulting to Logical CSS, Fugu APIs, Custom Media Queries, and WordPress vs. Italics originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>
Looks like 2021 is the time to start using CSS Logical Properties! Plus, Chrome recently shipped a few APIs that have raised eyebrows, SVG allows us to disable its aspect ratio, WordPress focuses on the accessibility of its typography, and there’s still no update (or progress) on the development of CSS custom media queries.

Let’s jump right into the news…

Logical CSS could soon become the new default

Six years after Mozilla shipped the first bits of CSS Logical Properties in Firefox, this feature is now on a path to full browser support in 2021. The categories of logical properties and values listed in the table below are already supported in Firefox, Chrome, and the latest Safari Preview.

CSS property or valueThe logical equivalent
margin-topmargin-block-start
text-align: righttext-align: end
bottominset-block-end
border-leftborder-inline-start
(n/a)margin-inline

Logical CSS also introduces a few useful shorthands for tasks that in the past required multiple declarations. For example, margin-inline sets the margin-left and margin-right properties, while inset sets the top, right, bottom and left properties.

/* BEFORE */
main {
  margin-left: auto;
  margin-right: auto;
}

/* AFTER */
main {
  margin-inline: auto;
}

A website can add support for an RTL (right-to-left) layout by replacing all instances of left and right with their logical counterparts in the site’s CSS code. Switching to logical CSS makes sense for all websites because the user may translate the site to a language that is written right-to-left using a machine translation service. The biggest languages with RTL scripts are Arabic (310 million native speakers), Persian (70 million), and Urdu (70 million).

/* Switch to RTL when Google translates the page to an RTL language */
.translated-rtl {
  direction: rtl;
}

David Bushell’s personal website now uses logical CSS and relies on Google’s translated-rtl class to toggle the site’s inline base direction. Try translating David’s website to an RTL language in Chrome and compare the RTL layout with the site’s default LTR layout.

Chrome ships three controversial Fugu APIs

Last week Chrome shipped three web APIs for “advanced hardware interactions”: the WebHID and Web Serial APIs on desktop, and Web NFC on Android. All three APIs are part of Google’s capabilities project, also known as Project Fugu, and were developed in W3C community groups (though they’re not web standards).

  • The WebHID API allows web apps to connect to old and uncommon human interface devices that don’t have a compatible device driver for the operating system (e.g., Nintendo’s Wii Remote).
  • The Web Serial API allows web apps to communicate (“byte by byte”) with peripheral devices, such as microcontrollers (e.g., the Arduino DHT11 temperature/humidity sensor) and 3D printers, through an emulated serial connection.
  • Web NFC allows web apps to wirelessly read from and write to NFC tags at short distances (less than 10 cm).

Apple and Mozilla, the developers of the other two major browser engines, are currently opposed to these APIs. Apple has decided to “not yet implement due to fingerprinting, security, and other concerns.” Mozilla’s concerns are summarized on the Mozilla Specification Positions page.

Source: webapicontroversy.com

Stretching SVG with preserveAspectRatio=none

By default, an SVG scales to fit the <svg> element’s content box, while maintaining the aspect ratio defined by the viewBox attribute. In some cases, the author may want to stretch the SVG so that it completely fills the content box on both axes. This can be achieved by setting the preserveAspectRatio attribute to none on the <svg> element.

View demo

Distorting SVG in this manner may seem counterintuitive, but disabling aspect ratio via the preserveAspectRatio=none value can make sense for simple, decorative SVG graphics on a responsive web page:

This value can be useful when you are using a path for a border or to add a little effect on a section (like a diagonal [line]), and you want the path to fill the space.

WordPress tones down the use of italics

An italic font can be used to highlight important words (e.g., the <em> element), titles of creative works (<cite>), technical terms, foreign phrases (<i>), and more. Italics are helpful when used discreetly in this manner, but long sections of italic text are considered an accessibility issue and should be avoided.

Italicized text can be difficult to read for some people with dyslexia or related forms of reading disorders.

Putting the entire help text in italics is not recommended

WordPress 5.7, which was released earlier this week, removed italics on descriptions, help text, labels, error details text, and other places in the WordPress admin to “improve accessibility and readability.”

In related news, WordPress 5.7 also dropped custom web fonts, opting for system fonts instead.

Still no progress on CSS custom media queries

The CSS Media Queries Level 5 module specifies a @custom-media rule for defining custom media queries. This proposed feature was originally added to the CSS spec almost seven years ago (in June 2014) and has since then not been further developed nor received any interest from browser vendors.

@custom-media --narrow-window (max-width: 30em);

@media (--narrow-window) {
  /* narrow window styles */
}

A media query used in multiple places can instead be assigned to a custom media query, which can be used everywhere, and editing the media query requires touching only one line of code.

Custom media queries may not ship in browsers for quite some time, but websites can start using this feature today via the official PostCSS plugin (or PostCSS Preset Env) to reduce code repetition and make media queries more readable.

On a related note, there is also the idea of author-defined environment variables, which (unlike custom properties) could be used in media queries, but this potential feature has not yet been fully fleshed out in the CSS spec.

@media (max-width: env(--narrow-window)) {
  /* narrow window styles */
}

Platform News: Defaulting to Logical CSS, Fugu APIs, Custom Media Queries, and WordPress vs. Italics originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>
https://css-tricks.com/platform-news-defaulting-to-logical-css-fugu-apis-custom-media-queries-and-wordpress-vs-italics/feed/ 2 336380
Clipping Scrollable Areas On The inline-start Side https://css-tricks.com/clipping-scrollable-areas-on-the-inline-start-side/ https://css-tricks.com/clipping-scrollable-areas-on-the-inline-start-side/#respond Fri, 19 Feb 2021 22:32:01 +0000 https://css-tricks.com/?p=335036 On a default left-to-right web page, “hanging” an element off the right side of the page (e.g. position: absolute; right: -100px;) triggers a horizontal scrollbar that scrolls as far as needed to make that whole element visible. But if …


Clipping Scrollable Areas On The inline-start Side originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>
On a default left-to-right web page, “hanging” an element off the right side of the page (e.g. position: absolute; right: -100px;) triggers a horizontal scrollbar that scrolls as far as needed to make that whole element visible. But if you hang an element of the left side of the page, it’s just hidden (no scrollbar is triggered). That’s called “data loss” in CSS terms, if you’re fancy. The same is true for the top edge of the page (hidden) and bottom of the page (scrolling happens).

Ahmad puts a point on this. It’s just one of those CSS things that you just need to know. I love how Ahmad uses logical directions like inline-start direction (and block-start direction) to describe the issue because those directions change when the direction or writing mode of the page changes. If the page is right-to-left (RTL) like <html dir="rtl">, then horizontal edges where the data loss occurs are flipped (except in Firefox 🤷‍♀️).

To Shared LinkPermalink on CSS-Tricks


Clipping Scrollable Areas On The inline-start Side originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>
https://css-tricks.com/clipping-scrollable-areas-on-the-inline-start-side/feed/ 0 335036
A Utility Class for Covering Elements https://css-tricks.com/a-utility-class-for-covering-elements/ https://css-tricks.com/a-utility-class-for-covering-elements/#comments Sat, 26 Dec 2020 14:53:04 +0000 https://css-tricks.com/?p=331673 Big ol’ same to Michelle Barker here:

Here’s something I find myself needing to do again and again in CSS: completely covering one element with another. It’s the same CSS every time: the first element (the one that needs


A Utility Class for Covering Elements originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>
Big ol’ same to Michelle Barker here:

Here’s something I find myself needing to do again and again in CSS: completely covering one element with another. It’s the same CSS every time: the first element (the one that needs to be covered) has position: relative applied to it. The second has position: absolute and is positioned so that all four sides align to the edges of the first element.

.original-element {
  position: relative;
}

.covering-element {
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
}

I have it stuck in my head somehow that it’s “not as reliable” to use bottom and right and that it’s safer to set the top and left then do width: 100% and height: 100%. But I can’t remember why anymore—maybe it was an older browser thing?

But speaking of modernizing things, my favorite bit from Michelle’s article is this:

.overlay {
  position: absolute;
  inset: 0;
}

The inset property is a Logical Property and clearly very handy here! Read the article for another trick involving CSS grid.

To Shared LinkPermalink on CSS-Tricks


A Utility Class for Covering Elements originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>
https://css-tricks.com/a-utility-class-for-covering-elements/feed/ 7 331673
Logical layout enhancements with flow-relative shorthands https://css-tricks.com/logical-layout-enhancements-with-flow-relative-shorthands/ https://css-tricks.com/logical-layout-enhancements-with-flow-relative-shorthands/#comments Mon, 16 Nov 2020 21:05:53 +0000 https://css-tricks.com/?p=325899 Admission: I’ve never worked on a website that was in anything other than English. I have worked on websites that were translated by other teams, but I didn’t have much to do with it. I do, however, spend a lot …


Logical layout enhancements with flow-relative shorthands originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>
Admission: I’ve never worked on a website that was in anything other than English. I have worked on websites that were translated by other teams, but I didn’t have much to do with it. I do, however, spend a lot of time thinking in terms of block-level and inline-level elements. It’s been a couple of years now since logical properties have started to drop, and they have definitely started to invade my CSS muscle memory.

If you work in top-to-bottom, left-to-right languages like English as I do, you just map top and bottom to block in your head (you probably already do) and left and right as inline. So instead of height, you think block-size. Instead of border-right, you think border-inline-end. Instead of padding: 0 1em, you think padding-inline: 1em. And instead of margin-top, you think margin-block-start.

I mapped out that stuff in another post.

One trouble is that browser support is a little weird. Like margin-block-end is gonna work anywhere that any logical properties at all work, but if you’re like, “I’d like to set both the start and the end (like margin: 1rem 0), so I’ll use just margin-block,” well, that doesn’t work in some browsers (yet). That makes a certain sense, because there is no “direct mapping” of margin-block to any ex-logical CSS property. There are enough other little caveats like that, making me a just a smidge squeamish about using them everywhere.

Still, I’m probably going to start using them a lot more, as even if I still mostly only work on English sites, I like the idea that if I use them consistently, it makes translating any site I work on to languages that aren’t left-to-right and top-to-bottom a lot easier. Not to mention, I just like the mental model of thinking of things as block and inline.

I’m trying to link to Adam Argyle and Oriol Brufau’s article here, so let me just end with a quote from it, putting a point on why using non-logical properties only makes sense for one “language style”:

In English, letters and words flow left to right while paragraphs are stacked top to bottom. In traditional Chinese, letters and words are top to bottom while paragraphs are stacked right to left. In just these 2 cases, if we write CSS that puts “margin top” on a paragraph, we’re only appropriately spacing 1 language style. If the page is translated into traditional Chinese from English, the margin may well not make sense in the new vertical writing mode.

To Shared LinkPermalink on CSS-Tricks


Logical layout enhancements with flow-relative shorthands originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>
https://css-tricks.com/logical-layout-enhancements-with-flow-relative-shorthands/feed/ 1 325899
Building Multi-Directional Layouts https://css-tricks.com/building-multi-directional-layouts/ https://css-tricks.com/building-multi-directional-layouts/#comments Thu, 23 Jan 2020 19:21:03 +0000 https://css-tricks.com/?p=302289 There are some new features in CSS that can assist us with building layouts for different directions and languages with ease. This article is about CSS logical properties and values (e.g. margin-inline-start).  These are a W3C working draft that …


Building Multi-Directional Layouts originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>
There are some new features in CSS that can assist us with building layouts for different directions and languages with ease. This article is about CSS logical properties and values (e.g. margin-inline-start).  These are a W3C working draft that still going under heavy editing, but have shipped in many browsers. I want to talk about this because I’ve been using these properties for a little while and have seen a significant boost to my workflow after switching to them.

I’ll talk about the specifications and how can you use it today in your work. I live in Egypt where we use Arabic as a primary language. Arabic is written from right to left, which means Arabic websites look like a mirror image of an English version. Most of the websites we create are bilingual, which means we provide a stylesheet specific for each direction. We do that by flipping values and properties of almost everything! I will not talk in details about this part but you can talk a quick look about a past article I wrote on the topic. 

It starts with declaring the dir attribute on the HTML tag. 

 <html dir="rtl">

This attribute accepts one of two values: ltr (which is the default value if none is specified) and rtl. According to its value, the browser starts to paint the elements following a specific algorithm. Text will be written with respect to the direction and punctuations will be placed in their correct location. Some elements, like tables, will have their direction switched (for example, a <td> starting from the right in rtl). Thankfully, some new specifications, like CSS Grid, and flexbox follow a similar approach to the table. That means we don’t have to change the order of anything because the browser will take care of it!

HTML5 introduced a new auto value for the dir attribute. It will check for the first character within the element and, if it belongs to a language that is written from left-to-right (like Latin characters), the element will have an ltr direction and vice versa. The W3C urges authors to avoid relying on this value to determine text direction and use a server-side solution instead. 

An interesting use case for the auto value is when you’re unsure about the direction of the content, such user-generated content, like a comment thread. I see a lot of people contributing to discussions in Arabic websites in English. The support for auto is pretty good except, for Internet Explorer and Edge.

Introducing the :dir() pseudo-class

The :dir() pseudo-class is a new selector modifier that selects an element based on its direction value. It works like this:

/* Select all paragraphs that have their direction value set to rtl */
p:dir(rtl) {
  font-size: 16px; /* Sometimes Arabic glyphs need a size boost to feel right. */
}


/* Select all paragraphs that have their direction value set to ltr */
p:dir(ltr) {
  font-size: 14px;
}

This selector will select the element if it has a direction set directly or evaluates the automatically set value using auto, it will still correctly the element based on its content!

<style>
  p:dir(ltr) {
    background: green;
  }
  p:dir(rtl) {
    background: red;
  }
</style>


<!-- The following paragraph will have a green background -->
<p dir="auto">This is a paragraph that starts with a latin character</p>
<!-- The following paragraph will have a red background -->
<p dir="auto">هذا النص يستخدم حروف عربية</p>

Sadly, the support for :dir() isn’t great and limited only to Firefox.

This browser support data is from Caniuse, which has more detail. A number indicates that browser supports the feature at that version and up.

Desktop

ChromeFirefoxIEEdgeSafari
No17*NoNoTP

Mobile / Tablet

Android ChromeAndroid FirefoxAndroidiOS Safari
No107NoNo

Even if the browser support was great, the selector only allows you to target elements and manually apply certain styles to them. That means that we still should flip the values for everything (like margins, paddings, floats, positions, etc.) which doesn’t really enhance our workflow or reduce the effort to produce multi-directional layouts.

Introducing CSS logical properties and values

As defined by the W3C, logical properties and values provide us with the ability to control layout through logical, rather than physical, direction and dimension mappings. Let’s skip the technical jargon and jump directly to the details. These provide us with new properties and values that will evaluate differently according to certain conditions.

Logical values

Let’s say we have a paragraph that we want to align in a direction that’s opposite to the natural direction of the language. Let’s say this is in English that follows the ltr direction. We would do something like this:

<article>
  <p class="opposite">
    Lorem ipsum dolor sit amis ..
  </p>
</article>

And the CSS file would be like this:

.opposite {
  text-align: right;
}

To provide the opposite for the rtl version, we would override the selector by targeting the <html> tag with the dir attribute, or simply provide a different file for the rtl version, like this:

html[dir="rtl"] .opposite {
  text-align : left;
}

Logical properties and values were created to solve this problem. Why don’t we use values that evaluates to the correct context instead of using left and right? In an ltr element, the value left means the beginning or the start of the element while on the rtl element, the value right means the start! It’s simple, right?

So instead of what we wrote before, we can use:

.opposite {
  text-align: end;
}

And that’s it! If the element’s computed direction is ltr, the text would be aligned right; and the computed direction would be opposite for the rtl elements. So, instead of using left and right values for text-align, we can simply replace it with start and end. This is a lot easier and more convenient than our previous options.

Logical properties

What we just looked at were logical values, so let’s turn now to logical properties. Logical properties are new properties that have the same idea; they evaluate differently according to the direction of the element. Take a look at margin as an example. Previously, we wanted to add some space toward the start of the paragraph. We can do so in the ltr document by using:

article img {
  margin-left: 15px;
}

Now, in the case of the rtl version, we will need to add the margin to the opposite direction in addition to resetting the left value:

html[dir="rtl"] article img {
  margin-left: 0;
  margin-right: 15px;
}

We can do better with logical properties. Consider the following:

article img {
  margin-inline-start: 15px;
}

The -inline-start part evaluates to the beginning of the horizontal axis of the image. In the case of ltr, that means left, and in the case of rtl, that means right.

The start and end are probably obvious by now, but what is with the word inline and why do we need it? To understand it, we need to talk about something called CSS writing modes. Jen Simmons wrote an excellent article on that topic. I won’t regurgitate everything explained there, but the bottom line is that we can use writing modes to define the writing direction. Some languages, like the Chinese, Korean, and Japanese, can be written vertically from top to bottom. CSS writing modes allow us to control that flow. Take a look at the following paragraph:

You can clearly identify the top, bottom, left and right edges of the block. What will happen if we change the direction of the paragraph using CSS writing modes to flow vertically?

When we talk about the “top” of this rotated paragraph, do we mean the where the content begins or what was the right edge when it wasn’t rotated? Identifying the four directions becomes confusing. Let’s look at them from a different perspective. In “normal” writing conditions, the vertical axis will have the suffix -block and the horizontal axis will have the suffix -inline, both followed by start or end:

And if we rotate it, it should be like this:

Since we are talking about normal horizontal layout, we will be using -inline-start and -inline-end, but it is good to know about the other properties as well. We can also write logical shorthand values by using the logical keyword. Consider the following:

article img {
  margin: logical 10px 20px 30px 40px;
}

The computed value of the image’s margin will be the following:

article img {
  margin-block-start: 10px;
  margin-inline-start: 20px;
  margin-block-end: 30px;
  margin-inline-end: 40px;
}

The logical keyword is an experimental feature at this point in time, which means it may change or it may be replaced by the time the spec becomes official. There’s an open discussion on the topic that you can follow in the meantime.

Logical properties also allow us to apply values to a certain axis, meaning we have margin-inline and margin-block for the horizontal and vertical axises, respectively.

PropertyLogical Property
margin-topmargin-block-start
margin-leftmargin-inline-start
margin-rightmargin-inline-end
margin-bottommargin-block-end

Just like with the logical margin properties, we also have logical padding properties which follow the same rules as the margin.

PropertyLogical Property
padding-toppadding-block-start
padding-leftpadding-inline-start
padding-rightpadding-inline-end
padding-bottompadding-block-end

Logical positioning properties

In the previous examples we were able to modify the meaning of the property by appending suffixes, but what about the positions? The properties names changed completely from what we know now as top, right, bottom, and left.

.element {
  position: absolute;
  inset-block-start: 0;  /* evaluates to top */
  inset-block-end: 0;    /* evaluates to bottom */
  inset-inline-start: 0; /* evaluates to left in ltr and right in rtl */
  inset-inline-end: 0;   /* evaluates to right in ltr and left in rtl */
}

Learning new properties and values can be hard but, hey, we get a shorthand property called inset to make it a little easier:

/* Shorthand FTW! */
.element {
  position: absolute;
  inset: logical 10px 20px 30px 40px;
}


/* It evaluates to this */
.element {
  position: absolute;
  inset-block-start: 10px;
  inset-inline-start: 20px;
  inset-block-end: 30px;
  inset-inline-end: 40px;
}

inset supports both inset-block and inset-inline just like margin and padding.

PropertyLogical Property
topinset-block-start
leftinset-inline-start
rightinset-inline-end
bottominset-block-end

Logical border properties

Border properties can also become logical by appending the -inline-start and -block-start.

PropertyLogical Property
border-top{-size|style|color}border-block-start{-size|style|color}
border-left{-size|style|color}border-inline-start{-size|style|color}
border-right{-size|style|color}border-inline-end{-size|style|color}
border-bottom{-size|style|color}border-block-end{-size|style|color}

In her deep dive on logical properties and values, Rachel Andrew includes an excellent demo that demonstrates logical border properties and how they respond to different writing modes.

How can we start using all this today?

We can start using all the magic of logical properties and value today, thanks to the power of PostCSS! Jonathan Neal wrote this lovely PostCSS plugin that enables us to write logically and compile the code to something today’s browsers will understand. The plugin works in three stages:

  • It translates the new syntax to existing standards that unsupported browsers will recognize, using the :dir pseudo-class to create output to ltr and rtl.
  • It uses another one of Neal’s plugins to translate :dir to an attribute selector, like this:
 .element:dir(ltr) {
   ...
 }
 [dir="ltr"] .element {
   ...
 }
  • It uses the postcss-nested plugin to transform nested selectors to one-line selectors, the same way other CSS preprocessors do.

PostCSS works with any workflow. You can try it with Grunt, Gulp, and webpack.


I will close by saying I have seen a lot of benefits since making the shift to logical properties and values. Sure, building multi-directional layouts takes time. There’s the learning curve, the addition of more properties to write, and of course, testing. Our previous methods for creating multi-directional layouts were either taking care of both directions in development or working on one direction at a time — neither of which is all that suitable for big projects. With logical properties and values you write your code once and it works for both directions without any consideration.

References


Building Multi-Directional Layouts originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>
https://css-tricks.com/building-multi-directional-layouts/feed/ 6 302289
The Web in 2020: Extensibility and Interoperability https://css-tricks.com/the-web-in-2020-extensibility-and-interoperability/ Wed, 22 Jan 2020 21:38:00 +0000 https://css-tricks.com/?p=301879 In the past few years, we’ve seen a lot of change and diversion in regard to web technologies. In 2020, I foresee us as a web community heading toward two major trends/goals: extensibility and interoperability. Let’s break those down.

Extensibility…


The Web in 2020: Extensibility and Interoperability originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>
In the past few years, we’ve seen a lot of change and diversion in regard to web technologies. In 2020, I foresee us as a web community heading toward two major trends/goals: extensibility and interoperability. Let’s break those down.

Extensibility

Extensibility describes how much someone can take a particular technology and extend it to their own needs. We’ve built a component-based web over the last few years in terms of both development (React components! Vue components! Svelte components! Web components!) and design (Design systems!). Interesting how form follows function, isn’t it?

Now we’re trying to make that component system look and feel more unique. Extensibility on the web allows us to tailor the platform to our own needs, and experiment with outcomes.

CSS itself is becoming much more extensible…

CSS Houdini

With CSS Houdini, developers will be able to extend what’s currently possible in the CSS Object Model and teach the browser how they want it to read and render their CSS.

That means that things that weren’t previously possible on the web, like angled corners or round layout, now become possible.

If you’re not yet familiar with Houdini, it’s an umbrella term that describes a few different browser APIs, intended to improve browser performance. It makes styling more extensible and lets users dictate their own CSS features. Houdini’s current APIs include:

With these APIs, users can tap into meaningful semantic CSS (thanks to the Typed Object Model), and even apply semantics to their CSS variables (Properties and Values). With the Paint API, you can draw a canvas and have it applied as a border image (hello, gradient borders), or create animated sparkles that accept dynamic arguments and are implemented with a single line of CSS.

.sparkles {
  background: paint(sparkles)
}

You can build round menus without placing the items manually through margins (via the Layout API), and you can integrate your own interactions that live off of the main thread (using the Animation Worklet).

Houdini is definitely one to watch in the new year, and now is a great time to start experimenting with it if you haven’t yet.

Variable fonts

Another technology that falls in line with the goal of making websites more performant while offering more user extensibility is variable fonts. With so many new variable fonts popping up — and Google Fonts’ recent beta launch — variable fonts are now more available and easy to use than ever.

Variable fonts are vector-based and allow for a broad range of values to be set for various font axes, like weight and slant. The interpolation of these axes allows fonts to transition smoothly between points.

Here’s an example:

Variable fonts also allow for new axes to help designers and developers be even more creative with their work. Here’s an example of some of those from an excellent resource called v-fonts:

Variable fonts are relatively well supported, with 87% of modern browsers supporting the required font format.

Custom Properties

Custom properties, like variable fonts, are also well supported. While they’re not new, we’re still discovering all of the things we can do with custom properties.

Custom properties allow for truly dynamic CSS variables, meaning we can adjust them in JavaScript, separating logic and style. A great example of this comes from David Khourshid, who shows us how to create reactive animations and sync up the styling without sweating it.

We’re also starting to experiment with more logic in our stylesheets. I recently published a blog post that explains how to create dynamic color themes using the native CSS calc() function, along with custom properties.

This eliminates the need for additional tools to process our CSS, and ensures that this technique for theming works across any technology stack — which brings me to my next 2020 vision: interoperability.

Interoperability

Interoperability, by my definition in this post, means the ability to work between technologies and human needs. From a technical perspective, with the fragmented web, a lot of companies have migrated stacks in the recent past, or have multiple internal stacks, and are now likely interested in safeguarding their technology stack against future changes to maintain some semblance of uniformity.

Web components

Web components try to solve this problem by attacking the problem of component-based architecture from a web-standards perspective. The vision is to introduce a standard format that can be used with or without a library, benefiting the developer experience and establishing uniformity between components.

Each web component is encapsulated and works in modern browsers without dependencies. This technology is still evolving and I think we’ll see a lot of growth in 2020.

Logical properties

Logical properties challenge us to adjust our mental model of how we apply layout sizing on a page in order for us to make our pages more friendly across languages and reading modes. They allow for our layouts to be interoperable with user experiences.

In English, and other left-to-right languages, we think of the layout world in terms of height and width, and use a compass-type expression for margins, border, and padding (top, left, bottom, right). However if we style this way and then adjust the language to a right-to-left language, like Arabic, the padding-left of our paragraphs no longer means padding from the beginning of where we would read. This breaks the layout.

If you were to write padding-inline-start instead of padding-left, the padding would correctly swap to the other side of the page (the start of where one would be reading) when switching to the right-to-left language, maintaining layout integrity.

Preference media queries

Preference media queries are also on the rise, with more capability coming in 2020. They allow us to tailor our sites to work with people who prefer high contrast or dark mode, as well as people who prefer a less animation-heavy experience.

The upcoming preference media queries include:

In this video, I go over how to create a preference media query for dark mode, using custom properties for styling:

Runner up: Speed

Speed is also a topic I see as a big focus of the web world in 2020. Several of the technologies I mentioned above have the benefit of improving web performance, even if it isn’t the main focus (e.g. how variable fonts may reduce the total weight of fonts downloaded). Performance becomes increasingly important when we think about the next billion users coming online in areas where network speeds may be lacking.

In addition, Web Assembly, which is a wrapper that lets users write closer to the browser metal, is gaining popularity. I also foresee a lot more work with WebGL in the coming year, which uses similar techniques for advanced and speedy graphics rendering. Writing lower-level code allows for speedier experiences, and in some cases of WebGL, may be required to prevent advanced visualization from crashing our browsers. I think we’ll see these two technologies grow and see more WebGL demos in 2020.


The web is constantly evolving and that’s what makes it so exciting to be a part of. What do you see as a goal or technology to watch in 2020? Tell us in the comments!


The Web in 2020: Extensibility and Interoperability originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>
301879
Bidirectional Horizontal Rules in CSS https://css-tricks.com/bidirectional-horizontal-rules-in-css/ Fri, 25 Oct 2019 21:53:36 +0000 https://css-tricks.com/?p=297824 Say you have a <blockquote> and the design calls for a thick border along the left side. Well, you might not necessarily mean left side, but actually mean on the side of the start of the text.

That’s exactly …


Bidirectional Horizontal Rules in CSS originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>
Say you have a <blockquote> and the design calls for a thick border along the left side. Well, you might not necessarily mean left side, but actually mean on the side of the start of the text.

That’s exactly what CSS logical properties are meant to address, and Hussein Al Hammad has a nice article laying out some use cases, including the blockquote thing I mentioned above.

By using logical properties, you don’t have to mess around with manually writing selectors including [dir="rtl"] or needing to be aware of writing modes and such. The box model stuff (borders, padding, margin…) will adjust where it needs to be.

Hussein’s blockquote is a good baby step example for understanding of all this:

blockquote {
  /* Rather than... */
  border-left: 4px solid #aaa;
  padding-left: 1.75rem;

  /* You'd do... */
  border-inline-start: 4px solid #aaa;
  padding-inline-start: 1.75rem;
}

See the Pen
Logical properties demo: blockquote
by Hussein Al Hammad (@hus_hmd)
on CodePen.

Support is pretty good.

This browser support data is from Caniuse, which has more detail. A number indicates that browser supports the feature at that version and up.

Desktop

ChromeFirefoxIEEdgeSafari
8966No8915

Mobile / Tablet

Android ChromeAndroid FirefoxAndroidiOS Safari
10810710815.0-15.1

One thing that threw me off in the article is the term “Horizontal Rules.” First I imagined the <hr> element. Then I imagined wanting to reverse the direction of the design with logical properties. Usually an <hr> is just a line so horizontal direction doesn’t matter, but let’s say it’s like a shorter line along the edge where new lines start after wrapping.

We could draw the shorter line with backgrounds that cover different parts of the box model, then use logical properties where the padding applies. This is a pretty unique edge case, but it’s fun to fiddle with:

See the Pen
<hr>s that are direction aware kinda
by Chris Coyier (@chriscoyier)
on CodePen.

It would be even easier if we had logical gradients.

To Shared LinkPermalink on CSS-Tricks


Bidirectional Horizontal Rules in CSS originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>
297824
What’s New In CSS? https://css-tricks.com/whats-new-in-css/ Fri, 02 Nov 2018 22:44:06 +0000 http://css-tricks.com/?p=278395 Rachel hooks us up with what the CSS Working Group is talking about:

  • Styling scrollbars. This would come with properties like scrollbar-width and scrollbar-color. The best we have right now is proprietary WebKit stuff.
  • Aspect ratios. I imagine


What’s New In CSS? originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>
Rachel hooks us up with what the CSS Working Group is talking about:

  • Styling scrollbars. This would come with properties like scrollbar-width and scrollbar-color. The best we have right now is proprietary WebKit stuff.
  • Aspect ratios. I imagine the CSS portion of this journey will be best handled if it plays nicely with the HTML intrinsicsize stuff.
  • Matching without specificity. :where() is :matches() with no specificity, and :matches() may become :is().
  • Logical Properties shorthand. The team is discussing a shorthand syntax for Logical Properties and the possibility logical would be default over the current physical with a defined “mode” in the stylesheet.

To Shared LinkPermalink on CSS-Tricks


What’s New In CSS? originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>
278395
CSS Logical Properties https://css-tricks.com/css-logical-properties/ Tue, 21 Aug 2018 19:22:01 +0000 http://css-tricks.com/?p=275378 A property like margin-left seems fairly logical, but as Manuel Rego Casasnovas says:

Imagine that you have some right-to-left (RTL) content on your website your left might be probably the physical right, so if you are usually setting margin-left: 100px


CSS Logical Properties originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>
A property like margin-left seems fairly logical, but as Manuel Rego Casasnovas says:

Imagine that you have some right-to-left (RTL) content on your website your left might be probably the physical right, so if you are usually setting margin-left: 100px for some elements, you might want to replace that with margin-right: 100px.

Direction, writing mode, and even flexbox all have the power to flip things around and make properties less logical and more difficult to maintain than you’d hope. Now we’ll have margin-inline-start for that. The full list is:

  • margin-{block,inline}-{start,end}
  • padding-{block,inline}-{start,end}
  • border-{block,inline}-{start,end}-{width,style,color}

Manuel gets into all the browser support details.

Rachel Andrew also explains the logic:

… these values have moved away from the underlying assumption that content on the web maps to the physical dimensions of the screen, with the first word of a sentence being top left of the box it is in. The order of lines in grid-area makes complete sense if you had never encountered the existing way that we set these values in a shorthand.

Here’s the logical properties and how they map to existing properties in a default left to right nothing-else-happening sort of way.

Property Logical Property
margin-top margin-block-start
margin-left margin-inline-start
margin-right margin-inline-end
margin-bottom margin-block-end
Property Logical Property
padding-top padding-block-start
padding-left padding-inline-start
padding-right padding-inline-end
padding-bottom padding-block-end
Property Logical Property
border-top{-size|style|color} border-block-start{-size|style|color}
border-left{-size|style|color} border-inline-start{-size|style|color}
border-right{-size|style|color} border-inline-end{-size|style|color}
border-bottom{-size|style|color} border-block-end{-size|style|color}
Property Logical Property
top inset-block-start
left inset-inline-start
right inset-inline-end
bottom inset-block-end

To Shared LinkPermalink on CSS-Tricks


CSS Logical Properties originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>
275378