Is the CSS3 transform translate percentage values relative to its width and/or height?
In this section http://www.w3.org/TR/css3-transforms/#transform-property it states:
Percentages: refer to the size of bounding box
The definition of bounding box is (source)
A bounding box is the object bounding box for all SVG elements without an associated CSS layout box and the border box for all other elements. The bounding box of a table is the border box of its table wrapper box, not its table box.
And border box is (source)
The width and height properties include the padding and border, but not the margin. Note that padding and border will be inside of the box e.g. .box {width: 350px; border: 10px solid black;} lead to a box rendered in the browser of width: 350px.
I hope this helps
css3 translate in percent
The percentage there is not of the parent container in the way you might expect but of the element itself. The spec describes it as:
[The percentage] refer[s] to the size of the element's box
Regarding %s, the spec says:
Note that values are not allowed in the translateZ
translation-value, and if present will cause the propery value to be
invalid.
Though, it seems that instead, they aren't valid in any of them for Chrome at least.
Sorry :(
TranslateY based on width of object
It could be done with javascript.
Get element actual height: var height = document.getElementById("someId").clientHeight;
and set it as value to transform property: element.style.transform = translateY('${height}')
note: used temlpate literals to put variable inside string
position child element with translateY (100%)
Just add top position as 100% and remove translate.
const data = [
{
id: 1,
name: "SIMPLES NACIONAL – MEI",
funcionarioIncrease: 49.99,
maxFuncionario: 1,
socioIncrease: 0,
maxSocio: 5,
FATURAMENTO: [
{
name: "ATÉ 30.000,00",
value: 49.99,
},
{
name: "De 30.001,00 a 50.000,00 ",
value: 99.99,
},
],
},
{
id: 2,
name: "SIMPLES NACIONAL – SERVIÇOS",
funcionarioIncrease: 25,
maxFuncionario: 3,
socioIncrease: 25,
maxSocio: 5,
FATURAMENTO: [
{
name: "ATÉ 30.000,00",
value: 149.99,
},
{
name: "De 30.001,00 a 50.000,00 ",
value: 199.99,
},
],
},
];
function createInput(id, value) {
var inputRadio = document.createElement("input");
if (id && value) {
inputRadio.id = value;
inputRadio.name = "category";
inputRadio.type = "radio";
inputRadio.value = value;
inputRadio.classList.add("radio");
return inputRadio;
}
return null;
}
function createOptions() {
const container = document.querySelector(".options-container");
data.forEach((value) => {
const optionDiv = document.createElement("div");
optionDiv.classList.add("option");
container.append(optionDiv);
const input = createInput(value.name, value.id);
if (!input) {
return null;
}
optionDiv.append(input);
var label = document.createElement("label");
label.htmlFor = value.id;
label.innerHTML = value.name;
optionDiv.append(label);
});
}
function initalize() {
createOptions();
const selected = document.querySelector(".selected");
const optionsContainer = document.querySelector(".options-container");
const optionsList = document.querySelectorAll(".option");
selected.addEventListener("click", () => {
optionsContainer.classList.toggle("active");
});
optionsList.forEach((o) => {
o.addEventListener("click", () => {
let input = o.querySelector("input").id;
selected.innerHTML = o.querySelector("label").innerHTML;
selected.setAttribute("data-value", input);
optionsContainer.classList.remove("active");
});
});
}
initalize();
.select-box {
display: flex;
width: 100%;
max-height: 50px;
flex-direction: column;
position: relative;
z-index: 2;
}
.select-box .options-container {
background: #2f3640;
color: #f5f6fa;
max-height: 0;
width: 100%;
opacity: 0;
transition: all 0.4s;
border-radius: 8px;
overflow: hidden;
position: absolute;
top:100%;
order: 1;
z-index: 2;
}
.selected {
background: #2f3640;
border-radius: 8px;
margin-bottom: 8px;
color: #f5f6fa;
position: relative;
order: 0;
}
.selected::after {
content: "";
background: url("img/arrow-down.svg");
background-size: contain;
background-repeat: no-repeat;
position: absolute;
height: 100%;
width: 32px;
right: 10px;
top: 5px;
transition: all 0.4s;
}
.select-box .options-container.active {
max-height: 240px;
opacity: 1;
overflow-y: scroll;
}
.select-box .options-container.active + .selected::after {
transform: rotateX(180deg);
top: -6px;
}
.select-box .options-container::-webkit-scrollbar {
width: 8px;
background: #0d141f;
border-radius: 0 8px 8px 0;
}
.select-box .options-container::-webkit-scrollbar-thumb {
background: #525861;
border-radius: 0 8px 8px 0;
}
.select-box .option,
.selected {
padding: 12px 24px;
cursor: pointer;
}
.select-box .option:hover {
background: #414b57;
}
.select-box label {
cursor: pointer;
color: white;
}
.select-box .option .radio {
display: none;
}
<div class="inputs_container">
<div class="service_mode flex">
<div class="select-box">
<div class="options-container"></div>
<div class="selected">
Select Video Category
</div>
</div>
</div>
</div>
Change value of translateX and size of element based on size of parent element OR size of window
You can try do it with just css. You can use viewport units so all values will depend on viewport size.
.planet {
width: 10vw;
height: 10vw;
background: url(http://placehold.it/940x940) no-repeat center center;
background-size: contain;
z-index: 1;
}
.moon {
position: absolute;
background: url(http://placehold.it/140x140) no-repeat center center;
background-size: contain;
width: 5vw;
height: 5vw;
-webkit-animation: myOrbit 20s linear infinite;
-moz-animation: myOrbit 20s linear infinite;
-o-animation: myOrbit 20s linear infinite;
animation: myOrbit 20s linear infinite;
}
@keyframes myOrbit {
from { transform: rotate(0deg) translateX(20vw) rotate(0deg); z-index:1}
to { transform: rotate(360deg) translateX(20vw) rotate(-360deg); z-index:2}
}
Sample -> here
Probably you will need to add some media queries to handle different screen aspect ratios. Current viewport units support -> caniuse.com
Keeping translate css (x,y) values same for all screen resolutions?
Using pixel measurements it's impossible to have something work on all resolutions unless you are always assuming the smallest, which is unviable for larger screens.
So you have two basic solutions:
Use percentage based positioning, the main issue with this is that you never have true control over where your elements will be positioned on screen, since 20% of a 320px wide screen is vastly different from 20% on a 1920px wide display.
Use media queries, this is probably the best solution, it does involve a bit more work though. I reccommend setting your canvas/container to a specific width/height on each resolution jump, this way you can probably get away with 3 or 4 different sizes.
An important thing to note is that you can combine both at some points depending on your exact needs, here's a basic example for how i'd set the container's sizes up:
.container {
width: 1200px;
height: 800px;
}
.container .child {
/*animation stuff*/
}
@media (max-width: 1199px){
.container {
width: 900px;
height: 600px;
}
.container .child {
/* animation adjustments */
}
}
/* etc... */
Another neat thing about setting up static sizes is that you have better control with your percentages, specially if you keep the width/height proportions equal.
Related Topics
Ie Crossing Out Pseudo Element CSS
Bootstrap Drop Down Cutting Off
CSS Expression to Set Height of Div
Failed to Decode Downloaded Font, Ots Parsing Error: Invalid Version Tag + Rails 4
How to Use Chrome Web Inspector to View Hover Code
Embedding Extra Styles with Noscript
CSS Transition Opacity Fade Background
Height: Calc(100%) Not Working Correctly in CSS
Hex Colors: Numeric Representation for "Transparent"
CSS Background-Position Not Working in Mobile Safari (Iphone/Ipad)
Background Color of Tspan Element