Jump to content

Title: CSS appears as raw text inside HTML section – possibly triggered by PHP foreach?


Recommended Posts

Hi everyone 👋

I'm running into a strange issue where my CSS styles are being displayed as raw text inside a specific <section> on my site, rather than being properly applied. The affected area is my "Latest News" section, which pulls content dynamically using a PHP foreach loop.

Here’s what’s going on:

My project structure uses index.php, which includes /inc/main.php.

In main.php, I have the section:

<section id="latest-news">
  <h2>Latest News</h2>
  <div class="news-thumbnails">
    <?php foreach (hentNyheter() as $nyhet): ?>
      <!-- news card markup -->
    <?php endforeach; ?>
  </div>
</section>
 

The function hentNyheter() is defined in /db/db.php and returns rows from the news table in MySQL.

Each row has columns like id, title, summary, image, published_at.

Problem: Instead of rendering styled cards, the CSS itself is being printed as raw text inside the .news-thumbnails area on the front page – almost as if a CSS file was pasted into the page as content. It's appearing in a vertical column inside the section.

Things I've confirmed:

CSS is loaded via proper <link href="/css/styles.css" rel="stylesheet"> in <head>.

I'm not using .css.php files anymore.

There is no accidental echo or misplaced <style> inside the HTML section.

All variable names used (like $nyhet['title'], $nyhet['summary'], etc.) match the database columns.

Function h() is used to escape HTML properly:

function h(?string $v): string {
    return htmlspecialchars((string)$v, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8');
}

-------
Here is the databasetable:
 

-- MySQL dump 10.13  Distrib 8.0.42, for Win64 (x86_64)
--
-- Host: sql11.hmg9.webhuset.no    Database: 204088_matsnakk
-- ------------------------------------------------------
-- Server version    8.0.36

/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!50503 SET NAMES utf8 */;
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
/*!40103 SET TIME_ZONE='+00:00' */;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;

--
-- Table structure for table `news`
--

DROP TABLE IF EXISTS `news`;
/*!40101 SET @saved_cs_client     = @@character_set_client */;
/*!50503 SET character_set_client = utf8mb4 */;
CREATE TABLE `news` (
  `id` int NOT NULL AUTO_INCREMENT,
  `title` varchar(200) COLLATE utf8mb4_unicode_ci NOT NULL,
  `slug` varchar(220) COLLATE utf8mb4_unicode_ci NOT NULL,
  `summary` text COLLATE utf8mb4_unicode_ci,
  `content` mediumtext COLLATE utf8mb4_unicode_ci,
  `image` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
  `published_at` datetime DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`),
  UNIQUE KEY `slug` (`slug`),
  KEY `published_at` (`published_at`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
/*!40101 SET character_set_client = @saved_cs_client */;

--
-- Dumping data for table `news`
--

LOCK TABLES `news` WRITE;
/*!40000 ALTER TABLE `news` DISABLE KEYS */;
INSERT INTO `news` VALUES (1,'Norsk eplesesong i gang','norsk-eplesesong','Slik bruker du epler i alt fra salater til kaker.','Langt nyhetsinnhold...','news1.jpg','2025-08-06 08:04:35'),(2,'Trend: Fermentering hjemme','fermentering-hjemme','Kimchi og kombucha er i vinden.','Langt nyhetsinnhold...','news2.jpg','2025-08-04 08:04:35');
/*!40000 ALTER TABLE `news` ENABLE KEYS */;
UNLOCK TABLES;
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;

/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;

-- Dump completed on 2025-08-06 18:09:21
-----------------------------------------------

Here is the db.ph database connection:
 

<?php
// /db/db.php
declare(strict_types=1);

$configFile = __DIR__ . '/config.php';
if (is_file($configFile)) {
    require_once $configFile;
} else {
    // Fallback til miljøvariabler eller feilmelding
    define('DB_HOST', getenv('DB_HOST') ?: '');
    define('DB_NAME', getenv('DB_NAME') ?: '');
    define('DB_USER', getenv('DB_USER') ?: '');
    define('DB_PASS', getenv('DB_PASS') ?: '');
    define('DB_CHARSET', 'utf8mb4');
    if (!getenv('DB_HOST')) {
        die('Mangler /db/config.php. Kjør installasjonen via /install.php.');
    }
}

function db(): PDO {
    static $pdo = null;
    if ($pdo instanceof PDO) return $pdo;

    $dsn = 'mysql:host=' . DB_HOST . ';dbname=' . DB_NAME . ';charset=' . DB_CHARSET;
    $options = [
        PDO::ATTR_ERRMODE            => PDO::ERRMODE_EXCEPTION,
        PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
        PDO::ATTR_EMULATE_PREPARES   => false,
        PDO::MYSQL_ATTR_INIT_COMMAND => "SET sql_mode='STRICT_ALL_TABLES'",
    ];

    try {
        $pdo = new PDO($dsn, DB_USER, DB_PASS, $options);
    } catch (PDOException $e) {
        die('Databasefeil: ' . h($e->getMessage()));
    }

    return $pdo;
}

function hentNyheter(int $limit = 6): array {
    $pdo = db();
    $stmt = $pdo->prepare("SELECT id, title, summary, image, published_at FROM news ORDER BY published_at DESC LIMIT :limit");
    $stmt->bindValue(':limit', $limit, PDO::PARAM_INT);
    $stmt->execute();
    return $stmt->fetchAll();
}

function h(?string $v): string {
    return htmlspecialchars((string)$v, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8');
}



------

My suspicion is that either:

Something is going wrong in how the loop outputs data (possibly empty or malformed values).

I'm accidentally printing something unexpected into the HTML (like a full CSS string from the database?)

Or perhaps h() is escaping CSS markup that was accidentally inserted into the wrong database column?

Has anyone experienced this behavior before, where CSS appears in-page like raw text rather than being interpreted?

Let me know if you'd like to see the full files — I can post excerpts from index.php, main.php, and db.php.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.