A very useful CSS tip to help you deal with various scenarios

A very useful CSS tip to help you deal with various scenarios

Problem background

When designing pages, we often encounter page layouts like this:

In the picture, there are multiple content blocks in a container, and each block has an underline at the bottom, but generally for aesthetics, the underline of the last content block is removed

Next, let's look at how to deal with this style under normal circumstances:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
    /* Here is the basic display style, you can ignore it*/
        .container{
            border: 1px solid black;
            border-radius: 10px;
            width: 300px;
            height: 500px;
            margin: 100px auto;
        }
        .child{
            margin: 0 auto;
            width: 200px;
            height: 98px;
            border-bottom: 1px solid rgb(172, 163, 163);
            line-height: 98px;
        }
        
       /* Here is the key style to see*/
        .last{
         border-bottom: 0;
        }
    </style>
</head>
<body>
    <div class="container"></div>

    <script>
        const elementList = ['I am content 1','I am content 2','I am content 3','I am content 4','I am content 5']
        const container = document.querySelector('.container')
        
       //Dynamically add child elements to the container
        elementList.forEach((v, i, a) => {
            const el = document.createElement('div')
           /* Determine whether the added child element is the last
             If yes, give a last class name
            */
            el.className = i == a.length-1?'child last':'child'
            el.innerHTML = v
            container.appendChild(el)
        })
    </script>
</body>
</html>

The above code, assuming we do not know the total number of sub-elements to be added to the container, we can only judge for themselves every time you add is the last, and if so, add a lastclass name for Clearborder-bottom

This is indeed completed to solve the problem, but there is a "defect" , that is, if after adding these content, and dynamically add more content to this container, the bottom of the last content block of the last time is not underlined as it is added to a lastclass name, this time is similar to "pull down to load more" such a scenario, let's look at a very simple simulation:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
       /* Here is the basic display style, you can ignore it*/
        .container{
            border: 1px solid black;
            border-radius: 10px;
            width: 300px;
            height: 500px;
            margin: 100px auto;
            overflow: scroll;
        }
        .child{
            margin: 0 auto;
            width: 200px;
            height: 98px;
            border-bottom: 1px solid rgb(172, 163, 163);
            line-height: 98px;
        }
       /* Here is the key style to see*/
        .last{
            border-bottom: 0;
        }
    </style>
</head>
<body>
    <div class="container"></div>

    <script>
        const container = document.querySelector('.container')
        const elementList = ['I am content 1','I am content 2','I am content 3','I am content 4','I am content 5']

        function debounce(fn, delay=500) {
            let timer = null
            return function(...args) {
                if(timer) clearTimeout(timer);
                timer = setTimeout(() => {
                    fn.apply(this, args)
                    clearTimeout(timer)
                }, delay)
            }
        }
       //Anti-shake processing
        let addMore = debounce(function(container, list) {
            list.forEach((v, i, a) => {
                const el = document.createElement('div')
                el.className = i == a.length-1?'child last':'child'
                el.innerHTML = v
                container.appendChild(el)
            })
        })

       //The first time the page loads, dynamically add content to the container
        addMore(container, elementList)

       //Add a scroll event to the container
        container.addEventListener('scroll', function() {
            addMore(container, elementList)
        })
        
    </script>
</body>
</html>

Let's see what happens when the container scrolls down:

It can be clearly seen in the above animation that every time a piece of content is loaded, the bottom of the last content block of the previous piece of content is not underlined, which is very unfriendly

Next, I will introduce a small CSS trick to solve the embarrassment of the above problem.

solution

Here you can use css of "brothers selector" , that is element1 + element2, it represents the choice element1after all at the same levelelement2

Let's take a look at the specific code implementation:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
       /* Here is the basic display style, you can ignore it*/
        .container{
            border: 1px solid black;
            border-radius: 10px;
            width: 300px;
            height: 500px;
            margin: 100px auto;
            overflow: scroll;
        }
        .child{
            margin: 0 auto;
            width: 200px;
            height: 98px;
            line-height: 98px;
        }
       /* Here is the key style to see*/
        .child + .child {
            border-top: 1px solid rgb(172, 163, 163);
        }
    </style>
</head>
<body>
    <div class="container"></div>

    <script>
        const container = document.querySelector('.container')
        const elementList = ['I am content 1','I am content 2','I am content 3','I am content 4','I am content 5']

        function debounce(fn, delay=500) {
            let timer = null
            return function(...args) {
                if(timer) clearTimeout(timer);
                timer = setTimeout(() => {
                    fn.apply(this, args)
                    clearTimeout(timer)
                }, delay)
            }
        }
       //Anti-shake processing
        let addMore = debounce(function(container, list) {
            list.forEach((v, i, a) => {
                const el = document.createElement('div')
                el.className ='child'
                el.innerHTML = v
                container.appendChild(el)
            })
        })

       //The first time the page loads, dynamically add content to the container
        addMore(container, elementList)

       //Add a scroll event to the container
        container.addEventListener('scroll', function() {
            addMore(container, elementList)
        })
        
    </script>
</body>
</html>

The above code .child + .childindicating the selection class called childall the same level of class named after the childelements, so the first class named childelement can not be selected to, so in order to achieve the desired effect, we choose to select to each Element settings border-top, so that the desired effect is achieved, and even if more elements are dynamically added later, there will be no problem

Effectiveness verification:

summary

Briefly summarize the "advantages" of the CSS tips introduced in this article :

  1. Make the project code more concise
  2. Will not have redundant class names like traditional processing methods
  3. Elements that can adapt to dynamic changes

I hope this little trick is helpful to you. If there are other more ingenious methods, you can comment and tell me~

Reference: https://cloud.tencent.com/developer/article/1762195 A very useful CSS tip to help you deal with various scenarios-Cloud + Community-Tencent Cloud