I have a horizontal scrolling div with several child items. Depending on the width, child items can get cropped. So you might get 4 and a 1/2 visible items. So I've used Javascript to force a width to evenly distribute the child items.
I've used Javascript to detect the width of .palette and divide that by the number of items I want to show (minus margins) and applied that to each .swatch. Not sure if there's a better/simpler way?
If this is the solution, I need a bit of help making this more responsible so it updates on resize of window.
I'd like the offsetWidth to update on resize so the widths update.
Is it possible to use matchMedia to use a different value above certain 'breakpoints'? This is partially working!
let palette = document.querySelector('.palette');
let paletteWidth = palette.offsetWidth;
let swatch = document.querySelectorAll('.swatch')
swatch.forEach((item) => {
if (window.matchMedia("(min-width: 700px)").matches) {
item.style.width = (paletteWidth - 40) / 5 + "px";
} else {
item.style.width = (paletteWidth - 30) / 4 + "px";
}
});
const handleResize = () => {
let paletteWidth = palette.offsetWidth;
};
window.addEventListener('resize', handleResize);
.p-card {
background: #eee;
box-sizing: border-box;
display: flex;
flex-shrink: 0;
overflow: hidden;
padding: 30px 15px;
max-width: 50%;
}
.palette {
display: flex;
overflow-x: scroll;
}
.palette__inner {
display: flex;
overflow-x: scroll;
scroll-snap-type: x mandatory;
scrollbar-width: none; /* Firefox */
-ms-overflow-style: none; /* IE and Edge */
}
.palette__inner::-webkit-scrollbar {
display: none;
}
.palette__group {
display: flex;
flex-direction: column;
}
.palette__title {
font-family: "Arial", sans-serif;
font-size: 11px;
font-weight: normal;
margin: 0 10px 10px 0;
padding: 0;
position: sticky;
align-self: flex-start;
left: 0;
}
.palette__swatches {
display: flex;
}
.swatch {
background: red;
display: flex;
height: 20px;
margin-right: 10px;
scroll-snap-align: start;
width: 40px;
}
<div class="p-card">
<div class="palette">
<div class="palette__inner">
<div class="palette__group">
<h4 class="palette__title">Classic</h4>
<div class="palette__swatches">
<div class="swatch" style="background: red;"></div>
<div class="swatch" style="background: red;"></div>
<div class="swatch" style="background: red;"></div>
<div class="swatch" style="background: red;"></div>
<div class="swatch" style="background: red;"></div>
<div class="swatch" style="background: red;"></div>
</div>
</div>
<div class="palette__group">
<h4 class="palette__title">Matte</h4>
<div class="palette__swatches">
<div class="swatch" style="background: blue;"></div>
<div class="swatch" style="background: blue;"></div>
<div class="swatch" style="background: blue;"></div>
<div class="swatch" style="background: blue;"></div>
<div class="swatch" style="background: blue;"></div>
<div class="swatch" style="background: blue;"></div>
</div>
</div>
<div class="palette__group">
<h4 class="palette__title">Glimmer</h4>
<div class="palette__swatches">
<div class="swatch" style="background: green;"></div>
<div class="swatch" style="background: green;"></div>
<div class="swatch" style="background: green;"></div>
<div class="swatch" style="background: green;"></div>
<div class="swatch" style="background: green;"></div>
<div class="swatch" style="background: green;"></div>
</div>
</div>
</div>
</div>
</div>
The idea is that in your resize callback function, you're just updating the width of the parent element (.palette) but not the width of the children elements (.swatch).
New JS code to adopt:
let palette = document.querySelector('.palette');
let swatchs = document.querySelectorAll('.swatch')
function setSwatchWidth(n = 5) {
let paletteWidth = palette.offsetWidth;
swatchs.forEach((swatch) => {
swatch.style.width = (
paletteWidth - (n-1) * 10
) / n + "px";
});
}
onload = () => setSwatchWidth();
onresize = () => setSwatchWidth();
Bonus: I made the function more generic so that you can choose how many children you want in the sliding window.
Related
hello guys i got small problem in javascript..
i want to change the background color of .gradient_color class and the color should be another class attribute value... i want to do this with 50+ divs all divs with different color .. how can i set the .gradient_color div background with the value of data-clipboard-text
<div class="box">
<div class="gradient_color"></div>
<div
class="copyButton"
data-clipboard-text="background: linear-gradient(to right, #8e2de2,#8f6ba8);"
>
COPY
</div>
</div>
<div class="box">
<div class="gradient_color"></div>
<div
class="copyButton"
data-clipboard-text="linear-gradient(to right, #ee9ca7, #ffdde1)"
>
COPY
</div>
</div>
you could get all the .gradient_color elements using querySelectorAll and loop over the returned collection. In each iteration, get the next element sibling for the current .gradient_color element and read its data-clipboard-text attribute and set is as background of the current .gradient_color element
const divs = document.querySelectorAll('.gradient_color');
divs.forEach(d => {
d.style.background = d.nextElementSibling.dataset.clipboardText;
})
.gradient_color {
width: 50px;
height: 50px;
border: 1px solid;
}
<div class="box">
<div class="gradient_color"></div>
<div class="copyButton" data-clipboard-text="linear-gradient(to right, #8e2de2,#8f6ba8)">
COPY
</div>
</div>
<div class="box">
<div class="gradient_color"></div>
<div class="copyButton" data-clipboard-text="linear-gradient(to right, #ee9ca7, #ffdde1)">
COPY
</div>
</div>
This should work as well:
const gradientColors = document.querySelectorAll('.gradient_color');
const copyButtons = document.querySelectorAll('.copyButton');
gradientColors.forEach((div,index)=>{
const color = copyButtons[index].dataset.clipboardText;
div.style.background=color;
});
.gradient_color {
width: 50px;
height: 50px;
border: 1px solid;
}
<div class="box">
<div class="gradient_color"></div>
<div class="copyButton" data-clipboard-text="linear-gradient(to right, #8e2de2,#8f6ba8)">
COPY
</div>
</div>
<div class="box">
<div class="gradient_color"></div>
<div class="copyButton" data-clipboard-text="linear-gradient(to right, #ee9ca7, #ffdde1)">
COPY
</div>
</div>
I hope this answers your question?
let elem_with_color_class = document.querySelectorAll('.copyButton');
elem_with_color_class.forEach((elem) => {
elem.addEventListener('click', function() {
let parent = this.parentElement;
let target_elem = parent.querySelector('.gradient_color');
target_elem.style.background = this.getAttribute('data-clipboard-text');
});
});
.box {
display: inline-flex;
justify-content: space-around;
align-items: center;
}
.gradient_color {
height: 30px;
width: 50px;
border: 1px solid #aaa;
margin: 1em;
display: inline-block;
}
.copyButton {
height: 30px;
width: 100px;
font-size: 12px;
font-weight: 500;
font-family: "Quicksand", sans-serif;
display: inline-flex;
justify-content: center;
align-items: center;
cursor: pointer;
color: #fff;
user-select: none;
outline: none;
background: darkseagreen;
border-radius: 2px;
box-shadow: 0 5px 10px 0 rgba(0, 0, 0, 0.10);
}
<div class="box">
<div class="gradient_color"></div>
<div class="copyButton" data-clipboard-text="linear-gradient(to right, #8e2de2,#8f6ba8)">COPY</div>
</div>
<div class="box">
<div class="gradient_color"></div>
<div class="copyButton" data-clipboard-text="linear-gradient(to right, #ee9ca7, #ffdde1)">COPY</div>
</div>
Please run this demo:
.app {
background:pink;
width: 90vw;
overflow: hidden;
}
.app__item {
background: lightblue;
width: 200px;
float :left;
margin:5px;
height: 40px;
}
.app__item:last-child {
float: right;
}
.app__item--size2 {
height: 90px;
}
<div class="app">
<div class="app__item app__item--size2">1</div>
<div class="app__item">2</div>
<div class="app__item">3</div>
<div class="app__item">4</div>
<div class="app__item">5</div>
<div class="app__item">6</div>
<div class="app__item">7</div>
<div class="app__item">8</div>
<div class="app__item">9</div>
<div class="app__item">10</div>
<div class="app__item">
<button>search</button>
</div>
</div>
Please notice the red color text which is what I want:
How to Let Float Items Split the Blank Area in Average?
This gif point out what I want and also the reason why I am using float layout.
If using flex, the result would be
.app {
background:pink;
width: 80vw;
display: flex;
flex-flow: row wrap;
}
.app__item,
.app__item_wrapper {
margin:5px;
width: 200px;
flex: 0 0 auto;
}
.app__item {
background: lightblue;
height: 40px;
}
.app__item_wrapper {
display: flex;
flex-flow: column;
justify-content: space-between;
}
.app__item--size2 {
height: 90px;
}
.app__item--inner {
margin:0;
flex: 0 0 auto;
}
<div class="app">
<div class="app__item app__item--size2">1</div>
<div class=" app__item_wrapper app__item--size2">
<div class="app__item app__item--inner">2</div>
<div class="app__item app__item--inner">3</div>
</div>
<div class=" app__item_wrapper app__item--size2">
<div class="app__item app__item--inner">4</div>
<div class="app__item app__item--inner">5</div>
</div>
<div class="app__item">6</div>
<div class="app__item">7</div>
<div class="app__item">8</div>
<div class="app__item">
<button>search</button>
</div>
</div>
And the con is that it won't work well when viewport is changing. See this:
and this is the con:
If I understand correctly, you're wanting the cells to the right of "cell 1" to stretch-to-fill the reaming horizontal space of the enclosing div (with pink background).
You could use CSS Grid to achieve this as shown below:
.app {
background:pink;
width: 90vw;
padding:5px;
display:grid;
/* Cause first column with to be 200px, remaining two columns
to scale to fit remaining width */
grid-template-columns: 200px repeat(2, 1fr);
/* Set spacing between cells */
grid-gap:10px;
}
.app__item {
background: lightblue;
width: 100%;
height: 40px;
}
.app__item--size2 {
/* Cause top left cell to occupy two rows */
grid-row: 1 / 3;
height:100%;
}
<div class="app">
<div class="app__item app__item--size2">1</div>
<div class="app__item">2</div>
<div class="app__item">3</div>
<div class="app__item">4</div>
<div class="app__item">5</div>
<div class="app__item">6</div>
<div class="app__item">7</div>
<div class="app__item">8</div>
<div class="app__item">9</div>
<div class="app__item">10</div>
<div class="app__item">
<button>search</button>
</div>
</div>
Thank #Dacre Denny for giving me inspiration. Finally, I got it.
.app {
background:pink;
width: 90vw;
padding:5px;
display:grid;
grid-template-columns: repeat(auto-fit,200px);
justify-content:space-evenly;
grid-gap: 5px;
}
.app__item {
background: lightblue;
width: 200px;
height: 40px;
}
.app__item--size2 {
/* Cause top left cell to occupy two rows */
grid-row: 1 / 3;
height:100%;
}
.app__item:last-child {
grid-column-end: -1
}
<div class="app">
<div class="app__item app__item--size2">1</div>
<div class="app__item">2</div>
<div class="app__item">3</div>
<div class="app__item">4</div>
<div class="app__item">5</div>
<div class="app__item">6</div>
<div class="app__item">7</div>
<div class="app__item">8</div>
<div class="app__item">9</div>
<div class="app__item">10</div>
<div class="app__item">
<button>search</button>
</div>
</div>
See this gif when viewport is changing.
I have class numberdisplay which I want to display number inside a handing board.
I have the below code which display nine boxes exactly inside a name board with responsiveness.
My problem is that the digit of numberdisplay didn't get displayed in hanging board and is not responsive and is fixed, when window resizes the size an alignment changes.
I want the numberdisplayed to be fixed inside the hanging board and should be responsive.
How can this be done and how to achieve this?
.box {
width: calc(33.3% - 4px);
display: inline-block;
border-radius: 5px;
border: 2px solid #333;
border: #000 border-color: #e6e600;
margin: -2px;
border-radius: 10%;
background-color: #99ffff;
}
.numberdisplay {
margin-left: 73.99%;
margin-top: 20%;
margin-bottom: 100%;
background-color: #ffff00 2px;
border: px solid #000066;
}
.containerr {
border: px solid #FF3399;
}
.pic {
background-size: 100% 100%;
}
p {
font: "Courier New", Courier, monospace;
color: #000000;
text-align: center;
}
body {
background-image: url(https://image.ibb.co/eV5WW9/background.jpg);
background-size: 100vw 100vh;
}
.box {
height: 15vh;
display: inline-flex;
align-items: center;
justify-content: center
}
.container2 {
width: 35vw;
position: fixed;
top: 41.5vh;
left: 14vw;
}
.box p {
font-size: calc(2vw + 10px);
}
<div class="container2">
<div class="containerr">
<div class="pic" id="content">
<div id="container">
<div class="box" id="10">
<p name="values" data-item-index="0">1:40</p>
</div>
<div class="box" id="11">
<p name="values" data-item-index="7">8:10</p>
</div>
<div class="box" id="12">
<p name="values" data-item-index="4">5:35</p>
</div>
</div>
<div id="2container">
<div class="box" id="10">
<p name="values" data-item-index="11">12:50</p>
</div>
<div class="box" id="11">
<p name="values" data-item-index="9">10:40</p>
</div>
<div class="box" id="12">
<p name="values" data-item-index="11">12:50</p>
</div>
</div>
<div id="3container">
<div class="box" id="10">
<p name="values" data-item-index="0">1:40</p>
</div>
<div class="box" id="11">
<p name="values" data-item-index="3">4:45</p>
</div>
<div class="box" id="12">
<p name="values" data-item-index="2">3:50</p>
</div>
</div>
</div>
</div>
</div>
<div class="numberdisplay" id="2">
<img src="https://via.placeholder.com/75x75?text=11" style="width:160px; height:160px; border-radius: 50%;" border="rounded" />
</div>
I can't think of any way to calculate the width and height of a part of an image using CSS or JS.
But, I can calculate it by hit-and-trial method and it comes out that the hanging board was 0.16% of the background width always.
Changes done in CSS:
/* for .numberdisplay */
margin-left: 72.5%;
margin-top: 16%;
/* for body */
background-size: 100vw auto;
The Javascript:
var body = document.querySelector('body');
var number11 = document.querySelector('.numberdisplay img');
function changeSize() {
var length = parseInt(window.getComputedStyle(body, null).width) * 0.16; // based on hit and trial
number11.style.height = length + 'px';
number11.style.width = length + 'px';
}
window.onresize = changeSize;
changeSize();
I had used window.getComputedStyle(Element, null).property to retrieve width of body.
Here is a Pen that will display the responsiveness.
I am not very good with CSS, so I am posting my problem here hoping for a solution:
What I need is following:
I need an HTML row/div/line that shows a date and after the date it shows a bar which will be a percentage of the remaining screen width.
Like so:
2015-11-17 ---------------------(50%)
2015-11-18 ------------------------------------------- (80%)
2015-11-19 ==================================================== (100%)
If you will please consider in the dashes as a proper bar (like 10px height for e.g.). You might notice that 50% and 80% have ---- while 100% has ====.
This is because for any percentage less than 100 I want the bar to be a mixed color like blue and white combo. For the 100% it will be a solid blue color bar.
I am trying to achieve this using HTML/CSS only, but I find my expertise to be lacking.
So far, I have following HTML/CSS:
<div style="padding-top: 10px;padding-bottom:10px; width:100%">
<div style='float:left'><strong>Date </strong>{{Today.date}}</div>
<div style='float:left;background-color:red;width:100%'></div>
</div>
The above code does not even show the second div with red background :(
Any pointers in helping me solve this is very much appreciated!
Flexbox could help here depending on your browser support requirements.
.wrap {
width: 80%;
margin: 1rem auto;
font-size: 24px;
display: flex;
align-items: center;
border: 1px solid grey;
}
.date {
padding: 0 1em;
}
.bar {
height: 10px;
background: #f00;
}
.bar-50 {
flex: .5;
}
.bar-80 {
flex: .8;
}
.bar-100 {
flex: 1;
}
<div class="wrap">
<div class="date">2015-11-17</div>
<div class="bar bar-50"></div>
</div>
<div class="wrap">
<div class="date">2015-11-18</div>
<div class="bar bar-80"></div>
</div>
<div class="wrap">
<div class="date">2015-11-19</div>
<div class="bar bar-100"></div>
</div>
Sneaky version with pseudo-element instead of extra HTML
.bar {
width: 80%;
margin: 1rem auto;
font-size: 24px;
display: flex;
align-items: center;
border: 1px solid grey;
}
.date {
padding: 0 1em;
}
.bar::after {
content: '';
height: 10px;
background: #f00;
}
.bar-50:after {
flex: .5;
}
.bar-80:after {
flex: .8;
}
.bar-100:after {
flex: 1;
}
<div class="bar bar-50">
<div class="date">2015-11-17</div>
</div>
<div class="bar bar-80">
<div class="date">2015-11-18</div>
</div>
<div class="bar bar-100">
<div class="date">2015-11-19</div>
</div>
Perhaps more semantically, use a progress element and a label.
Progess Element # MDN
div {
margin: 10px;
}
<div>
<label for="alpha">2015-11-17</label>
<progress id="alpha" value="50" max="100">50 %</progress>
</div>
<div>
<label for="beta">2015-11-18</label>
<progress id="beta" value="70" max="100">70 %</progress>
</div>
<div>
<label for="gamma">2015-11-19</label>
<progress id="gamma" value="100" max="100">70 %</progress>
</div>
You can try this
<div style="padding-top: 10px;padding-bottom:10px; width:100%;position: relative;">
<div style="float: left;width: 50%;display: inline-block;"><strong>Date </strong>{{Today.date}}</div>
<div style="float:left;width: 50%;height: 10px;display: inline-block;">
<div class="progress" style="background-color:red;width: 100%;height: 100%;">
</div></div>
</div>
Trying to do this with CSS only.
Have a Canvas on the left side that I want to shrink both width and height as the window is resized. Want the center and right divs to shrink in height to match the canvas. Don't want center and right divs to move under the canvas.
<div class="container">
<div class="left">
<canvas id="draw" width="250" height="300"></canvas>
</div>
<div id="center" class="center"></div>
<div id="right" class="right"></div>
</div>
Fiddle: https://jsfiddle.net/mrx6zk27/
Any help would be appreciated. Expecting I will probably need JavaScript to align the heights, but want to reduce JavaScript as much as possible.
Update: Fiddle using table layout (doesn't work): https://jsfiddle.net/mrx6zk27/2/
I sugest to use flexbox, It's required to update the center and right divs in the markup slightly for this solution. See the code snippet and demo as follows.
jsfiddle
var c = document.getElementById("draw");
ctx = c.getContext("2d");
ctx.fillStyle = "red";
ctx.fillRect(0, 0, 250, 300);
ctx.fillStyle = "white";
ctx.font = "bold 40pt Arial";
ctx.fillText("CANVAS", 10, 100);
tmp = "";
for (var i = 0; i < 100; i++) {
tmp += "<p>" + i + "</p>";
}
document.getElementById("center").innerHTML = tmp;
document.getElementById("right").innerHTML = tmp;
.container {
max-width: 650px;
margin: 0 auto;
border: 1px solid black;
display: flex;
}
.container > div {
position: relative;
min-width: 0;
}
.left {
max-width: 250px;
width: auto;
}
.left canvas {
display: block;
max-width: 100%;
height: auto;
}
.center {
flex: 0 0 200px;
overflow-y: scroll;
background-color: blue;
}
.right {
flex: 0 0 200px;
overflow-y: scroll;
background-color: green;
}
.scroll {
position: absolute;
width: 100%;
}
<div class="container">
<div class="left">
<canvas id="draw" width="250" height="300"></canvas>
</div>
<div class="center"><div id="center" class="scroll"></div></div>
<div class="right"><div id="right" class="scroll"></div></div>
</div>
Not very sure if this is what you want, but I think you use display:table.
<div id="container" style="display: table; width:100%;">
<div style="display: table-cell; background-color: red; width:-100%; height:200px"></div>
<div style="display: table-cell; background-color: blue; width:300px;"></div>
<div style="display: table-cell; background-color: green; width: 300px;"> </div>
</div>
http://jsfiddle.net/8mpx1kok/2/