123Hello
123Hello

Reputation: 43

How to make background color transition gradually into another color?

I would like to make my website's background to form a gradient from green at the top to blue halfway down the page, with a smooth gradient between the two colors.

How can I achieve this?

The top of the website is green and halfway down it changes to blue, like this:

website background color changes halfway down

Upvotes: 3

Views: 646

Answers (4)

Vladi Ciuperca
Vladi Ciuperca

Reputation: 1

You have to use a bit of JavaScript, because the browser treats the linear gradient background as an image, so for example transition: 1s won't work.

It can seem complicated, but I promise it's easyer than it looks:

// so the idea is taht u take the RGB values fomr an array on objects

// u can add as many sections as u want, i used 2
//editing these values changes the color

// the alkgorithm works by itself,
//  the only thing u have to modify ill show it later with a ##!imporant!## flag

//if i let some italian in my code, i apologize and say MAMMA MIA  :T

let info = [
    {
        bg: [0, 255, 76, 251, 255, 0],
        // "bg": "linear-gradient(0deg, rgb(0, 255, 76) 0%, rgb(251, 255, 0) 100%)"
    },
    {
        bg: [251, 255, 0, 0, 255, 76],
        // "bg": "linear-gradient(0deg, rgb(251, 255, 0) 0%, rgb(0, 255, 76) 100%)"
    },
    {
        bg: [253, 101, 0, 241, 0, 0],
        // "bg": "linear-gradient(0deg, rgb(253, 101, 0) 0%rgb(241, 0, 0)1) 100%)"
    },
    {
        bg: [255, 0, 0, 22211, 8, 193],
        // "bg": "linear-gradient(0deg, rgb(255, 0, 0) 0%, rgb(221, 8, 193) 100%)"
    },
    {
        bg: [255, 255, 255, 0, 0, 0],
        // "bg": "linear-gradient(0deg, rgb(255, 255, 255) 0%, rgb(0, 0, 0) 100%)"
    },
    {
        bg: [0, 0, 0, 255, 255, 255],
        // "bg": "linear-gradient(0deg, rgb(0, 0, 0) 0%, rgb(255, 255, 255) 100%)"
    },
];

let buttons = document.getElementsByClassName("btn");
let mainCont = document.getElementById("main_container");
let asdBtn = document.getElementById("asd");
let debug = document.getElementById("debug");
let debug_container = document.getElementById("debug_container");
let second_debug = document.getElementById("second_debug");
let indexImg = 0;
let shiftIndex
let step
let BgIndex = info[indexImg].bg;
let colorClass = []
let arrowClass = []

//-----// ##!important!## //-----//
// so this the only thing u ahve to edit if u want more RGB sections
// its 2 values per RBG section, i used 2 so its gon be 6
//heare i named them "val" but they essentially are (RED GREEN BLUE) and again (RED GREEN BLUE)
function getBg(val1, val2, val3, val4, val5, val6) {
    mainCont.style.background = ` linear-gradient(0deg, rgba(${val1},${val2},${val3}) 0%, rgba(${val4},${val5},${val6},1) 100%) `;
    return;
}


//-----// heare u call the function that converts the values in the linear gradient string //-----//
getBg(BgIndex[0], BgIndex[1], BgIndex[2], BgIndex[3], BgIndex[4], BgIndex[5]);



[...buttons].forEach((singleButton) => {
    singleButton.addEventListener("click", function () {


        if (singleButton.classList.contains("next")) {
            // click su next
            // i save shift index, this gon be the start and the new imageindex gon be the target
            shiftIndex = indexImg
            if (indexImg == info.length - 1) {
                indexImg = 0;
            } else {
                indexImg++;
            }
        }

        else if (singleButton.classList.contains("prev")) {
            // melo risalvoi anche qua?
            shiftIndex = indexImg
            if (indexImg == 0) {
                indexImg = info.length - 1;
            } else {
                indexImg--;
            }
        }
        // heare i call the function and i pass the "startPoint and the "target"
        changevalues(shiftIndex, indexImg)



    });
});


let startBG;

let DebIndex = info[2].bg;

function clearAllTimers() {
    // Clear all timeouts
    let id = setTimeout(() => { }, 0);
    while (id--) {
        clearTimeout(id);
        clearInterval(id);
    }
}


function changevalues(startIndex, TargetIndex) {

    clearAllTimers();

    startBG = info[startIndex].bg;
    let targetBG = info[TargetIndex].bg;
    let tempBG = startBG.slice();

    console.log("start is", startBG);
    console.log(targetBG);

    let timeoutId;

    function loop() {
        // u need this to stop the loop
        let reachedTarget = true;

        tempBG.forEach((index, x) => {
            if (index !== targetBG[x]) {
                reachedTarget = false;

                if (index < targetBG[x]) {
                    // step gotta slow down when closer to target, so it wont bug on odd numbers
                    //the step is the "lenght" of the step it makes every 10ms from a color to another
                    if ((targetBG[x] - tempBG[x]) < 5) {
                        step = 1
                    }
                    else {
                        step = 2
                    }
                    tempBG[x] += step;
                    colorClass[x] = "green"
                    arrowClass[x] = "fa-arrow-up"

                } else if (index > targetBG[x]) {
                    // step gotta slow down when closer to target, so it wont bug on odd numbers
                    if ((tempBG[x] - targetBG[x]) < 5) {
                        step = 1
                    }
                    else {
                        step = 2
                    }
                    tempBG[x] -= step;
                    colorClass[x] = "red"
                    arrowClass[x] = "fa-arrow-down"
                }
            }
        });


        // dont mind all this, this just 4 debug windows
        debug.innerHTML = `
            <span class="red">R1:<span class="value "> <span class="color_value">${tempBG[0]}</span><i class=" appear arrow ${colorClass[0]} fa-solid ${arrowClass[0]}"></i></span></span>
            <span class="green">G1:<span class="value"> <span class="color_value">${tempBG[1]}</span><i class=" appear arrow ${colorClass[1]} fa-solid ${arrowClass[1]}"></i></span></span>
            <span class="blue">B1:<span class="value"> <span class="color_value">${tempBG[2]}</span><i class=" appear arrow ${colorClass[2]} fa-solid ${arrowClass[2]}"></i></span></span>
            <div>-----------</div>
            <span class="red">R2:<span class="value"> <span class="color_value">${tempBG[3]}</span><i class=" appear arrow ${colorClass[3]} fa-solid ${arrowClass[3]}"></i></span></span>
            <span class="green">G2:<span class="value"> <span class="color_value">${tempBG[4]}</span><i class=" appear arrow ${colorClass[4]} fa-solid ${arrowClass[4]}"></i></span></span>
            <span class="blue">B2:<span class="value"> <span class="color_value">${tempBG[5]}</span><i class=" appear arrow ${colorClass[5]} fa-solid ${arrowClass[5]}"></i></span></span>
            <div class="d_flex"><div>prev.BG<div>${shiftIndex + 1}</div></div>
            <div>target.BG<div>${indexImg + 1}</div></div></div> `
        // dont mind all this, this just 4 debug windows
        second_debug.innerHTML = `
        <span>Real Time generated background string:</span>
        <div id="bg_string"> "linear-gradient(0deg, rgba(
            <span class="${colorClass[0]} string_value">${tempBG[0]}</span>,
            <span class="${colorClass[1]} string_value">${tempBG[1]}</span>,
            <span class="${colorClass[2]} string_value">${tempBG[2]}</span>) 0%, rgba(
            <span class="${colorClass[3]} string_value">${tempBG[3]}</span>,
            <span class="${colorClass[4]} string_value">${tempBG[4]}</span>,
            <span class="${colorClass[5]} string_value">${tempBG[5]}</span>) 100%)"
        </div>`



        // dont mind all this, this just 4 debug windows
        let color_value = document.getElementsByClassName("color_value");
        let arrows = document.getElementsByClassName("arrow");
        let str_values = document.getElementsByClassName("string_value");
        [...color_value].forEach((element, x) => {
            if (element.innerHTML == targetBG[x]) {
                arrows[x].classList.remove("appear")
                str_values[x].classList.remove("red", "green")
            }
        });


        getBg(tempBG[0], tempBG[1], tempBG[2], tempBG[3], tempBG[4], tempBG[5]);



        if (reachedTarget) {
            // u clear the timeout when u reached target
            clearTimeout(timeoutId);
        } else {
            // untill target not reached u keep launching
            timeoutId = setTimeout(loop, 10);
        }

    }
    // kickstart the function
    loop();
}


// this is 4 debug too dont mind it
asdBtn.addEventListener("click", function () {
    if (debug_container.classList.contains("appear")) {
        debug_container.classList.remove("appear")
    }
    else {
        debug_container.classList.add("appear")
    }
    if (second_debug.classList.contains("attiva")) {
        second_debug.classList.remove("attiva")
    }
    else {
        second_debug.classList.add("attiva")
    }
})
/* body {
    background: linear-gradient(0deg, rgba(189,169,96) 0%, rgba(72,73,0,1) 100%); 
} */
.d_flex {
    display: flex;
    margin-top: 10px;
    justify-content: space-between;
}

.arrow {
    font-size: 14px;
    padding-left: 2px;
    transform: scale(0);
}
.str_values{
    color: black;
}
#debug_container {
    display: flex;
    position: absolute;
    border: 2px solid green;
    top: -150px;
    left: 50%;
    transform: translate(-50%);
    padding: 1rem;
    background: rgba(245, 245, 245, 0.39);
    transition: .5s;
    border-radius: 10px;
    text-align: center;
}
#second_debug {
    position: absolute;
    left: 50%;
    transform: translate(-50%);
    bottom: 0;
    border: 2px solid green;
    border: 2px solid green;
    transition: .5s;
    padding: 1rem;
    border-radius: 10px;
    background: rgba(245, 245, 245, 0.39);
    text-align: center;
    bottom: -150px;
}

#bg_string{
    margin-top: 10px;
}

#asd {
    position: absolute;
    top: 10px;
}


.red {
    color: red !important;
}

.white {
    color: white !important;
}



.green {
    color: green !important;
}



.value {
    color: black;
    transition: .5s;
}

.appear {
    top: 10px !important;
}

* {
    box-sizing: border-box;
    margin: 0;
    padding: 0;
    font-family: Geneva, Verdana, sans-serif;
}

#main_container {
    transition: 1s;
    height: 100vh;
    display: flex;
    justify-content: center;
    align-items: center;
}



button {
    margin: 0 2rem;
    border: 2px solid rgba(255, 255, 255, 0.418);
    width: 60px;
    aspect-ratio: 1;
    border-radius: 50%;
    cursor: pointer;
    background: rgba(255, 255, 255, 0.192);
}

i {
    font-size: 3rem;
    color: rgba(255, 255, 255, 0.411);
}
<!DOCTYPE html>
<html lang="en">

<head>
    <link rel="shortcut icon" href="#">
    <meta charset="UTF-8">
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.7.2/css/all.min.css"
        integrity="sha512-Evv84Mr4kqVGRNSgIGL/F/aIDqQb7xQ2vcrdIwxfjThSH8CSR7PBEakCr51Ck+w+/U6swU2Im1vVX0SVk9ABhg=="
        crossorigin="anonymous" referrerpolicy="no-referrer" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="CSS/style.css">
    <title>Document</title>
</head>

<body>

    <button id="asd">debug</button>
    <div id="debug_container">
        <div id="debug">
            <span class="red">R1:
                <span class="value">__</span>
            </span>
            <span class="green">G1:
                <span class="value">__</span>
            </span>
            <span class="blue">B1:
                <span class="value">__</span>
            </span>
            <div>-----------</div>
            <span class="red">R2:
                <span class="value">__</span>
            </span>
            <span class="green">G2:
                <span class="value">__</span>
            </span>
            <span class="blue">B2:
                <span class="value">__</span>
            </span>
            <div class="d_flex">
                <div>
                    prev.BG
                    <div>___</div>
                </div>
                <div>
                    target.BG
                    <div>___</div>
                </div>
            </div>
        </div>
    </div>
    <div id="second_debug">
        <span>Real Time generated background string:</span>
        <div id="bg_string">___</div>
    </div>
    <!-- asd -->
    <div id="main_container">

        <button class="btn prev">
            <i class="fa-solid fa-circle-chevron-left"></i>
        </button>

      

        <button class="btn next">
            <i class="fa-solid fa-circle-chevron-right"></i>
        </button>


    </div>

</body>
<script type="text/javascript" src="JS/myscript.js"></script>

</html>

Upvotes: 0

Hiren Gabu
Hiren Gabu

Reputation: 85

body {
  background-image: linear-gradient(to top, green 50%, blue 50%);
  background-size: 100%;
  transition: background-position .5s;
  background-position: 0;
  border: none;
}

Upvotes: 0

Ghost
Ghost

Reputation: 5049

Super easy, use linear-gradient(), also add background-attachment:fixed; to make sure that the gradient isn't repeating.

body {
    background-image: linear-gradient(#d3ff6e, #00faff); /* customize colors here */
    background-attachment: fixed; 
}
<html>
    <body></body>
</html>

If you want to make the yellow color a bit more visible, add a percentage after the color like below:

body {
    background-image: linear-gradient(#d3ff6e 35%, #00faff); /* customize colors here */
    background-attachment: fixed; 
}
<html>
    <body></body>
</html>

Upvotes: 2

Eigen
Eigen

Reputation: 53

Not sure if this is what you need as there is no picture attached.

But try this:

<!DOCTYPE html>
<html>
<head>
    <style>
        body {
            margin: 0;
            height: 100vh;
            display: flex;
            align-items: center;
            justify-content: center;
            animation: colorshift 5s infinite;
            font-family: Arial, sans-serif;
        }

        @keyframes colorshift {
            0% {background: #eee;}
            50% {background: #000;}
            100% {background: #eee;}
        }

        h1 {
            color: white;
        }
    </style>
</head>
<body>
    <h1>Welcome to my website!</h1>
</body>
</html>

If this isn't what you need, please be more precise in formulating your question.

Upvotes: 0

Related Questions