/ Gists

Gists

On gists

Text overflowing (line & multiline)

CSS CSS trick

how.css #

/* CSS for Text Overflow in One Line */
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;


/* Displaying Multiline Text with Overflow */
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 3;
overflow: hidden;

On gists

CSS View function

CSS CSS trick

demo.txt #

https://jsbin.com/jegerowode/edit?html,output

On gists

Stacking context

CSS CSS trick

info.txt #

/* NEVYTVÁŘÍ stacking context */
.div1 {
  position: relative;
}

/* VYTVÁŘÍ stacking context */
.div2 {
  position: relative;
  z-index: 0;  /* nebo jakákoliv jiná hodnota */
}

/* VYTVÁŘÍ stacking context */
.div3 {
  isolation: isolate;
}

Tady je kompletní seznam, co vytváří stacking context:
------------------------------------------------------
Root element (<html>)
position: fixed nebo sticky
position: relative/absolute + jakýkoliv z-index kromě auto
Element s opacity < 1
Element s transform, filter, backdrop-filter
Element s isolation: isolate
mix-blend-mode jiné než normal
perspective hodnota jiná než none
contain s hodnotou layout, paint nebo strict
-webkit-overflow-scrolling: touch

On gists

Generated columns (Virtual/Stored)

MySql MySql tricks MySql - advanced

examples.sql #

-- Základní matematické operace
amount DECIMAL(10,2) GENERATED ALWAYS AS (quantity * price) STORED

-- Práce s textem
full_name VARCHAR(100) GENERATED ALWAYS AS (CONCAT(first_name, ' ', last_name)) VIRTUAL

-- Použití CASE
status_description VARCHAR(50) GENERATED ALWAYS AS (
    CASE 
        WHEN status = 1 THEN 'Active'
        WHEN status = 0 THEN 'Inactive'
        ELSE 'Unknown'
    END
) VIRTUAL

-- Práce s datumy
age INT GENERATED ALWAYS AS (TIMESTAMPDIFF(YEAR, birth_date, CURRENT_DATE)) VIRTUAL

-- Komplexnější výpočty
total_with_tax DECIMAL(10,2) GENERATED ALWAYS AS (
    CASE
        WHEN tax_rate IS NULL THEN amount
        ELSE amount * (1 + tax_rate/100)
    END
) STORED

-- Formátování a manipulace s textem
formatted_phone VARCHAR(20) GENERATED ALWAYS AS (
    CONCAT('+420 ', SUBSTR(phone, 1, 3), ' ', SUBSTR(phone, 4, 3), ' ', SUBSTR(phone, 7))
) VIRTUAL




On gists

Column check constraint

MySql MySql tricks MySql - advanced

examples.sql #

-- CONSTRAINT [constraint_name] CHECK (expression) [ENFORCED | NOT ENFORCED]

/*
ENFORCED - MySQL aktivně kontroluje podmínku při INSERT/UPDATE
NOT ENFORCED - MySQL podmínku nekontroluje, slouží jen jako dokumentace/metadata
*/

-- Kontrola formátu emailu pomocí REGEXP
CONSTRAINT valid_email CHECK (email REGEXP '^[A-Z0-9._%-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$')

-- Kontrola, že koncová data je později než počáteční
CONSTRAINT valid_date_range CHECK (end_date > start_date)

-- Kontrola že sloupec obsahuje pouze velká písmena
CONSTRAINT uppercase_only CHECK (column_name = UPPER(column_name))

-- Kontrola že věk je v rozumném rozsahu
CONSTRAINT valid_age CHECK (age >= 0 AND age < 150)

-- Kombinace více podmínek pro plat
CONSTRAINT salary_rules CHECK (
    (role = 'Junior' AND salary BETWEEN 30000 AND 50000) OR
    (role = 'Senior' AND salary BETWEEN 60000 AND 120000)
)

-- Kontrola že skóre je buď NULL nebo v rozsahu 0-100
CONSTRAINT valid_score CHECK (score IS NULL OR (score >= 0 AND score <= 100))

-- Kontrola že status je jedna z povolených hodnot
CONSTRAINT valid_status CHECK (
    status IN ('pending', 'approved', 'rejected', 'on_hold')
)

-- Komplexní validace telefonního čísla
CONSTRAINT valid_phone CHECK (
    phone_number REGEXP '^\\+?[1-9][0-9]{7,14}$'
)

-- Kontrola že discount je menší než cena
CONSTRAINT valid_discount CHECK (discount < price)

-- Kontrola že součet procentuálních hodnot nepřesáhne 100
CONSTRAINT percentage_sum CHECK (
    value1 + value2 + value3 <= 100
)


-- Komplexní kontrola hesla (minimální délka, musí obsahovat číslo a velké písmeno)
CONSTRAINT password_strength CHECK (
    LENGTH(password) >= 8 
    AND password REGEXP '[0-9]'
    AND password REGEXP '[A-Z]'
    AND password != username
)

-- Kontrola věku na základě data narození s aktuálním datem
CONSTRAINT valid_birth_date CHECK (
    YEAR(birth_date) >= 1900
    AND birth_date <= CURRENT_DATE
    AND TIMESTAMPDIFF(YEAR, birth_date, CURRENT_DATE) <= 120
)

-- Složitá business logika s CASE
CONSTRAINT complex_pricing CHECK (
    CASE 
        WHEN customer_type = 'VIP' THEN price >= 1000 AND discount <= price * 0.3
        WHEN customer_type = 'Regular' THEN price >= 500 AND discount <= price * 0.1
        WHEN customer_type = 'New' THEN price >= 100 AND discount = 0
        ELSE price >= 0
    END
)

-- Kombinace podmínek pro rezervační systém
CONSTRAINT valid_reservation CHECK (
    (status = 'confirmed' AND payment_id IS NOT NULL AND amount > 0)
    OR (status = 'pending' AND (payment_id IS NULL OR amount = 0))
    OR (status = 'cancelled' AND cancellation_reason IS NOT NULL)
)

-- Kontrola formátu a validity dat
CONSTRAINT valid_document CHECK (
    (doc_type = 'invoice' AND doc_number REGEXP '^INV-[0-9]{6}$')
    OR (doc_type = 'order' AND doc_number REGEXP '^ORD-[0-9]{6}$')
    AND issue_date <= due_date
    AND YEAR(issue_date) >= 2020
)

-- Kontrola závislostí mezi více sloupci
CONSTRAINT project_status_rules CHECK (
    (status = 'completed' AND end_date IS NOT NULL AND progress = 100)
    OR (status = 'in_progress' AND end_date IS NULL AND progress BETWEEN 1 AND 99)
    OR (status = 'planned' AND end_date IS NULL AND progress = 0)
)

-- Sezónní ceník s různými pravidly
CONSTRAINT seasonal_pricing CHECK (
    CASE 
        WHEN MONTH(booking_date) IN (6,7,8) THEN price >= 1000  -- Letní sezóna
        WHEN MONTH(booking_date) IN (12,1,2) THEN price >= 800  -- Zimní sezóna
        WHEN DAYOFWEEK(booking_date) IN (1,7) THEN price >= 700 -- Víkendy
        ELSE price >= 500  -- Mimo sezónu
    END
)

-- Validace adresy
CONSTRAINT valid_address CHECK (
    LENGTH(street) >= 3
    AND LENGTH(city) >= 2
    AND postal_code REGEXP '^[0-9]{5}$'
    AND (
        country = 'CZ' AND phone REGEXP '^\\+420[0-9]{9}$'
        OR 
        country = 'SK' AND phone REGEXP '^\\+421[0-9]{9}$'
    )
)

-- Komplexní kontrola produktu
CONSTRAINT product_rules CHECK (
    CASE product_type
        WHEN 'physical' THEN 
            weight > 0 
            AND dimensions IS NOT NULL 
            AND digital_url IS NULL
        WHEN 'digital' THEN 
            weight = 0 
            AND dimensions IS NULL 
            AND digital_url IS NOT NULL
        WHEN 'service' THEN 
            weight = 0 
            AND dimensions IS NULL 
            AND duration > 0
    END
    AND (
        price > 0
        OR (price = 0 AND is_free_sample = TRUE)
    )
)

On gists

Grid instead of wrapper containers (edges)

Tailwind CSS CSS CSS trick

grid.css #

/* Kevin Powell 
https://codepen.io/kevinpowell/pen/ExrZrrw
(https://ryanmulligan.dev/blog/layout-breakouts/)
*/

.content-grid {
  --padding-inline: 1rem;
  --content-max-width: 900px;
  --breakout-max-width: 1200px;

  --breakout-size: calc(
    (var(--breakout-max-width) - var(--content-max-width)) / 2
  );

  display: grid;
  grid-template-columns:
    [full-width-start] minmax(var(--padding-inline), 1fr)
    [breakout-start] minmax(0, var(--breakout-size))
    [content-start] min(
      100% - (var(--padding-inline) * 2),
      var(--content-max-width)
    )
    [content-end]
    minmax(0, var(--breakout-size)) [breakout-end]
    minmax(var(--padding-inline), 1fr) [full-width-end];
}

.content-grid > :not(.breakout, .full-width),
.full-width > :not(.breakout, .full-width) {
  grid-column: content;
}

.content-grid > .breakout {
  grid-column: breakout;
}

.content-grid > .full-width {
  grid-column: full-width;

  display: grid;
  grid-template-columns: inherit;
}

img.full-width {
  width: 100%;
  max-height: 45vh;
  object-fit: cover;
}

:root {
  --color-scheme: dark;

  --font-family: system-ui;

  --fs-300: clamp(0.94rem, calc(0.92rem + 0.08vw), 0.98rem);
  --fs-400: clamp(1.13rem, calc(1.06rem + 0.33vw), 1.31rem);
  --fs-500: clamp(1.35rem, calc(1.21rem + 0.69vw), 1.75rem);
  --fs-600: clamp(1.62rem, calc(1.37rem + 1.24vw), 2.33rem);
  --fs-700: clamp(1.94rem, calc(1.54rem + 2.03vw), 3.11rem);
  --fs-800: clamp(2.33rem, calc(1.7rem + 3.15vw), 4.14rem);
  --fs-900: clamp(2.8rem, calc(1.85rem + 4.74vw), 5.52rem);

  --clr-primary-300: hsl(219, 76%, 55%);
  --clr-primary-400: hsl(219, 76%, 40%);
  --clr-primary-500: hsl(219, 76%, 25%);
  --clr-secondary-300: hsl(269, 75%, 55%);
  --clr-secondary-400: hsl(269, 75%, 40%);
  --clr-secondary-500: hsl(269, 75%, 25%);
  --clr-accent-200: hsl(358, 85%, 80%);
  --clr-accent-300: hsl(358, 72%, 65%);
  --clr-accent-400: hsl(358, 72%, 50%);
  --clr-accent-500: hsl(358, 72%, 35%);
}

*,
*::before,
*::after {
  box-sizing: border-box;
}

html {
  color-scheme: var(--color-scheme);
}

body {
  margin: 0;
  font-family: var(--font-family);
  font-size: var(--fs-400);
  line-height: 1.6;
}

h1,
h2,
h3,
h4,
h5,
h6,
p,
figure {
  margin: 0;
}

img {
  max-width: 100%;
  display: block;
}

.site-title {
  font-size: var(--fs-900);
  line-height: 1.05;
  text-transform: uppercase;
}

.section-title {
  font-size: var(--fs-800);
  line-height: 1.1;
}

.bg-primary {
  background: var(--clr-primary-500);
}

.visually-hidden {
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  height: 1px;
  overflow: hidden;
  position: absolute;
  white-space: nowrap;
  width: 1px;
}

.call-to-action {
  padding: 1rem;
  background: hsl(0 0% 100% / 0.15);
}

.wrapper {
  width: calc(100% - 3rem);
  max-width: 900px;
  margin-inline: auto;
}

.flow > * + * {
  margin-top: var(--flow-spacing, 1em);
}

.section-padding {
  padding-block: 2.5rem;
}

.primary-header {
  padding-block: 1rem;
  margin-block-end: 3rem;
  background: var(--clr-accent-200);
  color: var(--clr-primary-500);
}

.primary-header__layout {
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.logo {
  max-width: 250px;
}

nav ul {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: max(5vw, 1rem);
}

nav a {
  color: inherit;
  text-decoration: none;
}

nav a:hover,
nav a:focus {
  color: var(--clr-accent-500);
  text-decoration: underline;
}

.even-columns {
  display: flex;
  gap: 1rem;
}

On gists

Regexp - "v" modifier multilang chars

JavaScript

regex.js #

const nameRegex = /^\p{Letter}+$/v;

function validateName(name) {
  if (nameRegex.test(name)) {
    console.log(`${name} is a valid name.`);
  } else {
    console.log(`${name} contains invalid characters.`);
  }
}

validateName("John"); // "John is a valid name."
validateName("María"); // "María is a valid name."
validateName("佐藤"); // "佐藤 is a valid name."
validateName("John123"); // "John123 contains invalid characters."

On gists

SVG Circle + TW + animation

Tailwind CSS HTML SVG

index.html #


<!--
https://play.tailwindcss.com/B8YFBxQAJO
-->

<div class="group relative flex h-[10em] w-[10em] items-center justify-center rounded-[1.5em] px-[0.5rem] pt-[1rem]">
  <svg class="absolute left-1/2 top-[calc(50%+8px)] h-[9rem] w-[9rem] -translate-x-1/2 -translate-y-1/2" viewBox="0 0 160 160" fill="none" height="160" width="160" xmlns="http://www.w3.org/2000/svg">
    <path d="M130.912 130.912a71.997 71.997 0 0 0-10.911-110.778A71.999 71.999 0 0 0 9.383 94.046a72.004 72.004 0 0 0 19.705 36.866" stroke-width="16" stroke-linecap="round" stroke="#EEDC82"></path>
    <path d="M146.65 52.764A72.004 72.004 0 0 0 69.647 8.748a71.998 71.998 0 0 0-40.559 122.164" class="duration-[1s] [stroke-dasharray:100] [stroke-dashoffset:-99] group-hover:[stroke-dashoffset:0]" pathLength="100" stroke-width="16" stroke-linecap="round" stroke="#B49A18"></path>
  </svg>
  <p class="text-[0.75rem] font-semibold">1729/2500 Steps</p>
</div>

On gists

Usefull detach handler

JavaScript

detach.js #

/*
https://javascript.plainenglish.io/7-infamous-javascript-bugs-that-shook-the-internet-3cf8f8f76098
*/

// Proper event listener cleanup to prevent memory leaks
function attachEvent() {
  const btn = document.querySelector("#myButton");
  const handleClick = () => console.log("Button clicked!");
  btn.addEventListener("click", handleClick);

  // Return a function to remove the listener and free up memory
  return () => btn.removeEventListener("click", handleClick);
}
const detach = attachEvent();
detach(); // Cleanup resources

On gists

Closure modifier

PHP

example.php #

<?php
//  TransportListResolver
	public function getList(Order\Order $order, ?\Closure $transportListResolverModifier = null): array
	{
		$orderItems = $order->getItems($order::ITEM_PRODUCT);

		$transportListResolver = $this->transport->getTransportSelectionResolver()
			->getBaseSelection()
			->setCountry($order->delivery__country_id)
			->setUserGroups($this->user->isLoggedIn() ? $this->user->getRoles() : NULL)
			->setWeight($order->getUniqueWeights())
			->setOnlyForProduct($this->transport->listTransportOnlyForProduct($orderItems))
			->setDistance(isset($order->distance) ? $order->distance : null);

		if ($transportListResolverModifier) {
			$transportListResolverModifier($transportListResolver);
		}

		$list = array_filter(
            $transportListResolver->toArray(),
            fn($transport) => !$transport->transport_carrier->mandatory_type_choice
				|| $this->transportTypeChoice->listTransportChoiceOnlyForProduct($transport->id, $orderItems)
				|| $this->transportTypeChoice->listTransportChoiceOnlyForProduct($transport->id, $orderItems) === null
			);

		return $list;
	}
	


// usage in another class
// we can modify object via closure
$transportList = $this->transportListResolver->getList($order, function (TransportEshopOrderSelectionResolver $transportListResolver) {
			$transportListResolver->setWithChoiceNeeded(true);
	});