Ahmad Shadeed

Have a dream, have dry goods, wechat search [big Move the world] pay attention to this in the early morning is still in the bowl washing wisdom.

In this paper, making github.com/qq449245884… Has been included, a line of large factory interview complete test sites, information and my series of articles.

Many times, we want to have a way to avoid a certain CSS problem or behavior. We know that web content is dynamic and that things on a page can change, increasing the likelihood of CSS problems or strange behavior.

Defensive CSS is a collection of fragments that help me write protected CSS. In other words, there will be more bugs.

1. Flexbox package

CSS Flexbox is one of the most useful CSS layout features available today. Add display: flex to a wrapper to sort the children next to each other.

The problem is that when space runs out, those children won’t be wrapped into a new row by default. We need to change this behavior with flex-wrap: wrap.

Here is a typical example.

.options-list {
    display: flex;
}
Copy the code

Horizontal scrolling occurs when there is less space. This should be expected and is not actually a “problem”.

.options-list {
    display: flex;
    flex-wrap: wrap;
}
Copy the code

When using Flexbox, the general rule of thumb is to allow packages unless you want a rolling package. That’s another story, but try to use flex-wrap to avoid unexpected layout behavior (in our case, horizontal scrolling).

Distance between 2.

We developers need to consider different lengths of content. This means that spacing should be added to the component even if it doesn’t seem necessary.

In this case, we have a section title and an action button on the right. So far, it looks good. But what happens if the headline is longer?

Notice that the text is too close to the button? Here, you might want to think about multiple line feeds, but for now, let’s focus on spacing.

If the title has Spaces and text truncation, we don’t see this problem.

.section__title {
    margin-right: 1rem;
}
Copy the code

3. Long content

When building a layout, it is important to consider long content. As you saw earlier, section titles are truncated when they are too long. This is optional, but it is important to take this into account for some UIs.

To me, this is a defensive CSS approach. It’s good to solve a “problem” before it actually happens.

Here’s a list of names that now look perfect

However, since this is user-generated content, we need to be careful how we defend the layout in case some content is too long. See the picture below:

Consistency is very important in this layout. To do this, we can simply truncate the name using text-overflow and its friends.

4. Prevent the image from being stretched or compressed

If the user uploads an image that doesn’t match the aspect ratio, it’s best to think ahead and provide a solution if you can’t control the aspect ratio.

In the example below, we have a card component with a photo. It looks good.

When the user uploads an image of a different size, it will be stretched. That’s not a good thing. See how the image is stretched!

The easiest way to fix this is to use CSS Object-Fit.

.card__thumb {
    object-fit: cover;
}
Copy the code

At the project level, I tend to add Object-fit to all images to avoid unexpected results.

5. Lock scroll links

Have you ever opened a mode and started scrolling, and then when you reached the end and continued scrolling, the content below the mode (the body element) would scroll? This is called a rolling chain.

By default, mobile browsers tend to provide a “bottoming” effect and even refresh the page when reaching the top or bottom of the page (or any other scrollable area). You may also have noticed that when a dialog box contains scrollable content, once you scroll to the edge of the dialog box, the content of the page below the dialog box also begins to scroll — this is called a “scroll chain.” .

Over the years, there have been some dark technologies to do this, but for now, we just need to use CSS, thanks to the overscroll-behavior CSS property.

In the figure below, you can see the default scrolling link behavior.

To avoid this in advance, we can add it to any component that needs scrolling (e.g. : chat component, move menu… , etc.). The nice thing about this property is that it doesn’t matter until there is scrolling.

.modal__content {
    overscroll-behavior-y: contain;
    overflow-y: auto;
}
Copy the code

6. The CSS variables are rolled back

CSS variables are increasingly used in web design. We can apply a way to use CSS variable values in a way that doesn’t spoil the experience in cases where they are empty for whatever reason.

This is especially useful when entering the values of CSS variables through JS. Here’s an example:

.message__bubble {
    max-width: calc(100% - var(--actions-width));
}
Copy the code

The variable –actions-width is used in the calc() function, and its value comes from JS. Suppose JS fails for some reason, what happens? Max-width is computed to zero.

We can avoid this in advance by adding a fallback value to var().

.message__bubble {
    max-width: calc(100% - var(--actions-width, 70px));
}
Copy the code

Thus, if the variable is not defined, a fallback (70px) is used. This approach can be used in situations where a variable might fail.

7. Use a fixed width or height

One of the most common ways to break a layout is to use a fixed width or height for an element that has content of different lengths.

Fixed height

I often see that the main content section has a fixed height and the content is larger than that, which leads to layout destruction. As follows:

.main {
    height: 350px;
}
Copy the code

To avoid this, use min-height instead of height:

A fixed width

Have you ever seen a button with a label too close to the left and right edges? This is due to the use of fixed widths.

.button {
    width: 100px;
}
Copy the code

If the button’s label is larger than 100px, it will be near the edge. If it’s too long, the text will leak out. This is not good!

To solve this problem, we can simply use min-width instead of width.

.button {
    min-width: 100px;
}
Copy the code

8. Forget background – Repeat

A lot of times, when using a large image as a background, we forget to consider the design when viewed on a large screen. The background will be repeated by default.

This is something you don’t see on most laptop screens, but it’s common on big screens.

To avoid this behavior in advance, be sure to reset background-repeat.

.hero { background-image: url('.. '); background-repeat: no-repeat; }Copy the code

9. Vertical media query

Sometimes it’s tempting to build a component that tests only by adjusting the width of the browser. Testing against the height of the browser can reveal some interesting issues.

Here’s an example THAT I’ve seen many times. We have a component with primary and secondary links. The secondary link should be at the bottom of the voice-over section.

Consider the following example. The main and secondary navigation looks good. In the example I saw, the developer added position: sticky to the secondary navigation so it would stick to the bottom.

However, if the height of the browser is smaller, a bug can occur. Notice how the two navigations overlap.

We can avoid this problem by using CSS vertical media queries.

@media (min-height: 600px) { .aside__secondary { position: sticky; bottom: 0; }}Copy the code

This way, secondary navigation is stuck to the bottom only if the viewport height is 600px or greater. Much better, right?

There are probably better ways to implement this behavior (such as using margin-Auto), but in this case focus on vertical queries.

10. Use the justify – the content: the space between

In a Flex container, we might use context-content to provide some spacing between subitems. If you have a certain number of subprojects, the layout looks good. However, as they increase or decrease, the layout can look strange.

Consider the following example:

We have a Flex container with four projects. The spacing between each item is not gap or margin, it exists because the container has context-content: space-between.

.wrapper {
    display: flex;
    flex-wrap: wrap;
    justify-content: space-between;
}
Copy the code

When the number of items is less than 4, the following happens:

This is not a good thing. There are different solutions to this:

  • margin
  • Flexbox Gap (Use with caution)
  • Padding (Parent element that can be applied to each child element)
  • Add an empty element as an interval.

For simplicity, I use gap.

.wrapper {
    display: flex;
    flex-wrap: wrap;
    gap: 1rem;
}
Copy the code

11. The text on the picture

When placing text on an image, you must take into account that the image will not load. What the text will look like. Here’s an example:

The text looks readable, but when the image fails to load, its readability becomes poor.

We can easily solve this problem by adding a background color to the element. This background is only displayed if the image fails to load.

12. Be careful of fixed values in the CSS grid

Suppose we have a grid containing aside and main. CSS looks like this:

.wrapper {
    display: grid;
    grid-template-columns: 250px 1fr;
    gap: 1rem;
}
Copy the code

This can be problematic at small viewport sizes due to lack of space. To avoid such problems, be sure to use media queries when using the CSS grid described above.

@media (min-width: 600px) { .wrapper { display: grid; grid-template-columns: 250px 1fr; gap: 1rem; }}Copy the code

13. Display scrollbars only when needed

We can control the display of scroll bars or not just in the case of long content. However, it is strongly recommended to use auto as the overflow value. Consider the following example:

Note that there is a scrollbar visible even if the content is short. That’s not good for a user interface. As a user, it can be confusing to see scrollbars when you don’t need them.

.element {
    overflow-y: auto;
}
Copy the code

With overflow-y: auto, the scroll bar is visible only if the content is long. Otherwise, it does not display.

14.Scrollbar Gutter

Another thing that has to do with scrolling is the Scrollbar Gutter. As in the previous example, adding a scrollbar causes the layout to shift as the content gets longer. The layout move occurs because there is space left for the scrollbar.

The Scrollbar Gutter is the space between the inner border edge and the outer fill edge. For a classic Scrollbar, the Scrollbar Gutter has the same size as the width of the Scrollbar. These scrollbars are usually opaque and take up some space from adjacent content.

See the picture below:

Notice how the scroll bar is shown and how it shifts as the content gets longer. We can avoid this behavior by using the scrollbar-gutter attribute.

.element {
    scrollbar-gutter: stable;
}
Copy the code

15. Minimum content size in CSS Flexbox

If text elements or images in a Flex project are larger or longer than the project itself, the browser will not zoom them out. This is the default behavior of Flexbox. Consider the following example:

.card {
    display: flex;
}
Copy the code

When a header has a long word, it is not wrapped in a new line.

Even if we use overflow-wrap: break-word, it won’t work.

.card__title {
    overflow-wrap: break-word;
}
Copy the code

To change this default behavior, we need to set the Min-width of the Flex project to 0. This is because the default value of min-width is auto, and overflow occurs.

.card__title {
    overflow-wrap: break-word;
    min-width: 0;
}
Copy the code

The same applies to flex-direction:column layouts, using min-height: 0.

16. Minimum content size in CSS grid

Like Flexbox, CSS Grid has a default minimum content size for its subprojects, auto. This means that if there is an element larger than the grid item, it will overflow.

In the example above, we have a Carousel in the main section.

<div class="wrapper">
    <main>
        <section class="carousel"></section>
    </main>
    <aside></aside>
</div>
Copy the code
@media (min-width: 1020px) {
    .wrapper {
        display: grid;
        grid-template-columns: 1fr 248px;
        grid-gap: 40px;
    }
}

.carousel {
    display: flex;
    overflow-x: auto;
}
Copy the code

Since Carousel is a Flex layout, there is no line breaking by default when content is exceeded, so horizontal scrolling occurs.

To solve this problem, we have three different solutions:

  • useminmax()
  • willmin-widthApply to grid projects
  • Add to the networkoverflow: hidden

As a defensive CSS mechanism, I would choose the first, which is to use the minmax() function.

@media (min-width: 1020px) { .wrapper { display: grid; grid-template-columns: minmax(0, 1fr) 248px; grid-gap: 40px; }}Copy the code

  1. Auto Fit Vs Auto Fill

When using the CSS grid minmax() function, it is important to decide whether to use the auto-fit or auto-fill keyword. Once used improperly, it can lead to unexpected results.

When using the minmax() function, the auto-fit keyword expands the grid project to fill the available space. Auto-fill will preserve the available space without changing the width of grid items.

That said, using auto-fit can cause grid projects to be too wide, especially if they are smaller than expected. Consider the following example.


The possible bugs in editing can not be known in real time. In order to solve these bugs after the event, I spent a lot of time on log debugging. By the way, I recommend a good bug monitoring tool for youFundebug.

Forgive: ishadeed.com/article/def…

communication

Have a dream, have dry goods, wechat search [big Move the world] pay attention to this in the early morning is still in the bowl washing wisdom.

In this paper, making github.com/qq449245884… Has been included, a line of large factory interview complete test sites, information and my series of articles.