Translate X and Y Percentage Values Based on Elements Height and Width

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



Leave a reply



Submit