/ Gists

Gists

On gists

Css animated border with css @property instead of css variable

CSS trick

example.css #

/*
@source: https://www.youtube.com/watch?v=ezP4kbOvs_E
@demo: https://jsbin.com/rixenodiga/3/edit?html,css,output
*/

body {
  background: #000;
}


@property --angle {
  syntax: "<angle>";
  initial-value: 0deg;
  inherits: false;
}

.card {
  
  /* nefunguje pro animaci, nahradi se  @property */
  /*
    --angle: 0deg
  */
  
  width: 300px;
  height: 300px;
  background: #000;
  border-radius: 10px;
  margin: 3rem;
  position: relative;
}

.card::after,
.card::before 
{
  content: "";
  position: absolute;
  z-index: -1;
  width: 100%;
  height: 100%;
  border-radius: 10px;
  
  /* vice barev */
   background-image: conic-gradient(from var(--angle), red, blue, pink, orange, lime); 

  /* jedna a do ztracena */
  /*background-image: conic-gradient(from var(--angle), transparent 80%, red); */ /* velikost definuje rozsah*/
  
  padding: 3px;
  top: 50%;
  left: 50%;
  translate: -50% -50%;

  animation: 3s spin linear infinite;

}

.card::before {
  filter: blur(1.5rem);
  opacity: 0.7;
}


@keyframes spin {
  from {
    --angle: 0deg;
  }
  
  to {
    --angle: 360deg;
  }
}

On gists

Position absolute + flex + pointer events

CSS CSS trick

index.html #

<!-- https://play.tailwindcss.com/FMLNwmWBhB -->
<!--
  1. flex funguje i pro absolutně napozicované prvky :)
  2. pointer-event: none umožní přes lupu se prokliknout na input
-->
<div class="border border-gray-300 m-5 relative flex items-center">
    <span class="bg-red-500 w-4 h-4 absolute pointer-events-none"></span>
  <input type="text" class="bg-gray-100 p-2 w-full block">
</div>

On gists

css grid - values

CSS

grid-values.css #

// https://www.vzhurudolu.cz/prirucka/css-minmax

minmax(100px, 200px)   - bude 200px, lze zmenšovat pod 100px
minmax(100px, max-content) - minimálně 100px, zvětšovat se to bude podle obsahu (obrázek = maximální pixelová věc, podle délky textu)
minmax(min-content, 100px) - bude hned 100px a v případě dlouhého obsahu bude délka nejdelšího slova (u obrázků nic takového nemáme / neznáme)
fit-content(100px) - dle obsahu s maximální šířkou 100px
~ lze použít i samostatně mimo fci minmax
min-content
max-content
auto

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

Popular ⭐ 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."