I'm writing a React app, but my question I'm thinking is not about React but about CSS. I have a bar from which the user can choose a sort option:
<div className="innerLineVisor">
<div className="sortLine" ref={lineRef}>
{cuisines.map(cuisine =>
<div key={cuisine.id} className="sortButton">{cuisine.value}</div>
)}
</div>
</div>
Here are their styles:
.innerLineVisor {
width: 80%;
height: 40px;
border: #C80303 1px solid;
overflow: hidden;
position: absolute;
box-sizing: border-box;
left: 10%;
bottom: 0;
}
.sortLine {
height: 40px;
background-color: white;
position: absolute;
left: 0;
bottom: 0;
display: inline;
transition: 1s;
}
.sortButton {
float: left;
width: 120px;
padding: 5px 10px;
border: darkgray 1px solid;
border-radius: 10px;
background-color: white;
margin-top: 5px;
margin-left: 5px;
margin-right: 5px;
display: flex;
justify-content: center;
align-items: center;
cursor: pointer;
box-sizing: border-box;
}
Now when one of the buttons does not fit on the left, I can see part of it. And on the right is empty until the button fits completely.
What can I do to see part of the button on the right as well?
This is the arrow code:
function leftMotion() {
setLimitPositions({...limitPositions, right: false})
if (linePosition + step > 0) {
lineRef.current.setAttribute('style', 'left: 0')
setLinePosition(0)
setLimitPositions({...limitPositions, left: true})
return
}
lineRef.current.setAttribute('style', 'left:' + (linePosition + step) + 'px')
setLinePosition(linePosition + step)
if (limitPositions.left && arrowsPressed.left) {
lineRef.current.setAttribute('style', 'left:' + (linePosition + 10) + 'px')
}
}
function rightMotion() {
setLimitPositions({...limitPositions, left: false})
lineRef.current.setAttribute('style', 'left:' + (linePosition - step) + 'px')
setLinePosition(linePosition - step)
const lineVisorWidth = getLineVisorWidth()
if (lineVisorWidth > (lineLength - (Math.abs(linePosition))) - lineVisorWidth) {
const limitRightPosition = lineLength - lineVisorWidth
lineRef.current.setAttribute('style', 'left:' + (-limitRightPosition) + 'px')
setLinePosition(-limitRightPosition)
setLimitPositions({...limitPositions, right: true})
}
}
I Want to convert below mentioned CSS format to SCSS using variables or methods. Please suggest how to achieve.
CSS Format is:
.section-1-1{
margin-left:0;
}
.section-1-1 + .section-1-2 {
margin-left: 15px;
}
.section-1-1 + .section-1-3 {
margin-left: 15px;
}
.section-2-1{
margin-left:0;
}
.section-2-1 + .section-2-2 {
margin-left: 15px;
}
.section-2-1 + .section-2-3 {
margin-left: 15px;
}
Note: I may have to write more like .section-3-1, .section-4-1.... vice versa.
With sass you can clean up your code like this, no need to create variables.
.section-1-1 {
margin-left: 0;
+ {
.section-1-2 {
margin-left: 15px;
}
.section-1-3 {
margin-left: 15px;
}
.section-x { } ...
}
}
.section-2-1 { .... }
If you have a lot of classes, you can create classes in a loop.
#for $i from 1 through 3 {
.section-#{$i}-1 {
margin-left: 0px;
}
#for $j from 1 through 3 {
.section-#{$i}-1 + .section-#{$i}-#{$j} {
margin-left: 15px;
}
}
}
This will generate the following CSS.
.section-1-1 {
margin-left: 0px;
}
.section-1-1 + .section-1-1 {
margin-left: 15px;
}
.section-1-1 + .section-1-2 {
margin-left: 15px;
}
.section-1-1 + .section-1-3 {
margin-left: 15px;
}
.section-2-1 {
margin-left: 0px;
}
.section-2-1 + .section-2-1 {
margin-left: 15px;
}
.section-2-1 + .section-2-2 {
margin-left: 15px;
}
.section-2-1 + .section-2-3 {
margin-left: 15px;
}
.section-3-1 {
margin-left: 0px;
}
.section-3-1 + .section-3-1 {
margin-left: 15px;
}
.section-3-1 + .section-3-2 {
margin-left: 15px;
}
.section-3-1 + .section-3-3 {
margin-left: 15px;
}
Use CSS to SCSS converter: https://beautifytools.com/css-to-scss-converter.php
Here's the converter's output for your CSS:
.section-1-1 {
margin-left: 0;
+ {
.section-1-2 {
margin-left: 15px;
}
.section-1-3 {
margin-left: 15px;
}
}
}
.section-2-1 {
margin-left: 0;
+ {
.section-2-2 {
margin-left: 15px;
}
.section-2-3 {
margin-left: 15px;
}
}
}
I am trying to use this Codepen to create inside each section of my grid container on the profile page separate progress circles, but I get only one visible circle, the others are just empty squares without progress circles.
Could someone please give me a clue what went wrong? I tried to re-name classes and tweaked the code, but it didn't work.
Part of html:
<div class="grid-container">
<div class="counter" data-cp-percentage="75" data-cp-color="#00bfeb"></div>
<div class="counter" data-cp-percentage="65" data-cp-color="#EA4C89"></div>
<div class="counter" data-cp-percentage="35" data-cp-color="#FF675B"></div>
<div class="counter" data-cp-percentage="44" data-cp-color="#FF9900"></div>
</div>
CSS
.profile_intro {
background: linear-gradient(-45deg, #ee7752, #e73c7e, #23a6d5, #23d5ab);
background-size: 400% 400%;
animation: gradient 15s ease infinite;
margin-top: 0px;
width: 100%;
height: 20%;
}
.profilepic-img {
vertical-align: center;
border-radius: 100px;
width: 100px;
height: 100px;
display: block;
margin-left: auto;
margin-right: auto;
z-index: 1;
}
#keyframes gradient {
0% {
background-position: 0% 50%;
}
50% {
background-position: 100% 50%;
}
100% {
background-position: 0% 50%;
}
}
.userinfo {
margin: auto;
width: 50%;
padding: 5px;
text-align: center;
}
.useremail {
margin-top: 5%;
}
table {
border: 2px solid #cccccc;
width: 80%;
border-collapse: collapse;
margin-left: auto;
margin-right: auto;
text-align: center;
color: grey;
}
th,
td {
padding: 5px;
text-align: center;
}
th {
font-size: 18px;
}
.grid-container {
display: grid;
/*important!
justify-content: space-evenly;
grid-template-columns: auto auto; /*important!!
/* grid-template-columns: 50px 50px; /*Make the grid smaller than the container*/
*/ grid-gap: 10px;
background-color: #f1eee3;
padding: 10px;
align-content: center;
left: 0px;
}
.grid-container>div {
background-color: rgba(255, 255, 255, 0.8);
text-align: center;
/* padding: 10px 0; */
font-size: 3vw;
border-radius: 25px;
background: #faf8f4;
width: 35vw;
height: 35vw;
box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19);
color: #383e3f;
text-decoration-style: solid;
}
/*progress Bar */
h1 {
background: rgba(255, 255, 255, 0.8);
box-shadow: 0px 1px 10px 2px rgba(0, 0, 0, 0.2);
border-bottom: 3px solid #00bfeb;
font-size: calc(1em + 1vmax);
}
.counter {
display: -webkit-inline-box;
display: inline-flex;
cursor: pointer;
width: 300px;
height: 300px;
max-width: 100%;
position: relative;
-webkit-box-pack: center;
justify-content: center;
-webkit-box-align: center;
align-items: center;
font-size: calc(1em + 1vmin);
-webkit-transition: height .2s ease-in-out;
transition: height .2s ease-in-out;
background: #fff;
border-radius: 50%;
box-shadow: 0px 1px 10px 2px rgba(0, 0, 0, 0.2);
margin: 1em 0;
}
.percentage {
position: absolute;
text-align: center;
top: 50%;
left: 0;
right: 0;
vertical-align: middle;
-webkit-transform: translate3d(0, -50%, 0);
transform: translate3d(0, -50%, 0);
}
Javascript
document.addEventListener("DOMContentLoaded", function() {
var circleProgress = (function(selector) {
var wrapper = document.querySelectorAll(selector);
Array.prototype.forEach.call(wrapper, function(wrapper, i) {
var wrapperWidth,
wrapperHeight,
percent,
innerHTML,
context,
lineWidth,
centerX,
centerY,
radius,
newPercent,
speed,
from,
to,
duration,
start,
strokeStyle,
text;
var getValues = function() {
wrapperWidth = parseInt(window.getComputedStyle(wrapper).width);
wrapperHeight = wrapperWidth;
percent = wrapper.getAttribute('data-cp-percentage');
innerHTML = '<span class="percentage"><strong>' + percent +
'</strong> %</span><canvas class="circleProgressCanvas"
width="' + (wrapperWidth * 2) + '" height="' + wrapperHeight *
2 + '"></canvas>';
wrapper.innerHTML = innerHTML;
text = wrapper.querySelector(".percentage");
canvas = wrapper.querySelector(".circleProgressCanvas");
wrapper.style.height = canvas.style.width = canvas.style.height
= wrapperWidth + "px";
context = canvas.getContext('2d');
centerX = canvas.width / 2;
centerY = canvas.height / 2;
newPercent = 0;
speed = 1;
from = 0;
to = percent;
duration = 1000;
lineWidth = 25;
radius = canvas.width / 2 - lineWidth;
strokeStyle = wrapper.getAttribute('data-cp-color');
start = new Date().getTime();
};
function animate() {
requestAnimationFrame(animate);
var time = new Date().getTime() - start;
if (time <= duration) {
var x = easeInOutQuart(time, from, to - from, duration);
newPercent = x;
text.innerHTML = Math.round(newPercent) + " %";
drawArc();
}
}
function drawArc() {
var circleStart = 1.5 * Math.PI;
var circleEnd = circleStart + (newPercent / 50) * Math.PI;
context.clearRect(0, 0, canvas.width, canvas.height);
context.beginPath();
context.arc(centerX, centerY, radius, circleStart, 4 * Math.PI,
false);
context.lineWidth = lineWidth;
context.strokeStyle = "#ddd";
context.stroke();
context.beginPath();
context.arc(centerX, centerY, radius, circleStart, circleEnd,
false);
context.lineWidth = lineWidth;
context.strokeStyle = strokeStyle;
context.stroke();
}
var update = function() {
getValues();
animate();
}
update();
var btnUpdate = document.querySelectorAll(".btn-update")[0];
btnUpdate.addEventListener("click", function() {
wrapper.setAttribute("data-cp-percentage",
Math.round(getRandom(5, 95)));
update();
});
wrapper.addEventListener("click", function() {
update();
});
var resizeTimer;
window.addEventListener("resize", function() {
clearTimeout(resizeTimer);
resizeTimer = setTimeout(function() {
clearTimeout(resizeTimer);
start = new Date().getTime();
update();
}, 250);
});
});
function easeInOutQuart(t, b, c, d) {
if ((t /= d / 2) < 1) return c / 2 * t * t * t * t + b;
return -c / 2 * ((t -= 2) * t * t * t - 2) + b;
}
});
circleProgress('.counter');
function getRandom(min, max) {
return Math.random() * (max - min) + min;
}
});
Found the bug: I didn't have in my HTML some elements that had been mentioned in JavaScript. Changed names of classes and it works fine at the moment. Thank you all!
I'm trying to achieve a loop for padding.
Example from less.org just modified
.generate-pad(10);
.generate-pad(#n, #i: 1) when (#i =< #n) {
.padd-top-#{i} {
padding-top: (#i * 100px / #n);
}
.generate-pad(#n, (#i + 1));
}
outputs the following when its compiled
.padd-top-1 {
padding-top: 10px;
}
.padd-top-2 {
padding-top: 20px;
}
.padd-top-3 {
padding-top: 30px;
}
.padd-top-4 {
padding-top: 40px;
}
.padd-top-5 {
padding-top: 50px;
}
.padd-top-6 {
padding-top: 60px;
}
.padd-top-7 {
padding-top: 70px;
}
.padd-top-8 {
padding-top: 80px;
}
.padd-top-9 {
padding-top: 90px;
}
.padd-top-10 {
padding-top: 100px;
}
but I am trying to replace .pad-top-#{i} with a variable so I can call it later. How can I achieve this?
I use LESS CSS. My code looks like this.
Repeatable pattern
Do you see the pattern in my code? The only thing that differs the two is the padding value and the class name.
Question
Is it possible in LESS CSS to make a function / mixin of a block like this with many different elements?
LESS CSS
&.pad-10 > [class*='cols-'] {
background: #ccc;
padding: 10px;
&:first-child {
padding-left: 0;
}
&:last-child {
padding-right: 0;
}
}
&.pad-20 > [class*='cols-'] {
background: #ccc;
padding: 20px;
&:first-child {
padding-left: 0;
}
&:last-child {
padding-right: 0;
}
}
Mixin suggestion
do_padding( $value ) {
&.pad-#value > [class*='cols-'] {
background: #ccc;
padding: #valuepx;
&:first-child {
padding-left: 0;
}
&:last-child {
padding-right: 0;
}
}
do_padding( 10 );
do_padding( 20 );
I know that my exact problem can be solved in other ways without LESS CSS, but I have this problem from time to time.
Yes, you just need to set up a proper counting and looping structure in LESS. Here's how:
LESS
.do_padding(#startValue, #increment) {
.loop(#value) when (#value > 0) {
//set top amount
&.pad-#{value} > [class*='cols-'] {
background: #ccc;
padding: #value * 1px;
&:first-child {
padding-left: 0;
}
&:last-child {
padding-right: 0;
}
}
// next iteration
.loop(#value - #increment);
}
// end the loop when index is 0 or less
.loop(#value) when not (#value > 0) {}
//start the loop
.loop(#startValue);
}
Use it
.myClass {
.do_padding(30, 10);
}
CSS Output
.myClass.pad-30 > [class*='cols-'] {
background: #ccc;
padding: 30px;
}
.myClass.pad-30 > [class*='cols-']:first-child {
padding-left: 0;
}
.myClass.pad-30 > [class*='cols-']:last-child {
padding-right: 0;
}
.myClass.pad-20 > [class*='cols-'] {
background: #ccc;
padding: 20px;
}
.myClass.pad-20 > [class*='cols-']:first-child {
padding-left: 0;
}
.myClass.pad-20 > [class*='cols-']:last-child {
padding-right: 0;
}
.myClass.pad-10 > [class*='cols-'] {
background: #ccc;
padding: 10px;
}
.myClass.pad-10 > [class*='cols-']:first-child {
padding-left: 0;
}
.myClass.pad-10 > [class*='cols-']:last-child {
padding-right: 0;
}