Can't get canvas to show up behind html - html

I need help with a simple link site and my canvas wont sit behind my text
I think the problem is specifically with my html
I haven't really done a lot with html5 canvases and this was a botched copy paste job:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta content="IE=edge" http-equiv="X-UA-Compatible">
<title>jetbrains.xyz</title>
<link href="main.css" rel="stylesheet">
<script src="main.js"></script>
</head>
<body>
<canvas id='c'></canvas>
<div class="mhm">
<div class="centered">
<h1>⎳⎳⎳</h1>
</div>
<ul class="bmenu">
<br />
<li>
sera
</li>
<br />
<li>
zonk
</li>
</ul>
</div>
</body>
</html>
https://jsfiddle.net/83c7npck/

To change the stacking order of HTML elements, you need the z-index CSS property. Think of the z-index as an expression of the element's depth, or Z axis, in relation to other elements in the HTML document. The X and Y axis' express the element's left/right and up/down values.
Z-index allows you to specify a 'stacking order', by assigning a number indicating a 'height' position. The higher the number, the 'closer' to the user that element will stack. So say a bunch of HTML elements each had one of these z-index values:
z-index: 1;
z-index: 999;
z-index: -10;
z-index: 50;
The stacking order, from farthest away to closest, will be:
z-index: -10;
z-index: 1;
z-index: 50;
z-index: 999;
A word of caution
Changing the stacking order means placing elements physically over the top of other elements. This means you are obscuring the user's ability to view and interact with them! Think carefully before placing elements behind others, it is best reserved for visual flair only.
Why it's not working
You haven't applied any CSS to your <canvas> elements, so the stacking order will default to that of the element type. Without CSS intervention, HTML elements will never overlap.
For a canvas element, that means block-level. You can read up on how a canvas element will behave by default and how to control it on the Mozilla Developer Network.
If you want to change the stacking order of your elements, you'd need to apply a few changes to your CSS:
canvas {
position: absolute; // this removes the element from the document flow and allows other elements to float over/under it
z-index:0; // alternately, we can simply make this '-1' to sit behind everything...
width: 100px; // just to make it clearly visible when it's working, very handy!
height:100px;
background-color: red;
}
div.mhm {
position:relative; // z-index only works if a position is set to relative or absolute
background-color: rgba(0,0,238,0.5);
z-index:10; // as long as this value is higher than that of the canvas' z-index, it will appear on top
}

Related

Why does CSS transform influence Site width?

I was always under the impression that CSS transforms are purely visual and don't influence the actual site layout in any way. I recently found a weird bug in my project, where an image which is transformed out of the viewport (to later fly in) changed the width of the page.
My coworkers and I are extremely confused by this. I provided an example below (also hosted here: https://transform-confusion.netlify.app/) that shows the phenomenon with a transform: scale(2) applied to a div completely changing the width of the browser.
Do I just misunderstand how CSS works, is this a weird browser bug or what is going on here?
Source code used here and in the video:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<style>
body {
border: 2px dotted black;
}
.scale {
transform: scale(2);
transform-origin: top left;
}
.scalable{
background: lightblue;
padding: 5px;
}
</style>
</head>
<body>
<h1>This is a test</h1>
<button>Toggle transform</button>
<div class="scalable">
Why does the Site start scrolling horizonally from a simple transform?
<pre>transform: scale(2)</pre>
</div>
<script>
const scalable = document.querySelector(".scalable");
document.querySelector("button").addEventListener("click", () => {
scalable.classList.toggle("scale");
})
</script>
</body>
</html>
I was always under the impression, that CSS transforms are purely visual and don't influence the actual site layouting in any way
This is correct since transformation will not affect the position of any other element and the layout will remain the same.
What you are facing is related to overflow:
The scrollable overflow of a box is the set of things extending outside of that box’s padding edge for which a scrolling mechanism needs to be provided.
The scrollable overflow area is the non-rectangular region occupied by the scrollable overflow, and the scrollable overflow rectangle is the minimal rectangle whose axes are aligned to the box’s axes and that contains the scrollable overflow area.
.. the border boxes of all boxes for which it is the containing block and whose border boxes are positioned not wholly outside its block-start or inline-start padding edges, accounting for transforms by projecting each box onto the plane of the element that establishes its 3D rendering context. ref
So transform is a part of the Scrollable Overflow
You will find that some properties are part of the Ink Overflow and this one doesn't generate a scroll:
The ink overflow of a box is the part of that box and its contents that creates a visual effect outside of the box’s border box. Ink overflow is the overflow of painting effects defined to not affect layout or otherwise extend the scrollable overflow area, such as box shadows, border images, text decoration, overhanging glyphs (with negative side bearings, or with ascenders/descenders extending outside the em box), outlines, etc.
For example box-shadow will never create a scroll
.box {
width:100px;
height:100px;
background:red;
box-shadow:0 0 0 1000vmax blue;
}
<div class="box"></div>
I just found the important bit of info in the Specs. My misunderstanding was the overflow behaviour:
For elements whose layout is governed by the CSS box model, the transform property does not affect the flow of the content surrounding the transformed element. However, the extent of the overflow area takes into account transformed elements. This behavior is similar to what happens when elements are offset via relative positioning. Therefore, if the value of the overflow property is scroll or auto, scrollbars will appear as needed to see content that is transformed outside the visible area. Specifically, transforms can extend (but do not shrink) the size of the overflow area, which is computed as the union of the bounds of the elements before and after the application of transforms.
from https://drafts.csswg.org/css-transforms/#transform-property
Slightly late to the party, but here's my solution to the problem:
html {
overflow-x: hidden;
}
Probably a bit hacky, but it works for me!

absolutely positioned elements adding scroll on mobile

I want to have a page that takes the full height and width of the client window. I want to be able to position divs within the page using position=absolute, with a specified transform. They will be playing cards on a table, so they'll have an x, y, and rotation. This all works great, but on mobile, when one of the absolutely positioned elements goes beyond the boundaries of the parent, the browser adds a scrollbar and lets you scroll to the out-of-bounds elements. I've found that I can clip the rendering of the absolutely positioned elements by using clip-path: inset(0) on the parent, but the mobile page still lets you scroll over to the white part beyond the application. Is there some other way to restrict the viewport to just the body so I can keep my full-page, non-scrolling experience in tact? I don't think overflow:hidden works here because of the absolute positioning.
here's an example. https://ddeklotz-static-page.s3.amazonaws.com/example.html
<html>
<head>
<title>Page Title</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="styles.css">
</head>
<body>
<div class="app">
<div class="square"/>
</div>
</body>
</html>
body {
margin: 0;
overflow: hidden;
}
.app {
background-color: red;
min-height: 100vh;
clip-path:inset(0);
}
.square {
background-color: blue;
width: 100px;
height: 100px;
position: absolute;
transform: translate(330px, 50px) rotate(20deg);
}
I think I found something that works: I needed to add "user-scalable=0" to my viewport meta tag's content. It looks like before the viewport was zoomed out to show the full extent of the clipped div's bounding region, which isn't what I wanted. Disabling user scaling means we just keep the layout viewport in view, I think.
It looks like I also could have use position:fixed (instead of absolute) to address this, but that would have made the positioning of the divs more difficult (as their parent isn't likely to have the same origin as the viewport).

How to position div next to HTML5 canvas

I am trying to create a web based paint software, and want to position a button to change the color of the paint brush (I will eventually change this to a bar). How would I position the button on the right of the canvas.
Html and css:
<!DOCTYPE html>
<html lang = "en">
<head>
<title>Paint</title>
<style>
#canvas{
background-color: cadetblue;
}
.button{
/* code to position button next to canvas */
}
</style>
</head>
<body>
<canvas id = "canvas" width = "800" height = "600"></canvas>
<div class = "button">RED</div>
</body>
</html>
<canvas> is just a normal block element, so you can position it however you will position a block element. You can apply float:left on the canvas & the button (please use a real <button>), you can display:inline-block them, you can add a wrapper around them and display: flex it, or even display: grid it or add position: relative to it and position: absolute to its children. There are lots of ways to achieve this. Here is a good starting point: https://developer.mozilla.org/en-US/docs/Learn/CSS/CSS_layout/Introduction

Giving background-color to body applying whole page. Why?

body {
background-color: red;
}
<body>
<div>Hello World!</div>
</body>
So the background-color: red; applies to whole page height but when I inspect the page the height of the body is only up to the div containing Hello World!.
Someone please explain this why it is happening like this.
The main reason is because the HTML takes the background-color of BODY since:
The background of the root element becomes the background of the
canvas and covers the entire canvas [...]
So since the default background-color of HTML is transparent it will take the one from BODY. However applying a color to both the HTML and BODY elements you will see that the BODY background doesn't cover the whole page anymore.
html {
background-color: blue;
}
body {
background-color: red;
}
<html>
<body>
<div>Hello World!</div>
</body>
</html>
The background of the root element becomes the background of the
canvas and covers the entire canvas, anchored (for
background-position) at the same point as it would be if it was
painted only for the root element itself. The root element does not
paint this background again.
For HTML documents, however, we recommend that authors specify the
background for the BODY element rather than the HTML element. For
documents whose root element is an HTML "HTML" element or an XHTML
"html" element that has computed values of transparent for
background-color and none for background-image, user agents must
instead use the computed value of the background properties from that
element's first HTML "BODY" element or XHTML "body" element child when
painting backgrounds for the canvas, and must not paint a background
for that child element. Such backgrounds must also be anchored at the
same point as they would be if they were painted only for the root
element.
From W3 - 14 Colors and Backgrounds.
it's actually pretty logic. First of all <html> and <body> tags are required tags in a webpage. Where the <html> tag contains all of the <html> code the <body> tag holds all of the contents.
Consider this standard structure for a basic HTML document:
<!DOCTYPE html>
<html lang="en">
<head>
<!-- Metadata and such -->
</head>
<body>
<!-- Where the content begins -->
<body>
</html>
The spec defines <html> as the root element of a document, and we can clearly see that in the above example: the element is the very top level of all other elements. The buck stops there because there are no more levels beyond that from which styles can be inherited.
From there, and make up the only two elements that fall directly inside . In fact, the spec defines directly in contrast to since those are the only two elements that need to be distinguished.
So, the bottom line here is that is the root element of a document where is a descendent contained within it. In fact, there is a :root selector in CSS. These target the exact same thing.
It's tempting to think that any styles we want to be inherited across the board should be applied directly to <html> because it is the root element of the document. <html> supersedes <body> in hierarchy, so it follows that it must contain all global styles.
But that's not exactly the case. In fact, inline attributes for the following were originally assigned to <body> in the spec:
background
bgcolor
marginbottom
marginleft
marginright
margintop
text
The background-color
There is a weird thing in CSS where the background-color on <body> floods the whole viewport even if the metrics of the element itself don't cover that whole area. Unless the background-color gets set on the html element, then it doesn't.
If flooding is the goal, it can be smart to just set it on the html element to begin with.
CSS tricks has a related post in merit link . It seems that body styles are expanded to html because:
html is the root element of a document where body is a descendent
contained within it. In fact, there is a :root selector in CSS. These
target the exact same thing
height you see in inspect is min-height That is equal height's element div, background-color change max-height That is equal 100% his parents(html).
For Example:
change min-height and run inspect and see result :
body {
background-color: red;
min-height: 200px;
}
<div>Hello World!</div>
So, You see height in inspect Change 200px; But color red cover whole page.
Body means all page that display in the browser. so you want give color only to div you can use either a id or a class to give a style to that dive. as in first answer.
<body>
<div class="some">Hello World!</div>
</body>
.some{
background-color: red;
}
or
<body>
<div id="some">Hello World!</div>
</body>
#some{
background-color: red;
}
.some{
background-color: red;
}
<div class="some">Hello World!</div>
try this, as if you give color to body the whole webpage will be colored

z-index not working with image and p tag

i have an image and a paragraph on a html page.
the code is as follows:-
<!DOCTYPE html>
<html>
<head>
<style>
img
{
position:absolute;
left:0px;
top:0px;
background-color:red;
z-index:1;
}
p
{
z-index:2;
}
</style>
</head>
<body>
<h1>This is a heading</h1>
<img src="w3css.gif" width="100" height="140" />
<p>This is a sample paragraph for z-index testing</p>
</body>
</html>
here when is put z-index for image lesser than p tag then also it appears above p tag.
can anyone tell me why z-index in not working in my case???
thanks in advance
assign position: relative to <p> for z-index to work.
For OP's Clarification :
from : Any weird rules about z-index I should know about?
In addition, a child can never be below its parent. This example, also on Jsfiddle illustrates it.
Based on the example you added it's clear the trouble you're having:
z-index is only relative to its parent, which in most cases is the document itself. If the z-index of one sibling is lower than another, nothing you change about first sibling's children can move it above its parents sibling. Read more about stacking context if you're interested.
Here is a visual:
Crossed out in red is what you want to do, and it is not possible with CSS (considering those small boxes are children of the bigger box, with markup which might look like this:
<div class="one">
</div>
<div class="two">
<div> I can never be above "one", if my parent "two" isn't. </div>
</div>
A solution would be to move the "overlay" inside the wall, or better yet use a pseudo element (which is rendered as a child of the element it is applied to), because the overlay sounds like it something presentational, and thus should remain in the domain of CSS if an overlay div would add no semantic meaning.
z-index will work only if position property is specified,
so specify position: relative for the p tag
p
{
position: relative;
z-index:2;
}
DEMO
Your p tag needs a position value too, so the z-index can affect him. But in this case you can asign float:left to the image, and place it inside the p tag so the paragraph text will wrap next to the image.
change z-index to -1 for your image
img
{
position:absolute;
left:0px;
top:0px;
background-color:red;
z-index: -1;
}
An element with greater stack order is always in front of an element with a lower stack order.
In your code, the p tag has a stack order of 2, whereas your img tag has a stack order of 1. Your p tag thus has a greater stack order, meaning the text will be shown in front of the image.
If you want the opposite result, try using negative values for both the image and the paragraph.
img {
position: absolute;
left: 0px;
top: 0px;
z-index: -1;
}
p {
position: absolute;
left: 15px;
top: 45px;
z-index: -2;
}
See if the above snippet helps you.