Asked  7 Months ago    Answers:  5   Viewed   16 times

$("#toggle").click(function(){
    $("html").toggleClass("bg");
});
html.bg {
    background: blue;
}

body {
    background: yellow;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<!DOCTYPE html>
<html class="bg">
<head>
</head>

<body>
    Test
    <br>
    <button id="toggle">Toggle HTML background</button>
</body>
</html>

I found that if you apply a CSS background to body, it takes up the whole page (no matter what the actual height or width of body is).

However, if you apply a CSS background to both html and body, the background for body does not take up the whole page.

Is this discrepancy expected behavior?

How would I go about superimposing two fullscreen backgrounds (say, a background color and a semi-transparent image?)

 Answers

29

This is correct behavior.1 In standards mode, body, as well as html, doesn't immediately take up the entire height of the viewport, even though it appears so when you only apply a background to the latter. In fact, the html element will take on the background of body if you don't give it its own background, and html will pass this on to the canvas:

The background of the root element becomes the background of the canvas and its background painting area extends to cover the entire canvas, although any images are sized and positioned relative to the root element as if they were painted for that element alone. (In other words, the background positioning area is determined as for the root element.) If the root's ‘background-color’ value is ‘transparent’, the canvas's background color is UA dependent. The root element does not paint this background again, i.e., the used value of its background is transparent.

For documents whose root element is an HTML HTML element or an XHTML html element: if the computed value of ‘background-image’ on the root element is ‘none’ and its ‘background-color’ is ‘transparent’, user agents must instead propagate the computed values of the background properties from that element's first HTML BODY or XHTML body child element. The used values of that BODY element's background properties are their initial values, and the propagated values are treated as if they were specified on the root element. It is recommended that authors of HTML documents specify the canvas background for the BODY element rather than the HTML element.

That said, however, you can superimpose any background image over a background color on a single element (either html or body), without having to rely on two elements — simply use background-color and background-image or combine them in the background shorthand property:

body {
    background: #ddd url(background.png) center top no-repeat;
}

If you wish to combine two background images, you need to rely on multiple backgrounds. There are chiefly two days to do this:

  • In CSS2, this is where styling both elements comes in handy: simply set a background image to html and another image to body which you wish to superimpose over the first. To ensure the background image on body displays at full viewport height, you need to apply height and min-height respectively as well:

    html {
        height: 100%;
        background: #ddd url(background1.png) repeat;
    }
    
    body {
        min-height: 100%;
        background: transparent url(background2.png) center top no-repeat;
    }
    

    Incidentally, the reason why you have to specify height and min-height to html and body respectively is because neither element has any intrinsic height. Both are height: auto by default. It is the viewport that has 100% height, so height: 100% is taken from the viewport, then applied to body as a minimum to allow for scrolling of content.

  • In CSS3, the syntax has been extended so you can declare multiple background values in a single property, eliminating the need to apply backgrounds to multiple elements (or adjust height/min-height):

    body {
        background: url(background2.png) center top no-repeat, 
                    #ddd url(background1.png) repeat;
    }
    

    The only caveat is that in a single multi-layered background, only the bottommost layer may have a background color. You can see in this example that the transparent value is missing from the upper layer.

    And don't worry — the behavior specified above with propagating background values works exactly the same even if you use multi-layered backgrounds.

If you need to support older browsers, though, you'll need to go with the CSS2 method, which is supported all the way back to IE7.

My comments under this other answer explain, with an accompanying fiddle, how body is actually offset from html by default margins even though it looks like it's being padded out instead, again owing to this seemingly strange phenomenon.


1 This may have its roots in setting the HTML background and bgcolor attributes of body causing the background attribute to apply to the entire viewport. More on that here.

Tuesday, June 1, 2021
 
rojo
answered 7 Months ago
79

So what you're wanting is for the rows to alternate 2 at a time. So they go dark dark, light light, dark dark

I think, similar to @rusmus solution, you should apply a class to the rows.

Put this right before your foreach loop:

$black = true;
$rownumber = 0;

Put this in your loop

if(($rownumber % 2) == 0){//if the number is even
    $black = !$black;  //switch the state

    if($black){
        $class = 'blackRow';
    }else{
        $class = 'whiteRow';
    }
}  
$rownumber++;   

Basically what I've done is check if the row number is even. If it is, then we switch the color from being light to dark.

On your table row do something like this: <tr class='<?php echo $class; ?>' >

Here's a codepad example: http://codepad.org/JR4KOri4

Saturday, May 29, 2021
 
TheLovelySausage
answered 7 Months ago
34

Yes, it is possible - see this:

demo

.circle {
  position: relative;
  margin: 7em auto;
  width: 16em;
  height: 16em;
  border-radius: 50%;
  background: lightblue;
}

.arc {
  overflow: hidden;
  position: absolute;
  /* make sure top & left values are - the width of the border */
  /* the bottom right corner is the centre of the parent circle */
  top: -1em;
  right: 50%;
  bottom: 50%;
  left: -1em;
  /* the transform origin is the bottom right corner */
  transform-origin: 100% 100%;
  /* rotate by any angle */
  /* the skew angle is 90deg - the angle you want for the arc */
  transform: rotate(45deg) skewX(30deg);
}

.arc:before {
  box-sizing: border-box;
  display: block;
  border: solid 1em navy;
  width: 200%;
  height: 200%;
  border-radius: 50%;
  transform: skewX(-30deg);
  content: '';
}
<div class='circle'>
  <div class='arc'></div>
</div>
Thursday, June 3, 2021
 
SubniC
answered 7 Months ago
65

Yes it is via the new step-function easing curves property.

Instead of "ease-in" etc. use "step-start" or "step-end" which will make the transition happen instantaneously either at the beginning or end of the time period specified in transition-duration.

You can also have multiple steps: "steps(N, start | end ])" which will have the transition happen in equally spaced steps.

AFAIK this is only supported in Chrome to date.

Wednesday, August 25, 2021
 
xosp7tom
answered 4 Months ago
87

While the first part could indeed be solved in "text mode" using regular expressions or a more complete DOM implementation in JavaScript, for the second part (the height calculation), you'll need a real, full browser or a headless engine like PhantomJS.

From the PhantomJS homepage:

PhantomJS is a command-line tool that packs and embeds WebKit. Literally it acts like any other WebKit-based web browser, except that nothing gets displayed to the screen (thus, the term headless). In addition to that, PhantomJS can be controlled or scripted using its JavaScript API.


A schematic instruction (which I admit is not tested) follows.

In your modification script (say, modify-html-file.js) open an HTML page, modify it's DOM tree and console.log the HTML of the root element:

var page = new WebPage();

page.open(encodeURI('file://' + phantom.args[0]), function (status) {
    if (status === 'success') {
        var html = page.evaluate(function () {
            // your DOM manipulation here
            return document.documentElement.outerHTML;
        });
        console.log(html);
    }
    phantom.exit();
});

Next, save the new HTML by redirecting your script's output to a file:

#!/bin/bash

mkdir modified
for i in *.html; do
    phantomjs modify-html-file.js "$1" > modified/"$1"
done
Thursday, October 14, 2021
 
Ergwun
answered 2 Months ago
Only authorized users can answer the question. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :
 
Share