You were right to call them pips, that's what they are called on cards :) The vertical centering on the 7 and 8 middle pips is off from the correct placement, but otherwise it looked all correct to me! Source: Used to work with a company that made custom playing cards.
I think exercises like these can really help teach the thought process behind approaching new/unknown challenges. Planned out tutorials are great, but seeing someone who knows what they're doing step through their thought process and explain what they're thinking is a great way to learn, at least for me. You're videos have helped me so much in my web dev units at University. Also, we do the same tongue click thing when we're thinking about something. I thought it was funny 😂
Same. It would also save you having to do so many per card css rules and get rid of some of the pip population code. You could just have them hidden and use an object where each card has an array of nth pip elements that should be shown. Unhide them all. Also could include the large pip as the last one. const pipPositions = { A: [...], 2: [...] 3: [...] ... }
BTW, for anybody trying this on their own, you can get the "7" right by using a more complicated grid with 16 rows. I ended up using 6 columns as well in order to more precisely position pips on face cards. This is a great exercise for gaining experience with grid layouts.
Once you get to the fourth card all following numbered cards have the 4 pips in the corner which you could have them all with the same css rule, the same would go for any cards that share pips such as 8 and 10. As well within the stylesheet you could create comment blocks as a header for when css rules start for say Card 2, Card 3 just to help when scrolling over repetive regions otherwise I'm about 40 minutes in and seems like a fun challenge I definitely want to give a go.
Nice work! You could share some of the rules. For 2/3 they have the same positioning for the 2 pips with the additional rule for the 3. The same with 4/5 for the first 4 pips. The same with 6/7/8 for the first 6 pips and 7/8 for the 8th pip. The same with 9/10 for the first 8 pips -- they differ in position of the middle pips so can't share the 9th pip. Getting fancier, 3/5/9/A all have the same center pip, so can share rules for that. Likewise, 8/10 both share the same middle row, so can share rules for that (pip 7/9 for the top, pip 8/10 for the bottom). Getting fancier still, cards 4-10 all have pips in the 4 corners, so you could group those and have specific rules for placing the other outer pips as noted in my first paragraph, i.e. for 6/7/8 and 9/10 respectively. I think that's the best you can do rule wise.
Kyle, this raw content is amazing!! Definitely keep making more videos like this. Really helps me learn how to think through things better and also realize that even amazing developers like you go through the same stuff. Love it!!
It was interesting to see that you had some of the same problems I had when I created a deck of cards. I used more javascript, by creating arrays for my cards and you were heavy on the CSS. I also had problems with the corner 10's and the positioning of the "pips" as you called them but I used relative, absolute to position the "pips". Your programming was much more logically arranged than mine but the javascript arrays that included the data for my cards were probably about the same size byte-wise as the CSS used for your cards. Your approach to the this project was excellent. Different than mine but similar. However, it took you an hour. It took me days.LOL!!
Sorry man I had to crap out but I did add this to watch tomorrow. I enjoyed seeing the first 20 minutes so far. I'm a back-end dev but appreciate videos that show how our minds work to solve problems. I typically use brute force then find something better. But I'm out to sea on the front-end, you're using new stuff I've never seen in CSS. You rock. Will watch the rest tomorrow.
You can use attr function and your data-value attribute with ::before and ::after pseudo elements to style your corner numbers. Will make your markup cleaner, when you no longer need to declare these two element for each card.
It is great to see you coding “on live”, I mean, to see you coding something for the first time instead of the usual videos explaining something you already did. It is really pretty interesting to see how you are working. Also, it was very funny, so human...
It's probably an unpopular opinion but this video shows a fundamental problem with modern CSS (and HTML). All structure and layout should be defined inside HTML, It should be easy to create a layout template in HTML and repeat it X,Y times and fill it with specific data. IMO Grid doesn't really belong in CSS. CSS is for styling and html is for data and the layout of the data. It would make JavaScript manipulation so much easier and more effective. Don't get me wrong I think modern CSS has a lot great new features but HTML has so much unused potential and deserve much more love attention!
Grid has 100% its place in CSS. It would be a nightmare trying to code complex grid systems with HTML only (even if you're using a modern JS framework) and would likely bloat up your DOM size in more complex apps. After all, grid is just a way of styling / positioning items inside itself
Love the "live coding." I know you were focused on recreating those cards but I would have taken liberties with the format of the pips when you got to the 7. Personally I think a '2 3 2' column/row format looks cleaner.
Your 7 and 8 would look better with either 5 rows or the middle column being row span 3. Right now you place items in row 1, 2 and 4 which will be off center. You want row 2.5 and row 5.5 effectively for those middle items. Great video.
Wouldn't it be interesting if you would use a CSS preprocessor like sass or so? I think this would be extremely interesting to watch and would save a lot of work!! Also in this general kind of episodes not only for this one!
Would using grid-template-areas be more of a compact and readable solution? It would just define the grid container layout graphically in one css statement instead of playing with grid-row-start and grid-column-start with all grid items for all grid containers. Good video, anyways! :)
I think I found a pattern: if you look at the columns of pips, it's just a flex with equal spacing between elements except sometimes you have to offset the middle one (reduce height)
Great, I am inline with all the codes and thought process.i think I would also design this problem in a same manner. only change would have been I would not have created two version of SVG of same image instead I would have used fill property in css
I remember my first time trying to create logic for evaluating strength of poker hands. Was fun and not easy while starting. Should give it a try now :D
Hey thanks for the video! Can you make a video how to do an App for learning a language? You see the sentence of the language and then you have to klick on different building blocks - and then in a certain order it has to be placed. Or sth like that? Thanks!
Way easier to make unneeded pips invisible! 🙂80 lines of CSS total. (Plus 20 of JS for HTML). But the stuff unique to each card is literally just 7 lines of CSS: .card:nth-child(1) .pip:nth-child(n+2) { display:none; } .card:nth-child(2) .pip:nth-child(2) { display: none; } .card:nth-child(4) .pip:nth-child(3) { display: none; } .card:nth-child(6) .pip:nth-child(3n) { display: none; } .card:nth-child(7) .pip:nth-child(6) { opacity: 0; } .card:nth-child(9) .pip:nth-child(6n-3) { opacity: 0; } .card:nth-child(10) .pip:nth-child(6) { opacity: 0; } Also, the trick to kerning the '10' text is to use 'IO' (capital letters i and o). (Okay, I also skipped the face cards, because there's no way to do them justice. You can copy the Ace to add chess pieces if you want. :-P ) Whole thing on Fiddle: jsfiddle.net/JonMichaelGalindo/fzum5r73/6/
I wonder if the spacing issue could be solved by making the pips take up 3 rows, so you have one for the top middle and bottom part of the images for when a pip overlaps the top and bottom of another pip. That way, you can ensure that each of the offset pips overlap both pips in the other columns. You could then also fix the height of the rows so they are all consistent irrespective of whether or not they are showing a pip image.
Maybe having 3 columns and 4 rows would have worked out? I think you should be able to do the overlap but i haven't tested it. For example, the top overlapping symbol would start at row 1 and spanning 2 should go from row 1 - 3 and then if you align all items centre it should just work out, at least in my mind lol.
16:00 you are not seeing things lol, there is more space in bottom because you placed the second pip in the 7th row while the first pip is placed on the first row the second pip has space of one extra row
In this situation i would draw the pips using a css variable with an url encoded SVG on either background-image or content. The idea is to reduce http calls and don't flood the Dom with extra elements. Any drawbacks I am missing? I like the technique
Great video, Kyle. I think it's possible to use [data-suit="hearts"] .pip svg path { fill: "red"} in CSS to change the image color without having to duplicate the svg files for J, Q and K.
@@Da-mD you may be correct. Sometimes we need 2, 3, 5 or 7 even rows... there's no simple arrangement there.... maybe instead of positioning them, the solution should be changing the number of columns based on the value of the card
This channel is my inspiration. I have learnt and watched so many of your videos that it motivated me to start my own channel and do my best at creating JavaScript content. Thank you Kyle. Also anybody watching this, do checkout my channel, would appreciate some feedback and support. Thanks
You were right to call them pips, that's what they are called on cards :)
The vertical centering on the 7 and 8 middle pips is off from the correct placement, but otherwise it looked all correct to me!
Source: Used to work with a company that made custom playing cards.
This is really cool to see you problem solve and debug on the go! It's a great insight as to how you think. Keep the great vids coming :D
I think exercises like these can really help teach the thought process behind approaching new/unknown challenges. Planned out tutorials are great, but seeing someone who knows what they're doing step through their thought process and explain what they're thinking is a great way to learn, at least for me. You're videos have helped me so much in my web dev units at University.
Also, we do the same tongue click thing when we're thinking about something. I thought it was funny 😂
I would have had all the pips on every card, but only show the needed ones. The spacing issues are a lot easier to deal with that way.
Same. It would also save you having to do so many per card css rules and get rid of some of the pip population code. You could just have them hidden and use an object where each card has an array of nth pip elements that should be shown. Unhide them all. Also could include the large pip as the last one.
const pipPositions = {
A: [...],
2: [...]
3: [...]
...
}
I enjoyed this style of video in real time problem solving, good job
BTW, for anybody trying this on their own, you can get the "7" right by using a more complicated grid with 16 rows. I ended up using 6 columns as well in order to more precisely position pips on face cards. This is a great exercise for gaining experience with grid layouts.
thanks :)
Once you get to the fourth card all following numbered cards have the 4 pips in the corner which you could have them all with the same css rule, the same would go for any cards that share pips such as 8 and 10. As well within the stylesheet you could create comment blocks as a header for when css rules start for say Card 2, Card 3 just to help when scrolling over repetive regions otherwise I'm about 40 minutes in and seems like a fun challenge I definitely want to give a go.
for everyone that really want to fix the 8...
make the grid 3 columns, 16 rows and each pip span 2
then the posiotions are: (rows at columns: 1 | 2 | 3)
2: ( ~ | 2, 14 | ~ )
3: ( ~ | 2, 8, 14 | ~ )
4: ( 2, 14 | ~ | 2, 14 )
5: ( 2, 14 | 8 | 2, 14 )
6: ( 2, 8, 14 | ~ | 2, 8, 14 )
7: ( 2, 8, 14 | 5 | 2, 8, 14 )
8: ( 2, 8, 14 | 5, 11 | 2, 8, 14 )
9: ( 2, 6, 10, 14 | 8 | 2, 6, 10, 14 )
10: ( 2, 6, 10, 14 | 4, 12 | 2, 6, 10, 14 )
A: ( ~ | 8 | ~ )
and if u make it json, everything become easyier
did it for you:
{
"J": [[], [8], []], "Q": [[], [8], []], "K": [[], [8], []],
"A": [[], [8], []], "2": [[], [2, 14], []], "3": [[], [2, 8, 14], []],
"4": [[2, 14], [], [2, 14]], "5": [[2, 14], [8], [2, 14]], "6": [[2, 8, 14], [], [2, 8, 14]],
"7": [[2, 8, 14], [5], [2, 8, 14]], "8": [[2, 8, 14], [5, 11], [2, 8, 14]],
"9": [[2, 6, 10, 14], [8], [2, 6, 10, 14]], "10": [[2, 6, 10, 14], [4, 12], [2, 6, 10, 14]]
}
then you can do something like this:
document.querySelectorAll(".card").forEach((card) => {
const sign = card.getAttribute("data-sign")
const val = card.getAttribute("data-val")
POSITIONS[val].forEach((rows, col) => {
rows.forEach((row) => {
const pip = document.createElement("img"
pip.setAttribute("src", `./imgs/${sign}.svg`)
pip.classList.add("pip")
pip.style.setProperty("--row", row)
pip.style.setProperty("--column", col+1)
pip.classList.toggle("flip", row > 8)
card.append(pip)
})
})
card.append(createCornerNumber("top", val))
card.append(createCornerNumber("bottom", val))
})
Nice work!
You could share some of the rules. For 2/3 they have the same positioning for the 2 pips with the additional rule for the 3. The same with 4/5 for the first 4 pips. The same with 6/7/8 for the first 6 pips and 7/8 for the 8th pip. The same with 9/10 for the first 8 pips -- they differ in position of the middle pips so can't share the 9th pip.
Getting fancier, 3/5/9/A all have the same center pip, so can share rules for that. Likewise, 8/10 both share the same middle row, so can share rules for that (pip 7/9 for the top, pip 8/10 for the bottom).
Getting fancier still, cards 4-10 all have pips in the 4 corners, so you could group those and have specific rules for placing the other outer pips as noted in my first paragraph, i.e. for 6/7/8 and 9/10 respectively.
I think that's the best you can do rule wise.
Nice to see that my thinking process somehow matches to solve this problem. I am glad, thanks a lot.
Kyle, this raw content is amazing!! Definitely keep making more videos like this. Really helps me learn how to think through things better and also realize that even amazing developers like you go through the same stuff. Love it!!
This series of live coding is very helpful. Thank you
It was interesting to see that you had some of the same problems I had when I created a deck of cards. I used more javascript, by creating arrays for my cards and you were heavy on the CSS. I also had problems with the corner 10's and the positioning of the "pips" as you called them but I used relative, absolute to position the "pips". Your programming was much more logically arranged than mine but the javascript arrays that included the data for my cards were probably about the same size byte-wise as the CSS used for your cards. Your approach to the this project was excellent. Different than mine but similar. However, it took you an hour. It took me days.LOL!!
Sorry man I had to crap out but I did add this to watch tomorrow. I enjoyed seeing the first 20 minutes so far. I'm a back-end dev but appreciate videos that show how our minds work to solve problems. I typically use brute force then find something better. But I'm out to sea on the front-end, you're using new stuff I've never seen in CSS. You rock. Will watch the rest tomorrow.
You can use attr function and your data-value attribute with ::before and ::after pseudo elements to style your corner numbers. Will make your markup cleaner, when you no longer need to declare these two element for each card.
It is great to see you coding “on live”, I mean, to see you coding something for the first time instead of the usual videos explaining something you already did. It is really pretty interesting to see how you are working. Also, it was very funny, so human...
Who told you Kyle didn't prepare the "contents" ? :)
It's probably an unpopular opinion but this video shows a fundamental problem with modern CSS (and HTML). All structure and layout should be defined inside HTML, It should be easy to create a layout template in HTML and repeat it X,Y times and fill it with specific data. IMO Grid doesn't really belong in CSS. CSS is for styling and html is for data and the layout of the data. It would make JavaScript manipulation so much easier and more effective. Don't get me wrong I think modern CSS has a lot great new features but HTML has so much unused potential and deserve much more love attention!
Grid has 100% its place in CSS. It would be a nightmare trying to code complex grid systems with HTML only (even if you're using a modern JS framework) and would likely bloat up your DOM size in more complex apps. After all, grid is just a way of styling / positioning items inside itself
Loved the video, thanks! One suggestion is that you can group together some pip rules. For example the first 6 pips are the same for 6, 7 and 8
15:02 minecraft villager sound #69
Thank you so much!
I suggest you to make a video about painting using CSS only without SVGs :)
Love the "live coding." I know you were focused on recreating those cards but I would have taken liberties with the format of the pips when you got to the 7. Personally I think a '2 3 2' column/row format looks cleaner.
Instead of --width and --height variables at 4:25 you could simply set width to 10em and aspect-ratio property.
Your 7 and 8 would look better with either 5 rows or the middle column being row span 3.
Right now you place items in row 1, 2 and 4 which will be off center. You want row 2.5 and row 5.5 effectively for those middle items.
Great video.
Wouldn't it be interesting if you would use a CSS preprocessor like sass or so? I think this would be extremely interesting to watch and would save a lot of work!! Also in this general kind of episodes not only for this one!
Would using grid-template-areas be more of a compact and readable solution? It would just define the grid container layout graphically in one css statement instead of playing with grid-row-start and grid-column-start with all grid items for all grid containers. Good video, anyways! :)
I studied a bit those pip positions and it looks like we need 12 grid rows to set exact positions for those middle column pips.
I think I found a pattern: if you look at the columns of pips, it's just a flex with equal spacing between elements except sometimes you have to offset the middle one (reduce height)
I was able to clean up the CSS by implementing a config for pip placement in the javascript file. Each pip has a position (1-11), but positions 2, 4, 6, and 8 can have alterations in their positioning.
In the else clause of addCardElements, I'm grabbing the config at the index of the value variable. This value contains an array of the pip positions. I pass the position to the createPip function and createPip adds the position class to the pip element. I then styled each position class instead of accessing each card by its data-value.
script.js
const placementConfig = {
'2': ["two-end", "eight-end"],
'3': ["two-end", "five", "eight-end"],
'4': ["one", "three", "ten", "eleven"],
'5': ["one", "three", "five", "ten", "eleven"],
'6': ["one", "three", "four-center", "six-center", "ten", "eleven"],
'7': ["one", "two", "three", "four-center", "six-center", "ten", "eleven"],
'8': ["one", "two", "three", "four-center", "six-center", "eight", "ten", "eleven"],
'9': ["one", "three", "four", "five", "six", "seven", "nine", "ten", "eleven"],
'10': ["one", "two", "three", "four", "six", "seven", "eight", "nine", "ten", "eleven"]
}
function addCardElements(card) {
...
} else {
for (let i = 0; i < valueAsNumber; i++) {
const positions = placementConfig[value]
const pipPosition = positions[i]
card.append(createPip(pipPosition))
}
...
}
function createPip(position) {
const pip = document.createElement("div")
pip.classList.add("pip")
pip.classList.add(position)
return pip
}
style.css
.one {
grid-row-start: 1;
grid-column-start: 1;
}
.two {
grid-row-start: 2;
grid-column-start: 2;
}
.two-end {
grid-row-start: 1;
grid-column-start: 2;
}
.three {
grid-row-start: 1;
grid-column-start: 3;
}
.four-center {
grid-row-start: 4;
grid-column-start: 1;
}
.four {
grid-row-start: 3;
grid-column-start: 1;
}
.five {
grid-row-start: 4;
grid-column-start: 2;
}
.six-center {
grid-row-start: 4;
grid-column-start: 3;
}
.six {
grid-row-start: 3;
grid-column-start: 3;
}
.seven {
grid-row-start: 5;
grid-column-start: 1;
transform: rotate(180deg);
}
.eight-end {
grid-row-start: 8;
grid-column-start: 2;
transform: rotate(180deg);
}
.eight {
grid-row-start: 6;
grid-column-start: 2;
transform: rotate(180deg);
}
.nine {
grid-row-start: 5;
grid-column-start: 3;
transform: rotate(180deg);
}
.ten {
grid-row-start: 7;
grid-column-start: 1;
transform: rotate(180deg);
}
.eleven {
grid-row-start: 7;
grid-column-start: 3;
transform: rotate(180deg);
}
Fellow Kyle, try negative ch and/r ex values for letter spacing, its cool. em is a vertical unit.
I'm glad you submitted this to github. I'd like to submit an alternative method. Not that yours isn't quite nice. Just an alternative.
Great, I am inline with all the codes and thought process.i think I would also design this problem in a same manner. only change would have been I would not have created two version of SVG of same image instead I would have used fill property in css
Awesome video ... !! May I know what is your keyboard !! becoz it sounds greattt !!
I remember my first time trying to create logic for evaluating strength of poker hands. Was fun and not easy while starting. Should give it a try now :D
I would use 3x4 for grid and grid-template-area so we can center middle one pip of card 5(for example) using same area on 3 middle places.
Hey thanks for the video! Can you make a video how to do an App for learning a language? You see the sentence of the language and then you have to klick on different building blocks - and then in a certain order it has to be placed. Or sth like that? Thanks!
Way easier to make unneeded pips invisible! 🙂80 lines of CSS total. (Plus 20 of JS for HTML).
But the stuff unique to each card is literally just 7 lines of CSS:
.card:nth-child(1) .pip:nth-child(n+2) { display:none; }
.card:nth-child(2) .pip:nth-child(2) { display: none; }
.card:nth-child(4) .pip:nth-child(3) { display: none; }
.card:nth-child(6) .pip:nth-child(3n) { display: none; }
.card:nth-child(7) .pip:nth-child(6) { opacity: 0; }
.card:nth-child(9) .pip:nth-child(6n-3) { opacity: 0; }
.card:nth-child(10) .pip:nth-child(6) { opacity: 0; }
Also, the trick to kerning the '10' text is to use 'IO' (capital letters i and o).
(Okay, I also skipped the face cards, because there's no way to do them justice. You can copy the Ace to add chess pieces if you want. :-P )
Whole thing on Fiddle: jsfiddle.net/JonMichaelGalindo/fzum5r73/6/
Great video Kyle. You nailed it. Can you imagine trying to do this without grid or flex?
“Absolute” hell ;)
Easy tables
I wonder if the spacing issue could be solved by making the pips take up 3 rows, so you have one for the top middle and bottom part of the images for when a pip overlaps the top and bottom of another pip. That way, you can ensure that each of the offset pips overlap both pips in the other columns. You could then also fix the height of the rows so they are all consistent irrespective of whether or not they are showing a pip image.
i think you can optimize that huge css, if you just write classes for the pip positions, and add these classes from js to the pip class list
The letter-spacing needed to not apply to the first character of the number strings. It caused everything to shift over and not be properly centred.
Maybe having 3 columns and 4 rows would have worked out? I think you should be able to do the overlap but i haven't tested it. For example, the top overlapping symbol would start at row 1 and spanning 2 should go from row 1 - 3 and then if you align all items centre it should just work out, at least in my mind lol.
For the 7 and 8 cards, couldn't adjusting the span be a potential solution? Seems like they should either span 1 or span 3.
enjoyed this one
As somebody who sucks at CSS and hates it, this is really interesting to watch.
These are nice, when is the full game ready 😜
To clean up the CSS a little, could you do something like: if grid-row-start > 4 then add the transform rotate? :-)
Then the location will be correct
[data-value="7"] .pip:nth-child(3),
[data-value="8"] .pip:nth-child(3) {
grid-row-start: 2;
grid-column-start: 2;
grid-row-end: span 3;
}
[data-value="8"] .pip.down:nth-last-child(5) {
grid-row-start: 5;
grid-column-start: 2;
grid-row-end: span 3;
}
You might need 15 rows with a rowspan of 3. And force a height on the rows
I think you could fix the centering problem with the 7, 8 & 9 by using 9 columns and having a space between each element
Amazing!
Why not change the stroke value in CSS?
Why didn't you use Unicode for the pips, instead of SVG?
Great videos 👍
The real question is can you shred on that Jackson behind you?
Can you create a slide puzzle with Javascript?
16:00 you are not seeing things lol, there is more space in bottom because you placed the second pip in the 7th row while the first pip is placed on the first row the second pip has space of one extra row
I have often asked candidates how they would model a deck of cards in JavaScript. I love the idea of replicating a deck using CSS.
Great Content.
In this situation i would draw the pips using a css variable with an url encoded SVG on either background-image or content. The idea is to reduce http calls and don't flood the Dom with extra elements. Any drawbacks I am missing? I like the technique
One drawback is that if you are doing more atomic css and splitting your files, such images don't get cached
for card seven maybe have card eight but with an invisible heart to just take space, and you dont have to do much critical thinking
Next - guitar with CSS
48:12 you can just add empty space next to the 10 " "
Why not use SCSS?
Wow I’m currently coding a blackjack app this is perfect timing lol
If you would like a function is algo for creating a deck of cards, I can do a video on it. So when are we going to collaborate Kyle? :)
Thanks for always helping us man🍻
How can I use the svg didint quite get it?😅
Great video, Kyle.
I think it's possible to use
[data-suit="hearts"] .pip svg path { fill: "red"}
in CSS to change the image color without having to duplicate the svg files for J, Q and K.
if it would be inline svg yes otherwise no ;)
harder than it looks? nah, that looks hard from the start
40:22 Aahhhhhhooookey
After a while you get used to simple things becoming complex when trying to simulate them in computers
I didn't get to the end yet, but you need 10 rows in total to align everything fine
Look at the 8 card, the suits should not be overlapping, and they need 5 rows, considering each takes 2, you need 10 in total.
@@CyroMuniz i found it only possible with 16, cause evrything is good except the 8 middle have to get 1/2 row down, with 16 it is possible
@@Da-mD you may be correct. Sometimes we need 2, 3, 5 or 7 even rows... there's no simple arrangement there.... maybe instead of positioning them, the solution should be changing the number of columns based on the value of the card
Bro we need a keyboard shortcut cheat sheet...
Umm, did I misunderstand the meaning of easy?
nicee
body {
background-image:
url(“cards.png”);
}
Simple
no vector graphic, more blurry when more zoom in, useless website, 0/10
u're not create the shapes in css? thats cheating bruh
Kyle you stiff robot
Guys! do you actually enjoy doing this boring stuff ? please tell me
This channel is my inspiration. I have learnt and watched so many of your videos that it motivated me to start my own channel and do my best at creating JavaScript content. Thank you Kyle.
Also anybody watching this, do checkout my channel, would appreciate some feedback and support. Thanks