Sådan opretter du bølgede former og mønstre i CSS PlatoBlockchain Data Intelligence. Lodret søgning. Ai.

Sådan opretter du bølgede former og mønstre i CSS

Bølgen er nok en af ​​de sværeste former at lave i CSS. Vi forsøger altid at tilnærme det med egenskaber som border-radius og masser af magiske tal, indtil vi får noget, der føles lidt tæt på. Og det er før vi overhovedet kommer ind i bølgede mønstre, som er sværere.

"SVG det!" kan du sige, og du har sikkert ret i, at det er en bedre vej at gå. Men vi vil se, at CSS kan lave flotte bølger, og koden til det behøver ikke at være helt tosset. Og gæt hvad? jeg har en online generator for at gøre det endnu mere trivielt!

Hvis du leger med generatoren, kan du se, at den CSS, den spytter ud, kun er to gradienter og en CSS-maske-egenskab - bare de to ting, og vi kan lave enhver form for bølgeform eller mønster. For ikke at nævne, at vi nemt kan kontrollere størrelsen og krumningen af ​​bølgerne, mens vi er i gang.

Nogle af værdierne kan se ud som "magiske tal” men der er faktisk logik bag dem, og vi vil dissekere koden og opdage alle hemmelighederne bag at skabe bølger.

Denne artikel er en opfølgning på en tidligere hvor jeg byggede alle mulige forskellige zig-zag, scoped, scalloped, og ja, bølgede grænser. Jeg anbefaler stærkt at tjekke denne artikel, da den bruger den samme teknik, som vi vil dække her, men mere detaljeret.

Matematikken bag bølger

Strengt taget er der ikke én magisk formel bag bølgede former. Enhver form med kurver, der går op og ned, kan kaldes en bølge, så vi vil ikke begrænse os til kompleks matematik. I stedet vil vi gengive en bølge ved hjælp af det grundlæggende i geometri.

Lad os starte med et simpelt eksempel med to cirkelformer:

Sådan opretter du bølgede former og mønstre i CSS

Vi har to cirkler med samme radius ved siden af ​​hinanden. Kan du se den røde streg? Det dækker den øverste halvdel af den første cirkel og den nederste halvdel af den anden. Forestil dig nu, at du tager den linje og gentager den.

En snoet rød streg i form af bølger.
Sådan opretter du bølgede former og mønstre i CSS

Vi ser allerede bølgen. Lad os nu udfylde den nederste del (eller den øverste) for at få følgende:

Rødt bølgemønster.
Sådan opretter du bølgede former og mønstre i CSS

Tada! Vi har en bølget form, og en som vi kan styre ved hjælp af en variabel for cirkelradierne. Dette er en af ​​de nemmeste bølger, vi kan lave, og det er den, jeg viste mig frem i this forrige artikel

Lad os tilføje lidt kompleksitet ved at tage den første illustration og flytte cirklerne lidt:

To grå cirkler med to halverende stiplede linjer, der angiver afstand.
Sådan opretter du bølgede former og mønstre i CSS

Vi har stadig to cirkler med samme radius, men de er ikke længere horisontalt justeret. I dette tilfælde dækker den røde linje ikke længere halvdelen af ​​arealet af hver cirkel, men et mindre område i stedet. Dette område er begrænset af den stiplede røde linje. Den linje krydser det punkt, hvor begge cirkler mødes.

Tag nu den linje og gentag den, og du får endnu en bølge, en glattere.

En rød snoet streg.
Sådan opretter du bølgede former og mønstre i CSS
Et rødt bølgemønster.
Sådan opretter du bølgede former og mønstre i CSS

Jeg tror, ​​du forstår ideen. Ved at kontrollere placeringen og størrelsen af ​​cirklerne kan vi skabe enhver bølge, vi ønsker. Vi kan endda oprette variabler for dem, som jeg vil kalde P , S, henholdsvis.

Sådan opretter du bølgede former og mønstre i CSS PlatoBlockchain Data Intelligence. Lodret søgning. Ai.
Sådan opretter du bølgede former og mønstre i CSS

Du har sikkert bemærket, at vi i online-generatoren styrer bølgen ved hjælp af to indgange. De er knyttet til ovenstående variabler. S er "Bølgens størrelse" og P er "bølgens krumning".

Jeg definerer P as P = m*S hvor m er den variabel, du justerer, når du opdaterer bølgens krumning. Dette giver os mulighed for altid at have den samme krumning, selvom vi opdaterer S.

m kan være en hvilken som helst værdi imellem 0 , 2. 0 vil give os det første særlige tilfælde, hvor begge cirkler er justeret vandret. 2 er en slags maksimumværdi. Vi kan blive større, men efter et par test fandt jeg ud af, at noget ovenfor 2 producerer dårlige, flade former.

Lad os ikke glemme radius af vores cirkel! Det kan også defineres vha S , P sådan her:

R = sqrt(P² + S²)/2

Hvornår P er lig med 0, vi vil have R = S/2.

Vi har alt for at begynde at konvertere alt dette til gradienter i CSS!

Oprettelse af gradienter

Vores bølger bruger cirkler, og når vi taler om cirkler, taler vi om radiale gradienter. Og da to cirkler definerer vores bølge, vil vi logisk bruge to radiale gradienter.

Vi starter med det konkrete tilfælde, hvor P er lig med 0. Her er illustrationen af ​​den første gradient:

Denne gradient skaber den første krumning, mens hele bundområdet fyldes ud - så at sige "vandet" af bølgen.

Sådan opretter du bølgede former og mønstre i CSS PlatoBlockchain Data Intelligence. Lodret søgning. Ai.
Sådan opretter du bølgede former og mønstre i CSS
.wave {
  --size: 50px;

  mask: radial-gradient(var(--size) at 50% 0%, #0000 99%, red 101%) 
    50% var(--size)/calc(4 * var(--size)) 100% repeat-x;
}

--size variabel definerer radius og størrelsen af ​​den radiale gradient. Hvis vi sammenligner det med S variabel, så er den lig med S/2.

Lad os nu tilføje den anden gradient:

Den anden gradient er intet andet end en cirkel for at fuldende vores bølge:

radial-gradient(var(--size) at 50% var(--size), blue 99%, #0000 101%) 
  calc(50% - 2*var(--size)) 0/calc(4 * var(--size)) 100%

Hvis du markerer den forrige artikel du vil se, at jeg blot gentager, hvad jeg allerede gjorde der.

Jeg fulgte begge artikler, men gradientkonfigurationerne er ikke de samme.

Det er fordi vi kan nå det samme resultat ved at bruge forskellige gradientkonfigurationer. Du vil bemærke en lille forskel i justeringen, hvis du sammenligner begge konfigurationer, men tricket er det samme. Dette kan være forvirrende, hvis du ikke er bekendt med gradienter, men bare rolig. Med lidt øvelse vænner du dig til dem, og du vil selv opdage, at forskellig syntaks kan føre til det samme resultat.

Her er den fulde kode til vores første bølge:

.wave {
  --size: 50px;

  mask:
    radial-gradient(var(--size) at 50% var(--size),#000 99%, #0000 101%) 
      calc(50% - 2*var(--size)) 0/calc(4 * var(--size)) 100%,
    radial-gradient(var(--size) at 50% 0px, #0000 99%, #000 101%) 
      50% var(--size)/calc(4 * var(--size)) 100% repeat-x;
}

Lad os nu tage denne kode og justere den til, hvor vi introducerer en variabel, der gør denne fuldt genbrugelig til at skabe enhver bølge, vi ønsker. Som vi så i det foregående afsnit, er hovedtricket at flytte cirklerne, så de ikke længere er justeret, så lad os opdatere hver enkelts position. Vi flytter den første op og den anden ned.

Vores kode vil se sådan ud:

.wave {
  --size: 50px;
  --p: 25px;

  mask:
    radial-gradient(var(--size) at 50% calc(var(--size) + var(--p)), #000 99%, #0000 101%) 
      calc(50% - 2*var(--size)) 0/calc(4 * var(--size)) 100%,
    radial-gradient(var(--size) at 50% calc(-1*var(--p)), #0000 99%, #000 101%) 
      50% var(--size) / calc(4 * var(--size)) 100% repeat-x;
}

Jeg har introduceret en ny --p variabel, der har brugt den til at definere midterpositionen af ​​hver cirkel. Den første gradient bruger 50% calc(-1*var(--p)), så dens centrum bevæger sig op, mens den anden bruger calc(var(--size) + var(--p)) at flytte den ned.

En demo er mere end tusind ord værd:

Cirklerne er hverken justeret eller rører hinanden. Vi placerede dem langt fra hinanden uden at ændre deres radier, så vi mistede vores bølge. Men vi kan rette op på tingene ved at bruge den samme matematik, som vi brugte tidligere til at beregne den nye radius. Huske på, at R = sqrt(P² + S²)/2. I vores tilfælde, --size er lig med S/2; det samme for --p som også er lig med P/2 da vi flytter begge cirkler. Så afstanden mellem deres midtpunkter er dobbelt så stor som værdien af --p for det:

R = sqrt(var(--size) * var(--size) + var(--p) * var(--p))

Det giver os et resultat af 55.9px.

Vores bølge er tilbage! Lad os sætte den ligning ind i vores CSS:

.wave {
  --size: 50px;
  --p: 25px;
  --R: sqrt(var(--p) * var(--p) + var(--size)*var(--size));

  mask:
    radial-gradient(var(--R) at 50% calc(var(--size) + var(--p)), #000 99%, #0000 101%) 
      calc(50% - 2*var(--size)) 0 / calc(4 * var(--size)) 100%,
    radial-gradient(var(--R) at 50% calc(-1*var(--p)), #0000 99%, #000 101%) 
      50% var(--size)/calc(4 * var(--size)) 100% repeat-x;
}

Dette er gyldig CSS-kode. sqrt() er en del af specifikationen, men på det tidspunkt, jeg skriver dette, er der ingen browserunderstøttelse for det. Det betyder, at vi har brug for et drys JavaScript eller Sass for at beregne denne værdi, indtil vi bliver bredere sqrt() Support.

Det her er fandeme fedt: alt der skal til er to gradienter for at få en cool bølge, som du kan anvende på ethvert element ved hjælp af mask ejendom. Ikke flere forsøg og fejl - alt hvad du behøver er at opdatere to variabler, og du er godt i gang!

Vende bølgen

Hvad hvis vi vil have bølgerne i den anden retning, hvor vi fylder "himlen" i stedet for "vandet". Tro det eller ej, alt hvad vi skal gøre er at opdatere to værdier:

.wave {
  --size: 50px;
  --p: 25px;
  --R: sqrt(var(--p) * var(--p) + var(--size) * var(--size));

  mask:
    radial-gradient(var(--R) at 50% calc(100% - (var(--size) + var(--p))), #000 99%, #0000 101%)
      calc(50% - 2 * var(--size)) 0/calc(4 * var(--size)) 100%,
    radial-gradient(var(--R) at 50% calc(100% + var(--p)), #0000 99%, #000 101%) 
      50% calc(100% - var(--size)) / calc(4 * var(--size)) 100% repeat-x;
}

Alt jeg gjorde der var at tilføje en offset lig med 100%, fremhævet ovenfor. Her er resultatet:

Vi kan overveje en mere venlig syntaks ved hjælp af søgeordsværdier for at gøre det endnu nemmere:

.wave {
  --size: 50px;
  --p: 25px;
  --R: sqrt(var(--p)*var(--p) + var(--size) * var(--size));

  mask:
    radial-gradient(var(--R) at left 50% bottom calc(var(--size) + var(--p)), #000 99%, #0000 101%) 
      calc(50% - 2 * var(--size)) 0/calc(4 * var(--size)) 100%,
    radial-gradient(var(--R) at left 50% bottom calc(-1 * var(--p)), #0000 99%, #000 101%) 
      left 50% bottom var(--size) / calc(4 * var(--size)) 100% repeat-x;
}

Vi bruger left , bottom nøgleord for at specificere siderne og forskydningen. Som standard er browseren standard til left , top - det er derfor, vi bruger 100% for at flytte elementet til bunden. I virkeligheden flytter vi det fra top by 100%, så det er egentlig det samme som at sige bottom. Meget nemmere at læse end matematik!

Med denne opdaterede syntaks er alt, hvad vi skal gøre, at bytte bottom forum top — eller omvendt — for at ændre bølgens retning.

Og hvis du vil have både top- og bundbølger, kombinerer vi alle gradienterne i en enkelt erklæring:

.wave {
  --size: 50px;
  --p: 25px;
  --R: sqrt(var(--p)*var(--p) + var(--size)*var(--size));

  mask:
    /* Gradient 1 */
    radial-gradient(var(--R) at left 50% bottom calc(var(--size) + var(--p)), #000 99%, #0000 101%) 
      left calc(50% - 2*var(--size)) bottom 0 / calc(4 * var(--size)) 51% repeat-x,
    /* Gradient 2 */
    radial-gradient(var(--R) at left 50% bottom calc(-1 * var(--p)), #0000 99%, #000 101%) 
      left 50% bottom var(--size) / calc(4 * var(--size)) calc(51% - var(--size)) repeat-x,
    /* Gradient 3 */
    radial-gradient(var(--R) at left 50% top calc(var(--size) + var(--p)), #000 99%, #0000 101%) 
      left calc(50% - 2 * var(--size)) top 0 / calc(4 * var(--size)) 51% repeat-x,
    /* Gradient 4 */
    radial-gradient(var(--R) at left 50% top calc(-1 * var(--p)), #0000 99%, #000 101%) 
      left 50% top var(--size) / calc(4 * var(--size)) calc(51% - var(--size)) repeat-x;
}

Hvis du tjekker koden, vil du se, at jeg udover at kombinere alle gradienterne også har reduceret deres højde fra 100% til 51% så de begge dækker halvdelen af ​​elementet. Ja, 51%. Vi har brug for den lille ekstra procent til et lille overlap, der undgår huller.

Hvad med venstre og højre side?

Det er dine lektier! Tag det, vi gjorde med top- og bundsiden, og prøv at opdatere værdierne for at få højre og venstre værdier. Bare rolig, det er nemt, og det eneste du skal gøre er at bytte værdier.

Hvis du har problemer, kan du altid bruge online-generatoren for at tjekke koden og visualisere resultatet.

Bølgede linjer

Tidligere lavede vi vores første bølge ved hjælp af en rød linje og fyldte derefter den nederste del af elementet. Hvad med den bølgede linje? Det er også en bølge! Endnu bedre er det, hvis vi kan kontrollere dens tykkelse med en variabel, så vi kan genbruge den. Lad os gøre det!

Vi vil ikke starte fra bunden, men snarere tage den tidligere kode og opdatere den. Den første ting at gøre er at opdatere farvestoppene for gradienterne. Begge gradienter starter fra en gennemsigtig farve til en uigennemsigtig farve eller omvendt. For at simulere en linje eller kant skal vi starte fra gennemsigtig, gå til uigennemsigtig og derefter tilbage til gennemsigtig igen:

#0000 calc(99% - var(--b)), #000 calc(101% - var(--b)) 99%, #0000 101%

Jeg tror, ​​du allerede har gættet, at --b variabel er det, vi bruger til at kontrollere linjetykkelsen. Lad os anvende dette på vores gradienter:

Ja, resultatet er langt fra en bølget linje. Men ser vi nærmere, kan vi se, at en gradient korrekt skaber den nederste krumning. Så alt, hvad vi virkelig skal gøre, er at rette op på den anden gradient. I stedet for at holde en hel cirkel, lad os lave en delvis gradient som den anden.

Stadig langt, men vi har begge krumninger, vi skal bruge! Hvis du tjekker koden, vil du se, at vi har to identiske gradienter. Den eneste forskel er deres placering:

.wave {
  --size: 50px;
  --b: 10px;
  --p: 25px;
  --R: sqrt(var(--p)*var(--p) + var(--size)*var(--size));

  --_g: #0000 calc(99% - var(--b)), #000 calc(101% - var(--b)) 99%, #0000 101%;
  mask:
    radial-gradient(var(--R) at left 50% bottom calc(-1*var(--p)), var(--_g)) 
      calc(50% - 2*var(--size)) 0/calc(4*var(--size)) 100%,
    radial-gradient(var(--R) at left 50% top    calc(-1*var(--p)), var(--_g)) 
      50% var(--size)/calc(4*var(--size)) 100%;
}

Nu skal vi justere størrelsen og positionen til den endelige form. Vi har ikke længere brug for, at gradienten er i fuld højde, så vi kan erstatte 100% med dette:

/* Size plus thickness */
calc(var(--size) + var(--b))

Der er ingen matematisk logik bag denne værdi. Den skal kun være stor nok til krumningen. Vi vil se dets effekt på mønsteret om lidt. Lad os i mellemtiden også opdatere positionen for at centrere gradienterne lodret:

.wave {
  --size: 50px;
  --b: 10px;
  --p: 25px;
  --R: sqrt(var(--p)*var(--p) + var(--size)*var(--size));

  --_g: #0000 calc(99% - var(--b)), #000 calc(101% - var(--b)) 99%, #0000 101%;  
  mask:
    radial-gradient(var(--R) at left 50% bottom calc(-1*var(--p)), var(--_g)) 
      calc(50% - 2*var(--size)) 50%/calc(4 * var(--size)) calc(var(--size) + var(--b)) no-repeat,
    radial-gradient(var(--R) at left 50% top calc(-1 * var(--p)), var(--_g)) 50%
      50%/calc(4 * var(--size)) calc(var(--size) + var(--b)) no-repeat;
}

Stadig ikke helt der:

Den ene gradient skal bevæge sig lidt ned og den anden lidt op. Begge skal bevæge sig med halvdelen af ​​deres højde.

Vi er der næsten! Vi har brug for en lille fix for at radiussen skal have et perfekt overlap. Begge linjer skal forskydes med halvdelen af ​​grænsen (--b) tykkelse:

Vi har det! En perfekt bølget linje, som vi nemt kan justere ved at kontrollere et par variable:

.wave {
  --size: 50px;
  --b: 10px;
  --p: 25px;
  --R: calc(sqrt(var(--p) * var(--p) + var(--size) * var(--size)) + var(--b) / 2);

  --_g: #0000 calc(99% - var(--b)), #000 calc(101% - var(--b)) 99%, #0000 101%;
  mask:
    radial-gradient(var(--R) at left 50% bottom calc(-1 * var(--p)), var(--_g)) 
     calc(50% - 2*var(--size)) calc(50% - var(--size)/2 - var(--b)/2) / calc(4 * var(--size)) calc(var(--size) + var(--b)) repeat-x,
    radial-gradient(var(--R) at left 50% top calc(-1*var(--p)),var(--_g)) 
     50%  calc(50% + var(--size)/2 + var(--b)/2) / calc(4 * var(--size)) calc(var(--size) + var(--b)) repeat-x;
}

Jeg ved, at det tager lidt at forstå logikken. Det er fint, og som sagt er det ikke let at skabe en bølget form i CSS, for ikke at nævne den vanskelige matematik bag det. Det er derfor online generator er en livredder — du kan nemt få den endelige kode, selvom du ikke helt forstår logikken bag den.

Bølgede mønstre

Vi kan lave et mønster fra den bølgede linje, vi lige har lavet!

Åh nej, koden til mønsteret bliver endnu sværere at forstå!

Slet ikke! Vi har allerede koden. Alt vi skal gøre er at fjerne repeat-x fra hvad vi allerede har, og tada. 🎉

Et flot bølgemønster. Kan du huske den ligning, jeg sagde, vi ville gense?

/* Size plus thickness */
calc(var(--size) + var(--b))

Nå, det er det, der styrer afstanden mellem linjerne i mønsteret. Vi kan lave en variabel ud af det, men der er ikke behov for mere kompleksitet. Jeg bruger ikke engang en variabel til det i generatoren. Måske ændrer jeg det senere.

Her er det samme mønster, der går i en anden retning:

Jeg giver dig koden i den demo, men jeg vil gerne have dig til at dissekere den og forstå, hvilke ændringer jeg har foretaget for at få det til at ske.

Forenkling af koden

I alle de tidligere demoer definerer vi altid --size , --p selvstændigt. Men kan du huske, hvordan jeg tidligere nævnte, at online-generatoren evaluerer P som lig med m*SHvor m styrer bølgens krumning? Ved at definere en fast multiplikator kan vi arbejde med én bestemt bølge, og koden kan blive lettere. Dette er, hvad vi har brug for i de fleste tilfælde: en specifik bølget form og en variabel til at kontrollere dens størrelse.

Lad os opdatere vores kode og introducere m variabel:

.wave {
  --size: 50px;
  --R: calc(var(--size) * sqrt(var(--m) * var(--m) + 1));

  mask:
    radial-gradient(var(--R) at 50% calc(var(--size) * (1 + var(--m))), #000 99%, #0000 101%) 
      calc(50% - 2*var(--size)) 0/calc(4 * var(--size)) 100%,
    radial-gradient(var(--R) at 50% calc(-1 * var(--size) * var(--m)), #0000 99%, #000 101%) 
      50% var(--size) / calc(4 * var(--size)) 100% repeat-x;
  }

Som du kan se, har vi ikke længere brug for --p variabel. Jeg erstattede den med var(--m)*var(--size), og optimeret noget af matematikken i overensstemmelse hermed. Nu, hvis vi ønsker at arbejde med en bestemt bølget form, kan vi udelade --m variabel og erstatte den med en fast værdi. Lad os prøve .8 for eksempel.

--size: 50px;
--R: calc(var(--size) * 1.28);

mask:
  radial-gradient(var(--R) at 50% calc(1.8 * var(--size)), #000 99%, #0000 101%) 
    calc(50% - 2*var(--size)) 0/calc(4 * var(--size)) 100%,
  radial-gradient(var(--R) at 50% calc(-.8 * var(--size)), #0000 99%, #000 101%) 
    50% var(--size) / calc(4 * var(--size)) 100% repeat-x;

Se, hvordan koden er nemmere nu? Kun én variabel til at styre din bølge, plus du ikke længere behøver at stole på sqrt() som ikke har nogen browserunderstøttelse!

Du kan anvende den samme logik på alle de demoer, vi så, selv for de bølgede linjer og mønstret. Jeg startede med en detaljeret matematisk forklaring og gav den generiske kode, men du kan opleve, at du har brug for nemmere kode i et rigtigt tilfælde. Det er det, jeg gør hele tiden. Jeg bruger sjældent den generiske kode, men jeg overvejer altid en forenklet version, især fordi jeg i de fleste tilfælde bruger nogle kendte værdier, der ikke behøver at blive gemt som variable. (Spoiler alarm: Jeg vil dele et par eksempler til sidst!)

Begrænsninger for denne tilgang

Matematisk burde den kode, vi lavede, give os perfekte bølgede former og mønstre, men i virkeligheden vil vi stå over for nogle mærkelige resultater. Så ja, denne metode har sine begrænsninger. For eksempel er online-generatoren i stand til at producere dårlige resultater, især med bølgede linjer. En del af problemet skyldes en bestemt kombination af værdier, hvor resultatet bliver forvrænget, som at bruge en stor værdi for kanttykkelsen sammenlignet med størrelsen:

Sådan opretter du bølgede former og mønstre i CSS PlatoBlockchain Data Intelligence. Lodret søgning. Ai.
Sådan opretter du bølgede former og mønstre i CSS

For de andre tilfælde er det problemet relateret til en eller anden afrunding, der vil resultere i fejljustering og mellemrum mellem bølgerne:

Sådan opretter du bølgede former og mønstre i CSS PlatoBlockchain Data Intelligence. Lodret søgning. Ai.
Sådan opretter du bølgede former og mønstre i CSS

Når det er sagt, synes jeg stadig, at den metode, vi dækkede, forbliver en god, fordi den producerer jævne bølger i de fleste tilfælde, og vi kan nemt undgå de dårlige resultater ved at spille med forskellige værdier, indtil vi får den perfekt.

Indpakning op

Jeg håber, at du efter denne artikel ikke længere vil fumle rundt med trial and error for at bygge en bølget form eller et mønster. Ud over til online-generatoren, du har alle de matematiske hemmeligheder bag at skabe enhver form for bølge, du ønsker!

Artiklen slutter her, men nu har du et kraftfuldt værktøj til at skabe smarte designs, der bruger bølgede former. Her er inspiration til at komme i gang...

Hvad med dig? Brug min online generator (eller skriv koden manuelt, hvis du allerede har lært al matematikken udenad) og vis mig dine kreationer! Lad os få en god samling i kommentarfeltet.

Tidsstempel:

Mere fra CSS-tricks