Today I Learned

17 posts by krzysztofgolasik

Be careful about CSS shorthand properties

It’s always better to set certain property instead of using shorthand unless you exactly know what you’re doing.

Example:

  /*doesn't work*/
  background-repeat: no-repeat
  background-position: center
  background: url('http://someurl.jpg')


  /* works*/
  background-repeat: no-repeat
  background-position: center
  background-image: url('http://someurl.jpg')

  /* also works*/
  background: url('http://someurl.jpg')
  background-repeat: no-repeat
  background-position: center

Why?

background-image sets only image as a background

background property on the other hand sets all of these things:

  • background-attachment
  • background-clip
  • background-color
  • background-image
  • background-origin
  • background-position
  • background-repeat
  • background-size

If you don’t specify them intentionally those would be set to their default or unset value

Codepen: link

This is the same case as:

/* won't work - results in right margin to be 8px */
margin-right: 16px
margin: 8px

/* works */
margin: 8px
margin-right: 16px

What other shorthand properties should you be also careful about?

Those:

image

MDN source

Omit additional wrappers in CSS, display: contents;

In situation where you want to style elements like those were neighbours, but unfortunately two of them are in additional wrapper that you can’t get rid of:

<div class="flex">
  <div class="red-block"></div>
  <div class="wrapper">
    <div class="el">1</div>
    <div class="el">2</div>
  </div>
</div>

and you want them to be inside flex and be placed by eg. space-between and this is the result:

image

Add display: contents; to the wrapper and problem is solved: image

display: contents makes the element to ignore itself in styling.

Browser support: image

Codepen: here

Chrome CSS overview feature

What CSS overview is: new experimental feature, gives overview of CSS used on a site: what colors are used, different fonts and font-sizes, media-queries and lists some unused declarations (declaration that is in CSS but doesn’t affect the element in any way).

image image image image image

To enable this feature in Chrome:

  1. Open devtools
  2. Go to settings (cog icon)
  3. Open experiments tab
  4. Check CSS Overview

CSS user preferences media queries

We can aim user preferences by specific media queries which allows for example to read system color scheme:

@media (prefers-color-scheme: dark) {
   /* some styling */
}

Or also we can read if user prefers reduced motion

@media (prefers-reduced-motion) {
  /* ... */
}

Those two already have big browser support, in near future we can expect also: prefers-reduced-transparency, prefers-contrast and prefers-reduced-data

CSS - Element not perfectly centered

Sometimes you can notice that your element is not perfectly centered, doesn’t matter what centering method you use.

Most likely the reason is:

  • one element has even amount of pixels in size
  • second element has odd amount of pixels

Example:

  • Centering 40px element in 45px container
  • Centering 41px element in 46px container

Browser cannot split pixels in half!

image Link with examples

Setting half pixels won’t solve this issue

Half pixels only works for some browsers

Half pixels example

Safari half sticky element problem

Safari has weird bug about sticky elements in flexboxes, those sticky elements get scrolled after a while - more like in the half of the scrollbar, which is pretty confusing.

Problem:

Link

Open the link in the Safari, scroll the mid (yellow) section and notice that green bar (sticky element) gets also scrolled after a while.

Desktop elements

The problem is that in Safari sticky element cannot be flex item (direct child of a flex) whenever the sticky element is not the only child of a flex and the neighbour of sticky element has specified flex-shrink or flex-basis .

Solution:

Link

Simply add one additionalwrapper for sticky element and the problem should be solved :)

matchMedia - JS media queries

Instead of trying to copy media queries functionality in Javascript by using window.innerWidth or installing external packages for that.

Just simply use window.matchMedia which does exactly what you are looking for

if (window.matchMedia('all and (max-width: 767px)').matches) { 
  console.log('do something');
}

It works exactly like CSS media queries and has 100% browser support.

Fix for margin hell that affects your app container

Your app container has:

max-height: 100vh;

But your page still have a scroll

Whenever you hover over <body> you will see that it’s slightly off the top of the page. Suprisingly it has also margin: 0; The problem is that the children of your app container have some margins and it’s too much work the get rid all of them.

To fix the issue add to your app container:

display: flow-root;

grid/table/flex also works but only the flow-root keeps the block behaviour.

NOTE It doesn’t work on IE and some other browsers you don’t care about :)

Test it out: Link

SASS - Comments indent matters

As you might know, SASS has pretty nice nesting feature:

.selector
  color: red
  font-size: 12px

and SASS allows you to put comments, but beware of your comment indent because:

This looks completely fine in this IDE right?!

Yeah… but how does compiler see that?

… Boom!

.dark-theme
 // variables 
  @import 'base/dark-variables'

 // fonts
  @import 'fonts/dark'

Gray gradients on Safari

On Safari browsers gradients that includes transparent color might seem to be more gray(ish) than on other devices:

Typical look: Typical look

IOS mobile: Gray Safari look The mid part seems to be gray instead of light red.

So you have styles as follows:

.a {
  background-image: linear-gradient(#f00, transparent);
}

.b {
  background-image: linear-gradient(#f00, rgba(0,0,0,0));
}

.c {
  background-image: linear-gradient(#f00, #00F0);
}

.d {
  background-image: linear-gradient(#f00, #f000);
}

Which result on desktop is: Desktop elements

But on IOS mobile devices: Safari elements

As you might have already noticed, IOS cuts out the alpha part from color and use it like a mid-gradient part.

In case A and B it would be #000 (black)

In case C it would be #00F (blue)

In case D it would be #F00 (red) which is a result we expected from the beginning.

Codepen if you want to test it on your own: Link

ReactDatePicker Day off in Summer time issue

If you’re using react-datepicker, and the last time you’ve tested your date-picker was in winter time or sooner, please check if your date-picker still works properly.

Issue:

<DatePicker
  dateFormat="DD/MM/YYYY"
  onChange={val => this.setValue(input, val)}
  selected={input.value ? moment(input.value) : null}
  />

Seems pretty basic, right?

Date displayed:

React-date-picker displayed value

Real value:

Real value of date-picker

Solution:

Add

utcOffset={0}

to props in your react-date-picker.

<DatePicker
  dateFormat="DD/MM/YYYY"
  onChange={val => this.setValue(input, val)}
  selected={input.value ? moment(input.value) : null}
  utcOffset={0}
  />

You can read more about this issue Here.

Unicode special characters on IOS Mobile Safari

Issue

I’ve created custom checkbox using unicode checkmark: ✔️

Checkbox looks like this: Safari checkbox It looks the same on every browser/device except IOS mobile Safari, where it looks as following: Safari checkbox The problem is that both screens presents unchecked state, but on IOS Safari it looks more like it’s checked.

It turned out, that mobile Safari is the only one which translates ✔️ into emoji, which colors cannot be changed in any way.

Solution

To prevent Safari from translating special symbols into emoji add Variation Selector-16:

For HTML like this:

<p>✔&#fe0e;</p>

For CSS content like this:

content: '✔\fe0e'  

Where fe0e is mentioned above: Varation-selector-16. This variation code can be found Here