DEV Community

Sloan the DEV Moderator
Sloan the DEV Moderator

Posted on

How do you organize CSS files?

This is an anonymous question sent in by a member who does not want their name disclosed. Please be thoughtful with your responses, as these are usually tough to write. Email sloan@dev.to if you'd like to leave an anonymous comment or if you want to ask your own anonymous question.


Top comments (8)

Collapse
 
iamschulz profile image
Daniel Schulz

As usual: Depends on the project.

Smaller projects get global styles only. The whole page then gets constructed from more abstract components, like boxes, bars, layout modules, etc.

 styles/
├─ utility/
│  ├─ font-bold.css
│  ├─ underline.css
├─ typography.css
├─ colors.css
Enter fullscreen mode Exit fullscreen mode

I use sass as a preprocessor most of the time. That will handle the bundling and pack everything into a single CSS file.

In a larger, component-based codebases, I like to keep my styles as close to the associated HTML and JS, while still building upon global styles:

modal-component/
├─ html/
├─ js/
├─ css/
│  ├─ background.css
│  ├─ modal-container.css
global/
├─ styles/
│  ├─ utility/
│  │  ├─ font-bold.css
│  │  ├─ underline.css
│  ├─ typography.css
│  ├─ colors.css
Enter fullscreen mode Exit fullscreen mode

This will keep my track of CSS that is only used in their respective components (which is usually scoped to them) and global styling which affetcs the page as a whole, such as layouts, color management, base typography, and so on.
It also helps with code splitting. Global styles are loaded eagerly, components styles are loaded when needed.
It also also happens to work very well with single file components in Vue.

Very large projects may outgrow my workflow for global styles, but I usually know it when that's the case and it's usually not only my call to make at that point.

Collapse
 
ianbromwich profile image
Ian B • Edited

When not using react styled components I tend to try and use the 7-1 structure, or a generic atomic design structure (atoms, molecules, organisms, template, etc)

In the case of one of my current projects I'm following the existing structure, which is just whack everything in partials, regardless of what functionality they serve.

Collapse
 
thomasbnt profile image
Thomas Bnt • Edited

For a standard project :

├─ assets/
     ├─ js/
     ├─ css/
     │  ├─ main.css
     │  ├─ header.css
Enter fullscreen mode Exit fullscreen mode
Collapse
 
white__48f95e4bfe4 profile image
white ??? ???

<!DOCTYPE html>


Battle Royale 2D
<br> canvas {<br> border: 2px solid black;<br> }<br> body {<br> display: flex;<br> justify-content: center;<br> align-items: center;<br> height: 100vh;<br> margin: 0;<br> background: #333;<br> }<br>


<script>
    const canvas = document.getElementById('gameCanvas');
    const ctx = canvas.getContext('2d');

    // Player object
    const player = {
        x: 400,
        y: 300,
        radius: 15,
        color: '#00f',
        speed: 5,
        health: 100
    };

    // Game objects
    let bullets = [];
    let enemies = [];
    let score = 0;
    let gameArea = { x: 0, y: 0, width: 800, height: 600 };
    let shrinkTimer = 0;

    // Controls
    const keys = {
        w: false,
        a: false,
        s: false,
        d: false
    };

    // Event listeners
    document.addEventListener('keydown', (e) => {
        switch(e.key.toLowerCase()) {
            case 'w': keys.w = true; break;
            case 'a': keys.a = true; break;
            case 's': keys.s = true; break;
            case 'd': keys.d = true; break;
        }
    });

    document.addEventListener('keyup', (e) => {
        switch(e.key.toLowerCase()) {
            case 'w': keys.w = false; break;
            case 'a': keys.a = false; break;
            case 's': keys.s = false; break;
            case 'd': keys.d = false; break;
        }
    });

    canvas.addEventListener('click', shoot);

    // Game functions
    function movePlayer() {
        if(keys.w && player.y > gameArea.y) player.y -= player.speed;
        if(keys.a && player.x > gameArea.x) player.x -= player.speed;
        if(keys.s && player.y < gameArea.y + gameArea.height) player.y += player.speed;
        if(keys.d && player.x < gameArea.x + gameArea.width) player.x += player.speed;
    }

    function shoot(e) {
        const rect = canvas.getBoundingClientRect();
        const mouseX = e.clientX - rect.left;
        const mouseY = e.clientY - rect.top;

        const angle = Math.atan2(mouseY - player.y, mouseX - player.x);

        bullets.push({
            x: player.x,
            y: player.y,
            dx: Math.cos(angle) * 7,
            dy: Math.sin(angle) * 7,
            radius: 3
        });
    }

    function spawnEnemy() {
        enemies.push({
            x: Math.random() * gameArea.width,
            y: Math.random() * gameArea.height,
            radius: 12,
            color: '#f00',
            speed: 2
        });
    }

    function updateGame() {
        // Move player
        movePlayer();

        // Update bullets
        bullets.forEach((bullet, index) => {
            bullet.x += bullet.dx;
            bullet.y += bullet.dy;

            // Remove bullets out of bounds
            if(bullet.x < 0 || bullet.x > canvas.width || 
               bullet.y < 0 || bullet.y > canvas.height) {
                bullets.splice(index, 1);
            }
        });

        // Update enemies
        enemies.forEach((enemy, index) => {
            // Simple AI movement
            const dx = player.x - enemy.x;
            const dy = player.y - enemy.y;
            const distance = Math.sqrt(dx*dx + dy*dy);

            if(distance > 0) {
                enemy.x += dx/distance * enemy.speed;
                enemy.y += dy/distance * enemy.speed;
            }

            // Collision detection with player
            if(distance < player.radius + enemy.radius) {
                player.health -= 0.5;
            }
        });

        // Shrink game area over time
        shrinkTimer++;
        if(shrinkTimer % 500 === 0) {
            gameArea.x += 20;
            gameArea.y += 20;
            gameArea.width -= 40;
            gameArea.height -= 40;
        }

        // Spawn enemies periodically
        if(Math.random() < 0.03) {
            spawnEnemy();
        }
    }

    function draw() {
        // Clear canvas
        ctx.fillStyle = '#000';
        ctx.fillRect(0, 0, canvas.width, canvas.height);

        // Draw game area
        ctx.strokeStyle = '#0f0';
        ctx.lineWidth = 2;
        ctx.strokeRect(gameArea.x, gameArea.y, gameArea.width, gameArea.height);

        // Draw player
        ctx.beginPath();
        ctx.arc(player.x, player.y, player.radius, 0, Math.PI * 2);
        ctx.fillStyle = player.color;
        ctx.fill();
        ctx.closePath();

        // Draw bullets
        bullets.forEach(bullet => {
            ctx.beginPath();
            ctx.arc(bullet.x, bullet.y, bullet.radius, 0, Math.PI * 2);
            ctx.fillStyle = '#fff';
            ctx.fill();
            ctx.closePath();
        });

        // Draw enemies
        enemies.forEach(enemy => {
            ctx.beginPath();
            ctx.arc(enemy.x, enemy.y, enemy.radius, 0, Math.PI * 2);
            ctx.fillStyle = enemy.color;
            ctx.fill();
            ctx.closePath();
        });

        // Draw HUD
        ctx.fillStyle = '#fff';
        ctx.font = '20px Arial';
        ctx.fillText(`Health: ${Math.round(player.health)}`, 10, 30);
        ctx.fillText(`Score: ${score}`, 10, 60);

        // Game over condition
        if(player.health <= 0) {
            ctx.fillStyle = '#f00';
            ctx.font = '40px Arial';
            ctx.fillText('GAME OVER', canvas.width/2 - 100, canvas.height/2);
            return;
        }
    }

    // Game loop
    function gameLoop() {
        updateGame();
        draw();
        requestAnimationFrame(gameLoop);
    }

    // Start game
    gameLoop();
</script>



Kaha pust karu

Collapse
 
aleksanderwalczuk profile image
Alexander Walczuk

I use tailwind and Vue SFC. Moral - don't create CSS files, so you won't have to organise them :)

Collapse
 
corentinbettiol profile image
Corentin Bettiol • Edited

One ~small file per project. Few kB only during transfer, maybe a dozen kB uncompressed. See this file for an example.

Collapse
 
xowap profile image
Rémy 🤖

Vue SFC are the biggest game changer in that field for sure :)

Collapse
 
viet_nv profile image
Nguyen Van Viet

I use styled component, don't need to create css files. haha